From ef11db3310e272d3d8dbe8739e0770820dd20e52 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 31 May 2019 18:27:04 +0200 Subject: net: inetdevice: provide replacement iterators for in_ifaddr walk The ifa_list is protected either by rcu or rtnl lock, but the current iterators do not account for this. This adds two iterators as replacement, a later patch in the series will update them with the needed rcu/rtnl_dereference calls. Its not done in this patch yet to avoid sparse warnings -- the fields lack the proper __rcu annotation. Signed-off-by: Florian Westphal Signed-off-by: David S. Miller --- include/linux/inetdevice.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'include/linux/inetdevice.h') diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index 367dc2a0f84a..d5d05503a04b 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -186,7 +186,7 @@ __be32 inet_confirm_addr(struct net *net, struct in_device *in_dev, __be32 dst, struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, __be32 mask); struct in_ifaddr *inet_lookup_ifaddr_rcu(struct net *net, __be32 addr); -static __inline__ bool inet_ifa_match(__be32 addr, struct in_ifaddr *ifa) +static inline bool inet_ifa_match(__be32 addr, const struct in_ifaddr *ifa) { return !((addr^ifa->ifa_address)&ifa->ifa_mask); } @@ -215,6 +215,14 @@ static __inline__ bool bad_mask(__be32 mask, __be32 addr) #define endfor_ifa(in_dev) } +#define in_dev_for_each_ifa_rtnl(ifa, in_dev) \ + for (ifa = (in_dev)->ifa_list; ifa; \ + ifa = ifa->ifa_next) + +#define in_dev_for_each_ifa_rcu(ifa, in_dev) \ + for (ifa = (in_dev)->ifa_list; ifa; \ + ifa = ifa->ifa_next) + static inline struct in_device *__in_dev_get_rcu(const struct net_device *dev) { return rcu_dereference(dev->ip_ptr); -- cgit v1.2.3 From 2638eb8b50cfc16240e0bb080b9afbf541a9b39d Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 31 May 2019 18:27:09 +0200 Subject: net: ipv4: provide __rcu annotation for ifa_list ifa_list is protected by rcu, yet code doesn't reflect this. Add the __rcu annotations and fix up all places that are now reported by sparse. I've done this in the same commit to not add intermediate patches that result in new warnings. Reported-by: Eric Dumazet Signed-off-by: Florian Westphal Signed-off-by: David S. Miller --- include/linux/inetdevice.h | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'include/linux/inetdevice.h') diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index d5d05503a04b..3515ca64e638 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -26,7 +26,7 @@ struct in_device { struct net_device *dev; refcount_t refcnt; int dead; - struct in_ifaddr *ifa_list; /* IP ifaddr chain */ + struct in_ifaddr __rcu *ifa_list;/* IP ifaddr chain */ struct ip_mc_list __rcu *mc_list; /* IP multicast filter chain */ struct ip_mc_list __rcu * __rcu *mc_hash; @@ -136,7 +136,7 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev) struct in_ifaddr { struct hlist_node hash; - struct in_ifaddr *ifa_next; + struct in_ifaddr __rcu *ifa_next; struct in_device *ifa_dev; struct rcu_head rcu_head; __be32 ifa_local; @@ -206,22 +206,13 @@ static __inline__ bool bad_mask(__be32 mask, __be32 addr) return false; } -#define for_primary_ifa(in_dev) { struct in_ifaddr *ifa; \ - for (ifa = (in_dev)->ifa_list; ifa && !(ifa->ifa_flags&IFA_F_SECONDARY); ifa = ifa->ifa_next) - -#define for_ifa(in_dev) { struct in_ifaddr *ifa; \ - for (ifa = (in_dev)->ifa_list; ifa; ifa = ifa->ifa_next) - - -#define endfor_ifa(in_dev) } - #define in_dev_for_each_ifa_rtnl(ifa, in_dev) \ - for (ifa = (in_dev)->ifa_list; ifa; \ - ifa = ifa->ifa_next) + for (ifa = rtnl_dereference((in_dev)->ifa_list); ifa; \ + ifa = rtnl_dereference(ifa->ifa_next)) #define in_dev_for_each_ifa_rcu(ifa, in_dev) \ - for (ifa = (in_dev)->ifa_list; ifa; \ - ifa = ifa->ifa_next) + for (ifa = rcu_dereference((in_dev)->ifa_list); ifa; \ + ifa = rcu_dereference(ifa->ifa_next)) static inline struct in_device *__in_dev_get_rcu(const struct net_device *dev) { -- cgit v1.2.3