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 <fab...@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