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

ipv6: fix omitted netlink attributes when using RTEXT_FILTER_SKIP_STATS

Using RTEXT_FILTER_SKIP_STATS is incorrectly skipping non-stats IPv6
netlink attributes on link dump. This causes issues on userspace tools,
e.g iproute2 is not rendering address generation mode as it should due
to missing netlink attribute.

Move the filling of IFLA_INET6_STATS and IFLA_INET6_ICMP6STATS to a
helper function guarded by a flag check to avoid hitting the same
situation in the future.

Fixes: d5566fd72ec1 ("rtnetlink: RTEXT_FILTER_SKIP_STATS support to avoid dumping inet/inet6 stats")
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250402121751.3108-1-ffmancera@riseup.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Fernando Fernandez Mancera and committed by
Jakub Kicinski
7ac6ea4a e4546c64

+25 -12
+25 -12
net/ipv6/addrconf.c
··· 5784 5784 } 5785 5785 } 5786 5786 5787 + static int inet6_fill_ifla6_stats_attrs(struct sk_buff *skb, 5788 + struct inet6_dev *idev) 5789 + { 5790 + struct nlattr *nla; 5791 + 5792 + nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64)); 5793 + if (!nla) 5794 + goto nla_put_failure; 5795 + snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla)); 5796 + 5797 + nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64)); 5798 + if (!nla) 5799 + goto nla_put_failure; 5800 + snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla)); 5801 + 5802 + return 0; 5803 + 5804 + nla_put_failure: 5805 + return -EMSGSIZE; 5806 + } 5807 + 5787 5808 static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev, 5788 5809 u32 ext_filter_mask) 5789 5810 { ··· 5827 5806 5828 5807 /* XXX - MC not implemented */ 5829 5808 5830 - if (ext_filter_mask & RTEXT_FILTER_SKIP_STATS) 5831 - return 0; 5832 - 5833 - nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64)); 5834 - if (!nla) 5835 - goto nla_put_failure; 5836 - snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla)); 5837 - 5838 - nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64)); 5839 - if (!nla) 5840 - goto nla_put_failure; 5841 - snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla)); 5809 + if (!(ext_filter_mask & RTEXT_FILTER_SKIP_STATS)) { 5810 + if (inet6_fill_ifla6_stats_attrs(skb, idev) < 0) 5811 + goto nla_put_failure; 5812 + } 5842 5813 5843 5814 nla = nla_reserve(skb, IFLA_INET6_TOKEN, sizeof(struct in6_addr)); 5844 5815 if (!nla)