Branch data Line data Source code
1 : : #ifndef _NET_NEIGHBOUR_H
2 : : #define _NET_NEIGHBOUR_H
3 : :
4 : : #include <linux/neighbour.h>
5 : :
6 : : /*
7 : : * Generic neighbour manipulation
8 : : *
9 : : * Authors:
10 : : * Pedro Roque <roque@di.fc.ul.pt>
11 : : * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
12 : : *
13 : : * Changes:
14 : : *
15 : : * Harald Welte: <laforge@gnumonks.org>
16 : : * - Add neighbour cache statistics like rtstat
17 : : */
18 : :
19 : : #include <linux/atomic.h>
20 : : #include <linux/netdevice.h>
21 : : #include <linux/skbuff.h>
22 : : #include <linux/rcupdate.h>
23 : : #include <linux/seq_file.h>
24 : :
25 : : #include <linux/err.h>
26 : : #include <linux/sysctl.h>
27 : : #include <linux/workqueue.h>
28 : : #include <net/rtnetlink.h>
29 : :
30 : : /*
31 : : * NUD stands for "neighbor unreachability detection"
32 : : */
33 : :
34 : : #define NUD_IN_TIMER (NUD_INCOMPLETE|NUD_REACHABLE|NUD_DELAY|NUD_PROBE)
35 : : #define NUD_VALID (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY)
36 : : #define NUD_CONNECTED (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE)
37 : :
38 : : struct neighbour;
39 : :
40 : : struct neigh_parms {
41 : : #ifdef CONFIG_NET_NS
42 : : struct net *net;
43 : : #endif
44 : : struct net_device *dev;
45 : : struct neigh_parms *next;
46 : : int (*neigh_setup)(struct neighbour *);
47 : : void (*neigh_cleanup)(struct neighbour *);
48 : : struct neigh_table *tbl;
49 : :
50 : : void *sysctl_table;
51 : :
52 : : int dead;
53 : : atomic_t refcnt;
54 : : struct rcu_head rcu_head;
55 : :
56 : : int base_reachable_time;
57 : : int retrans_time;
58 : : int gc_staletime;
59 : : int reachable_time;
60 : : int delay_probe_time;
61 : :
62 : : int queue_len_bytes;
63 : : int ucast_probes;
64 : : int app_probes;
65 : : int mcast_probes;
66 : : int anycast_delay;
67 : : int proxy_delay;
68 : : int proxy_qlen;
69 : : int locktime;
70 : : };
71 : :
72 : : struct neigh_statistics {
73 : : unsigned long allocs; /* number of allocated neighs */
74 : : unsigned long destroys; /* number of destroyed neighs */
75 : : unsigned long hash_grows; /* number of hash resizes */
76 : :
77 : : unsigned long res_failed; /* number of failed resolutions */
78 : :
79 : : unsigned long lookups; /* number of lookups */
80 : : unsigned long hits; /* number of hits (among lookups) */
81 : :
82 : : unsigned long rcv_probes_mcast; /* number of received mcast ipv6 */
83 : : unsigned long rcv_probes_ucast; /* number of received ucast ipv6 */
84 : :
85 : : unsigned long periodic_gc_runs; /* number of periodic GC runs */
86 : : unsigned long forced_gc_runs; /* number of forced GC runs */
87 : :
88 : : unsigned long unres_discards; /* number of unresolved drops */
89 : : };
90 : :
91 : : #define NEIGH_CACHE_STAT_INC(tbl, field) this_cpu_inc((tbl)->stats->field)
92 : :
93 : : struct neighbour {
94 : : struct neighbour __rcu *next;
95 : : struct neigh_table *tbl;
96 : : struct neigh_parms *parms;
97 : : unsigned long confirmed;
98 : : unsigned long updated;
99 : : rwlock_t lock;
100 : : atomic_t refcnt;
101 : : struct sk_buff_head arp_queue;
102 : : unsigned int arp_queue_len_bytes;
103 : : struct timer_list timer;
104 : : unsigned long used;
105 : : atomic_t probes;
106 : : __u8 flags;
107 : : __u8 nud_state;
108 : : __u8 type;
109 : : __u8 dead;
110 : : seqlock_t ha_lock;
111 : : unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))];
112 : : struct hh_cache hh;
113 : : int (*output)(struct neighbour *, struct sk_buff *);
114 : : const struct neigh_ops *ops;
115 : : struct rcu_head rcu;
116 : : struct net_device *dev;
117 : : u8 primary_key[0];
118 : : };
119 : :
120 : : struct neigh_ops {
121 : : int family;
122 : : void (*solicit)(struct neighbour *, struct sk_buff *);
123 : : void (*error_report)(struct neighbour *, struct sk_buff *);
124 : : int (*output)(struct neighbour *, struct sk_buff *);
125 : : int (*connected_output)(struct neighbour *, struct sk_buff *);
126 : : };
127 : :
128 : : struct pneigh_entry {
129 : : struct pneigh_entry *next;
130 : : #ifdef CONFIG_NET_NS
131 : : struct net *net;
132 : : #endif
133 : : struct net_device *dev;
134 : : u8 flags;
135 : : u8 key[0];
136 : : };
137 : :
138 : : /*
139 : : * neighbour table manipulation
140 : : */
141 : :
142 : : #define NEIGH_NUM_HASH_RND 4
143 : :
144 : : struct neigh_hash_table {
145 : : struct neighbour __rcu **hash_buckets;
146 : : unsigned int hash_shift;
147 : : __u32 hash_rnd[NEIGH_NUM_HASH_RND];
148 : : struct rcu_head rcu;
149 : : };
150 : :
151 : :
152 : : struct neigh_table {
153 : : struct neigh_table *next;
154 : : int family;
155 : : int entry_size;
156 : : int key_len;
157 : : __u32 (*hash)(const void *pkey,
158 : : const struct net_device *dev,
159 : : __u32 *hash_rnd);
160 : : int (*constructor)(struct neighbour *);
161 : : int (*pconstructor)(struct pneigh_entry *);
162 : : void (*pdestructor)(struct pneigh_entry *);
163 : : void (*proxy_redo)(struct sk_buff *skb);
164 : : char *id;
165 : : struct neigh_parms parms;
166 : : /* HACK. gc_* should follow parms without a gap! */
167 : : int gc_interval;
168 : : int gc_thresh1;
169 : : int gc_thresh2;
170 : : int gc_thresh3;
171 : : unsigned long last_flush;
172 : : struct delayed_work gc_work;
173 : : struct timer_list proxy_timer;
174 : : struct sk_buff_head proxy_queue;
175 : : atomic_t entries;
176 : : rwlock_t lock;
177 : : unsigned long last_rand;
178 : : struct neigh_statistics __percpu *stats;
179 : : struct neigh_hash_table __rcu *nht;
180 : : struct pneigh_entry **phash_buckets;
181 : : };
182 : :
183 : : #define NEIGH_PRIV_ALIGN sizeof(long long)
184 : : #define NEIGH_ENTRY_SIZE(size) ALIGN((size), NEIGH_PRIV_ALIGN)
185 : :
186 : : static inline void *neighbour_priv(const struct neighbour *n)
187 : : {
188 : : return (char *)n + n->tbl->entry_size;
189 : : }
190 : :
191 : : /* flags for neigh_update() */
192 : : #define NEIGH_UPDATE_F_OVERRIDE 0x00000001
193 : : #define NEIGH_UPDATE_F_WEAK_OVERRIDE 0x00000002
194 : : #define NEIGH_UPDATE_F_OVERRIDE_ISROUTER 0x00000004
195 : : #define NEIGH_UPDATE_F_ISROUTER 0x40000000
196 : : #define NEIGH_UPDATE_F_ADMIN 0x80000000
197 : :
198 : : void neigh_table_init(struct neigh_table *tbl);
199 : : int neigh_table_clear(struct neigh_table *tbl);
200 : : struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
201 : : struct net_device *dev);
202 : : struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net,
203 : : const void *pkey);
204 : : struct neighbour *__neigh_create(struct neigh_table *tbl, const void *pkey,
205 : : struct net_device *dev, bool want_ref);
206 : : static inline struct neighbour *neigh_create(struct neigh_table *tbl,
207 : : const void *pkey,
208 : : struct net_device *dev)
209 : : {
210 : 1 : return __neigh_create(tbl, pkey, dev, true);
211 : : }
212 : : void neigh_destroy(struct neighbour *neigh);
213 : : int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb);
214 : : int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, u32 flags);
215 : : void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev);
216 : : int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
217 : : int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb);
218 : : int neigh_connected_output(struct neighbour *neigh, struct sk_buff *skb);
219 : : int neigh_compat_output(struct neighbour *neigh, struct sk_buff *skb);
220 : : int neigh_direct_output(struct neighbour *neigh, struct sk_buff *skb);
221 : : struct neighbour *neigh_event_ns(struct neigh_table *tbl,
222 : : u8 *lladdr, void *saddr,
223 : : struct net_device *dev);
224 : :
225 : : struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
226 : : struct neigh_table *tbl);
227 : : void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms);
228 : :
229 : : static inline
230 : : struct net *neigh_parms_net(const struct neigh_parms *parms)
231 : : {
232 : : return read_pnet(&parms->net);
233 : : }
234 : :
235 : : unsigned long neigh_rand_reach_time(unsigned long base);
236 : :
237 : : void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
238 : : struct sk_buff *skb);
239 : : struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, struct net *net,
240 : : const void *key, struct net_device *dev,
241 : : int creat);
242 : : struct pneigh_entry *__pneigh_lookup(struct neigh_table *tbl, struct net *net,
243 : : const void *key, struct net_device *dev);
244 : : int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *key,
245 : : struct net_device *dev);
246 : :
247 : : static inline struct net *pneigh_net(const struct pneigh_entry *pneigh)
248 : : {
249 : : return read_pnet(&pneigh->net);
250 : : }
251 : :
252 : : void neigh_app_ns(struct neighbour *n);
253 : : void neigh_for_each(struct neigh_table *tbl,
254 : : void (*cb)(struct neighbour *, void *), void *cookie);
255 : : void __neigh_for_each_release(struct neigh_table *tbl,
256 : : int (*cb)(struct neighbour *));
257 : : void pneigh_for_each(struct neigh_table *tbl,
258 : : void (*cb)(struct pneigh_entry *));
259 : :
260 : : struct neigh_seq_state {
261 : : struct seq_net_private p;
262 : : struct neigh_table *tbl;
263 : : struct neigh_hash_table *nht;
264 : : void *(*neigh_sub_iter)(struct neigh_seq_state *state,
265 : : struct neighbour *n, loff_t *pos);
266 : : unsigned int bucket;
267 : : unsigned int flags;
268 : : #define NEIGH_SEQ_NEIGH_ONLY 0x00000001
269 : : #define NEIGH_SEQ_IS_PNEIGH 0x00000002
270 : : #define NEIGH_SEQ_SKIP_NOARP 0x00000004
271 : : };
272 : : void *neigh_seq_start(struct seq_file *, loff_t *, struct neigh_table *,
273 : : unsigned int);
274 : : void *neigh_seq_next(struct seq_file *, void *, loff_t *);
275 : : void neigh_seq_stop(struct seq_file *, void *);
276 : :
277 : : int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
278 : : char *p_name, proc_handler *proc_handler);
279 : : void neigh_sysctl_unregister(struct neigh_parms *p);
280 : :
281 : : static inline void __neigh_parms_put(struct neigh_parms *parms)
282 : : {
283 : 2 : atomic_dec(&parms->refcnt);
284 : : }
285 : :
286 : : static inline struct neigh_parms *neigh_parms_clone(struct neigh_parms *parms)
287 : : {
288 : 4 : atomic_inc(&parms->refcnt);
289 : : return parms;
290 : : }
291 : :
292 : : /*
293 : : * Neighbour references
294 : : */
295 : :
296 : : static inline void neigh_release(struct neighbour *neigh)
297 : : {
298 [ # # # # : 1412 : if (atomic_dec_and_test(&neigh->refcnt))
# # - + -
+ - + - +
# # ]
299 : 93 : neigh_destroy(neigh);
300 : : }
301 : :
302 : : static inline struct neighbour * neigh_clone(struct neighbour *neigh)
303 : : {
304 : : if (neigh)
305 : : atomic_inc(&neigh->refcnt);
306 : : return neigh;
307 : : }
308 : :
309 : : #define neigh_hold(n) atomic_inc(&(n)->refcnt)
310 : :
311 : : static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
312 : : {
313 : 3764 : unsigned long now = jiffies;
314 : :
315 [ # # ][ + + ]: 3764 : if (neigh->used != now)
316 : 1063 : neigh->used = now;
317 [ # # ][ + + ]: 3764 : if (!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE)))
318 : 139 : return __neigh_event_send(neigh, skb);
319 : : return 0;
320 : : }
321 : :
322 : : #ifdef CONFIG_BRIDGE_NETFILTER
323 : : static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb)
324 : : {
325 : : unsigned int seq, hh_alen;
326 : :
327 : : do {
328 : : seq = read_seqbegin(&hh->hh_lock);
329 : : hh_alen = HH_DATA_ALIGN(ETH_HLEN);
330 : : memcpy(skb->data - hh_alen, hh->hh_data, ETH_ALEN + hh_alen - ETH_HLEN);
331 : : } while (read_seqretry(&hh->hh_lock, seq));
332 : : return 0;
333 : : }
334 : : #endif
335 : :
336 : : static inline int neigh_hh_output(const struct hh_cache *hh, struct sk_buff *skb)
337 : : {
338 : : unsigned int seq;
339 : : int hh_len;
340 : :
341 : : do {
342 : : seq = read_seqbegin(&hh->hh_lock);
343 : 50763 : hh_len = hh->hh_len;
344 [ + - # # ]: 50763 : if (likely(hh_len <= HH_DATA_MOD)) {
345 : : /* this is inlined by gcc */
346 : 50763 : memcpy(skb->data - HH_DATA_MOD, hh->hh_data, HH_DATA_MOD);
347 : : } else {
348 : 0 : int hh_alen = HH_DATA_ALIGN(hh_len);
349 : :
350 : 0 : memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
351 : : }
352 [ - + # # ]: 50764 : } while (read_seqretry(&hh->hh_lock, seq));
353 : :
354 : 50764 : skb_push(skb, hh_len);
355 : 50764 : return dev_queue_xmit(skb);
356 : : }
357 : :
358 : : static inline struct neighbour *
359 : : __neigh_lookup(struct neigh_table *tbl, const void *pkey, struct net_device *dev, int creat)
360 : : {
361 : 4822 : struct neighbour *n = neigh_lookup(tbl, pkey, dev);
362 : :
363 [ + + # # : 164 : if (n || !creat)
# # ]
364 : : return n;
365 : :
366 : : n = neigh_create(tbl, pkey, dev);
367 [ + - ][ # # ]: 1 : return IS_ERR(n) ? NULL : n;
[ # # ]
368 : : }
369 : :
370 : : static inline struct neighbour *
371 : : __neigh_lookup_errno(struct neigh_table *tbl, const void *pkey,
372 : : struct net_device *dev)
373 : : {
374 : 0 : struct neighbour *n = neigh_lookup(tbl, pkey, dev);
375 : :
376 [ # # ]: 0 : if (n)
377 : : return n;
378 : :
379 : : return neigh_create(tbl, pkey, dev);
380 : : }
381 : :
382 : : struct neighbour_cb {
383 : : unsigned long sched_next;
384 : : unsigned int flags;
385 : : };
386 : :
387 : : #define LOCALLY_ENQUEUED 0x1
388 : :
389 : : #define NEIGH_CB(skb) ((struct neighbour_cb *)(skb)->cb)
390 : :
391 : : static inline void neigh_ha_snapshot(char *dst, const struct neighbour *n,
392 : : const struct net_device *dev)
393 : : {
394 : : unsigned int seq;
395 : :
396 : : do {
397 : : seq = read_seqbegin(&n->ha_lock);
398 : 329 : memcpy(dst, n->ha, dev->addr_len);
399 [ - + - + ]: 329 : } while (read_seqretry(&n->ha_lock, seq));
400 : : }
401 : : #endif
|