diff options
Diffstat (limited to 'include/net/neighbour.h')
-rw-r--r-- | include/net/neighbour.h | 51 |
1 files changed, 37 insertions, 14 deletions
diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 242879b6c4df..4014b623880c 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h | |||
@@ -91,26 +91,28 @@ struct neigh_statistics { | |||
91 | #define NEIGH_CACHE_STAT_INC(tbl, field) this_cpu_inc((tbl)->stats->field) | 91 | #define NEIGH_CACHE_STAT_INC(tbl, field) this_cpu_inc((tbl)->stats->field) |
92 | 92 | ||
93 | struct neighbour { | 93 | struct neighbour { |
94 | struct neighbour *next; | 94 | struct neighbour __rcu *next; |
95 | struct neigh_table *tbl; | 95 | struct neigh_table *tbl; |
96 | struct neigh_parms *parms; | 96 | struct neigh_parms *parms; |
97 | struct net_device *dev; | ||
98 | unsigned long used; | ||
99 | unsigned long confirmed; | 97 | unsigned long confirmed; |
100 | unsigned long updated; | 98 | unsigned long updated; |
99 | rwlock_t lock; | ||
100 | atomic_t refcnt; | ||
101 | struct sk_buff_head arp_queue; | ||
102 | struct timer_list timer; | ||
103 | unsigned long used; | ||
104 | atomic_t probes; | ||
101 | __u8 flags; | 105 | __u8 flags; |
102 | __u8 nud_state; | 106 | __u8 nud_state; |
103 | __u8 type; | 107 | __u8 type; |
104 | __u8 dead; | 108 | __u8 dead; |
105 | atomic_t probes; | 109 | seqlock_t ha_lock; |
106 | rwlock_t lock; | ||
107 | unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; | 110 | unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; |
108 | struct hh_cache *hh; | 111 | struct hh_cache *hh; |
109 | atomic_t refcnt; | ||
110 | int (*output)(struct sk_buff *skb); | 112 | int (*output)(struct sk_buff *skb); |
111 | struct sk_buff_head arp_queue; | ||
112 | struct timer_list timer; | ||
113 | const struct neigh_ops *ops; | 113 | const struct neigh_ops *ops; |
114 | struct rcu_head rcu; | ||
115 | struct net_device *dev; | ||
114 | u8 primary_key[0]; | 116 | u8 primary_key[0]; |
115 | }; | 117 | }; |
116 | 118 | ||
@@ -138,13 +140,22 @@ struct pneigh_entry { | |||
138 | * neighbour table manipulation | 140 | * neighbour table manipulation |
139 | */ | 141 | */ |
140 | 142 | ||
143 | struct neigh_hash_table { | ||
144 | struct neighbour __rcu **hash_buckets; | ||
145 | unsigned int hash_mask; | ||
146 | __u32 hash_rnd; | ||
147 | struct rcu_head rcu; | ||
148 | }; | ||
149 | |||
141 | 150 | ||
142 | struct neigh_table { | 151 | struct neigh_table { |
143 | struct neigh_table *next; | 152 | struct neigh_table *next; |
144 | int family; | 153 | int family; |
145 | int entry_size; | 154 | int entry_size; |
146 | int key_len; | 155 | int key_len; |
147 | __u32 (*hash)(const void *pkey, const struct net_device *); | 156 | __u32 (*hash)(const void *pkey, |
157 | const struct net_device *dev, | ||
158 | __u32 hash_rnd); | ||
148 | int (*constructor)(struct neighbour *); | 159 | int (*constructor)(struct neighbour *); |
149 | int (*pconstructor)(struct pneigh_entry *); | 160 | int (*pconstructor)(struct pneigh_entry *); |
150 | void (*pdestructor)(struct pneigh_entry *); | 161 | void (*pdestructor)(struct pneigh_entry *); |
@@ -163,11 +174,9 @@ struct neigh_table { | |||
163 | atomic_t entries; | 174 | atomic_t entries; |
164 | rwlock_t lock; | 175 | rwlock_t lock; |
165 | unsigned long last_rand; | 176 | unsigned long last_rand; |
166 | struct kmem_cache *kmem_cachep; | 177 | struct kmem_cache *kmem_cachep; |
167 | struct neigh_statistics __percpu *stats; | 178 | struct neigh_statistics __percpu *stats; |
168 | struct neighbour **hash_buckets; | 179 | struct neigh_hash_table __rcu *nht; |
169 | unsigned int hash_mask; | ||
170 | __u32 hash_rnd; | ||
171 | struct pneigh_entry **phash_buckets; | 180 | struct pneigh_entry **phash_buckets; |
172 | }; | 181 | }; |
173 | 182 | ||
@@ -237,6 +246,7 @@ extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_en | |||
237 | struct neigh_seq_state { | 246 | struct neigh_seq_state { |
238 | struct seq_net_private p; | 247 | struct seq_net_private p; |
239 | struct neigh_table *tbl; | 248 | struct neigh_table *tbl; |
249 | struct neigh_hash_table *nht; | ||
240 | void *(*neigh_sub_iter)(struct neigh_seq_state *state, | 250 | void *(*neigh_sub_iter)(struct neigh_seq_state *state, |
241 | struct neighbour *n, loff_t *pos); | 251 | struct neighbour *n, loff_t *pos); |
242 | unsigned int bucket; | 252 | unsigned int bucket; |
@@ -293,7 +303,10 @@ static inline void neigh_confirm(struct neighbour *neigh) | |||
293 | 303 | ||
294 | static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) | 304 | static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) |
295 | { | 305 | { |
296 | neigh->used = jiffies; | 306 | unsigned long now = jiffies; |
307 | |||
308 | if (neigh->used != now) | ||
309 | neigh->used = now; | ||
297 | if (!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE))) | 310 | if (!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE))) |
298 | return __neigh_event_send(neigh, skb); | 311 | return __neigh_event_send(neigh, skb); |
299 | return 0; | 312 | return 0; |
@@ -364,4 +377,14 @@ struct neighbour_cb { | |||
364 | 377 | ||
365 | #define NEIGH_CB(skb) ((struct neighbour_cb *)(skb)->cb) | 378 | #define NEIGH_CB(skb) ((struct neighbour_cb *)(skb)->cb) |
366 | 379 | ||
380 | static inline void neigh_ha_snapshot(char *dst, const struct neighbour *n, | ||
381 | const struct net_device *dev) | ||
382 | { | ||
383 | unsigned int seq; | ||
384 | |||
385 | do { | ||
386 | seq = read_seqbegin(&n->ha_lock); | ||
387 | memcpy(dst, n->ha, dev->addr_len); | ||
388 | } while (read_seqretry(&n->ha_lock, seq)); | ||
389 | } | ||
367 | #endif | 390 | #endif |