Blame view

include/net/neighbour.h 10.7 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
  #ifndef _NET_NEIGHBOUR_H
  #define _NET_NEIGHBOUR_H
9067c722c   Thomas Graf   [NEIGH]: Move net...
3
  #include <linux/neighbour.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
5
6
7
8
9
10
11
12
13
14
15
  /*
   *	Generic neighbour manipulation
   *
   *	Authors:
   *	Pedro Roque		<roque@di.fc.ul.pt>
   *	Alexey Kuznetsov	<kuznet@ms2.inr.ac.ru>
   *
   * 	Changes:
   *
   *	Harald Welte:		<laforge@gnumonks.org>
   *		- Add neighbour cache statistics like rtstat
   */
60063497a   Arun Sharma   atomic: use <linu...
16
  #include <linux/atomic.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
  #include <linux/netdevice.h>
14c850212   Arnaldo Carvalho de Melo   [INET_SOCK]: Move...
18
  #include <linux/skbuff.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
20
21
22
23
  #include <linux/rcupdate.h>
  #include <linux/seq_file.h>
  
  #include <linux/err.h>
  #include <linux/sysctl.h>
e4c4e448c   Eric Dumazet   neigh: Convert ga...
24
  #include <linux/workqueue.h>
c8822a4e0   Thomas Graf   [NEIGH]: Use rtnl...
25
  #include <net/rtnetlink.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26

39971554d   Pavel Emelyanov   [NEIGH]: Add a co...
27
28
29
  /*
   * NUD stands for "neighbor unreachability detection"
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
31
32
33
34
  #define NUD_IN_TIMER	(NUD_INCOMPLETE|NUD_REACHABLE|NUD_DELAY|NUD_PROBE)
  #define NUD_VALID	(NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY)
  #define NUD_CONNECTED	(NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE)
  
  struct neighbour;
fd2c3ef76   Eric Dumazet   net: cleanup incl...
35
  struct neigh_parms {
57da52c1e   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
36
  #ifdef CONFIG_NET_NS
426b5303e   Eric W. Biederman   [NETNS]: Modify t...
37
  	struct net *net;
57da52c1e   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
38
  #endif
c7fb64db0   Thomas Graf   [NETLINK]: Neighb...
39
  	struct net_device *dev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
41
  	struct neigh_parms *next;
  	int	(*neigh_setup)(struct neighbour *);
ecbb41693   Alexey Kuznetsov   [NET]: Fix neighb...
42
  	void	(*neigh_cleanup)(struct neighbour *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
  	struct neigh_table *tbl;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
  
  	void	*sysctl_table;
  
  	int dead;
  	atomic_t refcnt;
  	struct rcu_head rcu_head;
  
  	int	base_reachable_time;
  	int	retrans_time;
  	int	gc_staletime;
  	int	reachable_time;
  	int	delay_probe_time;
  
  	int	queue_len;
  	int	ucast_probes;
  	int	app_probes;
  	int	mcast_probes;
  	int	anycast_delay;
  	int	proxy_delay;
  	int	proxy_qlen;
  	int	locktime;
  };
fd2c3ef76   Eric Dumazet   net: cleanup incl...
66
  struct neigh_statistics {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
68
69
  	unsigned long allocs;		/* number of allocated neighs */
  	unsigned long destroys;		/* number of destroyed neighs */
  	unsigned long hash_grows;	/* number of hash resizes */
9a6d276e8   Neil Horman   core: add stat to...
70
  	unsigned long res_failed;	/* number of failed resolutions */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
72
73
74
75
76
77
78
79
  
  	unsigned long lookups;		/* number of lookups */
  	unsigned long hits;		/* number of hits (among lookups) */
  
  	unsigned long rcv_probes_mcast;	/* number of received mcast ipv6 */
  	unsigned long rcv_probes_ucast; /* number of received ucast ipv6 */
  
  	unsigned long periodic_gc_runs;	/* number of periodic GC runs */
  	unsigned long forced_gc_runs;	/* number of forced GC runs */
