hi, allows you to announce prefixes from the kernel routing table selected by priority.
lightly tested, as in, the config part works. network inet priority 32 ok? (benno_bgpd_announce_network_by_priority.diff) diff --git usr.sbin/bgpd/bgpd.conf.5 usr.sbin/bgpd/bgpd.conf.5 index d49a239ca22..f44805155f0 100644 --- usr.sbin/bgpd/bgpd.conf.5 +++ usr.sbin/bgpd/bgpd.conf.5 @@ -273,6 +273,11 @@ Log received and sent updates. .Pq Ic inet Ns | Ns Ic inet6 .Ic rtlabel Ar label Op Ic set ...\& .Xc +.It Xo +.Ic network +.Pq Ic inet Ns | Ns Ic inet6 +.Ic priority Ar number Op Ic set ...\& +.Xc .\" NOT IMPLEMENTED. DO WE WANT THIS? .\" .It Xo .\" .Ic network prefix-set @@ -291,6 +296,11 @@ If set to routes with the specified .Ar label will be announced. +If set to +.Ic priority , +routes with the specified +.Ar priority +will be announced. .Bd -literal -offset indent network 192.168.7.0/24 .Ed diff --git usr.sbin/bgpd/bgpd.h usr.sbin/bgpd/bgpd.h index 5d53b019d97..bb8c4df42e6 100644 --- usr.sbin/bgpd/bgpd.h +++ usr.sbin/bgpd/bgpd.h @@ -344,7 +344,8 @@ enum network_type { NETWORK_STATIC, NETWORK_CONNECTED, NETWORK_RTLABEL, - NETWORK_MRTCLONE + NETWORK_MRTCLONE, + NETWORK_PRIORITY }; struct network_config { @@ -355,6 +356,7 @@ struct network_config { u_int16_t rtlabel; enum network_type type; u_int8_t prefixlen; + u_int8_t priority; u_int8_t old; /* used for reloading */ }; diff --git usr.sbin/bgpd/kroute.c usr.sbin/bgpd/kroute.c index be4811d132a..73d6c43c359 100644 --- usr.sbin/bgpd/kroute.c +++ usr.sbin/bgpd/kroute.c @@ -1127,6 +1127,10 @@ kr_net_match(struct ktable *kt, struct kroute *kr) case NETWORK_MRTCLONE: /* can not happen */ break; + case NETWORK_PRIORITY: + if (kr->priority == xn->net.priority) + return (xn); + break; } } return (NULL); @@ -1163,6 +1167,10 @@ kr_net_match6(struct ktable *kt, struct kroute6 *kr6) case NETWORK_MRTCLONE: /* can not happen */ break; + case NETWORK_PRIORITY: + if (kr6->priority == xn->net.priority) + return (xn); + break; } } return (NULL); diff --git usr.sbin/bgpd/parse.y usr.sbin/bgpd/parse.y index 2257473f7ce..86f8069e9a3 100644 --- usr.sbin/bgpd/parse.y +++ usr.sbin/bgpd/parse.y @@ -211,7 +211,7 @@ typedef struct { %token COMMUNITY EXTCOMMUNITY LARGECOMMUNITY %token PREFIX PREFIXLEN PREFIXSET SOURCEAS TRANSITAS PEERAS DELETE MAXASLEN %token MAXASSEQ SET LOCALPREF MED METRIC NEXTHOP REJECT BLACKHOLE NOMODIFY SELF -%token PREPEND_SELF PREPEND_PEER PFTABLE WEIGHT RTLABEL ORIGIN +%token PREPEND_SELF PREPEND_PEER PFTABLE WEIGHT RTLABEL ORIGIN PRIORITY %token ERROR INCLUDE %token IPSEC ESP AH SPI IKE %token IPV4 IPV6 @@ -794,6 +794,30 @@ network : NETWORK prefix filter_set { TAILQ_INSERT_TAIL(netconf, n, entry); } + | NETWORK family PRIORITY NUMBER filter_set { + struct network *n; + if ($4 < RTP_LOCAL && $4 > RTP_MAX) { + yyerror("priority %lld > max %d or < min %d", $4, + RTP_MAX, RTP_LOCAL); + YYERROR; + } + + if ((n = calloc(1, sizeof(struct network))) == NULL) + fatal("new_network"); + if (afi2aid($2, SAFI_UNICAST, &n->net.prefix.aid) == + -1) { + yyerror("unknown family"); + filterset_free($5); + free($5); + YYERROR; + } + n->net.type = NETWORK_PRIORITY; + n->net.priority = $4; + filterset_move($5, &n->net.attrset); + free($5); + + TAILQ_INSERT_TAIL(netconf, n, entry); + } | NETWORK family nettype filter_set { struct network *n; @@ -2576,6 +2600,7 @@ lookup(char *s) { "prefixlen", PREFIXLEN}, { "prepend-neighbor", PREPEND_PEER}, { "prepend-self", PREPEND_SELF}, + { "priority", PRIORITY}, { "qualify", QUALIFY}, { "quick", QUICK}, { "rd", RD}, @@ -2972,6 +2997,7 @@ parse_config(char *filename, struct bgpd_config *xconf, struct peer **xpeers) struct sym *sym, *next; struct peer *p, *pnext; struct rde_rib *rr; + struct network *n; int errors = 0; conf = new_config(); @@ -3010,6 +3036,15 @@ parse_config(char *filename, struct bgpd_config *xconf, struct peer **xpeers) errors = file->errors; popfile(); + /* check that we dont try to announce our own routes */ + TAILQ_FOREACH(n, netconf, entry) + if (n->net.priority == conf->fib_priority) { + errors++; + logit(LOG_CRIT, "network priority %d == fib-priority " + "%d is not allowed.", + n->net.priority, conf->fib_priority); + } + /* Free macros and check which have not been used. */ TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) { if ((cmd_opts & BGPD_OPT_VERBOSE2) && !sym->used) diff --git usr.sbin/bgpd/printconf.c usr.sbin/bgpd/printconf.c index df0b6e5ab78..cfba4c0dbba 100644 --- usr.sbin/bgpd/printconf.c +++ usr.sbin/bgpd/printconf.c @@ -410,6 +410,10 @@ print_network(struct network_config *n, const char *c) printf("%snetwork %s rtlabel \"%s\"", c, print_af(n->prefix.aid), rtlabel_id2name(n->rtlabel)); break; + case NETWORK_PRIORITY: + printf("%snetwork %s priority %d", c, + print_af(n->prefix.aid), n->priority); + break; default: printf("%snetwork %s/%u", c, log_addr(&n->prefix), n->prefixlen);