| .. | .. |
|---|
| 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); |
|---|