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);

Reply via email to