Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: ipv4: Fix rtnexthop len when RTA_FLOW is present

Multipath RTA_FLOW is embedded in nexthop. Dump it in fib_add_nexthop()
to get the length of rtnexthop correct.

Fixes: b0f60193632e ("ipv4: Refactor nexthop attributes in fib_dump_info")
Signed-off-by: Xiao Liang <shaw.leon@gmail.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Xiao Liang and committed by
David S. Miller
597aa16c 325fd36a

+14 -11
+1 -1
include/net/ip_fib.h
··· 597 597 int fib_nexthop_info(struct sk_buff *skb, const struct fib_nh_common *nh, 598 598 u8 rt_family, unsigned char *flags, bool skip_oif); 599 599 int fib_add_nexthop(struct sk_buff *skb, const struct fib_nh_common *nh, 600 - int nh_weight, u8 rt_family); 600 + int nh_weight, u8 rt_family, u32 nh_tclassid); 601 601 #endif /* _NET_FIB_H */
+1 -1
include/net/nexthop.h
··· 325 325 struct fib_nh_common *nhc = &nhi->fib_nhc; 326 326 int weight = nhg->nh_entries[i].weight; 327 327 328 - if (fib_add_nexthop(skb, nhc, weight, rt_family) < 0) 328 + if (fib_add_nexthop(skb, nhc, weight, rt_family, 0) < 0) 329 329 return -EMSGSIZE; 330 330 } 331 331
+9 -7
net/ipv4/fib_semantics.c
··· 1661 1661 1662 1662 #if IS_ENABLED(CONFIG_IP_ROUTE_MULTIPATH) || IS_ENABLED(CONFIG_IPV6) 1663 1663 int fib_add_nexthop(struct sk_buff *skb, const struct fib_nh_common *nhc, 1664 - int nh_weight, u8 rt_family) 1664 + int nh_weight, u8 rt_family, u32 nh_tclassid) 1665 1665 { 1666 1666 const struct net_device *dev = nhc->nhc_dev; 1667 1667 struct rtnexthop *rtnh; ··· 1678 1678 goto nla_put_failure; 1679 1679 1680 1680 rtnh->rtnh_flags = flags; 1681 + 1682 + if (nh_tclassid && nla_put_u32(skb, RTA_FLOW, nh_tclassid)) 1683 + goto nla_put_failure; 1681 1684 1682 1685 /* length of rtnetlink header + attributes */ 1683 1686 rtnh->rtnh_len = nlmsg_get_pos(skb) - (void *)rtnh; ··· 1709 1706 } 1710 1707 1711 1708 for_nexthops(fi) { 1712 - if (fib_add_nexthop(skb, &nh->nh_common, nh->fib_nh_weight, 1713 - AF_INET) < 0) 1714 - goto nla_put_failure; 1709 + u32 nh_tclassid = 0; 1715 1710 #ifdef CONFIG_IP_ROUTE_CLASSID 1716 - if (nh->nh_tclassid && 1717 - nla_put_u32(skb, RTA_FLOW, nh->nh_tclassid)) 1718 - goto nla_put_failure; 1711 + nh_tclassid = nh->nh_tclassid; 1719 1712 #endif 1713 + if (fib_add_nexthop(skb, &nh->nh_common, nh->fib_nh_weight, 1714 + AF_INET, nh_tclassid) < 0) 1715 + goto nla_put_failure; 1720 1716 } endfor_nexthops(fi); 1721 1717 1722 1718 mp_end:
+3 -2
net/ipv6/route.c
··· 5681 5681 goto nla_put_failure; 5682 5682 5683 5683 if (fib_add_nexthop(skb, &rt->fib6_nh->nh_common, 5684 - rt->fib6_nh->fib_nh_weight, AF_INET6) < 0) 5684 + rt->fib6_nh->fib_nh_weight, AF_INET6, 5685 + 0) < 0) 5685 5686 goto nla_put_failure; 5686 5687 5687 5688 list_for_each_entry_safe(sibling, next_sibling, 5688 5689 &rt->fib6_siblings, fib6_siblings) { 5689 5690 if (fib_add_nexthop(skb, &sibling->fib6_nh->nh_common, 5690 5691 sibling->fib6_nh->fib_nh_weight, 5691 - AF_INET6) < 0) 5692 + AF_INET6, 0) < 0) 5692 5693 goto nla_put_failure; 5693 5694 } 5694 5695