.. | .. |
---|
26 | 26 | struct net_device *dev; |
---|
27 | 27 | refcount_t refcnt; |
---|
28 | 28 | int dead; |
---|
29 | | - struct in_ifaddr *ifa_list; /* IP ifaddr chain */ |
---|
| 29 | + struct in_ifaddr __rcu *ifa_list;/* IP ifaddr chain */ |
---|
30 | 30 | |
---|
31 | 31 | struct ip_mc_list __rcu *mc_list; /* IP multicast filter chain */ |
---|
32 | 32 | struct ip_mc_list __rcu * __rcu *mc_hash; |
---|
.. | .. |
---|
136 | 136 | |
---|
137 | 137 | struct in_ifaddr { |
---|
138 | 138 | struct hlist_node hash; |
---|
139 | | - struct in_ifaddr *ifa_next; |
---|
| 139 | + struct in_ifaddr __rcu *ifa_next; |
---|
140 | 140 | struct in_device *ifa_dev; |
---|
141 | 141 | struct rcu_head rcu_head; |
---|
142 | 142 | __be32 ifa_local; |
---|
.. | .. |
---|
178 | 178 | |
---|
179 | 179 | int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b); |
---|
180 | 180 | int devinet_ioctl(struct net *net, unsigned int cmd, struct ifreq *); |
---|
| 181 | +#ifdef CONFIG_INET |
---|
| 182 | +int inet_gifconf(struct net_device *dev, char __user *buf, int len, int size); |
---|
| 183 | +#else |
---|
| 184 | +static inline int inet_gifconf(struct net_device *dev, char __user *buf, |
---|
| 185 | + int len, int size) |
---|
| 186 | +{ |
---|
| 187 | + return 0; |
---|
| 188 | +} |
---|
| 189 | +#endif |
---|
181 | 190 | void devinet_init(void); |
---|
182 | 191 | struct in_device *inetdev_by_index(struct net *, int); |
---|
183 | 192 | __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope); |
---|
.. | .. |
---|
186 | 195 | struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, |
---|
187 | 196 | __be32 mask); |
---|
188 | 197 | struct in_ifaddr *inet_lookup_ifaddr_rcu(struct net *net, __be32 addr); |
---|
189 | | -static __inline__ bool inet_ifa_match(__be32 addr, struct in_ifaddr *ifa) |
---|
| 198 | +static inline bool inet_ifa_match(__be32 addr, const struct in_ifaddr *ifa) |
---|
190 | 199 | { |
---|
191 | 200 | return !((addr^ifa->ifa_address)&ifa->ifa_mask); |
---|
192 | 201 | } |
---|
.. | .. |
---|
206 | 215 | return false; |
---|
207 | 216 | } |
---|
208 | 217 | |
---|
209 | | -#define for_primary_ifa(in_dev) { struct in_ifaddr *ifa; \ |
---|
210 | | - for (ifa = (in_dev)->ifa_list; ifa && !(ifa->ifa_flags&IFA_F_SECONDARY); ifa = ifa->ifa_next) |
---|
| 218 | +#define in_dev_for_each_ifa_rtnl(ifa, in_dev) \ |
---|
| 219 | + for (ifa = rtnl_dereference((in_dev)->ifa_list); ifa; \ |
---|
| 220 | + ifa = rtnl_dereference(ifa->ifa_next)) |
---|
211 | 221 | |
---|
212 | | -#define for_ifa(in_dev) { struct in_ifaddr *ifa; \ |
---|
213 | | - for (ifa = (in_dev)->ifa_list; ifa; ifa = ifa->ifa_next) |
---|
214 | | - |
---|
215 | | - |
---|
216 | | -#define endfor_ifa(in_dev) } |
---|
| 222 | +#define in_dev_for_each_ifa_rcu(ifa, in_dev) \ |
---|
| 223 | + for (ifa = rcu_dereference((in_dev)->ifa_list); ifa; \ |
---|
| 224 | + ifa = rcu_dereference(ifa->ifa_next)) |
---|
217 | 225 | |
---|
218 | 226 | static inline struct in_device *__in_dev_get_rcu(const struct net_device *dev) |
---|
219 | 227 | { |
---|
.. | .. |
---|
237 | 245 | return rtnl_dereference(dev->ip_ptr); |
---|
238 | 246 | } |
---|
239 | 247 | |
---|
| 248 | +/* called with rcu_read_lock or rtnl held */ |
---|
| 249 | +static inline bool ip_ignore_linkdown(const struct net_device *dev) |
---|
| 250 | +{ |
---|
| 251 | + struct in_device *in_dev; |
---|
| 252 | + bool rc = false; |
---|
| 253 | + |
---|
| 254 | + in_dev = rcu_dereference_rtnl(dev->ip_ptr); |
---|
| 255 | + if (in_dev && |
---|
| 256 | + IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev)) |
---|
| 257 | + rc = true; |
---|
| 258 | + |
---|
| 259 | + return rc; |
---|
| 260 | +} |
---|
| 261 | + |
---|
240 | 262 | static inline struct neigh_parms *__in_dev_arp_parms_get_rcu(const struct net_device *dev) |
---|
241 | 263 | { |
---|
242 | 264 | struct in_device *in_dev = __in_dev_get_rcu(dev); |
---|