First stab, only lightly tested, reload is *not* working. I need to think a bit more how to handle reloads exactly.
Note that if you try to shoot yourself in the foot by specifing another already used priority (e.g. 32), it will not only take of your foot but take the thigh right with it... (at least that's what I think, haven't tried it) diff --git bgpd.c bgpd.c index 9c48bb3..6cd4eab 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; @@ -161,6 +161,8 @@ main(int argc, char *argv[]) if (argc > 0) usage(); + conf.fib_priority = RTP_BGP; /* XXX how to handle default? */ + if (conf.opts & BGPD_OPT_NOACTION) { struct network_head net_l; struct rdomain_head rdom_l; @@ -276,12 +278,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 +363,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 +472,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 +509,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 +555,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 +584,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 +594,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 +658,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 +712,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..29681d8 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,15 @@ 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_decouple(u_int, 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 kroute.c kroute.c index d2426cc..6f2074d 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 *); @@ -162,10 +162,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 +239,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 +286,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 +298,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 +306,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 +320,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 +349,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 +363,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 +383,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 +412,7 @@ ktable_preload(void) } void -ktable_postload(void) +ktable_postload(u_int8_t bgp_prio) { struct ktable *kt; u_int i; @@ -417,7 +421,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 +456,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 +465,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 +506,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 +527,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 +565,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 +587,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 +602,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 +636,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 +659,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 +676,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 +710,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 +733,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 +756,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 +782,18 @@ 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_decouple(u_int rtableid, u_int8_t bgp_prio) { struct ktable *kt; struct kroute_node *kr; @@ -802,10 +807,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; @@ -2473,7 +2480,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 +2504,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 +2616,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 +2636,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 +2724,7 @@ retry: } int -fetchtable(struct ktable *kt) +fetchtable(struct ktable *kt, u_int8_t bgp_prio) { size_t len; int mib[7]; @@ -2863,15 +2872,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..c0623a6 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 < 0 || $2 > 255) { + 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}, @@ -2568,6 +2576,7 @@ parse_config(char *filename, struct bgpd_config *xconf, if ((conf = calloc(1, sizeof(struct bgpd_config))) == NULL) fatal(NULL); + conf->fib_priority = RTP_BGP; /* XXX how to handle default? */ conf->opts = xconf->opts; conf->csock = strdup(SOCKET_NAME); 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 -- I'm not entirely sure you are real.