Jon Williams([email protected]) on 2018.09.25 16:51:25 -0400:
> >Synopsis: Newly connected rtlabel networks are not advertised by bgpd
> >Category: system
> >Environment:
> System : OpenBSD 6.3
> Details : OpenBSD 6.3 (GENERIC.MP) #107: Sat Mar 24 14:21:59 MDT 2018
> [email protected]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
>
> Architecture: OpenBSD.amd64
> Machine : amd64
> >Description:
> "network (inet|inet6) rtlabel" should pick up new routes with the label.
> >How-To-Repeat:
> 1) Run bgpd with a configuration containing:
>
> network inet rtlabel export
>
> Add a route with this label and start bgpd.
>
> `bgpctl show network` will contain this route
>
> Delete the route and recreate it. `bgpctl show network` will *not* contain
> this route.
>
> 2) Run bgpd with a configuration containing:
>
> network inet static
>
> Add a static route and start bgpd.
>
> `bgpctl show network` will contain this route
>
> Delete the route and recreate it. `bgpctl show network` will contain this
> route.
Here is a possible fix for your problem, please test.
Diff is against -current.
If you apply this on 6.3, diff will show
Hunk #1 succeeded at 3146 (offset -31 lines).
...
That should be ok.
diff --git usr.sbin/bgpd/kroute.c usr.sbin/bgpd/kroute.c
index 99bda3c50a3..21a2ab27a8c 100644
--- usr.sbin/bgpd/kroute.c
+++ usr.sbin/bgpd/kroute.c
@@ -3177,10 +3177,12 @@ dispatch_rtmsg_addr(struct rt_msghdr *rtm, struct
sockaddr *rti_info[RTAX_MAX],
struct sockaddr *sa;
struct sockaddr_in *sa_in;
struct sockaddr_in6 *sa_in6;
+ struct sockaddr_rtlabel *label;
struct kroute_node *kr;
struct kroute6_node *kr6;
struct bgpd_addr prefix;
int flags, oflags, mpath = 0, changed = 0;
+ int rtlabel_changed = 0;
u_int16_t ifindex;
u_int8_t prefixlen;
u_int8_t prio;
@@ -3209,6 +3211,8 @@ dispatch_rtmsg_addr(struct rt_msghdr *rtm, struct
sockaddr *rti_info[RTAX_MAX],
#endif
prio = rtm->rtm_priority;
+ label = (struct sockaddr_rtlabel *)rti_info[RTAX_LABEL];
+
switch (sa->sa_family) {
case AF_INET:
prefix.aid = AID_INET;
@@ -3340,10 +3344,37 @@ dispatch_rtmsg_addr(struct rt_msghdr *rtm, struct
sockaddr *rti_info[RTAX_MAX],
if (kr->r.flags & F_NEXTHOP)
flags |= F_NEXTHOP;
+
+ if (label != NULL) {
+ rtlabel_unref(kr->r.labelid);
+ kr->r.labelid = 0;
+ flags |= F_RTLABEL;
+ kr->r.labelid =
+ rtlabel_name2id(label->sr_label);
+ rtlabel_changed = 1;
+ } else if (kr->r.labelid && label == NULL) {
+ rtlabel_unref(kr->r.labelid);
+ kr->r.labelid = 0;
+ flags &= ~F_RTLABEL;
+ rtlabel_changed = 1;
+ }
+
oflags = kr->r.flags;
if (flags != oflags)
changed = 1;
kr->r.flags = flags;
+
+ if (rtlabel_changed) {
+ if (oflags & F_REDISTRIBUTED) {
+ kr->r.flags |= F_REDISTRIBUTED;
+ kr_redistribute(
+ IMSG_NETWORK_REMOVE, kt,
+ &kr->r);
+ }
+ kr_redistribute(IMSG_NETWORK_ADD,
+ kt, &kr->r);
+ }
+
if ((oflags & F_CONNECTED) &&
!(flags & F_CONNECTED)) {
kif_kr_remove(kr);
@@ -3380,6 +3411,9 @@ add4:
kr->r.ifindex = ifindex;
kr->r.priority = prio;
+ kr->r.flags |= F_RTLABEL;
+ kr->r.labelid = rtlabel_name2id(label->sr_label);
+
kroute_insert(kt, kr);
}
break;
@@ -3418,10 +3452,37 @@ add4:
if (kr6->r.flags & F_NEXTHOP)
flags |= F_NEXTHOP;
+
+ if (label != NULL) {
+ rtlabel_unref(kr6->r.labelid);
+ kr6->r.labelid = 0;
+ flags |= F_RTLABEL;
+ kr6->r.labelid =
+ rtlabel_name2id(label->sr_label);
+ rtlabel_changed = 1;
+ } else if (kr6->r.labelid && label == NULL) {
+ rtlabel_unref(kr6->r.labelid);
+ kr6->r.labelid = 0;
+ flags &= ~F_RTLABEL;
+ rtlabel_changed = 1;
+ }
+
oflags = kr6->r.flags;
if (flags != oflags)
changed = 1;
kr6->r.flags = flags;
+
+ if (rtlabel_changed) {
+ if (oflags & F_REDISTRIBUTED) {
+ kr6->r.flags |= F_REDISTRIBUTED;
+ kr_redistribute6(
+ IMSG_NETWORK_REMOVE, kt,
+ &kr6->r);
+ }
+ kr_redistribute6(IMSG_NETWORK_ADD,
+ kt, &kr6->r);
+ }
+
if ((oflags & F_CONNECTED) &&
!(flags & F_CONNECTED)) {
kif_kr6_remove(kr6);
@@ -3434,6 +3495,7 @@ add4:
kr_redistribute6(IMSG_NETWORK_ADD,
kt, &kr6->r);
}
+
if (kr6->r.flags & F_NEXTHOP && changed)
knexthop_track(kt, kr6);
}
@@ -3461,6 +3523,9 @@ add6:
kr6->r.ifindex = ifindex;
kr6->r.priority = prio;
+ kr6->r.flags |= F_RTLABEL;
+ kr6->r.labelid = rtlabel_name2id(label->sr_label);
+
kroute6_insert(kt, kr6);
}
break;