[PATCH] sysdep/linux: fix IPv4-via-IPv6 with disabled MPLS kernel

Fabian Bläse fabian at blaese.de
Tue Apr 22 16:49:27 CEST 2025


When support for IPv4-via-IPv6 was added, the MPLS functions for adding
the RTA_VIA attribute were reused. However, instead of moving
nl_add_attr_via() out of the HAVE_MPLS_KERNEL ifdep block, the
IPv4-via-IPv6 feature was added into a HAVE_MPLS_KERNEL block, despite
being a distinct non-MPLS feature.

This leads to netlink errors when IPv4-via-IPv6 routes are installed,
because the IPv6 VIA is added to a RTA_GATEWAY attribute. The
RTA_GATEWAY attribute does not support IPv4-via-IPv6 resulting in
an invalid length error.

Move the nl_add_attr_via() function and calls to it out of the
HAVE_MPLS_KERNEL blocks and merge duplicate code into a single if-else
distinction.

Fixes: 53401bef63013dfee01b65d071ffbd88e457539f

Signed-off-by: Fabian Bläse <fabian at blaese.de>
---
 sysdep/linux/netlink.c | 44 +++++++++++++++++++-----------------------
 1 file changed, 20 insertions(+), 24 deletions(-)

diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c
index 299f132f..18af6014 100644
--- a/sysdep/linux/netlink.c
+++ b/sysdep/linux/netlink.c
@@ -601,25 +601,6 @@ nl_add_attr_ipa(struct nlmsghdr *h, uint bufsize, int code, ip_addr ipa)
     nl_add_attr_ip6(h, bufsize, code, ipa_to_ip6(ipa));
 }
 
-#ifdef HAVE_MPLS_KERNEL
-static inline void
-nl_add_attr_mpls(struct nlmsghdr *h, uint bufsize, int code, int len, u32 *stack)
-{
-  char buf[len*4];
-  mpls_put(buf, len, stack);
-  nl_add_attr(h, bufsize, code, buf, len*4);
-}
-
-static inline void
-nl_add_attr_mpls_encap(struct nlmsghdr *h, uint bufsize, int len, u32 *stack)
-{
-  nl_add_attr_u16(h, bufsize, RTA_ENCAP_TYPE, LWTUNNEL_ENCAP_MPLS);
-
-  struct rtattr *nest = nl_open_attr(h, bufsize, RTA_ENCAP);
-  nl_add_attr_mpls(h, bufsize, RTA_DST, len, stack);
-  nl_close_attr(h, nest);
-}
-
 static inline void
 nl_add_attr_via(struct nlmsghdr *h, uint bufsize, ip_addr ipa)
 {
@@ -638,6 +619,25 @@ nl_add_attr_via(struct nlmsghdr *h, uint bufsize, ip_addr ipa)
     nl_add_attr(h, bufsize, RTA_VIA, via, sizeof(struct rtvia) + 16);
   }
 }
+
+#ifdef HAVE_MPLS_KERNEL
+static inline void
+nl_add_attr_mpls(struct nlmsghdr *h, uint bufsize, int code, int len, u32 *stack)
+{
+  char buf[len*4];
+  mpls_put(buf, len, stack);
+  nl_add_attr(h, bufsize, code, buf, len*4);
+}
+
+static inline void
+nl_add_attr_mpls_encap(struct nlmsghdr *h, uint bufsize, int len, u32 *stack)
+{
+  nl_add_attr_u16(h, bufsize, RTA_ENCAP_TYPE, LWTUNNEL_ENCAP_MPLS);
+
+  struct rtattr *nest = nl_open_attr(h, bufsize, RTA_ENCAP);
+  nl_add_attr_mpls(h, bufsize, RTA_DST, len, stack);
+  nl_close_attr(h, nest);
+}
 #endif
 
 static inline struct rtnexthop *
@@ -669,6 +669,7 @@ nl_add_nexthop(struct nlmsghdr *h, uint bufsize, struct nexthop *nh, int af UNUS
       nl_add_attr_mpls(h, bufsize, RTA_NEWDST, nh->labels, nh->label);
     else
       nl_add_attr_mpls_encap(h, bufsize, nh->labels, nh->label);
+#endif
 
   if (ipa_nonzero(nh->gw))
   {
@@ -677,11 +678,6 @@ nl_add_nexthop(struct nlmsghdr *h, uint bufsize, struct nexthop *nh, int af UNUS
     else
       nl_add_attr_via(h, bufsize, nh->gw);
   }
-#else
-
-  if (ipa_nonzero(nh->gw))
-    nl_add_attr_ipa(h, bufsize, RTA_GATEWAY, nh->gw);
-#endif
 }
 
 static void
-- 
2.49.0



More information about the Bird-users mailing list