9a6d276e8   Neil Horman   core: add stat to...
80
81
  
  	unsigned long unres_discards;	/* number of unresolved drops */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
  };
4ea7334b6   Christoph Lameter   this_cpu: Use thi...
83
  #define NEIGH_CACHE_STAT_INC(tbl, field) this_cpu_inc((tbl)->stats->field)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84

fd2c3ef76   Eric Dumazet   net: cleanup incl...
85
  struct neighbour {
767e97e1e   Eric Dumazet   neigh: RCU conver...
86
  	struct neighbour __rcu	*next;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87
88
  	struct neigh_table	*tbl;
  	struct neigh_parms	*parms;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
90
  	unsigned long		confirmed;
  	unsigned long		updated;
46b13fc5c   Eric Dumazet   neigh: reorder st...
91
  	rwlock_t		lock;
367e5e376   Eric Dumazet   neigh: reorder fi...
92
  	atomic_t		refcnt;
e37ef961e   Eric Dumazet   neigh: reorder st...
93
94
95
  	struct sk_buff_head	arp_queue;
  	struct timer_list	timer;
  	unsigned long		used;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
  	atomic_t		probes;
46b13fc5c   Eric Dumazet   neigh: reorder st...
97
98
99
100
  	__u8			flags;
  	__u8			nud_state;
  	__u8			type;
  	__u8			dead;
0ed8ddf40   Eric Dumazet   neigh: Protect ne...
101
  	seqlock_t		ha_lock;
d924424aa   Stephen Hemminger   [NEIGHBOUR]: Use ...
102
  	unsigned char		ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))];
f6b72b621   David S. Miller   net: Embed hh_cac...
103
  	struct hh_cache		hh;
8f40b161d   David S. Miller   neigh: Pass neigh...
104
  	int			(*output)(struct neighbour *, struct sk_buff *);
89d69d2b7   Stephen Hemminger   net: make neigh_o...
105
  	const struct neigh_ops	*ops;
767e97e1e   Eric Dumazet   neigh: RCU conver...
106
  	struct rcu_head		rcu;
e37ef961e   Eric Dumazet   neigh: reorder st...
107
  	struct net_device	*dev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
109
  	u8			primary_key[0];
  };
