Since 128bit address space is not enough add the extra 32bit scope_id to
struct kroute6 so that we can track that as well.
With this using link local addresses as nexthops should work again.
Also the madness is a little bit less bad since we just copy the scope_id
in and out no matter what.
--
:wq Claudio
Index: kroute.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v
retrieving revision 1.269
diff -u -p -r1.269 kroute.c
--- kroute.c 24 Jun 2022 10:36:53 -0000 1.269
+++ kroute.c 25 Jun 2022 16:29:07 -0000
@@ -72,6 +72,8 @@ struct kroute6 {
struct kroute6 *next;
struct in6_addr prefix;
struct in6_addr nexthop;
+ uint32_t prefix_scope_id; /* because ... */
+ uint32_t nexthop_scope_id;
uint32_t mplslabel;
uint16_t flags;
uint16_t labelid;
@@ -582,8 +584,10 @@ kr6_change(struct ktable *kt, struct kro
return (-1);
}
memcpy(&kr6->prefix, &kl->prefix.v6, sizeof(struct in6_addr));
+ kr6->prefix_scope_id = kl->prefix.scope_id;
kr6->prefixlen = kl->prefixlen;
memcpy(&kr6->nexthop, &kl->nexthop.v6, sizeof(struct in6_addr));
+ kr6->nexthop_scope_id = kl->nexthop.scope_id;
kr6->flags = kl->flags | F_BGPD;
kr6->priority = RTP_MINE;
kr6->labelid = labelid;
@@ -595,6 +599,7 @@ kr6_change(struct ktable *kt, struct kro
}
} else {
memcpy(&kr6->nexthop, &kl->nexthop.v6, sizeof(struct in6_addr));
+ kr6->nexthop_scope_id = kl->nexthop.scope_id;
rtlabel_unref(kr6->labelid);
kr6->labelid = labelid;
if (kl->flags & F_BLACKHOLE)
@@ -1623,17 +1628,10 @@ kr6_tofull(struct kroute6 *kr6)
kf.prefix.aid = AID_INET6;
memcpy(&kf.prefix.v6, &kr6->prefix, sizeof(struct in6_addr));
- /* only set scope_id for link-local addresses because IPv6 */
- if (IN6_IS_ADDR_LINKLOCAL(&kr6->prefix) ||
- IN6_IS_ADDR_MC_LINKLOCAL(&kr6->prefix) ||
- IN6_IS_ADDR_MC_NODELOCAL(&kr6->prefix))
- kf.prefix.scope_id = kr6->ifindex;
+ kf.prefix.scope_id = kr6->prefix_scope_id;
kf.nexthop.aid = AID_INET6;
memcpy(&kf.nexthop.v6, &kr6->nexthop, sizeof(struct in6_addr));
- if (IN6_IS_ADDR_LINKLOCAL(&kr6->nexthop) ||
- IN6_IS_ADDR_MC_LINKLOCAL(&kr6->nexthop) ||
- IN6_IS_ADDR_MC_NODELOCAL(&kr6->nexthop))
- kf.nexthop.scope_id = kr6->ifindex;
+ kf.nexthop.scope_id = kr6->nexthop_scope_id;
strlcpy(kf.label, rtlabel_id2name(kr6->labelid), sizeof(kf.label));
kf.flags = kr6->flags;
kf.ifindex = kr6->ifindex;
@@ -2498,11 +2496,13 @@ knexthop_send_update(struct knexthop *kn
n.gateway.aid = AID_INET6;
memcpy(&n.gateway.v6, &kr6->nexthop,
sizeof(struct in6_addr));
+ n.gateway.scope_id = kr6->nexthop_scope_id;
}
if (n.connected) {
n.net.aid = AID_INET6;
memcpy(&n.net.v6, &kr6->prefix,
sizeof(struct in6_addr));
+ n.net.scope_id = kr6->prefix_scope_id;
n.netlen = kr6->prefixlen;
}
break;
@@ -3037,7 +3037,15 @@ send_rt6msg(int fd, int action, struct k
prefix.addr.sin6_family = AF_INET6;
memcpy(&prefix.addr.sin6_addr, &kroute->prefix,
sizeof(struct in6_addr));
- /* XXX scope does not matter or? */
+#ifdef __KAME__
+ /* XXX need to embed the stupid scope for now */
+ if (IN6_IS_ADDR_LINKLOCAL(&kroute->prefix) ||
+ IN6_IS_ADDR_MC_LINKLOCAL(&kroute->prefix) ||
+ IN6_IS_ADDR_MC_NODELOCAL(&kroute->prefix)) {
+ *(u_int16_t *)&prefix.addr.sin6_addr.s6_addr[2] =
+ htons(kroute->prefix_scope_id);
+ }
+#endif
/* adjust header */
hdr.rtm_addrs |= RTA_DST;
hdr.rtm_msglen += ROUNDUP(sizeof(struct sockaddr_in6));
@@ -3051,6 +3059,15 @@ send_rt6msg(int fd, int action, struct k
nexthop.addr.sin6_family = AF_INET6;
memcpy(&nexthop.addr.sin6_addr, &kroute->nexthop,
sizeof(struct in6_addr));
+#ifdef __KAME__
+ /* XXX need to embed the stupid scope for now */
+ if (IN6_IS_ADDR_LINKLOCAL(&kroute->nexthop) ||
+ IN6_IS_ADDR_MC_LINKLOCAL(&kroute->nexthop) ||
+ IN6_IS_ADDR_MC_NODELOCAL(&kroute->nexthop)) {
+ *(u_int16_t *)&nexthop.addr.sin6_addr.s6_addr[2] =
+ htons(kroute->nexthop_scope_id);
+ }
+#endif
/* adjust header */
hdr.rtm_flags |= RTF_GATEWAY;
hdr.rtm_addrs |= RTA_GATEWAY;
@@ -3208,9 +3225,10 @@ fetchtable(struct ktable *kt)
}
kr6->prefix = kl.prefix.v6;
kr6->prefixlen = kl.prefixlen;
- if (kl.nexthop.aid == AID_INET6)
+ if (kl.nexthop.aid == AID_INET6) {
kr6->nexthop = kl.nexthop.v6;
- else
+ kr6->nexthop_scope_id = kl.nexthop.scope_id;
+ } else
kr6->nexthop = in6addr_any;
kr6->flags = kl.flags;
kr6->ifindex = kl.ifindex;
@@ -3687,9 +3705,10 @@ add6:
}
kr6->prefix = kl->prefix.v6;
kr6->prefixlen = kl->prefixlen;
- if (kl->nexthop.aid == AID_INET6)
+ if (kl->nexthop.aid == AID_INET6) {
kr6->nexthop = kl->nexthop.v6;
- else
+ kr6->nexthop_scope_id = kl->nexthop.scope_id;
+ } else
kr6->nexthop = in6addr_any;
kr6->flags = flags;
kr6->ifindex = kl->ifindex;