It is quite common to want to do a cross-protocol readvertisement from IGP->EGP. We can add rtlabels in bgpd and ospfd, but only advertise in ospfd.
This diff lets bgpd announce routes based on rtlabels. The existing "cannot announce routes that point to localhost" and "cannot announce defaults" still apply. Should they? OK? Index: bgpd.conf.5 =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/bgpd.conf.5,v retrieving revision 1.146 diff -u -p -u -p -r1.146 bgpd.conf.5 --- bgpd.conf.5 17 Aug 2016 08:14:40 -0000 1.146 +++ bgpd.conf.5 14 Sep 2016 14:21:52 -0000 @@ -268,6 +268,10 @@ Log received and sent updates. .Pq Ic inet Ns | Ns Ic inet6 .Ic connected Op Ic set ...\& .Xc +.It Xo +.Ic network +.Ic rtlabel Ar label Op Ic set ...\& +.Xc Announce the specified network as belonging to our AS. If set to .Ic connected , @@ -275,6 +279,11 @@ routes to directly attached networks wil If set to .Ic static , all static routes will be announced. +If set to +.Ic rtlabel , +routes with the specified +.Ar label +will be announced. .Bd -literal -offset indent network 192.168.7.0/24 .Ed Index: bgpd.h =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v retrieving revision 1.295 diff -u -p -u -p -r1.295 bgpd.h --- bgpd.h 2 Sep 2016 14:00:29 -0000 1.295 +++ bgpd.h 14 Sep 2016 14:21:52 -0000 @@ -85,6 +85,7 @@ #define F_CTL_ADJ_IN 0x2000 #define F_CTL_ADJ_OUT 0x4000 #define F_CTL_ACTIVE 0x8000 +#define F_RTLABEL 0x10000 /* * Limit the number of control messages generated by the RDE and queued in @@ -334,6 +335,7 @@ enum network_type { NETWORK_DEFAULT, NETWORK_STATIC, NETWORK_CONNECTED, + NETWORK_RTLABEL, NETWORK_MRTCLONE }; @@ -342,6 +344,7 @@ struct network_config { struct filter_set_head attrset; struct rde_aspath *asp; u_int rtableid; + u_int16_t rtlabel; enum network_type type; u_int8_t prefixlen; u_int8_t old; /* used for reloading */ @@ -507,6 +510,7 @@ struct kroute_full { struct bgpd_addr prefix; struct bgpd_addr nexthop; char label[RTLABEL_LEN]; + u_int16_t labelid; u_int16_t flags; u_short ifindex; u_int8_t prefixlen; Index: kroute.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v retrieving revision 1.209 diff -u -p -u -p -r1.209 kroute.c --- kroute.c 8 Apr 2016 12:27:05 -0000 1.209 +++ kroute.c 14 Sep 2016 14:21:52 -0000 @@ -1111,6 +1111,10 @@ kr_net_match(struct ktable *kt, struct k if (kr->flags & F_CONNECTED) return (xn); break; + case NETWORK_RTLABEL: + if (kr->labelid == xn->net.rtlabel) + return (xn); + break; case NETWORK_MRTCLONE: /* can not happen */ break; @@ -1143,6 +1147,10 @@ kr_net_match6(struct ktable *kt, struct if (kr6->flags & F_CONNECTED) return (xn); break; + case NETWORK_RTLABEL: + if (kr6->labelid == xn->net.rtlabel) + return (xn); + break; case NETWORK_MRTCLONE: /* can not happen */ break; @@ -1269,6 +1277,7 @@ sendit: net.prefix.aid = AID_INET; net.prefix.v4.s_addr = kr->prefix.s_addr; net.prefixlen = kr->prefixlen; + net.rtlabel = kr->labelid; net.rtableid = kt->rtableid; return (send_network(type, &net, match ? &match->net.attrset : NULL)); @@ -1337,6 +1346,7 @@ sendit: net.prefix.aid = AID_INET6; memcpy(&net.prefix.v6, &kr6->prefix, sizeof(struct in6_addr)); net.prefixlen = kr6->prefixlen; + net.rtlabel = kr6->labelid; net.rtableid = kt->rtableid; return (send_network(type, &net, match ? &match->net.attrset : NULL)); @@ -1392,6 +1402,7 @@ kr_tofull(struct kroute *kr) kf.nexthop.aid = AID_INET; kf.nexthop.v4.s_addr = kr->nexthop.s_addr; strlcpy(kf.label, rtlabel_id2name(kr->labelid), sizeof(kf.label)); + kf.labelid = kr->labelid; kf.flags = kr->flags; kf.ifindex = kr->ifindex; kf.prefixlen = kr->prefixlen; @@ -1412,6 +1423,7 @@ kr6_tofull(struct kroute6 *kr6) kf.nexthop.aid = AID_INET6; memcpy(&kf.nexthop.v6, &kr6->nexthop, sizeof(struct in6_addr)); strlcpy(kf.label, rtlabel_id2name(kr6->labelid), sizeof(kf.label)); + kf.labelid = kr6->labelid; kf.flags = kr6->flags; kf.ifindex = kr6->ifindex; kf.prefixlen = kr6->prefixlen; @@ -2780,6 +2792,7 @@ fetchtable(struct ktable *kt, u_int8_t f struct sockaddr *sa, *gw, *rti_info[RTAX_MAX]; struct sockaddr_in *sa_in; struct sockaddr_in6 *sa_in6; + struct sockaddr_rtlabel *label; struct kroute_node *kr = NULL; struct kroute6_node *kr6 = NULL; @@ -2858,6 +2871,14 @@ fetchtable(struct ktable *kt, u_int8_t f else kr->r.prefixlen = prefixlen_classful(kr->r.prefix.s_addr); + rtlabel_unref(kr->r.labelid); + kr->r.labelid = 0; + if ((label = (struct sockaddr_rtlabel *) + rti_info[RTAX_LABEL]) != NULL) { + kr->r.flags |= F_RTLABEL; + kr->r.labelid = + rtlabel_name2id(label->sr_label); + } break; case AF_INET6: if ((kr6 = calloc(1, sizeof(struct kroute6_node))) == @@ -2891,6 +2912,14 @@ fetchtable(struct ktable *kt, u_int8_t f kr6->r.prefixlen = 128; else fatalx("INET6 route without netmask"); + rtlabel_unref(kr6->r.labelid); + kr6->r.labelid = 0; + if ((label = (struct sockaddr_rtlabel *) + rti_info[RTAX_LABEL]) != NULL) { + kr6->r.flags |= F_RTLABEL; + kr6->r.labelid = + rtlabel_name2id(label->sr_label); + } break; default: continue; Index: parse.y =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v retrieving revision 1.288 diff -u -p -u -p -r1.288 parse.y --- parse.y 21 Jun 2016 21:35:24 -0000 1.288 +++ parse.y 14 Sep 2016 14:21:52 -0000 @@ -674,6 +674,25 @@ network : NETWORK prefix filter_set { TAILQ_INSERT_TAIL(netconf, n, entry); } + | NETWORK family RTLABEL STRING filter_set { + struct network *n; + + 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_RTLABEL; + n->net.rtlabel = rtlabel_name2id($4); + filterset_move($5, &n->net.attrset); + free($5); + + TAILQ_INSERT_TAIL(netconf, n, entry); + } | NETWORK family nettype filter_set { struct network *n; Index: printconf.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v retrieving revision 1.97 diff -u -p -u -p -r1.97 printconf.c --- printconf.c 13 Jul 2016 20:07:38 -0000 1.97 +++ printconf.c 14 Sep 2016 14:21:52 -0000 @@ -336,6 +336,10 @@ print_network(struct network_config *n, case NETWORK_CONNECTED: printf("%snetwork %s connected", c, print_af(n->prefix.aid)); break; + case NETWORK_RTLABEL: + printf("%snetwork %s rtlabel \"%s\"", c, + print_af(n->prefix.aid), rtlabel_id2name(n->rtlabel)); + break; default: printf("%snetwork %s/%u", c, log_addr(&n->prefix), n->prefixlen); -- In 1915 pancake make-up was invented but most people still preferred syrup.