fd2c3ef76   Eric Dumazet   net: cleanup incl...
110
  struct neigh_ops {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
  	int			family;
8f40b161d   David S. Miller   neigh: Pass neigh...
112
113
114
115
  	void			(*solicit)(struct neighbour *, struct sk_buff *);
  	void			(*error_report)(struct neighbour *, struct sk_buff *);
  	int			(*output)(struct neighbour *, struct sk_buff *);
  	int			(*connected_output)(struct neighbour *, struct sk_buff *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
  };
fd2c3ef76   Eric Dumazet   net: cleanup incl...
117
  struct pneigh_entry {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
  	struct pneigh_entry	*next;
57da52c1e   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
119
  #ifdef CONFIG_NET_NS
426b5303e   Eric W. Biederman   [NETNS]: Modify t...
120
  	struct net		*net;
57da52c1e   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
121
  #endif
426b5303e   Eric W. Biederman   [NETNS]: Modify t...
122
  	struct net_device	*dev;
62dd93181   Ville Nuorvala   [IPV6] NDISC: Set...
123
  	u8			flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
125
126
127
128
129
  	u8			key[0];
  };
  
  /*
   *	neighbour table manipulation
   */
d6bf78171   Eric Dumazet   net neigh: RCU co...
130
  struct neigh_hash_table {
767e97e1e   Eric Dumazet   neigh: RCU conver...
131
  	struct neighbour __rcu	**hash_buckets;
cd0893369   David S. Miller   neigh: Store hash...
132
  	unsigned int		hash_shift;
d6bf78171   Eric Dumazet   net neigh: RCU co...
133
134
135
  	__u32			hash_rnd;
  	struct rcu_head		rcu;
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
136

fd2c3ef76   Eric Dumazet   net: cleanup incl...
137
  struct neigh_table {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
139
140
141
  	struct neigh_table	*next;
  	int			family;
  	int			entry_size;
  	int			key_len;
d6bf78171   Eric Dumazet   net neigh: RCU co...
142
143
144
  	__u32			(*hash)(const void *pkey,
  					const struct net_device *dev,
  					__u32 hash_rnd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
146
147
148
149
150
  	int			(*constructor)(struct neighbour *);
  	int			(*pconstructor)(struct pneigh_entry *);
  	void			(*pdestructor)(struct pneigh_entry *);
  	void			(*proxy_redo)(struct sk_buff *skb);
  	char			*id;
  	struct neigh_parms	parms;
787a34456   Kulikov Vasiliy   net/neighbour.h: ...
151
  	/* HACK. gc_* should follow parms without a gap! */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
153
154
155
156
  	int			gc_interval;
  	int			gc_thresh1;
  	int			gc_thresh2;
  	int			gc_thresh3;
  	unsigned long		last_flush;
e4c4e448c   Eric Dumazet   neigh: Convert ga...
157
  	struct delayed_work	gc_work;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
159
160
161
162
  	struct timer_list 	proxy_timer;
  	struct sk_buff_head	proxy_queue;
  	atomic_t		entries;
  	rwlock_t		lock;
  	unsigned long		last_rand;
367e5e376   Eric Dumazet   neigh: reorder fi...
163
  	struct kmem_cache	*kmem_cachep;
7d720c3e4   Tejun Heo   percpu: add __per...
164
  	struct neigh_statistics	__percpu *stats;
d6bf78171   Eric Dumazet   net neigh: RCU co...
165
  	struct neigh_hash_table __rcu *nht;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166
  	struct pneigh_entry	**phash_buckets;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167
168
169
170
171
172
173
174
175
176
  };
  
  /* flags for neigh_update() */
  #define NEIGH_UPDATE_F_OVERRIDE			0x00000001
  #define NEIGH_UPDATE_F_WEAK_OVERRIDE		0x00000002
  #define NEIGH_UPDATE_F_OVERRIDE_ISROUTER	0x00000004
  #define NEIGH_UPDATE_F_ISROUTER			0x40000000
  #define NEIGH_UPDATE_F_ADMIN			0x80000000
  
  extern void			neigh_table_init(struct neigh_table *tbl);
bd89efc53   Simon Kelley   [NEIGH]: Fix IP-o...
177
  extern void			neigh_table_init_no_netlink(struct neigh_table *tbl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
179
180
181
182
  extern int			neigh_table_clear(struct neigh_table *tbl);
  extern struct neighbour *	neigh_lookup(struct neigh_table *tbl,
  					     const void *pkey,
  					     struct net_device *dev);
  extern struct neighbour *	neigh_lookup_nodev(struct neigh_table *tbl,
426b5303e   Eric W. Biederman   [NETNS]: Modify t...
183
  						   struct net *net,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184
185
186
187
188
189
190
191
192
193
  						   const void *pkey);
  extern struct neighbour *	neigh_create(struct neigh_table *tbl,
  					     const void *pkey,
  					     struct net_device *dev);
  extern void			neigh_destroy(struct neighbour *neigh);
  extern int			__neigh_event_send(struct neighbour *neigh, struct sk_buff *skb);
  extern int			neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, 
  					     u32 flags);
  extern void			neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev);
  extern int			neigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
8f40b161d   David S. Miller   neigh: Pass neigh...
194
195
196
197
  extern int			neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb);
  extern int			neigh_connected_output(struct neighbour *neigh, struct sk_buff *skb);
  extern int			neigh_compat_output(struct neighbour *neigh, struct sk_buff *skb);
  extern int			neigh_direct_output(struct neighbour *neigh, struct sk_buff *skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
198
199
200
201
202
203
  extern struct neighbour 	*neigh_event_ns(struct neigh_table *tbl,
  						u8 *lladdr, void *saddr,
  						struct net_device *dev);
  
  extern struct neigh_parms	*neigh_parms_alloc(struct net_device *dev, struct neigh_table *tbl);
  extern void			neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms);
57da52c1e   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
204
205
206
207
  
  static inline
  struct net			*neigh_parms_net(const struct neigh_parms *parms)
  {
e42ea986e   Eric Dumazet   net: Cleanup of n...
208
  	return read_pnet(&parms->net);
57da52c1e   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
209
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
211
212
213
  extern unsigned long		neigh_rand_reach_time(unsigned long base);
  
  extern void			pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
  					       struct sk_buff *skb);
426b5303e   Eric W. Biederman   [NETNS]: Modify t...
214
  extern struct pneigh_entry	*pneigh_lookup(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev, int creat);
fa86d322d   Pavel Emelyanov   [NEIGH]: Fix race...
215
216
217
218
  extern struct pneigh_entry	*__pneigh_lookup(struct neigh_table *tbl,
  						 struct net *net,
  						 const void *key,
  						 struct net_device *dev);
426b5303e   Eric W. Biederman   [NETNS]: Modify t...
219
  extern int			pneigh_delete(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
220

57da52c1e   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
221
222
223
  static inline
  struct net			*pneigh_net(const struct pneigh_entry *pneigh)
  {
e42ea986e   Eric Dumazet   net: Cleanup of n...
224
  	return read_pnet(&pneigh->net);
57da52c1e   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
225
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
226
  extern void neigh_app_ns(struct neighbour *n);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
227
228
229
230
231
  extern void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie);
  extern void __neigh_for_each_release(struct neigh_table *tbl, int (*cb)(struct neighbour *));
  extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_entry *));
  
  struct neigh_seq_state {
425084614   Denis V. Lunev   [NEIGH]: Make /pr...
232
  	struct seq_net_private p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
  	struct neigh_table *tbl;
d6bf78171   Eric Dumazet   net neigh: RCU co...
234
  	struct neigh_hash_table *nht;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
235
236
237
238
239
240
241
242
243
244
245
246
247
248
  	void *(*neigh_sub_iter)(struct neigh_seq_state *state,
  				struct neighbour *n, loff_t *pos);
  	unsigned int bucket;
  	unsigned int flags;
  #define NEIGH_SEQ_NEIGH_ONLY	0x00000001
  #define NEIGH_SEQ_IS_PNEIGH	0x00000002
  #define NEIGH_SEQ_SKIP_NOARP	0x00000004
  };
  extern void *neigh_seq_start(struct seq_file *, loff_t *, struct neigh_table *, unsigned int);
  extern void *neigh_seq_next(struct seq_file *, void *, loff_t *);
  extern void neigh_seq_stop(struct seq_file *, void *);
  
  extern int			neigh_sysctl_register(struct net_device *dev, 
  						      struct neigh_parms *p,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249
  						      char *p_name,
f8572d8f2   Eric W. Biederman   sysctl net: Remov...
250
  						      proc_handler *proc_handler);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
