Hi Florian, good job. I think it's better to set minimum to RTP_CONNECTED+1 instead of RTP_NONE+1
-- Best regards, Loïc BLOT, UNIX systems, security and network engineer http://www.unix-experience.fr Le samedi 09 novembre 2013 à 21:04 +0000, Florian Obser a écrit : > now with reload working; check RTP_NONE < fib-priority <= RTP_MAX > > test reports / comments / OKs? > > diff --git bgpd.c bgpd.c > index 9c48bb3..8ad95fe 100644 > --- bgpd.c > +++ bgpd.c > @@ -43,7 +43,7 @@ int check_child(pid_t, const char *); > int send_filterset(struct imsgbuf *, struct filter_set_head *); > int reconfigure(char *, struct bgpd_config *, struct mrt_head *, > struct peer **); > -int dispatch_imsg(struct imsgbuf *, int); > +int dispatch_imsg(struct imsgbuf *, int, struct bgpd_config *); > int control_setup(struct bgpd_config *); > > int rfd = -1; > @@ -276,12 +276,14 @@ main(int argc, char *argv[]) > } > > if (nfds > 0 && pfd[PFD_PIPE_SESSION].revents & POLLIN) { > - if (dispatch_imsg(ibuf_se, PFD_PIPE_SESSION) == -1) > + if (dispatch_imsg(ibuf_se, PFD_PIPE_SESSION, &conf) == > + -1) > quit = 1; > } > > if (nfds > 0 && pfd[PFD_PIPE_ROUTE].revents & POLLIN) { > - if (dispatch_imsg(ibuf_rde, PFD_PIPE_ROUTE) == -1) > + if (dispatch_imsg(ibuf_rde, PFD_PIPE_ROUTE, &conf) == > + -1) > quit = 1; > } > > @@ -359,7 +361,7 @@ main(int argc, char *argv[]) > control_cleanup(conf.csock); > control_cleanup(conf.rcsock); > carp_demote_shutdown(); > - kr_shutdown(); > + kr_shutdown(conf.fib_priority); > pftable_clear_all(); > free(conf.listen_addrs); > > @@ -468,7 +470,7 @@ reconfigure(char *conffile, struct bgpd_config *conf, > struct mrt_head *mrt_l, > while ((rr = SIMPLEQ_FIRST(&ribnames))) { > SIMPLEQ_REMOVE_HEAD(&ribnames, entry); > if (ktable_update(rr->rtableid, rr->name, NULL, > - rr->flags) == -1) { > + rr->flags, conf->fib_priority) == -1) { > log_warnx("failed to load rdomain %d", > rr->rtableid); > return (-1); > @@ -505,7 +507,7 @@ reconfigure(char *conffile, struct bgpd_config *conf, > struct mrt_head *mrt_l, > while ((rd = SIMPLEQ_FIRST(&rdom_l)) != NULL) { > SIMPLEQ_REMOVE_HEAD(&rdom_l, entry); > if (ktable_update(rd->rtableid, rd->descr, rd->ifmpe, > - rd->flags) == -1) { > + rd->flags, conf->fib_priority) == -1) { > log_warnx("failed to load rdomain %d", > rd->rtableid); > return (-1); > @@ -551,7 +553,7 @@ reconfigure(char *conffile, struct bgpd_config *conf, > struct mrt_head *mrt_l, > } > > int > -dispatch_imsg(struct imsgbuf *ibuf, int idx) > +dispatch_imsg(struct imsgbuf *ibuf, int idx, struct bgpd_config *conf) > { > struct imsg imsg; > ssize_t n; > @@ -580,7 +582,8 @@ dispatch_imsg(struct imsgbuf *ibuf, int idx) > else if (imsg.hdr.len != IMSG_HEADER_SIZE + > sizeof(struct kroute_full)) > log_warnx("wrong imsg len"); > - else if (kr_change(imsg.hdr.peerid, imsg.data)) > + else if (kr_change(imsg.hdr.peerid, imsg.data, > + conf->fib_priority)) > rv = -1; > break; > case IMSG_KROUTE_DELETE: > @@ -589,7 +592,8 @@ dispatch_imsg(struct imsgbuf *ibuf, int idx) > else if (imsg.hdr.len != IMSG_HEADER_SIZE + > sizeof(struct kroute_full)) > log_warnx("wrong imsg len"); > - else if (kr_delete(imsg.hdr.peerid, imsg.data)) > + else if (kr_delete(imsg.hdr.peerid, imsg.data, > + conf->fib_priority)) > rv = -1; > break; > case IMSG_NEXTHOP_ADD: > @@ -652,13 +656,15 @@ dispatch_imsg(struct imsgbuf *ibuf, int idx) > if (idx != PFD_PIPE_SESSION) > log_warnx("couple request not from SE"); > else > - kr_fib_couple(imsg.hdr.peerid); > + kr_fib_couple(imsg.hdr.peerid, > + conf->fib_priority); > break; > case IMSG_CTL_FIB_DECOUPLE: > if (idx != PFD_PIPE_SESSION) > log_warnx("decouple request not from SE"); > else > - kr_fib_decouple(imsg.hdr.peerid); > + kr_fib_decouple(imsg.hdr.peerid, > + conf->fib_priority); > break; > case IMSG_CTL_KROUTE: > case IMSG_CTL_KROUTE_ADDR: > @@ -704,7 +710,7 @@ dispatch_imsg(struct imsgbuf *ibuf, int idx) > 0, -1, NULL, 0); > > /* finally fix kroute information */ > - ktable_postload(); > + ktable_postload(conf->fib_priority); > > /* redistribute list needs to be reloaded too */ > kr_reload(); > diff --git bgpd.conf.5 bgpd.conf.5 > index d352015..c7a0b8a 100644 > --- bgpd.conf.5 > +++ bgpd.conf.5 > @@ -206,6 +206,11 @@ dump all out "/tmp/all-out-%H%M" 300 > dump updates out "/tmp/updates-out-%H%M" 300 > .Ed > .Pp > +.It Ic fib-priority Ar prio > +Set the routing priority to > +.Ar prio . > +The default is 48. > +.Pp > .It Xo > .Ic fib-update > .Pq Ic yes Ns | Ns Ic no > diff --git bgpd.h bgpd.h > index 67f79fc..fc0ed0f 100644 > --- bgpd.h > +++ bgpd.h > @@ -209,6 +209,7 @@ struct bgpd_config { > u_int16_t holdtime; > u_int16_t min_holdtime; > u_int16_t connectretry; > + u_int8_t fib_priority; > }; > > enum announce_type { > @@ -932,15 +933,18 @@ int host(const char *, struct bgpd_addr *, > u_int8_t *); > > /* kroute.c */ > int kr_init(void); > -int ktable_update(u_int, char *, char *, int); > +int ktable_update(u_int, char *, char *, int, u_int8_t); > void ktable_preload(void); > -void ktable_postload(void); > +void ktable_postload(u_int8_t); > int ktable_exists(u_int, u_int *); > -int kr_change(u_int, struct kroute_full *); > -int kr_delete(u_int, struct kroute_full *); > -void kr_shutdown(void); > -void kr_fib_couple(u_int); > -void kr_fib_decouple(u_int); > +int kr_change(u_int, struct kroute_full *, u_int8_t); > +int kr_delete(u_int, struct kroute_full *, u_int8_t); > +void kr_shutdown(u_int8_t); > +void kr_fib_couple(u_int, u_int8_t); > +void kr_fib_couple_all(u_int8_t); > +void kr_fib_decouple(u_int, u_int8_t); > +void kr_fib_decouple_all(u_int8_t); > +void kr_fib_update_prio_all(u_int8_t); > int kr_dispatch_msg(void); > int kr_nexthop_add(u_int32_t, struct bgpd_addr *); > void kr_nexthop_delete(u_int32_t, struct bgpd_addr *); > diff --git config.c config.c > index 9e9abae..b10c139 100644 > --- config.c > +++ config.c > @@ -65,6 +65,9 @@ merge_config(struct bgpd_config *xconf, struct bgpd_config > *conf, > if ((conf->flags & BGPD_FLAG_REFLECTOR) && conf->clusterid == 0) > conf->clusterid = conf->bgpid; > > + if (!conf->fib_priority) > + conf->fib_priority = RTP_BGP; > + > free(xconf->csock); > free(xconf->rcsock); > > diff --git kroute.c kroute.c > index d2426cc..e460bbf 100644 > --- kroute.c > +++ kroute.c > @@ -84,17 +84,17 @@ struct kif_node { > struct kif_kr6_head kroute6_l; > }; > > -int ktable_new(u_int, u_int, char *, char *, int); > -void ktable_free(u_int); > -void ktable_destroy(struct ktable *); > +int ktable_new(u_int, u_int, char *, char *, int, u_int8_t); > +void ktable_free(u_int, u_int8_t); > +void ktable_destroy(struct ktable *, u_int8_t); > struct ktable *ktable_get(u_int); > > -int kr4_change(struct ktable *, struct kroute_full *); > -int kr6_change(struct ktable *, struct kroute_full *); > -int krVPN4_change(struct ktable *, struct kroute_full *); > -int kr4_delete(struct ktable *, struct kroute_full *); > -int kr6_delete(struct ktable *, struct kroute_full *); > -int krVPN4_delete(struct ktable *, struct kroute_full *); > +int kr4_change(struct ktable *, struct kroute_full *, u_int8_t); > +int kr6_change(struct ktable *, struct kroute_full *, u_int8_t); > +int krVPN4_change(struct ktable *, struct kroute_full *, u_int8_t); > +int kr4_delete(struct ktable *, struct kroute_full *, u_int8_t); > +int kr6_delete(struct ktable *, struct kroute_full *, u_int8_t); > +int krVPN4_delete(struct ktable *, struct kroute_full *, u_int8_t); > void kr_net_delete(struct network *); > struct network *kr_net_match(struct ktable *, struct kroute *); > struct network *kr_net_match6(struct ktable *, struct kroute6 *); > @@ -107,6 +107,7 @@ int kroute_compare(struct kroute_node *, struct > kroute_node *); > int kroute6_compare(struct kroute6_node *, struct kroute6_node *); > int knexthop_compare(struct knexthop_node *, struct knexthop_node *); > int kif_compare(struct kif_node *, struct kif_node *); > +void kr_fib_update_prio(u_int, u_int8_t); > > struct kroute_node *kroute_find(struct ktable *, in_addr_t, u_int8_t, > u_int8_t); > @@ -162,10 +163,12 @@ void get_rtaddrs(int, struct sockaddr *, > struct sockaddr **); > void if_change(u_short, int, struct if_data *); > void if_announce(void *); > > -int send_rtmsg(int, int, struct ktable *, struct kroute *); > -int send_rt6msg(int, int, struct ktable *, struct kroute6 *); > +int send_rtmsg(int, int, struct ktable *, struct kroute *, > + u_int8_t); > +int send_rt6msg(int, int, struct ktable *, struct kroute6 *, > + u_int8_t); > int dispatch_rtmsg(void); > -int fetchtable(struct ktable *); > +int fetchtable(struct ktable *, u_int8_t); > int fetchifs(int); > int dispatch_rtmsg_addr(struct rt_msghdr *, > struct sockaddr *[RTAX_MAX], struct ktable *); > @@ -237,7 +240,8 @@ kr_init(void) > } > > int > -ktable_new(u_int rtableid, u_int rdomid, char *name, char *ifname, int fs) > +ktable_new(u_int rtableid, u_int rdomid, char *name, char *ifname, int fs, > + u_int8_t bgp_prio) > { > struct ktable **xkrt; > struct ktable *kt; > @@ -283,7 +287,7 @@ ktable_new(u_int rtableid, u_int rdomid, char *name, char > *ifname, int fs) > } > > /* ... and load it */ > - if (fetchtable(kt) == -1) > + if (fetchtable(kt, bgp_prio) == -1) > return (-1); > if (protect_lo(kt) == -1) > return (-1); > @@ -295,7 +299,7 @@ ktable_new(u_int rtableid, u_int rdomid, char *name, char > *ifname, int fs) > } > > void > -ktable_free(u_int rtableid) > +ktable_free(u_int rtableid, u_int8_t bgp_prio) > { > struct ktable *kt, *nkt; > > @@ -303,7 +307,7 @@ ktable_free(u_int rtableid) > return; > > /* decouple from kernel, no new routes will be entered from here */ > - kr_fib_decouple(kt->rtableid); > + kr_fib_decouple(kt->rtableid, bgp_prio); > > /* first unhook from the nexthop table */ > nkt = ktable_get(kt->nhtableid); > @@ -317,16 +321,16 @@ ktable_free(u_int rtableid) > * free so check that kt != nkt). > */ > if (kt != nkt && nkt->nhrefcnt <= 0) > - ktable_destroy(nkt); > + ktable_destroy(nkt, bgp_prio); > if (kt->nhrefcnt <= 0) > - ktable_destroy(kt); > + ktable_destroy(kt, bgp_prio); > } > > void > -ktable_destroy(struct ktable *kt) > +ktable_destroy(struct ktable *kt, u_int8_t bgp_prio) > { > /* decouple just to be sure, does not hurt */ > - kr_fib_decouple(kt->rtableid); > + kr_fib_decouple(kt->rtableid, bgp_prio); > > log_debug("freeing ktable %s rtableid %u", kt->descr, kt->rtableid); > knexthop_clear(kt); > @@ -346,7 +350,8 @@ ktable_get(u_int rtableid) > } > > int > -ktable_update(u_int rtableid, char *name, char *ifname, int flags) > +ktable_update(u_int rtableid, char *name, char *ifname, int flags, u_int8_t > + bgp_prio) > { > struct ktable *kt, *rkt; > u_int rdomid; > @@ -359,7 +364,7 @@ ktable_update(u_int rtableid, char *name, char *ifname, > int flags) > if (rkt == NULL) { > char buf[32]; > snprintf(buf, sizeof(buf), "rdomain_%d", rdomid); > - if (ktable_new(rdomid, rdomid, buf, NULL, 0)) > + if (ktable_new(rdomid, rdomid, buf, NULL, 0, bgp_prio)) > return (-1); > } else { > /* there is no need for full fib synchronisation if > @@ -379,7 +384,7 @@ ktable_update(u_int rtableid, char *name, char *ifname, > int flags) > kt = ktable_get(rtableid); > if (kt == NULL) { > if (ktable_new(rtableid, rdomid, name, ifname, > - !(flags & F_RIB_NOFIBSYNC))) > + !(flags & F_RIB_NOFIBSYNC), bgp_prio)) > return (-1); > } else { > /* fib sync has higher preference then no sync */ > @@ -408,7 +413,7 @@ ktable_preload(void) > } > > void > -ktable_postload(void) > +ktable_postload(u_int8_t bgp_prio) > { > struct ktable *kt; > u_int i; > @@ -417,7 +422,7 @@ ktable_postload(void) > if ((kt = ktable_get(i - 1)) == NULL) > continue; > if (kt->state == RECONF_DELETE) > - ktable_free(i - 1); > + ktable_free(i - 1, bgp_prio); > else if (kt->state == RECONF_REINIT) > kt->fib_sync = kt->fib_conf; > } > @@ -452,7 +457,7 @@ ktable_exists(u_int rtableid, u_int *rdomid) > } > > int > -kr_change(u_int rtableid, struct kroute_full *kl) > +kr_change(u_int rtableid, struct kroute_full *kl, u_int8_t bgp_prio) > { > struct ktable *kt; > > @@ -461,25 +466,25 @@ kr_change(u_int rtableid, struct kroute_full *kl) > return (0); > switch (kl->prefix.aid) { > case AID_INET: > - return (kr4_change(kt, kl)); > + return (kr4_change(kt, kl, bgp_prio)); > case AID_INET6: > - return (kr6_change(kt, kl)); > + return (kr6_change(kt, kl, bgp_prio)); > case AID_VPN_IPv4: > - return (krVPN4_change(kt, kl)); > + return (krVPN4_change(kt, kl, bgp_prio)); > } > log_warnx("kr_change: not handled AID"); > return (-1); > } > > int > -kr4_change(struct ktable *kt, struct kroute_full *kl) > +kr4_change(struct ktable *kt, struct kroute_full *kl, u_int8_t bgp_prio) > { > struct kroute_node *kr; > int action = RTM_ADD; > u_int16_t labelid; > > if ((kr = kroute_find(kt, kl->prefix.v4.s_addr, kl->prefixlen, > - RTP_BGP)) != NULL) > + bgp_prio)) != NULL) > action = RTM_CHANGE; > > /* nexthop within 127/8 -> ignore silently */ > @@ -502,7 +507,7 @@ kr4_change(struct ktable *kt, struct kroute_full *kl) > kr->r.prefixlen = kl->prefixlen; > kr->r.nexthop.s_addr = kl->nexthop.v4.s_addr; > kr->r.flags = kl->flags | F_BGPD_INSERTED; > - kr->r.priority = RTP_BGP; > + kr->r.priority = bgp_prio; > kr->r.labelid = labelid; > > if (kroute_insert(kt, kr) == -1) { > @@ -523,21 +528,21 @@ kr4_change(struct ktable *kt, struct kroute_full *kl) > kr->r.flags &= ~F_REJECT; > } > > - if (send_rtmsg(kr_state.fd, action, kt, &kr->r) == -1) > + if (send_rtmsg(kr_state.fd, action, kt, &kr->r, bgp_prio) == -1) > return (-1); > > return (0); > } > > int > -kr6_change(struct ktable *kt, struct kroute_full *kl) > +kr6_change(struct ktable *kt, struct kroute_full *kl, u_int8_t bgp_prio) > { > struct kroute6_node *kr6; > struct in6_addr lo6 = IN6ADDR_LOOPBACK_INIT; > int action = RTM_ADD; > u_int16_t labelid; > > - if ((kr6 = kroute6_find(kt, &kl->prefix.v6, kl->prefixlen, RTP_BGP)) != > + if ((kr6 = kroute6_find(kt, &kl->prefix.v6, kl->prefixlen, bgp_prio)) != > NULL) > action = RTM_CHANGE; > > @@ -561,7 +566,7 @@ kr6_change(struct ktable *kt, struct kroute_full *kl) > memcpy(&kr6->r.nexthop, &kl->nexthop.v6, > sizeof(struct in6_addr)); > kr6->r.flags = kl->flags | F_BGPD_INSERTED; > - kr6->r.priority = RTP_BGP; > + kr6->r.priority = bgp_prio; > kr6->r.labelid = labelid; > > if (kroute6_insert(kt, kr6) == -1) { > @@ -583,14 +588,14 @@ kr6_change(struct ktable *kt, struct kroute_full *kl) > kr6->r.flags &= ~F_REJECT; > } > > - if (send_rt6msg(kr_state.fd, action, kt, &kr6->r) == -1) > + if (send_rt6msg(kr_state.fd, action, kt, &kr6->r, bgp_prio) == -1) > return (-1); > > return (0); > } > > int > -krVPN4_change(struct ktable *kt, struct kroute_full *kl) > +krVPN4_change(struct ktable *kt, struct kroute_full *kl, u_int8_t bgp_prio) > { > struct kroute_node *kr; > int action = RTM_ADD; > @@ -598,7 +603,7 @@ krVPN4_change(struct ktable *kt, struct kroute_full *kl) > u_int16_t labelid; > > if ((kr = kroute_find(kt, kl->prefix.vpn4.addr.s_addr, kl->prefixlen, > - RTP_BGP)) != NULL) > + bgp_prio)) != NULL) > action = RTM_CHANGE; > > /* nexthop within 127/8 -> ignore silently */ > @@ -632,7 +637,7 @@ krVPN4_change(struct ktable *kt, struct kroute_full *kl) > kr->r.prefixlen = kl->prefixlen; > kr->r.nexthop.s_addr = kl->nexthop.v4.s_addr; > kr->r.flags = kl->flags | F_BGPD_INSERTED | F_MPLS; > - kr->r.priority = RTP_BGP; > + kr->r.priority = bgp_prio; > kr->r.labelid = labelid; > kr->r.mplslabel = mplslabel; > > @@ -655,14 +660,14 @@ krVPN4_change(struct ktable *kt, struct kroute_full *kl) > kr->r.flags &= ~F_REJECT; > } > > - if (send_rtmsg(kr_state.fd, action, kt, &kr->r) == -1) > + if (send_rtmsg(kr_state.fd, action, kt, &kr->r, bgp_prio) == -1) > return (-1); > > return (0); > } > > int > -kr_delete(u_int rtableid, struct kroute_full *kl) > +kr_delete(u_int rtableid, struct kroute_full *kl, u_int8_t bgp_prio) > { > struct ktable *kt; > > @@ -672,29 +677,29 @@ kr_delete(u_int rtableid, struct kroute_full *kl) > > switch (kl->prefix.aid) { > case AID_INET: > - return (kr4_delete(kt, kl)); > + return (kr4_delete(kt, kl, bgp_prio)); > case AID_INET6: > - return (kr6_delete(kt, kl)); > + return (kr6_delete(kt, kl, bgp_prio)); > case AID_VPN_IPv4: > - return (krVPN4_delete(kt, kl)); > + return (krVPN4_delete(kt, kl, bgp_prio)); > } > log_warnx("kr_change: not handled AID"); > return (-1); > } > > int > -kr4_delete(struct ktable *kt, struct kroute_full *kl) > +kr4_delete(struct ktable *kt, struct kroute_full *kl, u_int8_t bgp_prio) > { > struct kroute_node *kr; > > if ((kr = kroute_find(kt, kl->prefix.v4.s_addr, kl->prefixlen, > - RTP_BGP)) == NULL) > + bgp_prio)) == NULL) > return (0); > > if (!(kr->r.flags & F_BGPD_INSERTED)) > return (0); > > - if (send_rtmsg(kr_state.fd, RTM_DELETE, kt, &kr->r) == -1) > + if (send_rtmsg(kr_state.fd, RTM_DELETE, kt, &kr->r, bgp_prio) == -1) > return (-1); > > rtlabel_unref(kr->r.labelid); > @@ -706,18 +711,18 @@ kr4_delete(struct ktable *kt, struct kroute_full *kl) > } > > int > -kr6_delete(struct ktable *kt, struct kroute_full *kl) > +kr6_delete(struct ktable *kt, struct kroute_full *kl, u_int8_t bgp_prio) > { > struct kroute6_node *kr6; > > - if ((kr6 = kroute6_find(kt, &kl->prefix.v6, kl->prefixlen, RTP_BGP)) == > + if ((kr6 = kroute6_find(kt, &kl->prefix.v6, kl->prefixlen, bgp_prio)) == > NULL) > return (0); > > if (!(kr6->r.flags & F_BGPD_INSERTED)) > return (0); > > - if (send_rt6msg(kr_state.fd, RTM_DELETE, kt, &kr6->r) == -1) > + if (send_rt6msg(kr_state.fd, RTM_DELETE, kt, &kr6->r, bgp_prio) == -1) > return (-1); > > rtlabel_unref(kr6->r.labelid); > @@ -729,18 +734,18 @@ kr6_delete(struct ktable *kt, struct kroute_full *kl) > } > > int > -krVPN4_delete(struct ktable *kt, struct kroute_full *kl) > +krVPN4_delete(struct ktable *kt, struct kroute_full *kl, u_int8_t bgp_prio) > { > struct kroute_node *kr; > > if ((kr = kroute_find(kt, kl->prefix.vpn4.addr.s_addr, kl->prefixlen, > - RTP_BGP)) == NULL) > + bgp_prio)) == NULL) > return (0); > > if (!(kr->r.flags & F_BGPD_INSERTED)) > return (0); > > - if (send_rtmsg(kr_state.fd, RTM_DELETE, kt, &kr->r) == -1) > + if (send_rtmsg(kr_state.fd, RTM_DELETE, kt, &kr->r, bgp_prio) == -1) > return (-1); > > rtlabel_unref(kr->r.labelid); > @@ -752,17 +757,17 @@ krVPN4_delete(struct ktable *kt, struct kroute_full *kl) > } > > void > -kr_shutdown(void) > +kr_shutdown(u_int8_t bgp_prio) > { > u_int i; > > for (i = krt_size; i > 0; i--) > - ktable_free(i - 1); > + ktable_free(i - 1, bgp_prio); > kif_clear(); > } > > void > -kr_fib_couple(u_int rtableid) > +kr_fib_couple(u_int rtableid, u_int8_t bgp_prio) > { > struct ktable *kt; > struct kroute_node *kr; > @@ -778,17 +783,27 @@ kr_fib_couple(u_int rtableid) > > RB_FOREACH(kr, kroute_tree, &kt->krt) > if ((kr->r.flags & F_BGPD_INSERTED)) > - send_rtmsg(kr_state.fd, RTM_ADD, kt, &kr->r); > + send_rtmsg(kr_state.fd, RTM_ADD, kt, &kr->r, bgp_prio); > RB_FOREACH(kr6, kroute6_tree, &kt->krt6) > if ((kr6->r.flags & F_BGPD_INSERTED)) > - send_rt6msg(kr_state.fd, RTM_ADD, kt, &kr6->r); > + send_rt6msg(kr_state.fd, RTM_ADD, kt, &kr6->r, > + bgp_prio); > > log_info("kernel routing table %u (%s) coupled", kt->rtableid, > kt->descr); > } > > void > -kr_fib_decouple(u_int rtableid) > +kr_fib_couple_all(u_int8_t bgp_prio) > +{ > + u_int i; > + > + for (i = krt_size; i > 0; i--) > + kr_fib_couple(i - 1, bgp_prio); > +} > + > +void > +kr_fib_decouple(u_int rtableid, u_int8_t bgp_prio) > { > struct ktable *kt; > struct kroute_node *kr; > @@ -802,10 +817,12 @@ kr_fib_decouple(u_int rtableid) > > RB_FOREACH(kr, kroute_tree, &kt->krt) > if ((kr->r.flags & F_BGPD_INSERTED)) > - send_rtmsg(kr_state.fd, RTM_DELETE, kt, &kr->r); > + send_rtmsg(kr_state.fd, RTM_DELETE, kt, &kr->r, > + bgp_prio); > RB_FOREACH(kr6, kroute6_tree, &kt->krt6) > if ((kr6->r.flags & F_BGPD_INSERTED)) > - send_rt6msg(kr_state.fd, RTM_DELETE, kt, &kr6->r); > + send_rt6msg(kr_state.fd, RTM_DELETE, kt, &kr6->r, > + bgp_prio); > > kt->fib_sync = 0; > > @@ -813,6 +830,43 @@ kr_fib_decouple(u_int rtableid) > kt->descr); > } > > +void > +kr_fib_decouple_all(u_int8_t bgp_prio) > +{ > + u_int i; > + > + for (i = krt_size; i > 0; i--) > + kr_fib_decouple(i - 1, bgp_prio); > +} > + > +void > +kr_fib_update_prio(u_int rtableid, u_int8_t bgp_prio) > +{ > + struct ktable *kt; > + struct kroute_node *kr; > + struct kroute6_node *kr6; > + > + if ((kt = ktable_get(rtableid)) == NULL) /* table does not exist */ > + return; > + > + RB_FOREACH(kr, kroute_tree, &kt->krt) > + if ((kr->r.flags & F_BGPD_INSERTED)) > + kr->r.priority = bgp_prio; > + > + RB_FOREACH(kr6, kroute6_tree, &kt->krt6) > + if ((kr6->r.flags & F_BGPD_INSERTED)) > + kr6->r.priority = bgp_prio; > +} > + > +void > +kr_fib_update_prio_all(u_int8_t bgp_prio) > +{ > + u_int i; > + > + for (i = krt_size; i > 0; i--) > + kr_fib_update_prio(i - 1, bgp_prio); > +} > + > int > kr_dispatch_msg(void) > { > @@ -2473,7 +2527,8 @@ if_announce(void *msg) > */ > > int > -send_rtmsg(int fd, int action, struct ktable *kt, struct kroute *kroute) > +send_rtmsg(int fd, int action, struct ktable *kt, struct kroute *kroute, > + u_int8_t bgp_prio) > { > struct iovec iov[7]; > struct rt_msghdr hdr; > @@ -2496,7 +2551,7 @@ send_rtmsg(int fd, int action, struct ktable *kt, > struct kroute *kroute) > hdr.rtm_version = RTM_VERSION; > hdr.rtm_type = action; > hdr.rtm_tableid = kt->rtableid; > - hdr.rtm_priority = RTP_BGP; > + hdr.rtm_priority = bgp_prio; > if (kroute->flags & F_BLACKHOLE) > hdr.rtm_flags |= RTF_BLACKHOLE; > if (kroute->flags & F_REJECT) > @@ -2608,7 +2663,8 @@ retry: > } > > int > -send_rt6msg(int fd, int action, struct ktable *kt, struct kroute6 *kroute) > +send_rt6msg(int fd, int action, struct ktable *kt, struct kroute6 *kroute, > + u_int8_t bgp_prio) > { > struct iovec iov[5]; > struct rt_msghdr hdr; > @@ -2627,7 +2683,7 @@ send_rt6msg(int fd, int action, struct ktable *kt, > struct kroute6 *kroute) > hdr.rtm_version = RTM_VERSION; > hdr.rtm_type = action; > hdr.rtm_tableid = kt->rtableid; > - hdr.rtm_priority = RTP_BGP; > + hdr.rtm_priority = bgp_prio; > if (kroute->flags & F_BLACKHOLE) > hdr.rtm_flags |= RTF_BLACKHOLE; > if (kroute->flags & F_REJECT) > @@ -2715,7 +2771,7 @@ retry: > } > > int > -fetchtable(struct ktable *kt) > +fetchtable(struct ktable *kt, u_int8_t bgp_prio) > { > size_t len; > int mib[7]; > @@ -2863,15 +2919,16 @@ fetchtable(struct ktable *kt) > } > > if (sa->sa_family == AF_INET) { > - if (rtm->rtm_priority == RTP_BGP) { > - send_rtmsg(kr_state.fd, RTM_DELETE, kt, &kr->r); > + if (rtm->rtm_priority == bgp_prio) { > + send_rtmsg(kr_state.fd, RTM_DELETE, kt, &kr->r, > + bgp_prio); > free(kr); > } else > kroute_insert(kt, kr); > } else if (sa->sa_family == AF_INET6) { > - if (rtm->rtm_priority == RTP_BGP) { > + if (rtm->rtm_priority == bgp_prio) { > send_rt6msg(kr_state.fd, RTM_DELETE, kt, > - &kr6->r); > + &kr6->r, bgp_prio); > free(kr6); > } else > kroute6_insert(kt, kr6); > diff --git parse.y parse.y > index 1492a08..92b4d70 100644 > --- parse.y > +++ parse.y > @@ -170,7 +170,7 @@ typedef struct { > > %} > > -%token AS ROUTERID HOLDTIME YMIN LISTEN ON FIBUPDATE RTABLE > +%token AS ROUTERID HOLDTIME YMIN LISTEN ON FIBUPDATE FIBPRIORITY RTABLE > %token RDOMAIN RD EXPORTTRGT IMPORTTRGT > %token RDE RIB EVALUATE IGNORE COMPARE > %token GROUP NEIGHBOR NETWORK > @@ -373,6 +373,13 @@ conf_main : AS as4number { > memcpy(&la->sa, addr2sa(&$3, BGP_PORT), sizeof(la->sa)); > TAILQ_INSERT_TAIL(listen_addrs, la, entry); > } > + | FIBPRIORITY NUMBER { > + if ($2 <= RTP_NONE || $2 > RTP_MAX) { > + yyerror("invalid fib-priority"); > + YYERROR; > + } > + conf->fib_priority = $2; > + } > | FIBUPDATE yesno { > struct rde_rib *rr; > rr = find_rib("Loc-RIB"); > @@ -2139,6 +2146,7 @@ lookup(char *s) > { "evaluate", EVALUATE}, > { "export-target", EXPORTTRGT}, > { "ext-community", EXTCOMMUNITY}, > + { "fib-priority", FIBPRIORITY}, > { "fib-update", FIBUPDATE}, > { "from", FROM}, > { "group", GROUP}, > @@ -2565,9 +2573,13 @@ parse_config(char *filename, struct bgpd_config *xconf, > struct rde_rib *rr; > struct rdomain *rd; > int errors = 0; > + u_int8_t old_prio; > + > + old_prio = xconf->fib_priority; > > if ((conf = calloc(1, sizeof(struct bgpd_config))) == NULL) > fatal(NULL); > + > conf->opts = xconf->opts; > conf->csock = strdup(SOCKET_NAME); > > @@ -2719,6 +2731,13 @@ parse_config(char *filename, struct bgpd_config *xconf, > free(peerfilter_l); > free(groupfilter_l); > > + if (!errors && old_prio != RTP_NONE && old_prio != > + xconf->fib_priority) { > + kr_fib_decouple_all(old_prio); > + kr_fib_update_prio_all(xconf->fib_priority); > + kr_fib_couple_all(xconf->fib_priority); > + } > + > return (errors ? -1 : 0); > } > > diff --git printconf.c printconf.c > index 484bdf2..2482556 100644 > --- printconf.c > +++ printconf.c > @@ -270,6 +270,7 @@ print_mainconf(struct bgpd_config *conf) > printf("nexthop qualify via bgp\n"); > if (conf->flags & BGPD_FLAG_NEXTHOP_DEFAULT) > printf("nexthop qualify via default\n"); > + printf("fib-priority %hhu", conf->fib_priority); > } > > void > >
signature.asc
Description: This is a digitally signed message part