On Wed, Jul 11, 2018 at 12:43:41AM +0200, Sebastian Benoit wrote:
> 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?
works in my lab setup. OK remi@
>
> (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);