251
252
253
254
255
256
  extern void			neigh_sysctl_unregister(struct neigh_parms *p);
  
  static inline void __neigh_parms_put(struct neigh_parms *parms)
  {
  	atomic_dec(&parms->refcnt);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
  static inline struct neigh_parms *neigh_parms_clone(struct neigh_parms *parms)
  {
  	atomic_inc(&parms->refcnt);
  	return parms;
  }
  
  /*
   *	Neighbour references
   */
  
  static inline void neigh_release(struct neighbour *neigh)
  {
  	if (atomic_dec_and_test(&neigh->refcnt))
  		neigh_destroy(neigh);
  }
  
  static inline struct neighbour * neigh_clone(struct neighbour *neigh)
  {
  	if (neigh)
  		atomic_inc(&neigh->refcnt);
  	return neigh;
  }
  
  #define neigh_hold(n)	atomic_inc(&(n)->refcnt)
  
  static inline void neigh_confirm(struct neighbour *neigh)
  {
  	if (neigh)
  		neigh->confirmed = jiffies;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
287
288
  static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
  {
ef22b7b65   Tetsuo Handa   net: Fix duplicat...
289
  	unsigned long now = jiffies;
0ed8ddf40   Eric Dumazet   neigh: Protect ne...
290
291
292
  	
  	if (neigh->used != now)
  		neigh->used = now;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293
294
295
296
  	if (!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE)))
  		return __neigh_event_send(neigh, skb);
  	return 0;
  }
