This diff is a bit of a cleanup and prepare diff to make the configuration of BGP MPLS VPNs a bit more flexible. Especially there is the request to route traffic through multiple mpe(4) interfaces per rdomain. So this is what this starts to clean up. Remove the static mpe interface in the kroute specific struct and allow the RDE to push this info the the parent.
OK? -- :wq Claudio Index: bgpd.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/bgpd.c,v retrieving revision 1.205 diff -u -p -r1.205 bgpd.c --- bgpd.c 27 Dec 2018 20:23:24 -0000 1.205 +++ bgpd.c 18 Jan 2019 00:25:58 -0000 @@ -487,8 +487,8 @@ reconfigure(char *conffile, struct bgpd_ /* RIBs for the RDE */ while ((rr = SIMPLEQ_FIRST(&ribnames))) { SIMPLEQ_REMOVE_HEAD(&ribnames, entry); - if (ktable_update(rr->rtableid, rr->name, NULL, - rr->flags, conf->fib_priority) == -1) { + if (ktable_update(rr->rtableid, rr->name, rr->flags, + conf->fib_priority) == -1) { log_warnx("failed to load rdomain %d", rr->rtableid); return (-1); @@ -624,8 +624,8 @@ reconfigure(char *conffile, struct bgpd_ while ((rd = SIMPLEQ_FIRST(&conf->rdomains)) != NULL) { SIMPLEQ_REMOVE_HEAD(&conf->rdomains, entry); - if (ktable_update(rd->rtableid, rd->descr, rd->ifmpe, - rd->flags, conf->fib_priority) == -1) { + if (ktable_update(rd->rtableid, rd->descr, rd->flags, + conf->fib_priority) == -1) { log_warnx("failed to load rdomain %d", rd->rtableid); return (-1); Index: bgpd.h =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v retrieving revision 1.361 diff -u -p -r1.361 bgpd.h --- bgpd.h 30 Dec 2018 13:53:07 -0000 1.361 +++ bgpd.h 18 Jan 2019 00:25:26 -0000 @@ -573,14 +573,12 @@ RB_HEAD(knexthop_tree, knexthop_node); struct ktable { char descr[PEER_DESCR_LEN]; - char ifmpe[IFNAMSIZ]; struct kroute_tree krt; struct kroute6_tree krt6; struct knexthop_tree knt; struct network_head krn; u_int rtableid; u_int nhtableid; /* rdomain id for nexthop lookup */ - u_int ifindex; /* ifindex of ifmpe */ int nhrefcnt; /* refcnt for nexthop table */ enum reconf_action state; u_int8_t fib_conf; /* configured FIB sync flag */ @@ -1158,7 +1156,7 @@ RB_PROTOTYPE(prefixset_tree, prefixset_i /* kroute.c */ int kr_init(void); -int ktable_update(u_int, char *, char *, int, u_int8_t); +int ktable_update(u_int, char *, int, u_int8_t); void ktable_preload(void); void ktable_postload(u_int8_t); int ktable_exists(u_int, u_int *); Index: kroute.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v retrieving revision 1.228 diff -u -p -r1.228 kroute.c --- kroute.c 30 Dec 2018 13:53:07 -0000 1.228 +++ kroute.c 18 Jan 2019 00:27:18 -0000 @@ -85,7 +85,7 @@ struct kif_node { struct kif_kr6_head kroute6_l; }; -int ktable_new(u_int, u_int, char *, char *, int, u_int8_t); +int ktable_new(u_int, u_int, 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); @@ -244,8 +244,7 @@ kr_init(void) } int -ktable_new(u_int rtableid, u_int rdomid, char *name, char *ifname, int fs, - u_int8_t fib_prio) +ktable_new(u_int rtableid, u_int rdomid, char *name, int fs, u_int8_t fib_prio) { struct ktable **xkrt; struct ktable *kt; @@ -286,10 +285,6 @@ ktable_new(u_int rtableid, u_int rdomid, kt->nhtableid = rdomid; /* bump refcount of rdomain table for the nexthop lookups */ ktable_get(kt->nhtableid)->nhrefcnt++; - if (ifname) { - strlcpy(kt->ifmpe, ifname, IFNAMSIZ); - kt->ifindex = if_nametoindex(ifname); - } /* ... and load it */ if (fetchtable(kt, fib_prio) == -1) @@ -356,8 +351,7 @@ ktable_get(u_int rtableid) } int -ktable_update(u_int rtableid, char *name, char *ifname, int flags, u_int8_t - fib_prio) +ktable_update(u_int rtableid, char *name, int flags, u_int8_t fib_prio) { struct ktable *kt, *rkt; u_int rdomid; @@ -370,7 +364,7 @@ ktable_update(u_int rtableid, char *name if (rkt == NULL) { char buf[32]; snprintf(buf, sizeof(buf), "rdomain_%d", rdomid); - if (ktable_new(rdomid, rdomid, buf, NULL, 0, fib_prio)) + if (ktable_new(rdomid, rdomid, buf, 0, fib_prio)) return (-1); } else { /* there is no need for full fib synchronisation if @@ -389,7 +383,7 @@ ktable_update(u_int rtableid, char *name kt = ktable_get(rtableid); if (kt == NULL) { - if (ktable_new(rtableid, rdomid, name, ifname, + if (ktable_new(rtableid, rdomid, name, !(flags & F_RIB_NOFIBSYNC), fib_prio)) return (-1); } else { @@ -646,6 +640,7 @@ krVPN4_change(struct ktable *kt, struct kr->r.priority = fib_prio; kr->r.labelid = labelid; kr->r.mplslabel = mplslabel; + kr->r.ifindex = kl->ifindex; if (kroute_insert(kt, kr) == -1) { free(kr); @@ -653,6 +648,7 @@ krVPN4_change(struct ktable *kt, struct } } else { kr->r.mplslabel = mplslabel; + kr->r.ifindex = kl->ifindex; kr->r.nexthop.s_addr = kl->nexthop.v4.s_addr; rtlabel_unref(kr->r.labelid); kr->r.labelid = labelid; @@ -720,6 +716,7 @@ krVPN6_change(struct ktable *kt, struct kr6->r.priority = fib_prio; kr6->r.labelid = labelid; kr6->r.mplslabel = mplslabel; + kr6->r.ifindex = kl->ifindex; if (kroute6_insert(kt, kr6) == -1) { free(kr6); @@ -727,6 +724,7 @@ krVPN6_change(struct ktable *kt, struct } } else { kr6->r.mplslabel = mplslabel; + kr6->r.ifindex = kl->ifindex; memcpy(&kr6->r.nexthop, &kl->nexthop.v6, sizeof(struct in6_addr)); rtlabel_unref(kr6->r.labelid); @@ -2759,20 +2757,19 @@ send_rtmsg(int fd, int action, struct kt iov[iovcnt].iov_base = &mask; iov[iovcnt++].iov_len = sizeof(mask); - if (kt->ifindex) { + if (kroute->flags & F_MPLS) { + /* need to force interface for mpe(4) routes */ bzero(&ifp, sizeof(ifp)); ifp.dl.sdl_len = sizeof(struct sockaddr_dl); ifp.dl.sdl_family = AF_LINK; - ifp.dl.sdl_index = kt->ifindex; + ifp.dl.sdl_index = kroute->ifindex; /* adjust header */ hdr.rtm_addrs |= RTA_IFP; hdr.rtm_msglen += ROUNDUP(sizeof(struct sockaddr_dl)); /* adjust iovec */ iov[iovcnt].iov_base = &ifp; iov[iovcnt++].iov_len = ROUNDUP(sizeof(struct sockaddr_dl)); - } - if (kroute->flags & F_MPLS) { bzero(&mpls, sizeof(mpls)); mpls.smpls_len = sizeof(mpls); mpls.smpls_family = AF_MPLS; @@ -2902,19 +2899,20 @@ send_rt6msg(int fd, int action, struct k iov[iovcnt].iov_base = &mask; iov[iovcnt++].iov_len = ROUNDUP(sizeof(struct sockaddr_in6)); - if (kt->ifindex) { - memset(&ifp, 0, sizeof(ifp)); + if (kroute->flags & F_MPLS) { + /* need to force interface for mpe(4) routes */ + bzero(&ifp, sizeof(ifp)); ifp.dl.sdl_len = sizeof(struct sockaddr_dl); ifp.dl.sdl_family = AF_LINK; - ifp.dl.sdl_index = kt->ifindex; + ifp.dl.sdl_index = kroute->ifindex; + /* adjust header */ hdr.rtm_addrs |= RTA_IFP; hdr.rtm_msglen += ROUNDUP(sizeof(struct sockaddr_dl)); + /* adjust iovec */ iov[iovcnt].iov_base = &ifp; iov[iovcnt++].iov_len = ROUNDUP(sizeof(struct sockaddr_dl)); - } - if (kroute->flags & F_MPLS) { - memset(&mpls, 0, sizeof(mpls)); + bzero(&mpls, sizeof(mpls)); mpls.smpls_len = sizeof(mpls); mpls.smpls_family = AF_MPLS; mpls.smpls_label = kroute->mplslabel; Index: rde.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v retrieving revision 1.458 diff -u -p -r1.458 rde.c --- rde.c 31 Dec 2018 08:53:09 -0000 1.458 +++ rde.c 18 Jan 2019 02:36:04 -0000 @@ -2579,6 +2579,8 @@ rde_send_kroute(struct rib *rib, struct memcpy(&kr.nexthop, &prefix_nexthop(p)->exit_nexthop, sizeof(kr.nexthop)); + /* XXX not ideal but this will change */ + kr.ifindex = if_nametoindex(rd->ifmpe); if (imsg_compose(ibuf_main, type, rd->rtableid, 0, -1, &kr, sizeof(kr)) == -1) fatal("%s %d imsg_compose error", __func__,