aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/neighbour.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/neighbour.h')
-rw-r--r--include/net/neighbour.h51
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
93struct neighbour { 93struct 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
143struct 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
142struct neigh_table { 151struct 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
237struct neigh_seq_state { 246struct 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
294static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) 304static 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
380static 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