e179e6322   Bart De Schuymer   netfilter: bridge...
297
298
299
300
301
302
303
304
305
306
307
308
309
  #ifdef CONFIG_BRIDGE_NETFILTER
  static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb)
  {
  	unsigned seq, hh_alen;
  
  	do {
  		seq = read_seqbegin(&hh->hh_lock);
  		hh_alen = HH_DATA_ALIGN(ETH_HLEN);
  		memcpy(skb->data - hh_alen, hh->hh_data, ETH_ALEN + hh_alen - ETH_HLEN);
  	} while (read_seqretry(&hh->hh_lock, seq));
  	return 0;
  }
  #endif
3644f0cee   Stephen Hemminger   [NET]: Convert hh...
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
  static inline int neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb)
  {
  	unsigned seq;
  	int hh_len;
  
  	do {
  		int hh_alen;
  
  		seq = read_seqbegin(&hh->hh_lock);
  		hh_len = hh->hh_len;
  		hh_alen = HH_DATA_ALIGN(hh_len);
  		memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
  	} while (read_seqretry(&hh->hh_lock, seq));
  
  	skb_push(skb, hh_len);
b23b5455b   David S. Miller   neigh: Kill hh_ca...
325
  	return dev_queue_xmit(skb);
3644f0cee   Stephen Hemminger   [NET]: Convert hh...
326
  }
05e3aa094   David S. Miller   net: Create and u...
327
328
329
  static inline int neigh_output(struct neighbour *n, struct sk_buff *skb)
  {
  	struct hh_cache *hh = &n->hh;
b23b5455b   David S. Miller   neigh: Kill hh_ca...
330
  	if ((n->nud_state & NUD_CONNECTED) && hh->hh_len)
05e3aa094   David S. Miller   net: Create and u...
331
332
  		return neigh_hh_output(hh, skb);
  	else
8f40b161d   David S. Miller   neigh: Pass neigh...
333
  		return n->output(n, skb);
05e3aa094   David S. Miller   net: Create and u...
334
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
  static inline struct neighbour *
  __neigh_lookup(struct neigh_table *tbl, const void *pkey, struct net_device *dev, int creat)
  {
  	struct neighbour *n = neigh_lookup(tbl, pkey, dev);
  
  	if (n || !creat)
  		return n;
  
  	n = neigh_create(tbl, pkey, dev);
  	return IS_ERR(n) ? NULL : n;
  }
  
  static inline struct neighbour *
  __neigh_lookup_errno(struct neigh_table *tbl, const void *pkey,
    struct net_device *dev)
  {
  	struct neighbour *n = neigh_lookup(tbl, pkey, dev);
  
  	if (n)
  		return n;
  
  	return neigh_create(tbl, pkey, dev);
  }
a61bbcf28   Patrick McHardy   [NET]: Store skb-...
358
359
360
361
362
363
364
365
  struct neighbour_cb {
  	unsigned long sched_next;
  	unsigned int flags;
  };
  
  #define LOCALLY_ENQUEUED 0x1
  
  #define NEIGH_CB(skb)	((struct neighbour_cb *)(skb)->cb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
366

0ed8ddf40   Eric Dumazet   neigh: Protect ne...
367
368
369
370
371
372
373
374
375
376
  static inline void neigh_ha_snapshot(char *dst, const struct neighbour *n,
  				     const struct net_device *dev)
  {
  	unsigned int seq;
  
  	do {
  		seq = read_seqbegin(&n->ha_lock);
  		memcpy(dst, n->ha, dev->addr_len);
  	} while (read_seqretry(&n->ha_lock, seq));
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
  #endif