diff options
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bgpd/bgpd.conf.5 | 8 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 15 | ||||
-rw-r--r-- | usr.sbin/bgpd/parse.y | 28 | ||||
-rw-r--r-- | usr.sbin/bgpd/printconf.c | 8 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.c | 19 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.h | 4 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_filter.c | 38 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_update.c | 11 |
8 files changed, 93 insertions, 38 deletions
diff --git a/usr.sbin/bgpd/bgpd.conf.5 b/usr.sbin/bgpd/bgpd.conf.5 index aecbf769d6b..460b2dcf92e 100644 --- a/usr.sbin/bgpd/bgpd.conf.5 +++ b/usr.sbin/bgpd/bgpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bgpd.conf.5,v 1.37 2004/08/20 14:56:09 claudio Exp $ +.\" $OpenBSD: bgpd.conf.5,v 1.38 2004/09/28 12:09:31 claudio Exp $ .\" .\" Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org> .\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -812,6 +812,12 @@ Add the prefix in the update to the specified 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 neighbor's AS +.Ar number +times to the +.Em AS path . +.Pp .It Ic prepend-self Ar number Prepend the local AS .Ar number diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index 231285bc476..8d600a76931 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.143 2004/09/16 17:58:13 henning Exp $ */ +/* $OpenBSD: bgpd.h,v 1.144 2004/09/28 12:09:31 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -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 { @@ -453,7 +454,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 { @@ -479,8 +482,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 diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y index 242461d5c04..2c257a2de7c 100644 --- a/usr.sbin/bgpd/parse.y +++ b/usr.sbin/bgpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.139 2004/08/24 15:33:48 henning Exp $ */ +/* $OpenBSD: parse.y,v 1.140 2004/09/28 12:09:31 claudio Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -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; @@ -1238,7 +1247,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}, @@ -1955,8 +1965,10 @@ merge_filterset(struct filter_set *a, struct filter_set *b) 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)); diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c index 5fc2ab112e1..e147eb23011 100644 --- a/usr.sbin/bgpd/printconf.c +++ b/usr.sbin/bgpd/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.29 2004/08/24 15:50:16 claudio Exp $ */ +/* $OpenBSD: printconf.c,v 1.30 2004/09/28 12:09:31 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -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("}"); } } diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index 406dba8fc72..91be3966ece 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.144 2004/09/16 17:36:29 henning Exp $ */ +/* $OpenBSD: rde.c,v 1.145 2004/09/28 12:09:31 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -689,7 +689,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) { @@ -765,7 +765,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: @@ -1954,13 +1955,15 @@ network_add(struct network_config *nc, int flagstatic) 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 diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h index 8db89dba774..e34efbe4171 100644 --- a/usr.sbin/bgpd/rde.h +++ b/usr.sbin/bgpd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.55 2004/08/13 14:03:20 claudio Exp $ */ +/* $OpenBSD: rde.h,v 1.56 2004/09/28 12:09:31 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and @@ -346,7 +346,7 @@ void pt_dump(void (*)(struct pt_entry *, void *), void *, 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__ */ diff --git a/usr.sbin/bgpd/rde_filter.c b/usr.sbin/bgpd/rde_filter.c index 33f2c5f8ef7..1b354fbf1f9 100644 --- a/usr.sbin/bgpd/rde_filter.c +++ b/usr.sbin/bgpd/rde_filter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_filter.c,v 1.18 2004/08/10 13:02:08 claudio Exp $ */ +/* $OpenBSD: rde_filter.c,v 1.19 2004/09/28 12:09:31 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org> @@ -45,7 +45,7 @@ rde_filter(struct rde_peer *peer, struct rde_aspath *asp, 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 rde_aspath *asp, } 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, struct filter_set *set, sa_family_t af) 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) { diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c index 1b0028154cf..167580656d4 100644 --- a/usr.sbin/bgpd/rde_update.c +++ b/usr.sbin/bgpd/rde_update.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_update.c,v 1.30 2004/08/20 15:31:56 claudio Exp $ */ +/* $OpenBSD: rde_update.c,v 1.31 2004/09/28 12:09:31 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org> @@ -334,6 +334,8 @@ up_generate_updates(struct rde_peer *peer, /* 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 *peer, /* 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) { |