| From fc863f52a731724f375a77bf82a491a1eef2bfd5 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 23 Sep 2021 23:03:19 +0800 |
| Subject: net: ipv4: Fix rtnexthop len when RTA_FLOW is present |
| |
| From: Xiao Liang <shaw.leon@gmail.com> |
| |
| [ Upstream commit 597aa16c782496bf74c5dc3b45ff472ade6cee64 ] |
| |
| 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> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| include/net/ip_fib.h | 2 +- |
| include/net/nexthop.h | 2 +- |
| net/ipv4/fib_semantics.c | 16 +++++++++------- |
| net/ipv6/route.c | 5 +++-- |
| 4 files changed, 14 insertions(+), 11 deletions(-) |
| |
| diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h |
| index 2ec062aaa978..4d431d7b4415 100644 |
| --- a/include/net/ip_fib.h |
| +++ b/include/net/ip_fib.h |
| @@ -553,5 +553,5 @@ int ip_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh, |
| int fib_nexthop_info(struct sk_buff *skb, const struct fib_nh_common *nh, |
| u8 rt_family, unsigned char *flags, bool skip_oif); |
| int fib_add_nexthop(struct sk_buff *skb, const struct fib_nh_common *nh, |
| - int nh_weight, u8 rt_family); |
| + int nh_weight, u8 rt_family, u32 nh_tclassid); |
| #endif /* _NET_FIB_H */ |
| diff --git a/include/net/nexthop.h b/include/net/nexthop.h |
| index 4c8c9fe9a3f0..fd87d727aa21 100644 |
| --- a/include/net/nexthop.h |
| +++ b/include/net/nexthop.h |
| @@ -211,7 +211,7 @@ int nexthop_mpath_fill_node(struct sk_buff *skb, struct nexthop *nh, |
| struct fib_nh_common *nhc = &nhi->fib_nhc; |
| int weight = nhg->nh_entries[i].weight; |
| |
| - if (fib_add_nexthop(skb, nhc, weight, rt_family) < 0) |
| + if (fib_add_nexthop(skb, nhc, weight, rt_family, 0) < 0) |
| return -EMSGSIZE; |
| } |
| |
| diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c |
| index 1f75dc686b6b..642503e89924 100644 |
| --- a/net/ipv4/fib_semantics.c |
| +++ b/net/ipv4/fib_semantics.c |
| @@ -1663,7 +1663,7 @@ EXPORT_SYMBOL_GPL(fib_nexthop_info); |
| |
| #if IS_ENABLED(CONFIG_IP_ROUTE_MULTIPATH) || IS_ENABLED(CONFIG_IPV6) |
| int fib_add_nexthop(struct sk_buff *skb, const struct fib_nh_common *nhc, |
| - int nh_weight, u8 rt_family) |
| + int nh_weight, u8 rt_family, u32 nh_tclassid) |
| { |
| const struct net_device *dev = nhc->nhc_dev; |
| struct rtnexthop *rtnh; |
| @@ -1681,6 +1681,9 @@ int fib_add_nexthop(struct sk_buff *skb, const struct fib_nh_common *nhc, |
| |
| rtnh->rtnh_flags = flags; |
| |
| + if (nh_tclassid && nla_put_u32(skb, RTA_FLOW, nh_tclassid)) |
| + goto nla_put_failure; |
| + |
| /* length of rtnetlink header + attributes */ |
| rtnh->rtnh_len = nlmsg_get_pos(skb) - (void *)rtnh; |
| |
| @@ -1708,14 +1711,13 @@ static int fib_add_multipath(struct sk_buff *skb, struct fib_info *fi) |
| } |
| |
| for_nexthops(fi) { |
| - if (fib_add_nexthop(skb, &nh->nh_common, nh->fib_nh_weight, |
| - AF_INET) < 0) |
| - goto nla_put_failure; |
| + u32 nh_tclassid = 0; |
| #ifdef CONFIG_IP_ROUTE_CLASSID |
| - if (nh->nh_tclassid && |
| - nla_put_u32(skb, RTA_FLOW, nh->nh_tclassid)) |
| - goto nla_put_failure; |
| + nh_tclassid = nh->nh_tclassid; |
| #endif |
| + if (fib_add_nexthop(skb, &nh->nh_common, nh->fib_nh_weight, |
| + AF_INET, nh_tclassid) < 0) |
| + goto nla_put_failure; |
| } endfor_nexthops(fi); |
| |
| mp_end: |
| diff --git a/net/ipv6/route.c b/net/ipv6/route.c |
| index 168a7b4d957a..a68a7d7c0728 100644 |
| --- a/net/ipv6/route.c |
| +++ b/net/ipv6/route.c |
| @@ -5566,14 +5566,15 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb, |
| goto nla_put_failure; |
| |
| if (fib_add_nexthop(skb, &rt->fib6_nh->nh_common, |
| - rt->fib6_nh->fib_nh_weight, AF_INET6) < 0) |
| + rt->fib6_nh->fib_nh_weight, AF_INET6, |
| + 0) < 0) |
| goto nla_put_failure; |
| |
| list_for_each_entry_safe(sibling, next_sibling, |
| &rt->fib6_siblings, fib6_siblings) { |
| if (fib_add_nexthop(skb, &sibling->fib6_nh->nh_common, |
| sibling->fib6_nh->fib_nh_weight, |
| - AF_INET6) < 0) |
| + AF_INET6, 0) < 0) |
| goto nla_put_failure; |
| } |
| |
| -- |
| 2.33.0 |
| |