From: Ondrej Zajicek Date: Thu, 12 Dec 2024 03:04:07 +0000 (+0100) Subject: Netlink: Handle onlink flag on BSD-Netlink X-Git-Tag: v2.17~68 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e0ed978e753c57b65b89e860b49fd29acb0b43ad;p=thirdparty%2Fbird.git Netlink: Handle onlink flag on BSD-Netlink On BSD, the onlink flag is not tracked or reported by kernel. We are using an heuristic that assigns the onlink flag to routes scanned from the kernel. We should use the same heuristic even in BSD-Netlink case, as the onlink flag is not reported here too. Thanks to Björn König for the original patch. --- diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c index d13e20a3e..e8e555af7 100644 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@ -394,30 +394,6 @@ krt_replace_rte(struct krt_proto *p, net *n UNUSED, rte *new, rte *old) } } -/** - * krt_assume_onlink - check if routes on interface are considered onlink - * @iface: The interface of the next hop - * @ipv6: Switch to only consider IPv6 or IPv4 addresses. - * - * The BSD kernel does not support an onlink flag. If the interface has only - * host addresses configured, all routes should be considered as onlink and - * the function returns 1. - */ -static int -krt_assume_onlink(struct iface *iface, int ipv6) -{ - const u8 type = ipv6 ? NET_IP6 : NET_IP4; - - struct ifa *ifa; - WALK_LIST(ifa, iface->addrs) - { - if ((ifa->prefix.type == type) && !(ifa->flags & IA_HOST)) - return 0; - } - - return 1; -} - #define SKIP(ARG...) do { DBG("KRT: Ignoring route - " ARG); return; } while(0) static void diff --git a/sysdep/cf/README b/sysdep/cf/README index af65aaec4..cdaf5da16 100644 --- a/sysdep/cf/README +++ b/sysdep/cf/README @@ -5,6 +5,7 @@ CONFIG_AUTO_ROUTES Device routes are added automagically by the kernel CONFIG_SELF_CONSCIOUS We're able to recognize whether route was installed by us CONFIG_MULTIPLE_TABLES The kernel supports multiple routing tables CONFIG_SINGLE_ROUTE There is only one route per network +CONFIG_ASSUME_ONLINK Assume ONLINK flag on scanned routes based on a heuristic CONFIG_MC_PROPER_SRC Multicast packets have source address according to socket saddr field CONFIG_SKIP_MC_BIND Don't call bind on multicast socket (def for *BSD) diff --git a/sysdep/cf/bsd-netlink.h b/sysdep/cf/bsd-netlink.h index 692978678..a65106a37 100644 --- a/sysdep/cf/bsd-netlink.h +++ b/sysdep/cf/bsd-netlink.h @@ -10,6 +10,7 @@ #define CONFIG_SELF_CONSCIOUS #define CONFIG_MULTIPLE_TABLES #define CONFIG_SINGLE_ROUTE +#define CONFIG_ASSUME_ONLINK #define CONFIG_SKIP_MC_BIND #define CONFIG_NO_IFACE_BIND diff --git a/sysdep/cf/bsd.h b/sysdep/cf/bsd.h index 22c542772..56ba0a1af 100644 --- a/sysdep/cf/bsd.h +++ b/sysdep/cf/bsd.h @@ -10,6 +10,7 @@ #define CONFIG_SELF_CONSCIOUS #define CONFIG_MULTIPLE_TABLES #define CONFIG_SINGLE_ROUTE +#define CONFIG_ASSUME_ONLINK #define CONFIG_SKIP_MC_BIND #define CONFIG_NO_IFACE_BIND diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index 533cc2686..299f132fe 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -788,6 +788,11 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, const net_addr if (ipa_nonzero(rv->gw)) { +#ifdef CONFIG_ASSUME_ONLINK + if (krt_assume_onlink(rv->iface, ipa_is_ip6(rv->gw))) + rv->flags |= RNF_ONLINK; +#endif + neighbor *nbr; nbr = neigh_find(&p->p, rv->gw, rv->iface, (rv->flags & RNF_ONLINK) ? NEF_ONLINK : 0); @@ -1739,6 +1744,11 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h) if ((i->rtm_family == AF_INET6) && ipa_in_netX(ra->nh.gw, (net_addr *) &sit)) return; +#ifdef CONFIG_ASSUME_ONLINK + if (krt_assume_onlink(ra->nh.iface, ipa_is_ip6(ra->nh.gw))) + ra->nh.flags |= RNF_ONLINK; +#endif + neighbor *nbr; nbr = neigh_find(&p->p, ra->nh.gw, ra->nh.iface, (ra->nh.flags & RNF_ONLINK) ? NEF_ONLINK : 0); diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index 51d0718c1..5baaf18b4 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -909,6 +909,30 @@ krt_scan_timer_kick(struct krt_proto *p) tm_start(p->scan_timer, 0); } +/** + * krt_assume_onlink - check if routes on interface are considered onlink + * @iface: The interface of the next hop + * @ipv6: Switch to only consider IPv6 or IPv4 addresses. + * + * The BSD kernel does not support an onlink flag. If the interface has only + * host addresses configured, all routes should be considered as onlink and + * the function returns 1. This is used when CONFIG_ASSUME_ONLINK is set. + */ +int +krt_assume_onlink(struct iface *iface, int ipv6) +{ + const u8 type = ipv6 ? NET_IP6 : NET_IP4; + + struct ifa *ifa; + WALK_LIST(ifa, iface->addrs) + { + if ((ifa->prefix.type == type) && !(ifa->flags & IA_HOST)) + return 0; + } + + return 1; +} + /* * Updates diff --git a/sysdep/unix/krt.h b/sysdep/unix/krt.h index e25f0b125..2b1dfa96d 100644 --- a/sysdep/unix/krt.h +++ b/sysdep/unix/krt.h @@ -83,6 +83,7 @@ void kif_request_scan(void); void krt_use_shared_scan(void); void krt_got_route(struct krt_proto *p, struct rte *e, s8 src); void krt_got_route_async(struct krt_proto *p, struct rte *e, int new, s8 src); +int krt_assume_onlink(struct iface *iface, int ipv6); static inline int krt_get_sync_error(struct krt_proto *p, struct rte *e)