[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: I may get punked for this ..
- To: misc_(_at_)_openbsd_(_dot_)_org
- Subject: Re: I may get punked for this ..
- From: Claudio Jeker <cjeker_(_at_)_diehard_(_dot_)_n-r-g_(_dot_)_com>
- Date: Fri, 20 Aug 2004 18:04:22 +0200
- Mail-followup-to: Claudio Jeker <cjeker_(_at_)_diehard_(_dot_)_n-r-g_(_dot_)_com>, misc_(_at_)_openbsd_(_dot_)_org
On Fri, Aug 20, 2004 at 04:38:35PM +0200, Henning Brauer wrote:
> * Per Engelbrecht <per_(_at_)_xterm_(_dot_)_dk> [2004-08-20 16:32]:
...
> > > One bug that remains: prepend-self works the wrong way, prepending
> > > on updates received, rather than on updates sent to (eBGP) peers;
> > > that's usually not what one wants.
> > No, it's not. I'm sure Henning will have it fixed sometime soon.
>
> actually, claudio is fixing it as we speak.
> It is not really a bug, it is a little unexpected semantic. but we are
> doing soem changes to have this work like expected.
>
And here is the patch to fix this. Please test and report if this fixes
your problem. This also adds the possibility to prepend AS pathes with the
remote neighbor-as.
--
:wq Claudio
Index: bgpd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.conf.5,v
retrieving revision 1.36
diff -u -p -r1.36 bgpd.conf.5
--- bgpd.conf.5 19 Aug 2004 16:12:31 -0000 1.36
+++ bgpd.conf.5 20 Aug 2004 12:12:41 -0000
@@ -812,6 +812,12 @@ Add the prefix in the update to the spec
radix table, regardless of whether or not the path was selected for routing.
This option may be useful in building realtime blacklists.
.Pp
+.It Ic prepend-neighbor Ar number
+Prepend the remote neighbor AS
+.Ar number
+times to the
+.Em AS path .
+.Pp
.It Ic prepend-self Ar number
Prepend the local AS
.Ar number
Index: bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.140
diff -u -p -r1.140 bgpd.h
--- bgpd.h 10 Aug 2004 13:02:07 -0000 1.140
+++ bgpd.h 20 Aug 2004 14:25:19 -0000
@@ -158,15 +158,16 @@ enum enforce_as {
struct filter_set {
u_int16_t flags;
+ u_int8_t prepend_self;
+ u_int8_t prepend_peer;
u_int32_t localpref;
u_int32_t med;
struct bgpd_addr nexthop;
- u_int8_t prepend;
- char pftable[PFTABLE_LEN];
struct {
int as;
int type;
} community;
+ char pftable[PFTABLE_LEN];
};
enum auth_method {
@@ -452,7 +453,9 @@ enum filter_actions {
enum directions {
DIR_IN=1,
- DIR_OUT
+ DIR_OUT,
+ DIR_DEFAULT_IN, /* only needed to apply default set */
+ DIR_DEFAULT_OUT
};
enum from_spec {
@@ -478,8 +481,8 @@ enum comp_ops {
#define SET_LOCALPREF 0x0001
#define SET_MED 0x0002
#define SET_NEXTHOP 0x0004
-#define SET_NEXTHOP6 0x0008
-#define SET_PREPEND 0x0010
+#define SET_PREPEND_SELF 0x0008
+#define SET_PREPEND_PEER 0x0010
#define SET_PFTABLE 0x0020
#define SET_COMMUNITY 0x0040
#define SET_NEXTHOP_REJECT 0x0080
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.134
diff -u -p -r1.134 parse.y
--- parse.y 17 Aug 2004 16:06:39 -0000 1.134
+++ parse.y 18 Aug 2004 14:33:03 -0000
@@ -147,7 +147,8 @@ typedef struct {
%token QUICK
%token FROM TO ANY
%token PREFIX PREFIXLEN SOURCEAS TRANSITAS COMMUNITY
-%token SET LOCALPREF MED METRIC NEXTHOP PREPEND PFTABLE REJECT BLACKHOLE
+%token SET LOCALPREF MED METRIC NEXTHOP REJECT BLACKHOLE
+%token PREPEND_SELF PREPEND_PEER PFTABLE
%token ERROR
%token IPSEC ESP AH SPI IKE
%token <v.string> STRING
@@ -1086,13 +1087,21 @@ filter_set_opt : LOCALPREF number {
| NEXTHOP REJECT {
$$.flags |= SET_NEXTHOP_REJECT;
}
- | PREPEND number {
- $$.flags = SET_PREPEND;
+ | PREPEND_SELF number {
+ $$.flags = SET_PREPEND_SELF;
if ($2 > 128) {
yyerror("to many prepends");
YYERROR;
}
- $$.prepend = $2;
+ $$.prepend_self = $2;
+ }
+ | PREPEND_PEER number {
+ $$.flags = SET_PREPEND_PEER;
+ if ($2 > 128) {
+ yyerror("to many prepends");
+ YYERROR;
+ }
+ $$.prepend_peer = $2;
}
| PFTABLE string {
$$.flags = SET_PFTABLE;
@@ -1237,7 +1246,8 @@ lookup(char *s)
{ "pftable", PFTABLE},
{ "prefix", PREFIX},
{ "prefixlen", PREFIXLEN},
- { "prepend-self", PREPEND},
+ { "prepend-neighbor", PREPEND_PEER},
+ { "prepend-self", PREPEND_SELF},
{ "quick", QUICK},
{ "reject", REJECT},
{ "remote-as", REMOTEAS},
@@ -1953,8 +1963,10 @@ merge_filterset(struct filter_set *a, st
if (b->flags & SET_NEXTHOP)
memcpy(&a->nexthop, &b->nexthop,
sizeof(a->nexthop));
- if (b->flags & SET_PREPEND)
- a->prepend = b->prepend;
+ if (b->flags & SET_PREPEND_SELF)
+ a->prepend_self = b->prepend_self;
+ if (b->flags & SET_PREPEND_PEER)
+ a->prepend_peer = b->prepend_peer;
if (b->flags & SET_PFTABLE)
strlcpy(a->pftable, b->pftable,
sizeof(a->pftable));
Index: printconf.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v
retrieving revision 1.27
diff -u -p -r1.27 printconf.c
--- printconf.c 13 Aug 2004 14:03:20 -0000 1.27
+++ printconf.c 19 Aug 2004 11:26:39 -0000
@@ -83,8 +83,10 @@ print_set(struct filter_set *set)
printf("nexthop reject ");
if (set->flags & SET_NEXTHOP_BLACKHOLE)
printf("nexthop blackhole ");
- if (set->flags & SET_PREPEND)
- printf("prepend-self %u ", set->prepend);
+ if (set->flags & SET_PREPEND_SELF)
+ printf("prepend-self %u ", set->prepend_self);
+ if (set->flags & SET_PREPEND_PEER)
+ printf("prepend-neighbor %u ", set->prepend_peer);
printf("}");
}
}
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.142
diff -u -p -r1.142 rde.c
--- rde.c 12 Aug 2004 10:24:16 -0000 1.142
+++ rde.c 20 Aug 2004 14:31:32 -0000
@@ -680,7 +680,7 @@ rde_update_dispatch(struct imsg *imsg)
}
/* apply default overrides */
- rde_apply_set(asp, &peer->conf.attrset, AF_INET);
+ rde_apply_set(asp, &peer->conf.attrset, AF_INET, peer, DIR_DEFAULT_IN);
/* parse nlri prefix */
while (nlri_len > 0) {
@@ -756,7 +756,8 @@ rde_update_dispatch(struct imsg *imsg)
mplen -= pos;
/* apply default overrides */
- rde_apply_set(asp, &peer->conf.attrset, AF_INET6);
+ rde_apply_set(asp, &peer->conf.attrset, AF_INET6, peer,
+ DIR_DEFAULT_IN);
switch (afi) {
case AFI_IPv6:
@@ -1944,13 +1945,15 @@ network_add(struct network_config *nc, i
F_ATTR_LOCALPREF | F_PREFIX_ANNOUNCED;
/* the nexthop is unset unless a default set overrides it */
- /* apply default overrides */
- rde_apply_set(asp, &nc->attrset, nc->prefix.af);
-
- if (flagstatic)
+ if (flagstatic) {
+ rde_apply_set(asp, &nc->attrset, nc->prefix.af, &peerself,
+ DIR_DEFAULT_IN);
path_update(&peerself, asp, &nc->prefix, nc->prefixlen);
- else
+ } else {
+ rde_apply_set(asp, &nc->attrset, nc->prefix.af, &peerdynamic,
+ DIR_DEFAULT_IN);
path_update(&peerdynamic, asp, &nc->prefix, nc->prefixlen);
+ }
}
void
Index: rde.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
retrieving revision 1.55
diff -u -p -r1.55 rde.h
--- rde.h 13 Aug 2004 14:03:20 -0000 1.55
+++ rde.h 20 Aug 2004 14:32:00 -0000
@@ -346,7 +346,7 @@ void pt_dump(void (*)(struct pt_entry
enum filter_actions rde_filter(struct rde_peer *, struct rde_aspath *,
struct bgpd_addr *, u_int8_t, enum directions);
void rde_apply_set(struct rde_aspath *, struct filter_set *,
- sa_family_t);
+ sa_family_t, struct rde_peer *, enum directions);
int rde_filter_community(struct rde_aspath *, int, int);
#endif /* __RDE_H__ */
Index: rde_filter.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_filter.c,v
retrieving revision 1.18
diff -u -p -r1.18 rde_filter.c
--- rde_filter.c 10 Aug 2004 13:02:08 -0000 1.18
+++ rde_filter.c 20 Aug 2004 14:30:29 -0000
@@ -45,7 +45,7 @@ rde_filter(struct rde_peer *peer, struct
f->peer.peerid != peer->conf.id)
continue;
if (rde_filter_match(f, asp, prefix, prefixlen)) {
- rde_apply_set(asp, &f->set, prefix->af);
+ rde_apply_set(asp, &f->set, prefix->af, asp->peer, dir);
if (f->action != ACTION_NONE)
action = f->action;
if (f->quick)
@@ -56,14 +56,40 @@ rde_filter(struct rde_peer *peer, struct
}
void
-rde_apply_set(struct rde_aspath *asp, struct filter_set *set, sa_family_t af)
+rde_apply_set(struct rde_aspath *asp, struct filter_set *set, sa_family_t af,
+ struct rde_peer *peer, enum directions dir)
{
struct aspath *new;
u_int16_t as;
+ u_int8_t prepend;
if (asp == NULL)
return;
+ if (set->flags & SET_PREPEND_SELF && dir != DIR_DEFAULT_IN) {
+ /* don't apply if this is a incomming default override */
+ as = rde_local_as();
+ prepend = set->prepend_self;
+ new = aspath_prepend(asp->aspath, as, prepend);
+ aspath_put(asp->aspath);
+ asp->aspath = new;
+ }
+
+ if (dir == DIR_DEFAULT_OUT)
+ /*
+ * default outgoing overrides are only allowed to
+ * set prepend-self
+ */
+ return;
+
+ if (set->flags & SET_PREPEND_PEER) {
+ as = peer->conf.remote_as;
+ prepend = set->prepend_peer;
+ new = aspath_prepend(asp->aspath, as, prepend);
+ aspath_put(asp->aspath);
+ asp->aspath = new;
+ }
+
if (set->flags & SET_LOCALPREF)
asp->lpref = set->localpref;
if (set->flags & SET_MED) {
@@ -73,12 +99,6 @@ rde_apply_set(struct rde_aspath *asp, st
nexthop_modify(asp, &set->nexthop, set->flags, af);
- if (set->flags & SET_PREPEND) {
- as = rde_local_as();
- new = aspath_prepend(asp->aspath, as, set->prepend);
- aspath_put(asp->aspath);
- asp->aspath = new;
- }
if (set->flags & SET_PFTABLE)
strlcpy(asp->pftable, set->pftable, sizeof(asp->pftable));
if (set->flags & SET_COMMUNITY) {
Index: rde_update.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_update.c,v
retrieving revision 1.29
diff -u -p -r1.29 rde_update.c
--- rde_update.c 13 Aug 2004 14:03:20 -0000 1.29
+++ rde_update.c 20 Aug 2004 14:44:29 -0000
@@ -334,6 +334,8 @@ up_generate_updates(struct rde_peer *pee
/* copy attributes for output filter */
fasp = path_copy(old->aspath);
+ /* default override not needed here as this is a withdraw */
+
pt_getaddr(old->prefix, &addr);
if (rde_filter(peer, fasp, &addr,
old->prefix->prefixlen, DIR_OUT) == ACTION_DENY) {
@@ -431,6 +433,13 @@ up_generate_updates(struct rde_peer *pee
/* copy attributes for output filter */
fasp = path_copy(new->aspath);
+ /*
+ * apply default outgoing overrides,
+ * acctually only prepend-self
+ */
+ rde_apply_set(fasp, &peer->conf.attrset, new->prefix->af,
+ fasp->peer, DIR_DEFAULT_OUT);
+
pt_getaddr(new->prefix, &addr);
if (rde_filter(peer, fasp, &addr,
new->prefix->prefixlen, DIR_OUT) == ACTION_DENY) {
Visit your host, monkey.org