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


-- 
I'm not entirely sure you are real.

Reply via email to