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

ipv4: Use per-netns RTNL helpers in inet_rtm_newaddr().

inet_rtm_to_ifa() and find_matching_ifa() are called
under rtnl_net_lock().

__in_dev_get_rtnl() and in_dev_for_each_ifa_rtnl() there
can use per-netns RTNL helpers.

Let's define and use __in_dev_get_rtnl_net() and
in_dev_for_each_ifa_rtnl_net().

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Kuniyuki Iwashima and committed by
Paolo Abeni
d4b48320 48725778

+13 -4
+9
include/linux/inetdevice.h
··· 226 226 for (ifa = rtnl_dereference((in_dev)->ifa_list); ifa; \ 227 227 ifa = rtnl_dereference(ifa->ifa_next)) 228 228 229 + #define in_dev_for_each_ifa_rtnl_net(net, ifa, in_dev) \ 230 + for (ifa = rtnl_net_dereference(net, (in_dev)->ifa_list); ifa; \ 231 + ifa = rtnl_net_dereference(net, ifa->ifa_next)) 232 + 229 233 #define in_dev_for_each_ifa_rcu(ifa, in_dev) \ 230 234 for (ifa = rcu_dereference((in_dev)->ifa_list); ifa; \ 231 235 ifa = rcu_dereference(ifa->ifa_next)) ··· 254 250 static inline struct in_device *__in_dev_get_rtnl(const struct net_device *dev) 255 251 { 256 252 return rtnl_dereference(dev->ip_ptr); 253 + } 254 + 255 + static inline struct in_device *__in_dev_get_rtnl_net(const struct net_device *dev) 256 + { 257 + return rtnl_net_dereference(dev_net(dev), dev->ip_ptr); 257 258 } 258 259 259 260 /* called with rcu_read_lock or rtnl held */
+4 -4
net/ipv4/devinet.c
··· 901 901 goto errout; 902 902 } 903 903 904 - in_dev = __in_dev_get_rtnl(dev); 904 + in_dev = __in_dev_get_rtnl_net(dev); 905 905 err = -ENOBUFS; 906 906 if (!in_dev) 907 907 goto errout; ··· 948 948 return ERR_PTR(err); 949 949 } 950 950 951 - static struct in_ifaddr *find_matching_ifa(struct in_ifaddr *ifa) 951 + static struct in_ifaddr *find_matching_ifa(struct net *net, struct in_ifaddr *ifa) 952 952 { 953 953 struct in_device *in_dev = ifa->ifa_dev; 954 954 struct in_ifaddr *ifa1; 955 955 956 - in_dev_for_each_ifa_rtnl(ifa1, in_dev) { 956 + in_dev_for_each_ifa_rtnl_net(net, ifa1, in_dev) { 957 957 if (ifa1->ifa_mask == ifa->ifa_mask && 958 958 inet_ifa_match(ifa1->ifa_address, ifa) && 959 959 ifa1->ifa_local == ifa->ifa_local) ··· 989 989 goto unlock; 990 990 } 991 991 992 - ifa_existing = find_matching_ifa(ifa); 992 + ifa_existing = find_matching_ifa(net, ifa); 993 993 if (!ifa_existing) { 994 994 /* It would be best to check for !NLM_F_CREATE here but 995 995 * userspace already relies on not having to provide this.