xref: /OK3568_Linux_fs/kernel/net/core/neighbour.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *	Generic address resolution entity
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  *	Authors:
6*4882a593Smuzhiyun  *	Pedro Roque		<roque@di.fc.ul.pt>
7*4882a593Smuzhiyun  *	Alexey Kuznetsov	<kuznet@ms2.inr.ac.ru>
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  *	Fixes:
10*4882a593Smuzhiyun  *	Vitaly E. Lavrov	releasing NULL neighbor in neigh_add.
11*4882a593Smuzhiyun  *	Harald Welte		Add neighbour cache statistics like rtstat
12*4882a593Smuzhiyun  */
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #include <linux/slab.h>
17*4882a593Smuzhiyun #include <linux/kmemleak.h>
18*4882a593Smuzhiyun #include <linux/types.h>
19*4882a593Smuzhiyun #include <linux/kernel.h>
20*4882a593Smuzhiyun #include <linux/module.h>
21*4882a593Smuzhiyun #include <linux/socket.h>
22*4882a593Smuzhiyun #include <linux/netdevice.h>
23*4882a593Smuzhiyun #include <linux/proc_fs.h>
24*4882a593Smuzhiyun #ifdef CONFIG_SYSCTL
25*4882a593Smuzhiyun #include <linux/sysctl.h>
26*4882a593Smuzhiyun #endif
27*4882a593Smuzhiyun #include <linux/times.h>
28*4882a593Smuzhiyun #include <net/net_namespace.h>
29*4882a593Smuzhiyun #include <net/neighbour.h>
30*4882a593Smuzhiyun #include <net/arp.h>
31*4882a593Smuzhiyun #include <net/dst.h>
32*4882a593Smuzhiyun #include <net/sock.h>
33*4882a593Smuzhiyun #include <net/netevent.h>
34*4882a593Smuzhiyun #include <net/netlink.h>
35*4882a593Smuzhiyun #include <linux/rtnetlink.h>
36*4882a593Smuzhiyun #include <linux/random.h>
37*4882a593Smuzhiyun #include <linux/string.h>
38*4882a593Smuzhiyun #include <linux/log2.h>
39*4882a593Smuzhiyun #include <linux/inetdevice.h>
40*4882a593Smuzhiyun #include <net/addrconf.h>
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun #include <trace/events/neigh.h>
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun #define DEBUG
45*4882a593Smuzhiyun #define NEIGH_DEBUG 1
46*4882a593Smuzhiyun #define neigh_dbg(level, fmt, ...)		\
47*4882a593Smuzhiyun do {						\
48*4882a593Smuzhiyun 	if (level <= NEIGH_DEBUG)		\
49*4882a593Smuzhiyun 		pr_debug(fmt, ##__VA_ARGS__);	\
50*4882a593Smuzhiyun } while (0)
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun #define PNEIGH_HASHMASK		0xF
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun static void neigh_timer_handler(struct timer_list *t);
55*4882a593Smuzhiyun static void __neigh_notify(struct neighbour *n, int type, int flags,
56*4882a593Smuzhiyun 			   u32 pid);
57*4882a593Smuzhiyun static void neigh_update_notify(struct neighbour *neigh, u32 nlmsg_pid);
58*4882a593Smuzhiyun static int pneigh_ifdown_and_unlock(struct neigh_table *tbl,
59*4882a593Smuzhiyun 				    struct net_device *dev);
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun #ifdef CONFIG_PROC_FS
62*4882a593Smuzhiyun static const struct seq_operations neigh_stat_seq_ops;
63*4882a593Smuzhiyun #endif
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun /*
66*4882a593Smuzhiyun    Neighbour hash table buckets are protected with rwlock tbl->lock.
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun    - All the scans/updates to hash buckets MUST be made under this lock.
69*4882a593Smuzhiyun    - NOTHING clever should be made under this lock: no callbacks
70*4882a593Smuzhiyun      to protocol backends, no attempts to send something to network.
71*4882a593Smuzhiyun      It will result in deadlocks, if backend/driver wants to use neighbour
72*4882a593Smuzhiyun      cache.
73*4882a593Smuzhiyun    - If the entry requires some non-trivial actions, increase
74*4882a593Smuzhiyun      its reference count and release table lock.
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun    Neighbour entries are protected:
77*4882a593Smuzhiyun    - with reference count.
78*4882a593Smuzhiyun    - with rwlock neigh->lock
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun    Reference count prevents destruction.
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun    neigh->lock mainly serializes ll address data and its validity state.
83*4882a593Smuzhiyun    However, the same lock is used to protect another entry fields:
84*4882a593Smuzhiyun     - timer
85*4882a593Smuzhiyun     - resolution queue
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun    Again, nothing clever shall be made under neigh->lock,
88*4882a593Smuzhiyun    the most complicated procedure, which we allow is dev->hard_header.
89*4882a593Smuzhiyun    It is supposed, that dev->hard_header is simplistic and does
90*4882a593Smuzhiyun    not make callbacks to neighbour tables.
91*4882a593Smuzhiyun  */
92*4882a593Smuzhiyun 
neigh_blackhole(struct neighbour * neigh,struct sk_buff * skb)93*4882a593Smuzhiyun static int neigh_blackhole(struct neighbour *neigh, struct sk_buff *skb)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun 	kfree_skb(skb);
96*4882a593Smuzhiyun 	return -ENETDOWN;
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun 
neigh_cleanup_and_release(struct neighbour * neigh)99*4882a593Smuzhiyun static void neigh_cleanup_and_release(struct neighbour *neigh)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun 	trace_neigh_cleanup_and_release(neigh, 0);
102*4882a593Smuzhiyun 	__neigh_notify(neigh, RTM_DELNEIGH, 0, 0);
103*4882a593Smuzhiyun 	call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
104*4882a593Smuzhiyun 	neigh_release(neigh);
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun /*
108*4882a593Smuzhiyun  * It is random distribution in the interval (1/2)*base...(3/2)*base.
109*4882a593Smuzhiyun  * It corresponds to default IPv6 settings and is not overridable,
110*4882a593Smuzhiyun  * because it is really reasonable choice.
111*4882a593Smuzhiyun  */
112*4882a593Smuzhiyun 
neigh_rand_reach_time(unsigned long base)113*4882a593Smuzhiyun unsigned long neigh_rand_reach_time(unsigned long base)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun 	return base ? (prandom_u32() % base) + (base >> 1) : 0;
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_rand_reach_time);
118*4882a593Smuzhiyun 
neigh_mark_dead(struct neighbour * n)119*4882a593Smuzhiyun static void neigh_mark_dead(struct neighbour *n)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun 	n->dead = 1;
122*4882a593Smuzhiyun 	if (!list_empty(&n->gc_list)) {
123*4882a593Smuzhiyun 		list_del_init(&n->gc_list);
124*4882a593Smuzhiyun 		atomic_dec(&n->tbl->gc_entries);
125*4882a593Smuzhiyun 	}
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun 
neigh_update_gc_list(struct neighbour * n)128*4882a593Smuzhiyun static void neigh_update_gc_list(struct neighbour *n)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun 	bool on_gc_list, exempt_from_gc;
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	write_lock_bh(&n->tbl->lock);
133*4882a593Smuzhiyun 	write_lock(&n->lock);
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	if (n->dead)
136*4882a593Smuzhiyun 		goto out;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	/* remove from the gc list if new state is permanent or if neighbor
139*4882a593Smuzhiyun 	 * is externally learned; otherwise entry should be on the gc list
140*4882a593Smuzhiyun 	 */
141*4882a593Smuzhiyun 	exempt_from_gc = n->nud_state & NUD_PERMANENT ||
142*4882a593Smuzhiyun 			 n->flags & NTF_EXT_LEARNED;
143*4882a593Smuzhiyun 	on_gc_list = !list_empty(&n->gc_list);
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	if (exempt_from_gc && on_gc_list) {
146*4882a593Smuzhiyun 		list_del_init(&n->gc_list);
147*4882a593Smuzhiyun 		atomic_dec(&n->tbl->gc_entries);
148*4882a593Smuzhiyun 	} else if (!exempt_from_gc && !on_gc_list) {
149*4882a593Smuzhiyun 		/* add entries to the tail; cleaning removes from the front */
150*4882a593Smuzhiyun 		list_add_tail(&n->gc_list, &n->tbl->gc_list);
151*4882a593Smuzhiyun 		atomic_inc(&n->tbl->gc_entries);
152*4882a593Smuzhiyun 	}
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun out:
155*4882a593Smuzhiyun 	write_unlock(&n->lock);
156*4882a593Smuzhiyun 	write_unlock_bh(&n->tbl->lock);
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun 
neigh_update_ext_learned(struct neighbour * neigh,u32 flags,int * notify)159*4882a593Smuzhiyun static bool neigh_update_ext_learned(struct neighbour *neigh, u32 flags,
160*4882a593Smuzhiyun 				     int *notify)
161*4882a593Smuzhiyun {
162*4882a593Smuzhiyun 	bool rc = false;
163*4882a593Smuzhiyun 	u8 ndm_flags;
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	if (!(flags & NEIGH_UPDATE_F_ADMIN))
166*4882a593Smuzhiyun 		return rc;
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun 	ndm_flags = (flags & NEIGH_UPDATE_F_EXT_LEARNED) ? NTF_EXT_LEARNED : 0;
169*4882a593Smuzhiyun 	if ((neigh->flags ^ ndm_flags) & NTF_EXT_LEARNED) {
170*4882a593Smuzhiyun 		if (ndm_flags & NTF_EXT_LEARNED)
171*4882a593Smuzhiyun 			neigh->flags |= NTF_EXT_LEARNED;
172*4882a593Smuzhiyun 		else
173*4882a593Smuzhiyun 			neigh->flags &= ~NTF_EXT_LEARNED;
174*4882a593Smuzhiyun 		rc = true;
175*4882a593Smuzhiyun 		*notify = 1;
176*4882a593Smuzhiyun 	}
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 	return rc;
179*4882a593Smuzhiyun }
180*4882a593Smuzhiyun 
neigh_del(struct neighbour * n,struct neighbour __rcu ** np,struct neigh_table * tbl)181*4882a593Smuzhiyun static bool neigh_del(struct neighbour *n, struct neighbour __rcu **np,
182*4882a593Smuzhiyun 		      struct neigh_table *tbl)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun 	bool retval = false;
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	write_lock(&n->lock);
187*4882a593Smuzhiyun 	if (refcount_read(&n->refcnt) == 1) {
188*4882a593Smuzhiyun 		struct neighbour *neigh;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 		neigh = rcu_dereference_protected(n->next,
191*4882a593Smuzhiyun 						  lockdep_is_held(&tbl->lock));
192*4882a593Smuzhiyun 		rcu_assign_pointer(*np, neigh);
193*4882a593Smuzhiyun 		neigh_mark_dead(n);
194*4882a593Smuzhiyun 		retval = true;
195*4882a593Smuzhiyun 	}
196*4882a593Smuzhiyun 	write_unlock(&n->lock);
197*4882a593Smuzhiyun 	if (retval)
198*4882a593Smuzhiyun 		neigh_cleanup_and_release(n);
199*4882a593Smuzhiyun 	return retval;
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun 
neigh_remove_one(struct neighbour * ndel,struct neigh_table * tbl)202*4882a593Smuzhiyun bool neigh_remove_one(struct neighbour *ndel, struct neigh_table *tbl)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun 	struct neigh_hash_table *nht;
205*4882a593Smuzhiyun 	void *pkey = ndel->primary_key;
206*4882a593Smuzhiyun 	u32 hash_val;
207*4882a593Smuzhiyun 	struct neighbour *n;
208*4882a593Smuzhiyun 	struct neighbour __rcu **np;
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	nht = rcu_dereference_protected(tbl->nht,
211*4882a593Smuzhiyun 					lockdep_is_held(&tbl->lock));
212*4882a593Smuzhiyun 	hash_val = tbl->hash(pkey, ndel->dev, nht->hash_rnd);
213*4882a593Smuzhiyun 	hash_val = hash_val >> (32 - nht->hash_shift);
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	np = &nht->hash_buckets[hash_val];
216*4882a593Smuzhiyun 	while ((n = rcu_dereference_protected(*np,
217*4882a593Smuzhiyun 					      lockdep_is_held(&tbl->lock)))) {
218*4882a593Smuzhiyun 		if (n == ndel)
219*4882a593Smuzhiyun 			return neigh_del(n, np, tbl);
220*4882a593Smuzhiyun 		np = &n->next;
221*4882a593Smuzhiyun 	}
222*4882a593Smuzhiyun 	return false;
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun 
neigh_forced_gc(struct neigh_table * tbl)225*4882a593Smuzhiyun static int neigh_forced_gc(struct neigh_table *tbl)
226*4882a593Smuzhiyun {
227*4882a593Smuzhiyun 	int max_clean = atomic_read(&tbl->gc_entries) - tbl->gc_thresh2;
228*4882a593Smuzhiyun 	unsigned long tref = jiffies - 5 * HZ;
229*4882a593Smuzhiyun 	struct neighbour *n, *tmp;
230*4882a593Smuzhiyun 	int shrunk = 0;
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	NEIGH_CACHE_STAT_INC(tbl, forced_gc_runs);
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	write_lock_bh(&tbl->lock);
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 	list_for_each_entry_safe(n, tmp, &tbl->gc_list, gc_list) {
237*4882a593Smuzhiyun 		if (refcount_read(&n->refcnt) == 1) {
238*4882a593Smuzhiyun 			bool remove = false;
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 			write_lock(&n->lock);
241*4882a593Smuzhiyun 			if ((n->nud_state == NUD_FAILED) ||
242*4882a593Smuzhiyun 			    (n->nud_state == NUD_NOARP) ||
243*4882a593Smuzhiyun 			    (tbl->is_multicast &&
244*4882a593Smuzhiyun 			     tbl->is_multicast(n->primary_key)) ||
245*4882a593Smuzhiyun 			    time_after(tref, n->updated))
246*4882a593Smuzhiyun 				remove = true;
247*4882a593Smuzhiyun 			write_unlock(&n->lock);
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 			if (remove && neigh_remove_one(n, tbl))
250*4882a593Smuzhiyun 				shrunk++;
251*4882a593Smuzhiyun 			if (shrunk >= max_clean)
252*4882a593Smuzhiyun 				break;
253*4882a593Smuzhiyun 		}
254*4882a593Smuzhiyun 	}
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	tbl->last_flush = jiffies;
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun 	write_unlock_bh(&tbl->lock);
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 	return shrunk;
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun 
neigh_add_timer(struct neighbour * n,unsigned long when)263*4882a593Smuzhiyun static void neigh_add_timer(struct neighbour *n, unsigned long when)
264*4882a593Smuzhiyun {
265*4882a593Smuzhiyun 	neigh_hold(n);
266*4882a593Smuzhiyun 	if (unlikely(mod_timer(&n->timer, when))) {
267*4882a593Smuzhiyun 		printk("NEIGH: BUG, double timer add, state is %x\n",
268*4882a593Smuzhiyun 		       n->nud_state);
269*4882a593Smuzhiyun 		dump_stack();
270*4882a593Smuzhiyun 	}
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun 
neigh_del_timer(struct neighbour * n)273*4882a593Smuzhiyun static int neigh_del_timer(struct neighbour *n)
274*4882a593Smuzhiyun {
275*4882a593Smuzhiyun 	if ((n->nud_state & NUD_IN_TIMER) &&
276*4882a593Smuzhiyun 	    del_timer(&n->timer)) {
277*4882a593Smuzhiyun 		neigh_release(n);
278*4882a593Smuzhiyun 		return 1;
279*4882a593Smuzhiyun 	}
280*4882a593Smuzhiyun 	return 0;
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun 
pneigh_queue_purge(struct sk_buff_head * list,struct net * net)283*4882a593Smuzhiyun static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun 	struct sk_buff_head tmp;
286*4882a593Smuzhiyun 	unsigned long flags;
287*4882a593Smuzhiyun 	struct sk_buff *skb;
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 	skb_queue_head_init(&tmp);
290*4882a593Smuzhiyun 	spin_lock_irqsave(&list->lock, flags);
291*4882a593Smuzhiyun 	skb = skb_peek(list);
292*4882a593Smuzhiyun 	while (skb != NULL) {
293*4882a593Smuzhiyun 		struct sk_buff *skb_next = skb_peek_next(skb, list);
294*4882a593Smuzhiyun 		if (net == NULL || net_eq(dev_net(skb->dev), net)) {
295*4882a593Smuzhiyun 			__skb_unlink(skb, list);
296*4882a593Smuzhiyun 			__skb_queue_tail(&tmp, skb);
297*4882a593Smuzhiyun 		}
298*4882a593Smuzhiyun 		skb = skb_next;
299*4882a593Smuzhiyun 	}
300*4882a593Smuzhiyun 	spin_unlock_irqrestore(&list->lock, flags);
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	while ((skb = __skb_dequeue(&tmp))) {
303*4882a593Smuzhiyun 		dev_put(skb->dev);
304*4882a593Smuzhiyun 		kfree_skb(skb);
305*4882a593Smuzhiyun 	}
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun 
neigh_flush_dev(struct neigh_table * tbl,struct net_device * dev,bool skip_perm)308*4882a593Smuzhiyun static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev,
309*4882a593Smuzhiyun 			    bool skip_perm)
310*4882a593Smuzhiyun {
311*4882a593Smuzhiyun 	int i;
312*4882a593Smuzhiyun 	struct neigh_hash_table *nht;
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun 	nht = rcu_dereference_protected(tbl->nht,
315*4882a593Smuzhiyun 					lockdep_is_held(&tbl->lock));
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 	for (i = 0; i < (1 << nht->hash_shift); i++) {
318*4882a593Smuzhiyun 		struct neighbour *n;
319*4882a593Smuzhiyun 		struct neighbour __rcu **np = &nht->hash_buckets[i];
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun 		while ((n = rcu_dereference_protected(*np,
322*4882a593Smuzhiyun 					lockdep_is_held(&tbl->lock))) != NULL) {
323*4882a593Smuzhiyun 			if (dev && n->dev != dev) {
324*4882a593Smuzhiyun 				np = &n->next;
325*4882a593Smuzhiyun 				continue;
326*4882a593Smuzhiyun 			}
327*4882a593Smuzhiyun 			if (skip_perm && n->nud_state & NUD_PERMANENT) {
328*4882a593Smuzhiyun 				np = &n->next;
329*4882a593Smuzhiyun 				continue;
330*4882a593Smuzhiyun 			}
331*4882a593Smuzhiyun 			rcu_assign_pointer(*np,
332*4882a593Smuzhiyun 				   rcu_dereference_protected(n->next,
333*4882a593Smuzhiyun 						lockdep_is_held(&tbl->lock)));
334*4882a593Smuzhiyun 			write_lock(&n->lock);
335*4882a593Smuzhiyun 			neigh_del_timer(n);
336*4882a593Smuzhiyun 			neigh_mark_dead(n);
337*4882a593Smuzhiyun 			if (refcount_read(&n->refcnt) != 1) {
338*4882a593Smuzhiyun 				/* The most unpleasant situation.
339*4882a593Smuzhiyun 				   We must destroy neighbour entry,
340*4882a593Smuzhiyun 				   but someone still uses it.
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 				   The destroy will be delayed until
343*4882a593Smuzhiyun 				   the last user releases us, but
344*4882a593Smuzhiyun 				   we must kill timers etc. and move
345*4882a593Smuzhiyun 				   it to safe state.
346*4882a593Smuzhiyun 				 */
347*4882a593Smuzhiyun 				__skb_queue_purge(&n->arp_queue);
348*4882a593Smuzhiyun 				n->arp_queue_len_bytes = 0;
349*4882a593Smuzhiyun 				n->output = neigh_blackhole;
350*4882a593Smuzhiyun 				if (n->nud_state & NUD_VALID)
351*4882a593Smuzhiyun 					n->nud_state = NUD_NOARP;
352*4882a593Smuzhiyun 				else
353*4882a593Smuzhiyun 					n->nud_state = NUD_NONE;
354*4882a593Smuzhiyun 				neigh_dbg(2, "neigh %p is stray\n", n);
355*4882a593Smuzhiyun 			}
356*4882a593Smuzhiyun 			write_unlock(&n->lock);
357*4882a593Smuzhiyun 			neigh_cleanup_and_release(n);
358*4882a593Smuzhiyun 		}
359*4882a593Smuzhiyun 	}
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun 
neigh_changeaddr(struct neigh_table * tbl,struct net_device * dev)362*4882a593Smuzhiyun void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev)
363*4882a593Smuzhiyun {
364*4882a593Smuzhiyun 	write_lock_bh(&tbl->lock);
365*4882a593Smuzhiyun 	neigh_flush_dev(tbl, dev, false);
366*4882a593Smuzhiyun 	write_unlock_bh(&tbl->lock);
367*4882a593Smuzhiyun }
368*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_changeaddr);
369*4882a593Smuzhiyun 
__neigh_ifdown(struct neigh_table * tbl,struct net_device * dev,bool skip_perm)370*4882a593Smuzhiyun static int __neigh_ifdown(struct neigh_table *tbl, struct net_device *dev,
371*4882a593Smuzhiyun 			  bool skip_perm)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun 	write_lock_bh(&tbl->lock);
374*4882a593Smuzhiyun 	neigh_flush_dev(tbl, dev, skip_perm);
375*4882a593Smuzhiyun 	pneigh_ifdown_and_unlock(tbl, dev);
376*4882a593Smuzhiyun 	pneigh_queue_purge(&tbl->proxy_queue, dev ? dev_net(dev) : NULL);
377*4882a593Smuzhiyun 	if (skb_queue_empty_lockless(&tbl->proxy_queue))
378*4882a593Smuzhiyun 		del_timer_sync(&tbl->proxy_timer);
379*4882a593Smuzhiyun 	return 0;
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun 
neigh_carrier_down(struct neigh_table * tbl,struct net_device * dev)382*4882a593Smuzhiyun int neigh_carrier_down(struct neigh_table *tbl, struct net_device *dev)
383*4882a593Smuzhiyun {
384*4882a593Smuzhiyun 	__neigh_ifdown(tbl, dev, true);
385*4882a593Smuzhiyun 	return 0;
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_carrier_down);
388*4882a593Smuzhiyun 
neigh_ifdown(struct neigh_table * tbl,struct net_device * dev)389*4882a593Smuzhiyun int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
390*4882a593Smuzhiyun {
391*4882a593Smuzhiyun 	__neigh_ifdown(tbl, dev, false);
392*4882a593Smuzhiyun 	return 0;
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_ifdown);
395*4882a593Smuzhiyun 
neigh_alloc(struct neigh_table * tbl,struct net_device * dev,u8 flags,bool exempt_from_gc)396*4882a593Smuzhiyun static struct neighbour *neigh_alloc(struct neigh_table *tbl,
397*4882a593Smuzhiyun 				     struct net_device *dev,
398*4882a593Smuzhiyun 				     u8 flags, bool exempt_from_gc)
399*4882a593Smuzhiyun {
400*4882a593Smuzhiyun 	struct neighbour *n = NULL;
401*4882a593Smuzhiyun 	unsigned long now = jiffies;
402*4882a593Smuzhiyun 	int entries;
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	if (exempt_from_gc)
405*4882a593Smuzhiyun 		goto do_alloc;
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	entries = atomic_inc_return(&tbl->gc_entries) - 1;
408*4882a593Smuzhiyun 	if (entries >= tbl->gc_thresh3 ||
409*4882a593Smuzhiyun 	    (entries >= tbl->gc_thresh2 &&
410*4882a593Smuzhiyun 	     time_after(now, tbl->last_flush + 5 * HZ))) {
411*4882a593Smuzhiyun 		if (!neigh_forced_gc(tbl) &&
412*4882a593Smuzhiyun 		    entries >= tbl->gc_thresh3) {
413*4882a593Smuzhiyun 			net_info_ratelimited("%s: neighbor table overflow!\n",
414*4882a593Smuzhiyun 					     tbl->id);
415*4882a593Smuzhiyun 			NEIGH_CACHE_STAT_INC(tbl, table_fulls);
416*4882a593Smuzhiyun 			goto out_entries;
417*4882a593Smuzhiyun 		}
418*4882a593Smuzhiyun 	}
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun do_alloc:
421*4882a593Smuzhiyun 	n = kzalloc(tbl->entry_size + dev->neigh_priv_len, GFP_ATOMIC);
422*4882a593Smuzhiyun 	if (!n)
423*4882a593Smuzhiyun 		goto out_entries;
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun 	__skb_queue_head_init(&n->arp_queue);
426*4882a593Smuzhiyun 	rwlock_init(&n->lock);
427*4882a593Smuzhiyun 	seqlock_init(&n->ha_lock);
428*4882a593Smuzhiyun 	n->updated	  = n->used = now;
429*4882a593Smuzhiyun 	n->nud_state	  = NUD_NONE;
430*4882a593Smuzhiyun 	n->output	  = neigh_blackhole;
431*4882a593Smuzhiyun 	n->flags	  = flags;
432*4882a593Smuzhiyun 	seqlock_init(&n->hh.hh_lock);
433*4882a593Smuzhiyun 	n->parms	  = neigh_parms_clone(&tbl->parms);
434*4882a593Smuzhiyun 	timer_setup(&n->timer, neigh_timer_handler, 0);
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 	NEIGH_CACHE_STAT_INC(tbl, allocs);
437*4882a593Smuzhiyun 	n->tbl		  = tbl;
438*4882a593Smuzhiyun 	refcount_set(&n->refcnt, 1);
439*4882a593Smuzhiyun 	n->dead		  = 1;
440*4882a593Smuzhiyun 	INIT_LIST_HEAD(&n->gc_list);
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun 	atomic_inc(&tbl->entries);
443*4882a593Smuzhiyun out:
444*4882a593Smuzhiyun 	return n;
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun out_entries:
447*4882a593Smuzhiyun 	if (!exempt_from_gc)
448*4882a593Smuzhiyun 		atomic_dec(&tbl->gc_entries);
449*4882a593Smuzhiyun 	goto out;
450*4882a593Smuzhiyun }
451*4882a593Smuzhiyun 
neigh_get_hash_rnd(u32 * x)452*4882a593Smuzhiyun static void neigh_get_hash_rnd(u32 *x)
453*4882a593Smuzhiyun {
454*4882a593Smuzhiyun 	*x = get_random_u32() | 1;
455*4882a593Smuzhiyun }
456*4882a593Smuzhiyun 
neigh_hash_alloc(unsigned int shift)457*4882a593Smuzhiyun static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift)
458*4882a593Smuzhiyun {
459*4882a593Smuzhiyun 	size_t size = (1 << shift) * sizeof(struct neighbour *);
460*4882a593Smuzhiyun 	struct neigh_hash_table *ret;
461*4882a593Smuzhiyun 	struct neighbour __rcu **buckets;
462*4882a593Smuzhiyun 	int i;
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun 	ret = kmalloc(sizeof(*ret), GFP_ATOMIC);
465*4882a593Smuzhiyun 	if (!ret)
466*4882a593Smuzhiyun 		return NULL;
467*4882a593Smuzhiyun 	if (size <= PAGE_SIZE) {
468*4882a593Smuzhiyun 		buckets = kzalloc(size, GFP_ATOMIC);
469*4882a593Smuzhiyun 	} else {
470*4882a593Smuzhiyun 		buckets = (struct neighbour __rcu **)
471*4882a593Smuzhiyun 			  __get_free_pages(GFP_ATOMIC | __GFP_ZERO,
472*4882a593Smuzhiyun 					   get_order(size));
473*4882a593Smuzhiyun 		kmemleak_alloc(buckets, size, 1, GFP_ATOMIC);
474*4882a593Smuzhiyun 	}
475*4882a593Smuzhiyun 	if (!buckets) {
476*4882a593Smuzhiyun 		kfree(ret);
477*4882a593Smuzhiyun 		return NULL;
478*4882a593Smuzhiyun 	}
479*4882a593Smuzhiyun 	ret->hash_buckets = buckets;
480*4882a593Smuzhiyun 	ret->hash_shift = shift;
481*4882a593Smuzhiyun 	for (i = 0; i < NEIGH_NUM_HASH_RND; i++)
482*4882a593Smuzhiyun 		neigh_get_hash_rnd(&ret->hash_rnd[i]);
483*4882a593Smuzhiyun 	return ret;
484*4882a593Smuzhiyun }
485*4882a593Smuzhiyun 
neigh_hash_free_rcu(struct rcu_head * head)486*4882a593Smuzhiyun static void neigh_hash_free_rcu(struct rcu_head *head)
487*4882a593Smuzhiyun {
488*4882a593Smuzhiyun 	struct neigh_hash_table *nht = container_of(head,
489*4882a593Smuzhiyun 						    struct neigh_hash_table,
490*4882a593Smuzhiyun 						    rcu);
491*4882a593Smuzhiyun 	size_t size = (1 << nht->hash_shift) * sizeof(struct neighbour *);
492*4882a593Smuzhiyun 	struct neighbour __rcu **buckets = nht->hash_buckets;
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun 	if (size <= PAGE_SIZE) {
495*4882a593Smuzhiyun 		kfree(buckets);
496*4882a593Smuzhiyun 	} else {
497*4882a593Smuzhiyun 		kmemleak_free(buckets);
498*4882a593Smuzhiyun 		free_pages((unsigned long)buckets, get_order(size));
499*4882a593Smuzhiyun 	}
500*4882a593Smuzhiyun 	kfree(nht);
501*4882a593Smuzhiyun }
502*4882a593Smuzhiyun 
neigh_hash_grow(struct neigh_table * tbl,unsigned long new_shift)503*4882a593Smuzhiyun static struct neigh_hash_table *neigh_hash_grow(struct neigh_table *tbl,
504*4882a593Smuzhiyun 						unsigned long new_shift)
505*4882a593Smuzhiyun {
506*4882a593Smuzhiyun 	unsigned int i, hash;
507*4882a593Smuzhiyun 	struct neigh_hash_table *new_nht, *old_nht;
508*4882a593Smuzhiyun 
509*4882a593Smuzhiyun 	NEIGH_CACHE_STAT_INC(tbl, hash_grows);
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun 	old_nht = rcu_dereference_protected(tbl->nht,
512*4882a593Smuzhiyun 					    lockdep_is_held(&tbl->lock));
513*4882a593Smuzhiyun 	new_nht = neigh_hash_alloc(new_shift);
514*4882a593Smuzhiyun 	if (!new_nht)
515*4882a593Smuzhiyun 		return old_nht;
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun 	for (i = 0; i < (1 << old_nht->hash_shift); i++) {
518*4882a593Smuzhiyun 		struct neighbour *n, *next;
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun 		for (n = rcu_dereference_protected(old_nht->hash_buckets[i],
521*4882a593Smuzhiyun 						   lockdep_is_held(&tbl->lock));
522*4882a593Smuzhiyun 		     n != NULL;
523*4882a593Smuzhiyun 		     n = next) {
524*4882a593Smuzhiyun 			hash = tbl->hash(n->primary_key, n->dev,
525*4882a593Smuzhiyun 					 new_nht->hash_rnd);
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun 			hash >>= (32 - new_nht->hash_shift);
528*4882a593Smuzhiyun 			next = rcu_dereference_protected(n->next,
529*4882a593Smuzhiyun 						lockdep_is_held(&tbl->lock));
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun 			rcu_assign_pointer(n->next,
532*4882a593Smuzhiyun 					   rcu_dereference_protected(
533*4882a593Smuzhiyun 						new_nht->hash_buckets[hash],
534*4882a593Smuzhiyun 						lockdep_is_held(&tbl->lock)));
535*4882a593Smuzhiyun 			rcu_assign_pointer(new_nht->hash_buckets[hash], n);
536*4882a593Smuzhiyun 		}
537*4882a593Smuzhiyun 	}
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 	rcu_assign_pointer(tbl->nht, new_nht);
540*4882a593Smuzhiyun 	call_rcu(&old_nht->rcu, neigh_hash_free_rcu);
541*4882a593Smuzhiyun 	return new_nht;
542*4882a593Smuzhiyun }
543*4882a593Smuzhiyun 
neigh_lookup(struct neigh_table * tbl,const void * pkey,struct net_device * dev)544*4882a593Smuzhiyun struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
545*4882a593Smuzhiyun 			       struct net_device *dev)
546*4882a593Smuzhiyun {
547*4882a593Smuzhiyun 	struct neighbour *n;
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 	NEIGH_CACHE_STAT_INC(tbl, lookups);
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun 	rcu_read_lock_bh();
552*4882a593Smuzhiyun 	n = __neigh_lookup_noref(tbl, pkey, dev);
553*4882a593Smuzhiyun 	if (n) {
554*4882a593Smuzhiyun 		if (!refcount_inc_not_zero(&n->refcnt))
555*4882a593Smuzhiyun 			n = NULL;
556*4882a593Smuzhiyun 		NEIGH_CACHE_STAT_INC(tbl, hits);
557*4882a593Smuzhiyun 	}
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun 	rcu_read_unlock_bh();
560*4882a593Smuzhiyun 	return n;
561*4882a593Smuzhiyun }
562*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_lookup);
563*4882a593Smuzhiyun 
neigh_lookup_nodev(struct neigh_table * tbl,struct net * net,const void * pkey)564*4882a593Smuzhiyun struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net,
565*4882a593Smuzhiyun 				     const void *pkey)
566*4882a593Smuzhiyun {
567*4882a593Smuzhiyun 	struct neighbour *n;
568*4882a593Smuzhiyun 	unsigned int key_len = tbl->key_len;
569*4882a593Smuzhiyun 	u32 hash_val;
570*4882a593Smuzhiyun 	struct neigh_hash_table *nht;
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 	NEIGH_CACHE_STAT_INC(tbl, lookups);
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun 	rcu_read_lock_bh();
575*4882a593Smuzhiyun 	nht = rcu_dereference_bh(tbl->nht);
576*4882a593Smuzhiyun 	hash_val = tbl->hash(pkey, NULL, nht->hash_rnd) >> (32 - nht->hash_shift);
577*4882a593Smuzhiyun 
578*4882a593Smuzhiyun 	for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]);
579*4882a593Smuzhiyun 	     n != NULL;
580*4882a593Smuzhiyun 	     n = rcu_dereference_bh(n->next)) {
581*4882a593Smuzhiyun 		if (!memcmp(n->primary_key, pkey, key_len) &&
582*4882a593Smuzhiyun 		    net_eq(dev_net(n->dev), net)) {
583*4882a593Smuzhiyun 			if (!refcount_inc_not_zero(&n->refcnt))
584*4882a593Smuzhiyun 				n = NULL;
585*4882a593Smuzhiyun 			NEIGH_CACHE_STAT_INC(tbl, hits);
586*4882a593Smuzhiyun 			break;
587*4882a593Smuzhiyun 		}
588*4882a593Smuzhiyun 	}
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun 	rcu_read_unlock_bh();
591*4882a593Smuzhiyun 	return n;
592*4882a593Smuzhiyun }
593*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_lookup_nodev);
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun static struct neighbour *
___neigh_create(struct neigh_table * tbl,const void * pkey,struct net_device * dev,u8 flags,bool exempt_from_gc,bool want_ref)596*4882a593Smuzhiyun ___neigh_create(struct neigh_table *tbl, const void *pkey,
597*4882a593Smuzhiyun 		struct net_device *dev, u8 flags,
598*4882a593Smuzhiyun 		bool exempt_from_gc, bool want_ref)
599*4882a593Smuzhiyun {
600*4882a593Smuzhiyun 	u32 hash_val, key_len = tbl->key_len;
601*4882a593Smuzhiyun 	struct neighbour *n1, *rc, *n;
602*4882a593Smuzhiyun 	struct neigh_hash_table *nht;
603*4882a593Smuzhiyun 	int error;
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun 	n = neigh_alloc(tbl, dev, flags, exempt_from_gc);
606*4882a593Smuzhiyun 	trace_neigh_create(tbl, dev, pkey, n, exempt_from_gc);
607*4882a593Smuzhiyun 	if (!n) {
608*4882a593Smuzhiyun 		rc = ERR_PTR(-ENOBUFS);
609*4882a593Smuzhiyun 		goto out;
610*4882a593Smuzhiyun 	}
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun 	memcpy(n->primary_key, pkey, key_len);
613*4882a593Smuzhiyun 	n->dev = dev;
614*4882a593Smuzhiyun 	dev_hold(dev);
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun 	/* Protocol specific setup. */
617*4882a593Smuzhiyun 	if (tbl->constructor &&	(error = tbl->constructor(n)) < 0) {
618*4882a593Smuzhiyun 		rc = ERR_PTR(error);
619*4882a593Smuzhiyun 		goto out_neigh_release;
620*4882a593Smuzhiyun 	}
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun 	if (dev->netdev_ops->ndo_neigh_construct) {
623*4882a593Smuzhiyun 		error = dev->netdev_ops->ndo_neigh_construct(dev, n);
624*4882a593Smuzhiyun 		if (error < 0) {
625*4882a593Smuzhiyun 			rc = ERR_PTR(error);
626*4882a593Smuzhiyun 			goto out_neigh_release;
627*4882a593Smuzhiyun 		}
628*4882a593Smuzhiyun 	}
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun 	/* Device specific setup. */
631*4882a593Smuzhiyun 	if (n->parms->neigh_setup &&
632*4882a593Smuzhiyun 	    (error = n->parms->neigh_setup(n)) < 0) {
633*4882a593Smuzhiyun 		rc = ERR_PTR(error);
634*4882a593Smuzhiyun 		goto out_neigh_release;
635*4882a593Smuzhiyun 	}
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun 	n->confirmed = jiffies - (NEIGH_VAR(n->parms, BASE_REACHABLE_TIME) << 1);
638*4882a593Smuzhiyun 
639*4882a593Smuzhiyun 	write_lock_bh(&tbl->lock);
640*4882a593Smuzhiyun 	nht = rcu_dereference_protected(tbl->nht,
641*4882a593Smuzhiyun 					lockdep_is_held(&tbl->lock));
642*4882a593Smuzhiyun 
643*4882a593Smuzhiyun 	if (atomic_read(&tbl->entries) > (1 << nht->hash_shift))
644*4882a593Smuzhiyun 		nht = neigh_hash_grow(tbl, nht->hash_shift + 1);
645*4882a593Smuzhiyun 
646*4882a593Smuzhiyun 	hash_val = tbl->hash(n->primary_key, dev, nht->hash_rnd) >> (32 - nht->hash_shift);
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun 	if (n->parms->dead) {
649*4882a593Smuzhiyun 		rc = ERR_PTR(-EINVAL);
650*4882a593Smuzhiyun 		goto out_tbl_unlock;
651*4882a593Smuzhiyun 	}
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun 	for (n1 = rcu_dereference_protected(nht->hash_buckets[hash_val],
654*4882a593Smuzhiyun 					    lockdep_is_held(&tbl->lock));
655*4882a593Smuzhiyun 	     n1 != NULL;
656*4882a593Smuzhiyun 	     n1 = rcu_dereference_protected(n1->next,
657*4882a593Smuzhiyun 			lockdep_is_held(&tbl->lock))) {
658*4882a593Smuzhiyun 		if (dev == n1->dev && !memcmp(n1->primary_key, n->primary_key, key_len)) {
659*4882a593Smuzhiyun 			if (want_ref)
660*4882a593Smuzhiyun 				neigh_hold(n1);
661*4882a593Smuzhiyun 			rc = n1;
662*4882a593Smuzhiyun 			goto out_tbl_unlock;
663*4882a593Smuzhiyun 		}
664*4882a593Smuzhiyun 	}
665*4882a593Smuzhiyun 
666*4882a593Smuzhiyun 	n->dead = 0;
667*4882a593Smuzhiyun 	if (!exempt_from_gc)
668*4882a593Smuzhiyun 		list_add_tail(&n->gc_list, &n->tbl->gc_list);
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 	if (want_ref)
671*4882a593Smuzhiyun 		neigh_hold(n);
672*4882a593Smuzhiyun 	rcu_assign_pointer(n->next,
673*4882a593Smuzhiyun 			   rcu_dereference_protected(nht->hash_buckets[hash_val],
674*4882a593Smuzhiyun 						     lockdep_is_held(&tbl->lock)));
675*4882a593Smuzhiyun 	rcu_assign_pointer(nht->hash_buckets[hash_val], n);
676*4882a593Smuzhiyun 	write_unlock_bh(&tbl->lock);
677*4882a593Smuzhiyun 	neigh_dbg(2, "neigh %p is created\n", n);
678*4882a593Smuzhiyun 	rc = n;
679*4882a593Smuzhiyun out:
680*4882a593Smuzhiyun 	return rc;
681*4882a593Smuzhiyun out_tbl_unlock:
682*4882a593Smuzhiyun 	write_unlock_bh(&tbl->lock);
683*4882a593Smuzhiyun out_neigh_release:
684*4882a593Smuzhiyun 	if (!exempt_from_gc)
685*4882a593Smuzhiyun 		atomic_dec(&tbl->gc_entries);
686*4882a593Smuzhiyun 	neigh_release(n);
687*4882a593Smuzhiyun 	goto out;
688*4882a593Smuzhiyun }
689*4882a593Smuzhiyun 
__neigh_create(struct neigh_table * tbl,const void * pkey,struct net_device * dev,bool want_ref)690*4882a593Smuzhiyun struct neighbour *__neigh_create(struct neigh_table *tbl, const void *pkey,
691*4882a593Smuzhiyun 				 struct net_device *dev, bool want_ref)
692*4882a593Smuzhiyun {
693*4882a593Smuzhiyun 	return ___neigh_create(tbl, pkey, dev, 0, false, want_ref);
694*4882a593Smuzhiyun }
695*4882a593Smuzhiyun EXPORT_SYMBOL(__neigh_create);
696*4882a593Smuzhiyun 
pneigh_hash(const void * pkey,unsigned int key_len)697*4882a593Smuzhiyun static u32 pneigh_hash(const void *pkey, unsigned int key_len)
698*4882a593Smuzhiyun {
699*4882a593Smuzhiyun 	u32 hash_val = *(u32 *)(pkey + key_len - 4);
700*4882a593Smuzhiyun 	hash_val ^= (hash_val >> 16);
701*4882a593Smuzhiyun 	hash_val ^= hash_val >> 8;
702*4882a593Smuzhiyun 	hash_val ^= hash_val >> 4;
703*4882a593Smuzhiyun 	hash_val &= PNEIGH_HASHMASK;
704*4882a593Smuzhiyun 	return hash_val;
705*4882a593Smuzhiyun }
706*4882a593Smuzhiyun 
__pneigh_lookup_1(struct pneigh_entry * n,struct net * net,const void * pkey,unsigned int key_len,struct net_device * dev)707*4882a593Smuzhiyun static struct pneigh_entry *__pneigh_lookup_1(struct pneigh_entry *n,
708*4882a593Smuzhiyun 					      struct net *net,
709*4882a593Smuzhiyun 					      const void *pkey,
710*4882a593Smuzhiyun 					      unsigned int key_len,
711*4882a593Smuzhiyun 					      struct net_device *dev)
712*4882a593Smuzhiyun {
713*4882a593Smuzhiyun 	while (n) {
714*4882a593Smuzhiyun 		if (!memcmp(n->key, pkey, key_len) &&
715*4882a593Smuzhiyun 		    net_eq(pneigh_net(n), net) &&
716*4882a593Smuzhiyun 		    (n->dev == dev || !n->dev))
717*4882a593Smuzhiyun 			return n;
718*4882a593Smuzhiyun 		n = n->next;
719*4882a593Smuzhiyun 	}
720*4882a593Smuzhiyun 	return NULL;
721*4882a593Smuzhiyun }
722*4882a593Smuzhiyun 
__pneigh_lookup(struct neigh_table * tbl,struct net * net,const void * pkey,struct net_device * dev)723*4882a593Smuzhiyun struct pneigh_entry *__pneigh_lookup(struct neigh_table *tbl,
724*4882a593Smuzhiyun 		struct net *net, const void *pkey, struct net_device *dev)
725*4882a593Smuzhiyun {
726*4882a593Smuzhiyun 	unsigned int key_len = tbl->key_len;
727*4882a593Smuzhiyun 	u32 hash_val = pneigh_hash(pkey, key_len);
728*4882a593Smuzhiyun 
729*4882a593Smuzhiyun 	return __pneigh_lookup_1(tbl->phash_buckets[hash_val],
730*4882a593Smuzhiyun 				 net, pkey, key_len, dev);
731*4882a593Smuzhiyun }
732*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(__pneigh_lookup);
733*4882a593Smuzhiyun 
pneigh_lookup(struct neigh_table * tbl,struct net * net,const void * pkey,struct net_device * dev,int creat)734*4882a593Smuzhiyun struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl,
735*4882a593Smuzhiyun 				    struct net *net, const void *pkey,
736*4882a593Smuzhiyun 				    struct net_device *dev, int creat)
737*4882a593Smuzhiyun {
738*4882a593Smuzhiyun 	struct pneigh_entry *n;
739*4882a593Smuzhiyun 	unsigned int key_len = tbl->key_len;
740*4882a593Smuzhiyun 	u32 hash_val = pneigh_hash(pkey, key_len);
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun 	read_lock_bh(&tbl->lock);
743*4882a593Smuzhiyun 	n = __pneigh_lookup_1(tbl->phash_buckets[hash_val],
744*4882a593Smuzhiyun 			      net, pkey, key_len, dev);
745*4882a593Smuzhiyun 	read_unlock_bh(&tbl->lock);
746*4882a593Smuzhiyun 
747*4882a593Smuzhiyun 	if (n || !creat)
748*4882a593Smuzhiyun 		goto out;
749*4882a593Smuzhiyun 
750*4882a593Smuzhiyun 	ASSERT_RTNL();
751*4882a593Smuzhiyun 
752*4882a593Smuzhiyun 	n = kzalloc(sizeof(*n) + key_len, GFP_KERNEL);
753*4882a593Smuzhiyun 	if (!n)
754*4882a593Smuzhiyun 		goto out;
755*4882a593Smuzhiyun 
756*4882a593Smuzhiyun 	write_pnet(&n->net, net);
757*4882a593Smuzhiyun 	memcpy(n->key, pkey, key_len);
758*4882a593Smuzhiyun 	n->dev = dev;
759*4882a593Smuzhiyun 	if (dev)
760*4882a593Smuzhiyun 		dev_hold(dev);
761*4882a593Smuzhiyun 
762*4882a593Smuzhiyun 	if (tbl->pconstructor && tbl->pconstructor(n)) {
763*4882a593Smuzhiyun 		if (dev)
764*4882a593Smuzhiyun 			dev_put(dev);
765*4882a593Smuzhiyun 		kfree(n);
766*4882a593Smuzhiyun 		n = NULL;
767*4882a593Smuzhiyun 		goto out;
768*4882a593Smuzhiyun 	}
769*4882a593Smuzhiyun 
770*4882a593Smuzhiyun 	write_lock_bh(&tbl->lock);
771*4882a593Smuzhiyun 	n->next = tbl->phash_buckets[hash_val];
772*4882a593Smuzhiyun 	tbl->phash_buckets[hash_val] = n;
773*4882a593Smuzhiyun 	write_unlock_bh(&tbl->lock);
774*4882a593Smuzhiyun out:
775*4882a593Smuzhiyun 	return n;
776*4882a593Smuzhiyun }
777*4882a593Smuzhiyun EXPORT_SYMBOL(pneigh_lookup);
778*4882a593Smuzhiyun 
779*4882a593Smuzhiyun 
pneigh_delete(struct neigh_table * tbl,struct net * net,const void * pkey,struct net_device * dev)780*4882a593Smuzhiyun int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *pkey,
781*4882a593Smuzhiyun 		  struct net_device *dev)
782*4882a593Smuzhiyun {
783*4882a593Smuzhiyun 	struct pneigh_entry *n, **np;
784*4882a593Smuzhiyun 	unsigned int key_len = tbl->key_len;
785*4882a593Smuzhiyun 	u32 hash_val = pneigh_hash(pkey, key_len);
786*4882a593Smuzhiyun 
787*4882a593Smuzhiyun 	write_lock_bh(&tbl->lock);
788*4882a593Smuzhiyun 	for (np = &tbl->phash_buckets[hash_val]; (n = *np) != NULL;
789*4882a593Smuzhiyun 	     np = &n->next) {
790*4882a593Smuzhiyun 		if (!memcmp(n->key, pkey, key_len) && n->dev == dev &&
791*4882a593Smuzhiyun 		    net_eq(pneigh_net(n), net)) {
792*4882a593Smuzhiyun 			*np = n->next;
793*4882a593Smuzhiyun 			write_unlock_bh(&tbl->lock);
794*4882a593Smuzhiyun 			if (tbl->pdestructor)
795*4882a593Smuzhiyun 				tbl->pdestructor(n);
796*4882a593Smuzhiyun 			if (n->dev)
797*4882a593Smuzhiyun 				dev_put(n->dev);
798*4882a593Smuzhiyun 			kfree(n);
799*4882a593Smuzhiyun 			return 0;
800*4882a593Smuzhiyun 		}
801*4882a593Smuzhiyun 	}
802*4882a593Smuzhiyun 	write_unlock_bh(&tbl->lock);
803*4882a593Smuzhiyun 	return -ENOENT;
804*4882a593Smuzhiyun }
805*4882a593Smuzhiyun 
pneigh_ifdown_and_unlock(struct neigh_table * tbl,struct net_device * dev)806*4882a593Smuzhiyun static int pneigh_ifdown_and_unlock(struct neigh_table *tbl,
807*4882a593Smuzhiyun 				    struct net_device *dev)
808*4882a593Smuzhiyun {
809*4882a593Smuzhiyun 	struct pneigh_entry *n, **np, *freelist = NULL;
810*4882a593Smuzhiyun 	u32 h;
811*4882a593Smuzhiyun 
812*4882a593Smuzhiyun 	for (h = 0; h <= PNEIGH_HASHMASK; h++) {
813*4882a593Smuzhiyun 		np = &tbl->phash_buckets[h];
814*4882a593Smuzhiyun 		while ((n = *np) != NULL) {
815*4882a593Smuzhiyun 			if (!dev || n->dev == dev) {
816*4882a593Smuzhiyun 				*np = n->next;
817*4882a593Smuzhiyun 				n->next = freelist;
818*4882a593Smuzhiyun 				freelist = n;
819*4882a593Smuzhiyun 				continue;
820*4882a593Smuzhiyun 			}
821*4882a593Smuzhiyun 			np = &n->next;
822*4882a593Smuzhiyun 		}
823*4882a593Smuzhiyun 	}
824*4882a593Smuzhiyun 	write_unlock_bh(&tbl->lock);
825*4882a593Smuzhiyun 	while ((n = freelist)) {
826*4882a593Smuzhiyun 		freelist = n->next;
827*4882a593Smuzhiyun 		n->next = NULL;
828*4882a593Smuzhiyun 		if (tbl->pdestructor)
829*4882a593Smuzhiyun 			tbl->pdestructor(n);
830*4882a593Smuzhiyun 		if (n->dev)
831*4882a593Smuzhiyun 			dev_put(n->dev);
832*4882a593Smuzhiyun 		kfree(n);
833*4882a593Smuzhiyun 	}
834*4882a593Smuzhiyun 	return -ENOENT;
835*4882a593Smuzhiyun }
836*4882a593Smuzhiyun 
837*4882a593Smuzhiyun static void neigh_parms_destroy(struct neigh_parms *parms);
838*4882a593Smuzhiyun 
neigh_parms_put(struct neigh_parms * parms)839*4882a593Smuzhiyun static inline void neigh_parms_put(struct neigh_parms *parms)
840*4882a593Smuzhiyun {
841*4882a593Smuzhiyun 	if (refcount_dec_and_test(&parms->refcnt))
842*4882a593Smuzhiyun 		neigh_parms_destroy(parms);
843*4882a593Smuzhiyun }
844*4882a593Smuzhiyun 
845*4882a593Smuzhiyun /*
846*4882a593Smuzhiyun  *	neighbour must already be out of the table;
847*4882a593Smuzhiyun  *
848*4882a593Smuzhiyun  */
neigh_destroy(struct neighbour * neigh)849*4882a593Smuzhiyun void neigh_destroy(struct neighbour *neigh)
850*4882a593Smuzhiyun {
851*4882a593Smuzhiyun 	struct net_device *dev = neigh->dev;
852*4882a593Smuzhiyun 
853*4882a593Smuzhiyun 	NEIGH_CACHE_STAT_INC(neigh->tbl, destroys);
854*4882a593Smuzhiyun 
855*4882a593Smuzhiyun 	if (!neigh->dead) {
856*4882a593Smuzhiyun 		pr_warn("Destroying alive neighbour %p\n", neigh);
857*4882a593Smuzhiyun 		dump_stack();
858*4882a593Smuzhiyun 		return;
859*4882a593Smuzhiyun 	}
860*4882a593Smuzhiyun 
861*4882a593Smuzhiyun 	if (neigh_del_timer(neigh))
862*4882a593Smuzhiyun 		pr_warn("Impossible event\n");
863*4882a593Smuzhiyun 
864*4882a593Smuzhiyun 	write_lock_bh(&neigh->lock);
865*4882a593Smuzhiyun 	__skb_queue_purge(&neigh->arp_queue);
866*4882a593Smuzhiyun 	write_unlock_bh(&neigh->lock);
867*4882a593Smuzhiyun 	neigh->arp_queue_len_bytes = 0;
868*4882a593Smuzhiyun 
869*4882a593Smuzhiyun 	if (dev->netdev_ops->ndo_neigh_destroy)
870*4882a593Smuzhiyun 		dev->netdev_ops->ndo_neigh_destroy(dev, neigh);
871*4882a593Smuzhiyun 
872*4882a593Smuzhiyun 	dev_put(dev);
873*4882a593Smuzhiyun 	neigh_parms_put(neigh->parms);
874*4882a593Smuzhiyun 
875*4882a593Smuzhiyun 	neigh_dbg(2, "neigh %p is destroyed\n", neigh);
876*4882a593Smuzhiyun 
877*4882a593Smuzhiyun 	atomic_dec(&neigh->tbl->entries);
878*4882a593Smuzhiyun 	kfree_rcu(neigh, rcu);
879*4882a593Smuzhiyun }
880*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_destroy);
881*4882a593Smuzhiyun 
882*4882a593Smuzhiyun /* Neighbour state is suspicious;
883*4882a593Smuzhiyun    disable fast path.
884*4882a593Smuzhiyun 
885*4882a593Smuzhiyun    Called with write_locked neigh.
886*4882a593Smuzhiyun  */
neigh_suspect(struct neighbour * neigh)887*4882a593Smuzhiyun static void neigh_suspect(struct neighbour *neigh)
888*4882a593Smuzhiyun {
889*4882a593Smuzhiyun 	neigh_dbg(2, "neigh %p is suspected\n", neigh);
890*4882a593Smuzhiyun 
891*4882a593Smuzhiyun 	neigh->output = neigh->ops->output;
892*4882a593Smuzhiyun }
893*4882a593Smuzhiyun 
894*4882a593Smuzhiyun /* Neighbour state is OK;
895*4882a593Smuzhiyun    enable fast path.
896*4882a593Smuzhiyun 
897*4882a593Smuzhiyun    Called with write_locked neigh.
898*4882a593Smuzhiyun  */
neigh_connect(struct neighbour * neigh)899*4882a593Smuzhiyun static void neigh_connect(struct neighbour *neigh)
900*4882a593Smuzhiyun {
901*4882a593Smuzhiyun 	neigh_dbg(2, "neigh %p is connected\n", neigh);
902*4882a593Smuzhiyun 
903*4882a593Smuzhiyun 	neigh->output = neigh->ops->connected_output;
904*4882a593Smuzhiyun }
905*4882a593Smuzhiyun 
neigh_periodic_work(struct work_struct * work)906*4882a593Smuzhiyun static void neigh_periodic_work(struct work_struct *work)
907*4882a593Smuzhiyun {
908*4882a593Smuzhiyun 	struct neigh_table *tbl = container_of(work, struct neigh_table, gc_work.work);
909*4882a593Smuzhiyun 	struct neighbour *n;
910*4882a593Smuzhiyun 	struct neighbour __rcu **np;
911*4882a593Smuzhiyun 	unsigned int i;
912*4882a593Smuzhiyun 	struct neigh_hash_table *nht;
913*4882a593Smuzhiyun 
914*4882a593Smuzhiyun 	NEIGH_CACHE_STAT_INC(tbl, periodic_gc_runs);
915*4882a593Smuzhiyun 
916*4882a593Smuzhiyun 	write_lock_bh(&tbl->lock);
917*4882a593Smuzhiyun 	nht = rcu_dereference_protected(tbl->nht,
918*4882a593Smuzhiyun 					lockdep_is_held(&tbl->lock));
919*4882a593Smuzhiyun 
920*4882a593Smuzhiyun 	/*
921*4882a593Smuzhiyun 	 *	periodically recompute ReachableTime from random function
922*4882a593Smuzhiyun 	 */
923*4882a593Smuzhiyun 
924*4882a593Smuzhiyun 	if (time_after(jiffies, tbl->last_rand + 300 * HZ)) {
925*4882a593Smuzhiyun 		struct neigh_parms *p;
926*4882a593Smuzhiyun 		tbl->last_rand = jiffies;
927*4882a593Smuzhiyun 		list_for_each_entry(p, &tbl->parms_list, list)
928*4882a593Smuzhiyun 			p->reachable_time =
929*4882a593Smuzhiyun 				neigh_rand_reach_time(NEIGH_VAR(p, BASE_REACHABLE_TIME));
930*4882a593Smuzhiyun 	}
931*4882a593Smuzhiyun 
932*4882a593Smuzhiyun 	if (atomic_read(&tbl->entries) < tbl->gc_thresh1)
933*4882a593Smuzhiyun 		goto out;
934*4882a593Smuzhiyun 
935*4882a593Smuzhiyun 	for (i = 0 ; i < (1 << nht->hash_shift); i++) {
936*4882a593Smuzhiyun 		np = &nht->hash_buckets[i];
937*4882a593Smuzhiyun 
938*4882a593Smuzhiyun 		while ((n = rcu_dereference_protected(*np,
939*4882a593Smuzhiyun 				lockdep_is_held(&tbl->lock))) != NULL) {
940*4882a593Smuzhiyun 			unsigned int state;
941*4882a593Smuzhiyun 
942*4882a593Smuzhiyun 			write_lock(&n->lock);
943*4882a593Smuzhiyun 
944*4882a593Smuzhiyun 			state = n->nud_state;
945*4882a593Smuzhiyun 			if ((state & (NUD_PERMANENT | NUD_IN_TIMER)) ||
946*4882a593Smuzhiyun 			    (n->flags & NTF_EXT_LEARNED)) {
947*4882a593Smuzhiyun 				write_unlock(&n->lock);
948*4882a593Smuzhiyun 				goto next_elt;
949*4882a593Smuzhiyun 			}
950*4882a593Smuzhiyun 
951*4882a593Smuzhiyun 			if (time_before(n->used, n->confirmed))
952*4882a593Smuzhiyun 				n->used = n->confirmed;
953*4882a593Smuzhiyun 
954*4882a593Smuzhiyun 			if (refcount_read(&n->refcnt) == 1 &&
955*4882a593Smuzhiyun 			    (state == NUD_FAILED ||
956*4882a593Smuzhiyun 			     time_after(jiffies, n->used + NEIGH_VAR(n->parms, GC_STALETIME)))) {
957*4882a593Smuzhiyun 				*np = n->next;
958*4882a593Smuzhiyun 				neigh_mark_dead(n);
959*4882a593Smuzhiyun 				write_unlock(&n->lock);
960*4882a593Smuzhiyun 				neigh_cleanup_and_release(n);
961*4882a593Smuzhiyun 				continue;
962*4882a593Smuzhiyun 			}
963*4882a593Smuzhiyun 			write_unlock(&n->lock);
964*4882a593Smuzhiyun 
965*4882a593Smuzhiyun next_elt:
966*4882a593Smuzhiyun 			np = &n->next;
967*4882a593Smuzhiyun 		}
968*4882a593Smuzhiyun 		/*
969*4882a593Smuzhiyun 		 * It's fine to release lock here, even if hash table
970*4882a593Smuzhiyun 		 * grows while we are preempted.
971*4882a593Smuzhiyun 		 */
972*4882a593Smuzhiyun 		write_unlock_bh(&tbl->lock);
973*4882a593Smuzhiyun 		cond_resched();
974*4882a593Smuzhiyun 		write_lock_bh(&tbl->lock);
975*4882a593Smuzhiyun 		nht = rcu_dereference_protected(tbl->nht,
976*4882a593Smuzhiyun 						lockdep_is_held(&tbl->lock));
977*4882a593Smuzhiyun 	}
978*4882a593Smuzhiyun out:
979*4882a593Smuzhiyun 	/* Cycle through all hash buckets every BASE_REACHABLE_TIME/2 ticks.
980*4882a593Smuzhiyun 	 * ARP entry timeouts range from 1/2 BASE_REACHABLE_TIME to 3/2
981*4882a593Smuzhiyun 	 * BASE_REACHABLE_TIME.
982*4882a593Smuzhiyun 	 */
983*4882a593Smuzhiyun 	queue_delayed_work(system_power_efficient_wq, &tbl->gc_work,
984*4882a593Smuzhiyun 			      NEIGH_VAR(&tbl->parms, BASE_REACHABLE_TIME) >> 1);
985*4882a593Smuzhiyun 	write_unlock_bh(&tbl->lock);
986*4882a593Smuzhiyun }
987*4882a593Smuzhiyun 
neigh_max_probes(struct neighbour * n)988*4882a593Smuzhiyun static __inline__ int neigh_max_probes(struct neighbour *n)
989*4882a593Smuzhiyun {
990*4882a593Smuzhiyun 	struct neigh_parms *p = n->parms;
991*4882a593Smuzhiyun 	return NEIGH_VAR(p, UCAST_PROBES) + NEIGH_VAR(p, APP_PROBES) +
992*4882a593Smuzhiyun 	       (n->nud_state & NUD_PROBE ? NEIGH_VAR(p, MCAST_REPROBES) :
993*4882a593Smuzhiyun 	        NEIGH_VAR(p, MCAST_PROBES));
994*4882a593Smuzhiyun }
995*4882a593Smuzhiyun 
neigh_invalidate(struct neighbour * neigh)996*4882a593Smuzhiyun static void neigh_invalidate(struct neighbour *neigh)
997*4882a593Smuzhiyun 	__releases(neigh->lock)
998*4882a593Smuzhiyun 	__acquires(neigh->lock)
999*4882a593Smuzhiyun {
1000*4882a593Smuzhiyun 	struct sk_buff *skb;
1001*4882a593Smuzhiyun 
1002*4882a593Smuzhiyun 	NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed);
1003*4882a593Smuzhiyun 	neigh_dbg(2, "neigh %p is failed\n", neigh);
1004*4882a593Smuzhiyun 	neigh->updated = jiffies;
1005*4882a593Smuzhiyun 
1006*4882a593Smuzhiyun 	/* It is very thin place. report_unreachable is very complicated
1007*4882a593Smuzhiyun 	   routine. Particularly, it can hit the same neighbour entry!
1008*4882a593Smuzhiyun 
1009*4882a593Smuzhiyun 	   So that, we try to be accurate and avoid dead loop. --ANK
1010*4882a593Smuzhiyun 	 */
1011*4882a593Smuzhiyun 	while (neigh->nud_state == NUD_FAILED &&
1012*4882a593Smuzhiyun 	       (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) {
1013*4882a593Smuzhiyun 		write_unlock(&neigh->lock);
1014*4882a593Smuzhiyun 		neigh->ops->error_report(neigh, skb);
1015*4882a593Smuzhiyun 		write_lock(&neigh->lock);
1016*4882a593Smuzhiyun 	}
1017*4882a593Smuzhiyun 	__skb_queue_purge(&neigh->arp_queue);
1018*4882a593Smuzhiyun 	neigh->arp_queue_len_bytes = 0;
1019*4882a593Smuzhiyun }
1020*4882a593Smuzhiyun 
neigh_probe(struct neighbour * neigh)1021*4882a593Smuzhiyun static void neigh_probe(struct neighbour *neigh)
1022*4882a593Smuzhiyun 	__releases(neigh->lock)
1023*4882a593Smuzhiyun {
1024*4882a593Smuzhiyun 	struct sk_buff *skb = skb_peek_tail(&neigh->arp_queue);
1025*4882a593Smuzhiyun 	/* keep skb alive even if arp_queue overflows */
1026*4882a593Smuzhiyun 	if (skb)
1027*4882a593Smuzhiyun 		skb = skb_clone(skb, GFP_ATOMIC);
1028*4882a593Smuzhiyun 	write_unlock(&neigh->lock);
1029*4882a593Smuzhiyun 	if (neigh->ops->solicit)
1030*4882a593Smuzhiyun 		neigh->ops->solicit(neigh, skb);
1031*4882a593Smuzhiyun 	atomic_inc(&neigh->probes);
1032*4882a593Smuzhiyun 	consume_skb(skb);
1033*4882a593Smuzhiyun }
1034*4882a593Smuzhiyun 
1035*4882a593Smuzhiyun /* Called when a timer expires for a neighbour entry. */
1036*4882a593Smuzhiyun 
neigh_timer_handler(struct timer_list * t)1037*4882a593Smuzhiyun static void neigh_timer_handler(struct timer_list *t)
1038*4882a593Smuzhiyun {
1039*4882a593Smuzhiyun 	unsigned long now, next;
1040*4882a593Smuzhiyun 	struct neighbour *neigh = from_timer(neigh, t, timer);
1041*4882a593Smuzhiyun 	unsigned int state;
1042*4882a593Smuzhiyun 	int notify = 0;
1043*4882a593Smuzhiyun 
1044*4882a593Smuzhiyun 	write_lock(&neigh->lock);
1045*4882a593Smuzhiyun 
1046*4882a593Smuzhiyun 	state = neigh->nud_state;
1047*4882a593Smuzhiyun 	now = jiffies;
1048*4882a593Smuzhiyun 	next = now + HZ;
1049*4882a593Smuzhiyun 
1050*4882a593Smuzhiyun 	if (!(state & NUD_IN_TIMER))
1051*4882a593Smuzhiyun 		goto out;
1052*4882a593Smuzhiyun 
1053*4882a593Smuzhiyun 	if (state & NUD_REACHABLE) {
1054*4882a593Smuzhiyun 		if (time_before_eq(now,
1055*4882a593Smuzhiyun 				   neigh->confirmed + neigh->parms->reachable_time)) {
1056*4882a593Smuzhiyun 			neigh_dbg(2, "neigh %p is still alive\n", neigh);
1057*4882a593Smuzhiyun 			next = neigh->confirmed + neigh->parms->reachable_time;
1058*4882a593Smuzhiyun 		} else if (time_before_eq(now,
1059*4882a593Smuzhiyun 					  neigh->used +
1060*4882a593Smuzhiyun 					  NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME))) {
1061*4882a593Smuzhiyun 			neigh_dbg(2, "neigh %p is delayed\n", neigh);
1062*4882a593Smuzhiyun 			neigh->nud_state = NUD_DELAY;
1063*4882a593Smuzhiyun 			neigh->updated = jiffies;
1064*4882a593Smuzhiyun 			neigh_suspect(neigh);
1065*4882a593Smuzhiyun 			next = now + NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME);
1066*4882a593Smuzhiyun 		} else {
1067*4882a593Smuzhiyun 			neigh_dbg(2, "neigh %p is suspected\n", neigh);
1068*4882a593Smuzhiyun 			neigh->nud_state = NUD_STALE;
1069*4882a593Smuzhiyun 			neigh->updated = jiffies;
1070*4882a593Smuzhiyun 			neigh_suspect(neigh);
1071*4882a593Smuzhiyun 			notify = 1;
1072*4882a593Smuzhiyun 		}
1073*4882a593Smuzhiyun 	} else if (state & NUD_DELAY) {
1074*4882a593Smuzhiyun 		if (time_before_eq(now,
1075*4882a593Smuzhiyun 				   neigh->confirmed +
1076*4882a593Smuzhiyun 				   NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME))) {
1077*4882a593Smuzhiyun 			neigh_dbg(2, "neigh %p is now reachable\n", neigh);
1078*4882a593Smuzhiyun 			neigh->nud_state = NUD_REACHABLE;
1079*4882a593Smuzhiyun 			neigh->updated = jiffies;
1080*4882a593Smuzhiyun 			neigh_connect(neigh);
1081*4882a593Smuzhiyun 			notify = 1;
1082*4882a593Smuzhiyun 			next = neigh->confirmed + neigh->parms->reachable_time;
1083*4882a593Smuzhiyun 		} else {
1084*4882a593Smuzhiyun 			neigh_dbg(2, "neigh %p is probed\n", neigh);
1085*4882a593Smuzhiyun 			neigh->nud_state = NUD_PROBE;
1086*4882a593Smuzhiyun 			neigh->updated = jiffies;
1087*4882a593Smuzhiyun 			atomic_set(&neigh->probes, 0);
1088*4882a593Smuzhiyun 			notify = 1;
1089*4882a593Smuzhiyun 			next = now + max(NEIGH_VAR(neigh->parms, RETRANS_TIME),
1090*4882a593Smuzhiyun 					 HZ/100);
1091*4882a593Smuzhiyun 		}
1092*4882a593Smuzhiyun 	} else {
1093*4882a593Smuzhiyun 		/* NUD_PROBE|NUD_INCOMPLETE */
1094*4882a593Smuzhiyun 		next = now + max(NEIGH_VAR(neigh->parms, RETRANS_TIME), HZ/100);
1095*4882a593Smuzhiyun 	}
1096*4882a593Smuzhiyun 
1097*4882a593Smuzhiyun 	if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) &&
1098*4882a593Smuzhiyun 	    atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) {
1099*4882a593Smuzhiyun 		neigh->nud_state = NUD_FAILED;
1100*4882a593Smuzhiyun 		notify = 1;
1101*4882a593Smuzhiyun 		neigh_invalidate(neigh);
1102*4882a593Smuzhiyun 		goto out;
1103*4882a593Smuzhiyun 	}
1104*4882a593Smuzhiyun 
1105*4882a593Smuzhiyun 	if (neigh->nud_state & NUD_IN_TIMER) {
1106*4882a593Smuzhiyun 		if (time_before(next, jiffies + HZ/100))
1107*4882a593Smuzhiyun 			next = jiffies + HZ/100;
1108*4882a593Smuzhiyun 		if (!mod_timer(&neigh->timer, next))
1109*4882a593Smuzhiyun 			neigh_hold(neigh);
1110*4882a593Smuzhiyun 	}
1111*4882a593Smuzhiyun 	if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) {
1112*4882a593Smuzhiyun 		neigh_probe(neigh);
1113*4882a593Smuzhiyun 	} else {
1114*4882a593Smuzhiyun out:
1115*4882a593Smuzhiyun 		write_unlock(&neigh->lock);
1116*4882a593Smuzhiyun 	}
1117*4882a593Smuzhiyun 
1118*4882a593Smuzhiyun 	if (notify)
1119*4882a593Smuzhiyun 		neigh_update_notify(neigh, 0);
1120*4882a593Smuzhiyun 
1121*4882a593Smuzhiyun 	trace_neigh_timer_handler(neigh, 0);
1122*4882a593Smuzhiyun 
1123*4882a593Smuzhiyun 	neigh_release(neigh);
1124*4882a593Smuzhiyun }
1125*4882a593Smuzhiyun 
__neigh_event_send(struct neighbour * neigh,struct sk_buff * skb)1126*4882a593Smuzhiyun int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
1127*4882a593Smuzhiyun {
1128*4882a593Smuzhiyun 	int rc;
1129*4882a593Smuzhiyun 	bool immediate_probe = false;
1130*4882a593Smuzhiyun 
1131*4882a593Smuzhiyun 	write_lock_bh(&neigh->lock);
1132*4882a593Smuzhiyun 
1133*4882a593Smuzhiyun 	rc = 0;
1134*4882a593Smuzhiyun 	if (neigh->nud_state & (NUD_CONNECTED | NUD_DELAY | NUD_PROBE))
1135*4882a593Smuzhiyun 		goto out_unlock_bh;
1136*4882a593Smuzhiyun 	if (neigh->dead)
1137*4882a593Smuzhiyun 		goto out_dead;
1138*4882a593Smuzhiyun 
1139*4882a593Smuzhiyun 	if (!(neigh->nud_state & (NUD_STALE | NUD_INCOMPLETE))) {
1140*4882a593Smuzhiyun 		if (NEIGH_VAR(neigh->parms, MCAST_PROBES) +
1141*4882a593Smuzhiyun 		    NEIGH_VAR(neigh->parms, APP_PROBES)) {
1142*4882a593Smuzhiyun 			unsigned long next, now = jiffies;
1143*4882a593Smuzhiyun 
1144*4882a593Smuzhiyun 			atomic_set(&neigh->probes,
1145*4882a593Smuzhiyun 				   NEIGH_VAR(neigh->parms, UCAST_PROBES));
1146*4882a593Smuzhiyun 			neigh_del_timer(neigh);
1147*4882a593Smuzhiyun 			neigh->nud_state     = NUD_INCOMPLETE;
1148*4882a593Smuzhiyun 			neigh->updated = now;
1149*4882a593Smuzhiyun 			next = now + max(NEIGH_VAR(neigh->parms, RETRANS_TIME),
1150*4882a593Smuzhiyun 					 HZ/100);
1151*4882a593Smuzhiyun 			neigh_add_timer(neigh, next);
1152*4882a593Smuzhiyun 			immediate_probe = true;
1153*4882a593Smuzhiyun 		} else {
1154*4882a593Smuzhiyun 			neigh->nud_state = NUD_FAILED;
1155*4882a593Smuzhiyun 			neigh->updated = jiffies;
1156*4882a593Smuzhiyun 			write_unlock_bh(&neigh->lock);
1157*4882a593Smuzhiyun 
1158*4882a593Smuzhiyun 			kfree_skb(skb);
1159*4882a593Smuzhiyun 			return 1;
1160*4882a593Smuzhiyun 		}
1161*4882a593Smuzhiyun 	} else if (neigh->nud_state & NUD_STALE) {
1162*4882a593Smuzhiyun 		neigh_dbg(2, "neigh %p is delayed\n", neigh);
1163*4882a593Smuzhiyun 		neigh_del_timer(neigh);
1164*4882a593Smuzhiyun 		neigh->nud_state = NUD_DELAY;
1165*4882a593Smuzhiyun 		neigh->updated = jiffies;
1166*4882a593Smuzhiyun 		neigh_add_timer(neigh, jiffies +
1167*4882a593Smuzhiyun 				NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME));
1168*4882a593Smuzhiyun 	}
1169*4882a593Smuzhiyun 
1170*4882a593Smuzhiyun 	if (neigh->nud_state == NUD_INCOMPLETE) {
1171*4882a593Smuzhiyun 		if (skb) {
1172*4882a593Smuzhiyun 			while (neigh->arp_queue_len_bytes + skb->truesize >
1173*4882a593Smuzhiyun 			       NEIGH_VAR(neigh->parms, QUEUE_LEN_BYTES)) {
1174*4882a593Smuzhiyun 				struct sk_buff *buff;
1175*4882a593Smuzhiyun 
1176*4882a593Smuzhiyun 				buff = __skb_dequeue(&neigh->arp_queue);
1177*4882a593Smuzhiyun 				if (!buff)
1178*4882a593Smuzhiyun 					break;
1179*4882a593Smuzhiyun 				neigh->arp_queue_len_bytes -= buff->truesize;
1180*4882a593Smuzhiyun 				kfree_skb(buff);
1181*4882a593Smuzhiyun 				NEIGH_CACHE_STAT_INC(neigh->tbl, unres_discards);
1182*4882a593Smuzhiyun 			}
1183*4882a593Smuzhiyun 			skb_dst_force(skb);
1184*4882a593Smuzhiyun 			__skb_queue_tail(&neigh->arp_queue, skb);
1185*4882a593Smuzhiyun 			neigh->arp_queue_len_bytes += skb->truesize;
1186*4882a593Smuzhiyun 		}
1187*4882a593Smuzhiyun 		rc = 1;
1188*4882a593Smuzhiyun 	}
1189*4882a593Smuzhiyun out_unlock_bh:
1190*4882a593Smuzhiyun 	if (immediate_probe)
1191*4882a593Smuzhiyun 		neigh_probe(neigh);
1192*4882a593Smuzhiyun 	else
1193*4882a593Smuzhiyun 		write_unlock(&neigh->lock);
1194*4882a593Smuzhiyun 	local_bh_enable();
1195*4882a593Smuzhiyun 	trace_neigh_event_send_done(neigh, rc);
1196*4882a593Smuzhiyun 	return rc;
1197*4882a593Smuzhiyun 
1198*4882a593Smuzhiyun out_dead:
1199*4882a593Smuzhiyun 	if (neigh->nud_state & NUD_STALE)
1200*4882a593Smuzhiyun 		goto out_unlock_bh;
1201*4882a593Smuzhiyun 	write_unlock_bh(&neigh->lock);
1202*4882a593Smuzhiyun 	kfree_skb(skb);
1203*4882a593Smuzhiyun 	trace_neigh_event_send_dead(neigh, 1);
1204*4882a593Smuzhiyun 	return 1;
1205*4882a593Smuzhiyun }
1206*4882a593Smuzhiyun EXPORT_SYMBOL(__neigh_event_send);
1207*4882a593Smuzhiyun 
neigh_update_hhs(struct neighbour * neigh)1208*4882a593Smuzhiyun static void neigh_update_hhs(struct neighbour *neigh)
1209*4882a593Smuzhiyun {
1210*4882a593Smuzhiyun 	struct hh_cache *hh;
1211*4882a593Smuzhiyun 	void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *)
1212*4882a593Smuzhiyun 		= NULL;
1213*4882a593Smuzhiyun 
1214*4882a593Smuzhiyun 	if (neigh->dev->header_ops)
1215*4882a593Smuzhiyun 		update = neigh->dev->header_ops->cache_update;
1216*4882a593Smuzhiyun 
1217*4882a593Smuzhiyun 	if (update) {
1218*4882a593Smuzhiyun 		hh = &neigh->hh;
1219*4882a593Smuzhiyun 		if (READ_ONCE(hh->hh_len)) {
1220*4882a593Smuzhiyun 			write_seqlock_bh(&hh->hh_lock);
1221*4882a593Smuzhiyun 			update(hh, neigh->dev, neigh->ha);
1222*4882a593Smuzhiyun 			write_sequnlock_bh(&hh->hh_lock);
1223*4882a593Smuzhiyun 		}
1224*4882a593Smuzhiyun 	}
1225*4882a593Smuzhiyun }
1226*4882a593Smuzhiyun 
1227*4882a593Smuzhiyun 
1228*4882a593Smuzhiyun 
1229*4882a593Smuzhiyun /* Generic update routine.
1230*4882a593Smuzhiyun    -- lladdr is new lladdr or NULL, if it is not supplied.
1231*4882a593Smuzhiyun    -- new    is new state.
1232*4882a593Smuzhiyun    -- flags
1233*4882a593Smuzhiyun 	NEIGH_UPDATE_F_OVERRIDE allows to override existing lladdr,
1234*4882a593Smuzhiyun 				if it is different.
1235*4882a593Smuzhiyun 	NEIGH_UPDATE_F_WEAK_OVERRIDE will suspect existing "connected"
1236*4882a593Smuzhiyun 				lladdr instead of overriding it
1237*4882a593Smuzhiyun 				if it is different.
1238*4882a593Smuzhiyun 	NEIGH_UPDATE_F_ADMIN	means that the change is administrative.
1239*4882a593Smuzhiyun 	NEIGH_UPDATE_F_USE	means that the entry is user triggered.
1240*4882a593Smuzhiyun 	NEIGH_UPDATE_F_OVERRIDE_ISROUTER allows to override existing
1241*4882a593Smuzhiyun 				NTF_ROUTER flag.
1242*4882a593Smuzhiyun 	NEIGH_UPDATE_F_ISROUTER	indicates if the neighbour is known as
1243*4882a593Smuzhiyun 				a router.
1244*4882a593Smuzhiyun 
1245*4882a593Smuzhiyun    Caller MUST hold reference count on the entry.
1246*4882a593Smuzhiyun  */
1247*4882a593Smuzhiyun 
__neigh_update(struct neighbour * neigh,const u8 * lladdr,u8 new,u32 flags,u32 nlmsg_pid,struct netlink_ext_ack * extack)1248*4882a593Smuzhiyun static int __neigh_update(struct neighbour *neigh, const u8 *lladdr,
1249*4882a593Smuzhiyun 			  u8 new, u32 flags, u32 nlmsg_pid,
1250*4882a593Smuzhiyun 			  struct netlink_ext_ack *extack)
1251*4882a593Smuzhiyun {
1252*4882a593Smuzhiyun 	bool ext_learn_change = false;
1253*4882a593Smuzhiyun 	u8 old;
1254*4882a593Smuzhiyun 	int err;
1255*4882a593Smuzhiyun 	int notify = 0;
1256*4882a593Smuzhiyun 	struct net_device *dev;
1257*4882a593Smuzhiyun 	int update_isrouter = 0;
1258*4882a593Smuzhiyun 
1259*4882a593Smuzhiyun 	trace_neigh_update(neigh, lladdr, new, flags, nlmsg_pid);
1260*4882a593Smuzhiyun 
1261*4882a593Smuzhiyun 	write_lock_bh(&neigh->lock);
1262*4882a593Smuzhiyun 
1263*4882a593Smuzhiyun 	dev    = neigh->dev;
1264*4882a593Smuzhiyun 	old    = neigh->nud_state;
1265*4882a593Smuzhiyun 	err    = -EPERM;
1266*4882a593Smuzhiyun 
1267*4882a593Smuzhiyun 	if (neigh->dead) {
1268*4882a593Smuzhiyun 		NL_SET_ERR_MSG(extack, "Neighbor entry is now dead");
1269*4882a593Smuzhiyun 		new = old;
1270*4882a593Smuzhiyun 		goto out;
1271*4882a593Smuzhiyun 	}
1272*4882a593Smuzhiyun 	if (!(flags & NEIGH_UPDATE_F_ADMIN) &&
1273*4882a593Smuzhiyun 	    (old & (NUD_NOARP | NUD_PERMANENT)))
1274*4882a593Smuzhiyun 		goto out;
1275*4882a593Smuzhiyun 
1276*4882a593Smuzhiyun 	ext_learn_change = neigh_update_ext_learned(neigh, flags, &notify);
1277*4882a593Smuzhiyun 	if (flags & NEIGH_UPDATE_F_USE) {
1278*4882a593Smuzhiyun 		new = old & ~NUD_PERMANENT;
1279*4882a593Smuzhiyun 		neigh->nud_state = new;
1280*4882a593Smuzhiyun 		err = 0;
1281*4882a593Smuzhiyun 		goto out;
1282*4882a593Smuzhiyun 	}
1283*4882a593Smuzhiyun 
1284*4882a593Smuzhiyun 	if (!(new & NUD_VALID)) {
1285*4882a593Smuzhiyun 		neigh_del_timer(neigh);
1286*4882a593Smuzhiyun 		if (old & NUD_CONNECTED)
1287*4882a593Smuzhiyun 			neigh_suspect(neigh);
1288*4882a593Smuzhiyun 		neigh->nud_state = new;
1289*4882a593Smuzhiyun 		err = 0;
1290*4882a593Smuzhiyun 		notify = old & NUD_VALID;
1291*4882a593Smuzhiyun 		if ((old & (NUD_INCOMPLETE | NUD_PROBE)) &&
1292*4882a593Smuzhiyun 		    (new & NUD_FAILED)) {
1293*4882a593Smuzhiyun 			neigh_invalidate(neigh);
1294*4882a593Smuzhiyun 			notify = 1;
1295*4882a593Smuzhiyun 		}
1296*4882a593Smuzhiyun 		goto out;
1297*4882a593Smuzhiyun 	}
1298*4882a593Smuzhiyun 
1299*4882a593Smuzhiyun 	/* Compare new lladdr with cached one */
1300*4882a593Smuzhiyun 	if (!dev->addr_len) {
1301*4882a593Smuzhiyun 		/* First case: device needs no address. */
1302*4882a593Smuzhiyun 		lladdr = neigh->ha;
1303*4882a593Smuzhiyun 	} else if (lladdr) {
1304*4882a593Smuzhiyun 		/* The second case: if something is already cached
1305*4882a593Smuzhiyun 		   and a new address is proposed:
1306*4882a593Smuzhiyun 		   - compare new & old
1307*4882a593Smuzhiyun 		   - if they are different, check override flag
1308*4882a593Smuzhiyun 		 */
1309*4882a593Smuzhiyun 		if ((old & NUD_VALID) &&
1310*4882a593Smuzhiyun 		    !memcmp(lladdr, neigh->ha, dev->addr_len))
1311*4882a593Smuzhiyun 			lladdr = neigh->ha;
1312*4882a593Smuzhiyun 	} else {
1313*4882a593Smuzhiyun 		/* No address is supplied; if we know something,
1314*4882a593Smuzhiyun 		   use it, otherwise discard the request.
1315*4882a593Smuzhiyun 		 */
1316*4882a593Smuzhiyun 		err = -EINVAL;
1317*4882a593Smuzhiyun 		if (!(old & NUD_VALID)) {
1318*4882a593Smuzhiyun 			NL_SET_ERR_MSG(extack, "No link layer address given");
1319*4882a593Smuzhiyun 			goto out;
1320*4882a593Smuzhiyun 		}
1321*4882a593Smuzhiyun 		lladdr = neigh->ha;
1322*4882a593Smuzhiyun 	}
1323*4882a593Smuzhiyun 
1324*4882a593Smuzhiyun 	/* Update confirmed timestamp for neighbour entry after we
1325*4882a593Smuzhiyun 	 * received ARP packet even if it doesn't change IP to MAC binding.
1326*4882a593Smuzhiyun 	 */
1327*4882a593Smuzhiyun 	if (new & NUD_CONNECTED)
1328*4882a593Smuzhiyun 		neigh->confirmed = jiffies;
1329*4882a593Smuzhiyun 
1330*4882a593Smuzhiyun 	/* If entry was valid and address is not changed,
1331*4882a593Smuzhiyun 	   do not change entry state, if new one is STALE.
1332*4882a593Smuzhiyun 	 */
1333*4882a593Smuzhiyun 	err = 0;
1334*4882a593Smuzhiyun 	update_isrouter = flags & NEIGH_UPDATE_F_OVERRIDE_ISROUTER;
1335*4882a593Smuzhiyun 	if (old & NUD_VALID) {
1336*4882a593Smuzhiyun 		if (lladdr != neigh->ha && !(flags & NEIGH_UPDATE_F_OVERRIDE)) {
1337*4882a593Smuzhiyun 			update_isrouter = 0;
1338*4882a593Smuzhiyun 			if ((flags & NEIGH_UPDATE_F_WEAK_OVERRIDE) &&
1339*4882a593Smuzhiyun 			    (old & NUD_CONNECTED)) {
1340*4882a593Smuzhiyun 				lladdr = neigh->ha;
1341*4882a593Smuzhiyun 				new = NUD_STALE;
1342*4882a593Smuzhiyun 			} else
1343*4882a593Smuzhiyun 				goto out;
1344*4882a593Smuzhiyun 		} else {
1345*4882a593Smuzhiyun 			if (lladdr == neigh->ha && new == NUD_STALE &&
1346*4882a593Smuzhiyun 			    !(flags & NEIGH_UPDATE_F_ADMIN))
1347*4882a593Smuzhiyun 				new = old;
1348*4882a593Smuzhiyun 		}
1349*4882a593Smuzhiyun 	}
1350*4882a593Smuzhiyun 
1351*4882a593Smuzhiyun 	/* Update timestamp only once we know we will make a change to the
1352*4882a593Smuzhiyun 	 * neighbour entry. Otherwise we risk to move the locktime window with
1353*4882a593Smuzhiyun 	 * noop updates and ignore relevant ARP updates.
1354*4882a593Smuzhiyun 	 */
1355*4882a593Smuzhiyun 	if (new != old || lladdr != neigh->ha)
1356*4882a593Smuzhiyun 		neigh->updated = jiffies;
1357*4882a593Smuzhiyun 
1358*4882a593Smuzhiyun 	if (new != old) {
1359*4882a593Smuzhiyun 		neigh_del_timer(neigh);
1360*4882a593Smuzhiyun 		if (new & NUD_PROBE)
1361*4882a593Smuzhiyun 			atomic_set(&neigh->probes, 0);
1362*4882a593Smuzhiyun 		if (new & NUD_IN_TIMER)
1363*4882a593Smuzhiyun 			neigh_add_timer(neigh, (jiffies +
1364*4882a593Smuzhiyun 						((new & NUD_REACHABLE) ?
1365*4882a593Smuzhiyun 						 neigh->parms->reachable_time :
1366*4882a593Smuzhiyun 						 0)));
1367*4882a593Smuzhiyun 		neigh->nud_state = new;
1368*4882a593Smuzhiyun 		notify = 1;
1369*4882a593Smuzhiyun 	}
1370*4882a593Smuzhiyun 
1371*4882a593Smuzhiyun 	if (lladdr != neigh->ha) {
1372*4882a593Smuzhiyun 		write_seqlock(&neigh->ha_lock);
1373*4882a593Smuzhiyun 		memcpy(&neigh->ha, lladdr, dev->addr_len);
1374*4882a593Smuzhiyun 		write_sequnlock(&neigh->ha_lock);
1375*4882a593Smuzhiyun 		neigh_update_hhs(neigh);
1376*4882a593Smuzhiyun 		if (!(new & NUD_CONNECTED))
1377*4882a593Smuzhiyun 			neigh->confirmed = jiffies -
1378*4882a593Smuzhiyun 				      (NEIGH_VAR(neigh->parms, BASE_REACHABLE_TIME) << 1);
1379*4882a593Smuzhiyun 		notify = 1;
1380*4882a593Smuzhiyun 	}
1381*4882a593Smuzhiyun 	if (new == old)
1382*4882a593Smuzhiyun 		goto out;
1383*4882a593Smuzhiyun 	if (new & NUD_CONNECTED)
1384*4882a593Smuzhiyun 		neigh_connect(neigh);
1385*4882a593Smuzhiyun 	else
1386*4882a593Smuzhiyun 		neigh_suspect(neigh);
1387*4882a593Smuzhiyun 	if (!(old & NUD_VALID)) {
1388*4882a593Smuzhiyun 		struct sk_buff *skb;
1389*4882a593Smuzhiyun 
1390*4882a593Smuzhiyun 		/* Again: avoid dead loop if something went wrong */
1391*4882a593Smuzhiyun 
1392*4882a593Smuzhiyun 		while (neigh->nud_state & NUD_VALID &&
1393*4882a593Smuzhiyun 		       (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) {
1394*4882a593Smuzhiyun 			struct dst_entry *dst = skb_dst(skb);
1395*4882a593Smuzhiyun 			struct neighbour *n2, *n1 = neigh;
1396*4882a593Smuzhiyun 			write_unlock_bh(&neigh->lock);
1397*4882a593Smuzhiyun 
1398*4882a593Smuzhiyun 			rcu_read_lock();
1399*4882a593Smuzhiyun 
1400*4882a593Smuzhiyun 			/* Why not just use 'neigh' as-is?  The problem is that
1401*4882a593Smuzhiyun 			 * things such as shaper, eql, and sch_teql can end up
1402*4882a593Smuzhiyun 			 * using alternative, different, neigh objects to output
1403*4882a593Smuzhiyun 			 * the packet in the output path.  So what we need to do
1404*4882a593Smuzhiyun 			 * here is re-lookup the top-level neigh in the path so
1405*4882a593Smuzhiyun 			 * we can reinject the packet there.
1406*4882a593Smuzhiyun 			 */
1407*4882a593Smuzhiyun 			n2 = NULL;
1408*4882a593Smuzhiyun 			if (dst && dst->obsolete != DST_OBSOLETE_DEAD) {
1409*4882a593Smuzhiyun 				n2 = dst_neigh_lookup_skb(dst, skb);
1410*4882a593Smuzhiyun 				if (n2)
1411*4882a593Smuzhiyun 					n1 = n2;
1412*4882a593Smuzhiyun 			}
1413*4882a593Smuzhiyun 			n1->output(n1, skb);
1414*4882a593Smuzhiyun 			if (n2)
1415*4882a593Smuzhiyun 				neigh_release(n2);
1416*4882a593Smuzhiyun 			rcu_read_unlock();
1417*4882a593Smuzhiyun 
1418*4882a593Smuzhiyun 			write_lock_bh(&neigh->lock);
1419*4882a593Smuzhiyun 		}
1420*4882a593Smuzhiyun 		__skb_queue_purge(&neigh->arp_queue);
1421*4882a593Smuzhiyun 		neigh->arp_queue_len_bytes = 0;
1422*4882a593Smuzhiyun 	}
1423*4882a593Smuzhiyun out:
1424*4882a593Smuzhiyun 	if (update_isrouter)
1425*4882a593Smuzhiyun 		neigh_update_is_router(neigh, flags, &notify);
1426*4882a593Smuzhiyun 	write_unlock_bh(&neigh->lock);
1427*4882a593Smuzhiyun 
1428*4882a593Smuzhiyun 	if (((new ^ old) & NUD_PERMANENT) || ext_learn_change)
1429*4882a593Smuzhiyun 		neigh_update_gc_list(neigh);
1430*4882a593Smuzhiyun 
1431*4882a593Smuzhiyun 	if (notify)
1432*4882a593Smuzhiyun 		neigh_update_notify(neigh, nlmsg_pid);
1433*4882a593Smuzhiyun 
1434*4882a593Smuzhiyun 	trace_neigh_update_done(neigh, err);
1435*4882a593Smuzhiyun 
1436*4882a593Smuzhiyun 	return err;
1437*4882a593Smuzhiyun }
1438*4882a593Smuzhiyun 
neigh_update(struct neighbour * neigh,const u8 * lladdr,u8 new,u32 flags,u32 nlmsg_pid)1439*4882a593Smuzhiyun int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
1440*4882a593Smuzhiyun 		 u32 flags, u32 nlmsg_pid)
1441*4882a593Smuzhiyun {
1442*4882a593Smuzhiyun 	return __neigh_update(neigh, lladdr, new, flags, nlmsg_pid, NULL);
1443*4882a593Smuzhiyun }
1444*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_update);
1445*4882a593Smuzhiyun 
1446*4882a593Smuzhiyun /* Update the neigh to listen temporarily for probe responses, even if it is
1447*4882a593Smuzhiyun  * in a NUD_FAILED state. The caller has to hold neigh->lock for writing.
1448*4882a593Smuzhiyun  */
__neigh_set_probe_once(struct neighbour * neigh)1449*4882a593Smuzhiyun void __neigh_set_probe_once(struct neighbour *neigh)
1450*4882a593Smuzhiyun {
1451*4882a593Smuzhiyun 	if (neigh->dead)
1452*4882a593Smuzhiyun 		return;
1453*4882a593Smuzhiyun 	neigh->updated = jiffies;
1454*4882a593Smuzhiyun 	if (!(neigh->nud_state & NUD_FAILED))
1455*4882a593Smuzhiyun 		return;
1456*4882a593Smuzhiyun 	neigh->nud_state = NUD_INCOMPLETE;
1457*4882a593Smuzhiyun 	atomic_set(&neigh->probes, neigh_max_probes(neigh));
1458*4882a593Smuzhiyun 	neigh_add_timer(neigh,
1459*4882a593Smuzhiyun 			jiffies + max(NEIGH_VAR(neigh->parms, RETRANS_TIME),
1460*4882a593Smuzhiyun 				      HZ/100));
1461*4882a593Smuzhiyun }
1462*4882a593Smuzhiyun EXPORT_SYMBOL(__neigh_set_probe_once);
1463*4882a593Smuzhiyun 
neigh_event_ns(struct neigh_table * tbl,u8 * lladdr,void * saddr,struct net_device * dev)1464*4882a593Smuzhiyun struct neighbour *neigh_event_ns(struct neigh_table *tbl,
1465*4882a593Smuzhiyun 				 u8 *lladdr, void *saddr,
1466*4882a593Smuzhiyun 				 struct net_device *dev)
1467*4882a593Smuzhiyun {
1468*4882a593Smuzhiyun 	struct neighbour *neigh = __neigh_lookup(tbl, saddr, dev,
1469*4882a593Smuzhiyun 						 lladdr || !dev->addr_len);
1470*4882a593Smuzhiyun 	if (neigh)
1471*4882a593Smuzhiyun 		neigh_update(neigh, lladdr, NUD_STALE,
1472*4882a593Smuzhiyun 			     NEIGH_UPDATE_F_OVERRIDE, 0);
1473*4882a593Smuzhiyun 	return neigh;
1474*4882a593Smuzhiyun }
1475*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_event_ns);
1476*4882a593Smuzhiyun 
1477*4882a593Smuzhiyun /* called with read_lock_bh(&n->lock); */
neigh_hh_init(struct neighbour * n)1478*4882a593Smuzhiyun static void neigh_hh_init(struct neighbour *n)
1479*4882a593Smuzhiyun {
1480*4882a593Smuzhiyun 	struct net_device *dev = n->dev;
1481*4882a593Smuzhiyun 	__be16 prot = n->tbl->protocol;
1482*4882a593Smuzhiyun 	struct hh_cache	*hh = &n->hh;
1483*4882a593Smuzhiyun 
1484*4882a593Smuzhiyun 	write_lock_bh(&n->lock);
1485*4882a593Smuzhiyun 
1486*4882a593Smuzhiyun 	/* Only one thread can come in here and initialize the
1487*4882a593Smuzhiyun 	 * hh_cache entry.
1488*4882a593Smuzhiyun 	 */
1489*4882a593Smuzhiyun 	if (!hh->hh_len)
1490*4882a593Smuzhiyun 		dev->header_ops->cache(n, hh, prot);
1491*4882a593Smuzhiyun 
1492*4882a593Smuzhiyun 	write_unlock_bh(&n->lock);
1493*4882a593Smuzhiyun }
1494*4882a593Smuzhiyun 
1495*4882a593Smuzhiyun /* Slow and careful. */
1496*4882a593Smuzhiyun 
neigh_resolve_output(struct neighbour * neigh,struct sk_buff * skb)1497*4882a593Smuzhiyun int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb)
1498*4882a593Smuzhiyun {
1499*4882a593Smuzhiyun 	int rc = 0;
1500*4882a593Smuzhiyun 
1501*4882a593Smuzhiyun 	if (!neigh_event_send(neigh, skb)) {
1502*4882a593Smuzhiyun 		int err;
1503*4882a593Smuzhiyun 		struct net_device *dev = neigh->dev;
1504*4882a593Smuzhiyun 		unsigned int seq;
1505*4882a593Smuzhiyun 
1506*4882a593Smuzhiyun 		if (dev->header_ops->cache && !READ_ONCE(neigh->hh.hh_len))
1507*4882a593Smuzhiyun 			neigh_hh_init(neigh);
1508*4882a593Smuzhiyun 
1509*4882a593Smuzhiyun 		do {
1510*4882a593Smuzhiyun 			__skb_pull(skb, skb_network_offset(skb));
1511*4882a593Smuzhiyun 			seq = read_seqbegin(&neigh->ha_lock);
1512*4882a593Smuzhiyun 			err = dev_hard_header(skb, dev, ntohs(skb->protocol),
1513*4882a593Smuzhiyun 					      neigh->ha, NULL, skb->len);
1514*4882a593Smuzhiyun 		} while (read_seqretry(&neigh->ha_lock, seq));
1515*4882a593Smuzhiyun 
1516*4882a593Smuzhiyun 		if (err >= 0)
1517*4882a593Smuzhiyun 			rc = dev_queue_xmit(skb);
1518*4882a593Smuzhiyun 		else
1519*4882a593Smuzhiyun 			goto out_kfree_skb;
1520*4882a593Smuzhiyun 	}
1521*4882a593Smuzhiyun out:
1522*4882a593Smuzhiyun 	return rc;
1523*4882a593Smuzhiyun out_kfree_skb:
1524*4882a593Smuzhiyun 	rc = -EINVAL;
1525*4882a593Smuzhiyun 	kfree_skb(skb);
1526*4882a593Smuzhiyun 	goto out;
1527*4882a593Smuzhiyun }
1528*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_resolve_output);
1529*4882a593Smuzhiyun 
1530*4882a593Smuzhiyun /* As fast as possible without hh cache */
1531*4882a593Smuzhiyun 
neigh_connected_output(struct neighbour * neigh,struct sk_buff * skb)1532*4882a593Smuzhiyun int neigh_connected_output(struct neighbour *neigh, struct sk_buff *skb)
1533*4882a593Smuzhiyun {
1534*4882a593Smuzhiyun 	struct net_device *dev = neigh->dev;
1535*4882a593Smuzhiyun 	unsigned int seq;
1536*4882a593Smuzhiyun 	int err;
1537*4882a593Smuzhiyun 
1538*4882a593Smuzhiyun 	do {
1539*4882a593Smuzhiyun 		__skb_pull(skb, skb_network_offset(skb));
1540*4882a593Smuzhiyun 		seq = read_seqbegin(&neigh->ha_lock);
1541*4882a593Smuzhiyun 		err = dev_hard_header(skb, dev, ntohs(skb->protocol),
1542*4882a593Smuzhiyun 				      neigh->ha, NULL, skb->len);
1543*4882a593Smuzhiyun 	} while (read_seqretry(&neigh->ha_lock, seq));
1544*4882a593Smuzhiyun 
1545*4882a593Smuzhiyun 	if (err >= 0)
1546*4882a593Smuzhiyun 		err = dev_queue_xmit(skb);
1547*4882a593Smuzhiyun 	else {
1548*4882a593Smuzhiyun 		err = -EINVAL;
1549*4882a593Smuzhiyun 		kfree_skb(skb);
1550*4882a593Smuzhiyun 	}
1551*4882a593Smuzhiyun 	return err;
1552*4882a593Smuzhiyun }
1553*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_connected_output);
1554*4882a593Smuzhiyun 
neigh_direct_output(struct neighbour * neigh,struct sk_buff * skb)1555*4882a593Smuzhiyun int neigh_direct_output(struct neighbour *neigh, struct sk_buff *skb)
1556*4882a593Smuzhiyun {
1557*4882a593Smuzhiyun 	return dev_queue_xmit(skb);
1558*4882a593Smuzhiyun }
1559*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_direct_output);
1560*4882a593Smuzhiyun 
neigh_proxy_process(struct timer_list * t)1561*4882a593Smuzhiyun static void neigh_proxy_process(struct timer_list *t)
1562*4882a593Smuzhiyun {
1563*4882a593Smuzhiyun 	struct neigh_table *tbl = from_timer(tbl, t, proxy_timer);
1564*4882a593Smuzhiyun 	long sched_next = 0;
1565*4882a593Smuzhiyun 	unsigned long now = jiffies;
1566*4882a593Smuzhiyun 	struct sk_buff *skb, *n;
1567*4882a593Smuzhiyun 
1568*4882a593Smuzhiyun 	spin_lock(&tbl->proxy_queue.lock);
1569*4882a593Smuzhiyun 
1570*4882a593Smuzhiyun 	skb_queue_walk_safe(&tbl->proxy_queue, skb, n) {
1571*4882a593Smuzhiyun 		long tdif = NEIGH_CB(skb)->sched_next - now;
1572*4882a593Smuzhiyun 
1573*4882a593Smuzhiyun 		if (tdif <= 0) {
1574*4882a593Smuzhiyun 			struct net_device *dev = skb->dev;
1575*4882a593Smuzhiyun 
1576*4882a593Smuzhiyun 			__skb_unlink(skb, &tbl->proxy_queue);
1577*4882a593Smuzhiyun 			if (tbl->proxy_redo && netif_running(dev)) {
1578*4882a593Smuzhiyun 				rcu_read_lock();
1579*4882a593Smuzhiyun 				tbl->proxy_redo(skb);
1580*4882a593Smuzhiyun 				rcu_read_unlock();
1581*4882a593Smuzhiyun 			} else {
1582*4882a593Smuzhiyun 				kfree_skb(skb);
1583*4882a593Smuzhiyun 			}
1584*4882a593Smuzhiyun 
1585*4882a593Smuzhiyun 			dev_put(dev);
1586*4882a593Smuzhiyun 		} else if (!sched_next || tdif < sched_next)
1587*4882a593Smuzhiyun 			sched_next = tdif;
1588*4882a593Smuzhiyun 	}
1589*4882a593Smuzhiyun 	del_timer(&tbl->proxy_timer);
1590*4882a593Smuzhiyun 	if (sched_next)
1591*4882a593Smuzhiyun 		mod_timer(&tbl->proxy_timer, jiffies + sched_next);
1592*4882a593Smuzhiyun 	spin_unlock(&tbl->proxy_queue.lock);
1593*4882a593Smuzhiyun }
1594*4882a593Smuzhiyun 
pneigh_enqueue(struct neigh_table * tbl,struct neigh_parms * p,struct sk_buff * skb)1595*4882a593Smuzhiyun void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
1596*4882a593Smuzhiyun 		    struct sk_buff *skb)
1597*4882a593Smuzhiyun {
1598*4882a593Smuzhiyun 	unsigned long now = jiffies;
1599*4882a593Smuzhiyun 
1600*4882a593Smuzhiyun 	unsigned long sched_next = now + (prandom_u32() %
1601*4882a593Smuzhiyun 					  NEIGH_VAR(p, PROXY_DELAY));
1602*4882a593Smuzhiyun 
1603*4882a593Smuzhiyun 	if (tbl->proxy_queue.qlen > NEIGH_VAR(p, PROXY_QLEN)) {
1604*4882a593Smuzhiyun 		kfree_skb(skb);
1605*4882a593Smuzhiyun 		return;
1606*4882a593Smuzhiyun 	}
1607*4882a593Smuzhiyun 
1608*4882a593Smuzhiyun 	NEIGH_CB(skb)->sched_next = sched_next;
1609*4882a593Smuzhiyun 	NEIGH_CB(skb)->flags |= LOCALLY_ENQUEUED;
1610*4882a593Smuzhiyun 
1611*4882a593Smuzhiyun 	spin_lock(&tbl->proxy_queue.lock);
1612*4882a593Smuzhiyun 	if (del_timer(&tbl->proxy_timer)) {
1613*4882a593Smuzhiyun 		if (time_before(tbl->proxy_timer.expires, sched_next))
1614*4882a593Smuzhiyun 			sched_next = tbl->proxy_timer.expires;
1615*4882a593Smuzhiyun 	}
1616*4882a593Smuzhiyun 	skb_dst_drop(skb);
1617*4882a593Smuzhiyun 	dev_hold(skb->dev);
1618*4882a593Smuzhiyun 	__skb_queue_tail(&tbl->proxy_queue, skb);
1619*4882a593Smuzhiyun 	mod_timer(&tbl->proxy_timer, sched_next);
1620*4882a593Smuzhiyun 	spin_unlock(&tbl->proxy_queue.lock);
1621*4882a593Smuzhiyun }
1622*4882a593Smuzhiyun EXPORT_SYMBOL(pneigh_enqueue);
1623*4882a593Smuzhiyun 
lookup_neigh_parms(struct neigh_table * tbl,struct net * net,int ifindex)1624*4882a593Smuzhiyun static inline struct neigh_parms *lookup_neigh_parms(struct neigh_table *tbl,
1625*4882a593Smuzhiyun 						      struct net *net, int ifindex)
1626*4882a593Smuzhiyun {
1627*4882a593Smuzhiyun 	struct neigh_parms *p;
1628*4882a593Smuzhiyun 
1629*4882a593Smuzhiyun 	list_for_each_entry(p, &tbl->parms_list, list) {
1630*4882a593Smuzhiyun 		if ((p->dev && p->dev->ifindex == ifindex && net_eq(neigh_parms_net(p), net)) ||
1631*4882a593Smuzhiyun 		    (!p->dev && !ifindex && net_eq(net, &init_net)))
1632*4882a593Smuzhiyun 			return p;
1633*4882a593Smuzhiyun 	}
1634*4882a593Smuzhiyun 
1635*4882a593Smuzhiyun 	return NULL;
1636*4882a593Smuzhiyun }
1637*4882a593Smuzhiyun 
neigh_parms_alloc(struct net_device * dev,struct neigh_table * tbl)1638*4882a593Smuzhiyun struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
1639*4882a593Smuzhiyun 				      struct neigh_table *tbl)
1640*4882a593Smuzhiyun {
1641*4882a593Smuzhiyun 	struct neigh_parms *p;
1642*4882a593Smuzhiyun 	struct net *net = dev_net(dev);
1643*4882a593Smuzhiyun 	const struct net_device_ops *ops = dev->netdev_ops;
1644*4882a593Smuzhiyun 
1645*4882a593Smuzhiyun 	p = kmemdup(&tbl->parms, sizeof(*p), GFP_KERNEL);
1646*4882a593Smuzhiyun 	if (p) {
1647*4882a593Smuzhiyun 		p->tbl		  = tbl;
1648*4882a593Smuzhiyun 		refcount_set(&p->refcnt, 1);
1649*4882a593Smuzhiyun 		p->reachable_time =
1650*4882a593Smuzhiyun 				neigh_rand_reach_time(NEIGH_VAR(p, BASE_REACHABLE_TIME));
1651*4882a593Smuzhiyun 		dev_hold(dev);
1652*4882a593Smuzhiyun 		p->dev = dev;
1653*4882a593Smuzhiyun 		write_pnet(&p->net, net);
1654*4882a593Smuzhiyun 		p->sysctl_table = NULL;
1655*4882a593Smuzhiyun 
1656*4882a593Smuzhiyun 		if (ops->ndo_neigh_setup && ops->ndo_neigh_setup(dev, p)) {
1657*4882a593Smuzhiyun 			dev_put(dev);
1658*4882a593Smuzhiyun 			kfree(p);
1659*4882a593Smuzhiyun 			return NULL;
1660*4882a593Smuzhiyun 		}
1661*4882a593Smuzhiyun 
1662*4882a593Smuzhiyun 		write_lock_bh(&tbl->lock);
1663*4882a593Smuzhiyun 		list_add(&p->list, &tbl->parms.list);
1664*4882a593Smuzhiyun 		write_unlock_bh(&tbl->lock);
1665*4882a593Smuzhiyun 
1666*4882a593Smuzhiyun 		neigh_parms_data_state_cleanall(p);
1667*4882a593Smuzhiyun 	}
1668*4882a593Smuzhiyun 	return p;
1669*4882a593Smuzhiyun }
1670*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_parms_alloc);
1671*4882a593Smuzhiyun 
neigh_rcu_free_parms(struct rcu_head * head)1672*4882a593Smuzhiyun static void neigh_rcu_free_parms(struct rcu_head *head)
1673*4882a593Smuzhiyun {
1674*4882a593Smuzhiyun 	struct neigh_parms *parms =
1675*4882a593Smuzhiyun 		container_of(head, struct neigh_parms, rcu_head);
1676*4882a593Smuzhiyun 
1677*4882a593Smuzhiyun 	neigh_parms_put(parms);
1678*4882a593Smuzhiyun }
1679*4882a593Smuzhiyun 
neigh_parms_release(struct neigh_table * tbl,struct neigh_parms * parms)1680*4882a593Smuzhiyun void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
1681*4882a593Smuzhiyun {
1682*4882a593Smuzhiyun 	if (!parms || parms == &tbl->parms)
1683*4882a593Smuzhiyun 		return;
1684*4882a593Smuzhiyun 	write_lock_bh(&tbl->lock);
1685*4882a593Smuzhiyun 	list_del(&parms->list);
1686*4882a593Smuzhiyun 	parms->dead = 1;
1687*4882a593Smuzhiyun 	write_unlock_bh(&tbl->lock);
1688*4882a593Smuzhiyun 	if (parms->dev)
1689*4882a593Smuzhiyun 		dev_put(parms->dev);
1690*4882a593Smuzhiyun 	call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
1691*4882a593Smuzhiyun }
1692*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_parms_release);
1693*4882a593Smuzhiyun 
neigh_parms_destroy(struct neigh_parms * parms)1694*4882a593Smuzhiyun static void neigh_parms_destroy(struct neigh_parms *parms)
1695*4882a593Smuzhiyun {
1696*4882a593Smuzhiyun 	kfree(parms);
1697*4882a593Smuzhiyun }
1698*4882a593Smuzhiyun 
1699*4882a593Smuzhiyun static struct lock_class_key neigh_table_proxy_queue_class;
1700*4882a593Smuzhiyun 
1701*4882a593Smuzhiyun static struct neigh_table *neigh_tables[NEIGH_NR_TABLES] __read_mostly;
1702*4882a593Smuzhiyun 
neigh_table_init(int index,struct neigh_table * tbl)1703*4882a593Smuzhiyun void neigh_table_init(int index, struct neigh_table *tbl)
1704*4882a593Smuzhiyun {
1705*4882a593Smuzhiyun 	unsigned long now = jiffies;
1706*4882a593Smuzhiyun 	unsigned long phsize;
1707*4882a593Smuzhiyun 
1708*4882a593Smuzhiyun 	INIT_LIST_HEAD(&tbl->parms_list);
1709*4882a593Smuzhiyun 	INIT_LIST_HEAD(&tbl->gc_list);
1710*4882a593Smuzhiyun 	list_add(&tbl->parms.list, &tbl->parms_list);
1711*4882a593Smuzhiyun 	write_pnet(&tbl->parms.net, &init_net);
1712*4882a593Smuzhiyun 	refcount_set(&tbl->parms.refcnt, 1);
1713*4882a593Smuzhiyun 	tbl->parms.reachable_time =
1714*4882a593Smuzhiyun 			  neigh_rand_reach_time(NEIGH_VAR(&tbl->parms, BASE_REACHABLE_TIME));
1715*4882a593Smuzhiyun 
1716*4882a593Smuzhiyun 	tbl->stats = alloc_percpu(struct neigh_statistics);
1717*4882a593Smuzhiyun 	if (!tbl->stats)
1718*4882a593Smuzhiyun 		panic("cannot create neighbour cache statistics");
1719*4882a593Smuzhiyun 
1720*4882a593Smuzhiyun #ifdef CONFIG_PROC_FS
1721*4882a593Smuzhiyun 	if (!proc_create_seq_data(tbl->id, 0, init_net.proc_net_stat,
1722*4882a593Smuzhiyun 			      &neigh_stat_seq_ops, tbl))
1723*4882a593Smuzhiyun 		panic("cannot create neighbour proc dir entry");
1724*4882a593Smuzhiyun #endif
1725*4882a593Smuzhiyun 
1726*4882a593Smuzhiyun 	RCU_INIT_POINTER(tbl->nht, neigh_hash_alloc(3));
1727*4882a593Smuzhiyun 
1728*4882a593Smuzhiyun 	phsize = (PNEIGH_HASHMASK + 1) * sizeof(struct pneigh_entry *);
1729*4882a593Smuzhiyun 	tbl->phash_buckets = kzalloc(phsize, GFP_KERNEL);
1730*4882a593Smuzhiyun 
1731*4882a593Smuzhiyun 	if (!tbl->nht || !tbl->phash_buckets)
1732*4882a593Smuzhiyun 		panic("cannot allocate neighbour cache hashes");
1733*4882a593Smuzhiyun 
1734*4882a593Smuzhiyun 	if (!tbl->entry_size)
1735*4882a593Smuzhiyun 		tbl->entry_size = ALIGN(offsetof(struct neighbour, primary_key) +
1736*4882a593Smuzhiyun 					tbl->key_len, NEIGH_PRIV_ALIGN);
1737*4882a593Smuzhiyun 	else
1738*4882a593Smuzhiyun 		WARN_ON(tbl->entry_size % NEIGH_PRIV_ALIGN);
1739*4882a593Smuzhiyun 
1740*4882a593Smuzhiyun 	rwlock_init(&tbl->lock);
1741*4882a593Smuzhiyun 	INIT_DEFERRABLE_WORK(&tbl->gc_work, neigh_periodic_work);
1742*4882a593Smuzhiyun 	queue_delayed_work(system_power_efficient_wq, &tbl->gc_work,
1743*4882a593Smuzhiyun 			tbl->parms.reachable_time);
1744*4882a593Smuzhiyun 	timer_setup(&tbl->proxy_timer, neigh_proxy_process, 0);
1745*4882a593Smuzhiyun 	skb_queue_head_init_class(&tbl->proxy_queue,
1746*4882a593Smuzhiyun 			&neigh_table_proxy_queue_class);
1747*4882a593Smuzhiyun 
1748*4882a593Smuzhiyun 	tbl->last_flush = now;
1749*4882a593Smuzhiyun 	tbl->last_rand	= now + tbl->parms.reachable_time * 20;
1750*4882a593Smuzhiyun 
1751*4882a593Smuzhiyun 	neigh_tables[index] = tbl;
1752*4882a593Smuzhiyun }
1753*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_table_init);
1754*4882a593Smuzhiyun 
neigh_table_clear(int index,struct neigh_table * tbl)1755*4882a593Smuzhiyun int neigh_table_clear(int index, struct neigh_table *tbl)
1756*4882a593Smuzhiyun {
1757*4882a593Smuzhiyun 	neigh_tables[index] = NULL;
1758*4882a593Smuzhiyun 	/* It is not clean... Fix it to unload IPv6 module safely */
1759*4882a593Smuzhiyun 	cancel_delayed_work_sync(&tbl->gc_work);
1760*4882a593Smuzhiyun 	del_timer_sync(&tbl->proxy_timer);
1761*4882a593Smuzhiyun 	pneigh_queue_purge(&tbl->proxy_queue, NULL);
1762*4882a593Smuzhiyun 	neigh_ifdown(tbl, NULL);
1763*4882a593Smuzhiyun 	if (atomic_read(&tbl->entries))
1764*4882a593Smuzhiyun 		pr_crit("neighbour leakage\n");
1765*4882a593Smuzhiyun 
1766*4882a593Smuzhiyun 	call_rcu(&rcu_dereference_protected(tbl->nht, 1)->rcu,
1767*4882a593Smuzhiyun 		 neigh_hash_free_rcu);
1768*4882a593Smuzhiyun 	tbl->nht = NULL;
1769*4882a593Smuzhiyun 
1770*4882a593Smuzhiyun 	kfree(tbl->phash_buckets);
1771*4882a593Smuzhiyun 	tbl->phash_buckets = NULL;
1772*4882a593Smuzhiyun 
1773*4882a593Smuzhiyun 	remove_proc_entry(tbl->id, init_net.proc_net_stat);
1774*4882a593Smuzhiyun 
1775*4882a593Smuzhiyun 	free_percpu(tbl->stats);
1776*4882a593Smuzhiyun 	tbl->stats = NULL;
1777*4882a593Smuzhiyun 
1778*4882a593Smuzhiyun 	return 0;
1779*4882a593Smuzhiyun }
1780*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_table_clear);
1781*4882a593Smuzhiyun 
neigh_find_table(int family)1782*4882a593Smuzhiyun static struct neigh_table *neigh_find_table(int family)
1783*4882a593Smuzhiyun {
1784*4882a593Smuzhiyun 	struct neigh_table *tbl = NULL;
1785*4882a593Smuzhiyun 
1786*4882a593Smuzhiyun 	switch (family) {
1787*4882a593Smuzhiyun 	case AF_INET:
1788*4882a593Smuzhiyun 		tbl = neigh_tables[NEIGH_ARP_TABLE];
1789*4882a593Smuzhiyun 		break;
1790*4882a593Smuzhiyun 	case AF_INET6:
1791*4882a593Smuzhiyun 		tbl = neigh_tables[NEIGH_ND_TABLE];
1792*4882a593Smuzhiyun 		break;
1793*4882a593Smuzhiyun 	case AF_DECnet:
1794*4882a593Smuzhiyun 		tbl = neigh_tables[NEIGH_DN_TABLE];
1795*4882a593Smuzhiyun 		break;
1796*4882a593Smuzhiyun 	}
1797*4882a593Smuzhiyun 
1798*4882a593Smuzhiyun 	return tbl;
1799*4882a593Smuzhiyun }
1800*4882a593Smuzhiyun 
1801*4882a593Smuzhiyun const struct nla_policy nda_policy[NDA_MAX+1] = {
1802*4882a593Smuzhiyun 	[NDA_UNSPEC]		= { .strict_start_type = NDA_NH_ID },
1803*4882a593Smuzhiyun 	[NDA_DST]		= { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
1804*4882a593Smuzhiyun 	[NDA_LLADDR]		= { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
1805*4882a593Smuzhiyun 	[NDA_CACHEINFO]		= { .len = sizeof(struct nda_cacheinfo) },
1806*4882a593Smuzhiyun 	[NDA_PROBES]		= { .type = NLA_U32 },
1807*4882a593Smuzhiyun 	[NDA_VLAN]		= { .type = NLA_U16 },
1808*4882a593Smuzhiyun 	[NDA_PORT]		= { .type = NLA_U16 },
1809*4882a593Smuzhiyun 	[NDA_VNI]		= { .type = NLA_U32 },
1810*4882a593Smuzhiyun 	[NDA_IFINDEX]		= { .type = NLA_U32 },
1811*4882a593Smuzhiyun 	[NDA_MASTER]		= { .type = NLA_U32 },
1812*4882a593Smuzhiyun 	[NDA_PROTOCOL]		= { .type = NLA_U8 },
1813*4882a593Smuzhiyun 	[NDA_NH_ID]		= { .type = NLA_U32 },
1814*4882a593Smuzhiyun 	[NDA_FDB_EXT_ATTRS]	= { .type = NLA_NESTED },
1815*4882a593Smuzhiyun };
1816*4882a593Smuzhiyun 
neigh_delete(struct sk_buff * skb,struct nlmsghdr * nlh,struct netlink_ext_ack * extack)1817*4882a593Smuzhiyun static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh,
1818*4882a593Smuzhiyun 			struct netlink_ext_ack *extack)
1819*4882a593Smuzhiyun {
1820*4882a593Smuzhiyun 	struct net *net = sock_net(skb->sk);
1821*4882a593Smuzhiyun 	struct ndmsg *ndm;
1822*4882a593Smuzhiyun 	struct nlattr *dst_attr;
1823*4882a593Smuzhiyun 	struct neigh_table *tbl;
1824*4882a593Smuzhiyun 	struct neighbour *neigh;
1825*4882a593Smuzhiyun 	struct net_device *dev = NULL;
1826*4882a593Smuzhiyun 	int err = -EINVAL;
1827*4882a593Smuzhiyun 
1828*4882a593Smuzhiyun 	ASSERT_RTNL();
1829*4882a593Smuzhiyun 	if (nlmsg_len(nlh) < sizeof(*ndm))
1830*4882a593Smuzhiyun 		goto out;
1831*4882a593Smuzhiyun 
1832*4882a593Smuzhiyun 	dst_attr = nlmsg_find_attr(nlh, sizeof(*ndm), NDA_DST);
1833*4882a593Smuzhiyun 	if (!dst_attr) {
1834*4882a593Smuzhiyun 		NL_SET_ERR_MSG(extack, "Network address not specified");
1835*4882a593Smuzhiyun 		goto out;
1836*4882a593Smuzhiyun 	}
1837*4882a593Smuzhiyun 
1838*4882a593Smuzhiyun 	ndm = nlmsg_data(nlh);
1839*4882a593Smuzhiyun 	if (ndm->ndm_ifindex) {
1840*4882a593Smuzhiyun 		dev = __dev_get_by_index(net, ndm->ndm_ifindex);
1841*4882a593Smuzhiyun 		if (dev == NULL) {
1842*4882a593Smuzhiyun 			err = -ENODEV;
1843*4882a593Smuzhiyun 			goto out;
1844*4882a593Smuzhiyun 		}
1845*4882a593Smuzhiyun 	}
1846*4882a593Smuzhiyun 
1847*4882a593Smuzhiyun 	tbl = neigh_find_table(ndm->ndm_family);
1848*4882a593Smuzhiyun 	if (tbl == NULL)
1849*4882a593Smuzhiyun 		return -EAFNOSUPPORT;
1850*4882a593Smuzhiyun 
1851*4882a593Smuzhiyun 	if (nla_len(dst_attr) < (int)tbl->key_len) {
1852*4882a593Smuzhiyun 		NL_SET_ERR_MSG(extack, "Invalid network address");
1853*4882a593Smuzhiyun 		goto out;
1854*4882a593Smuzhiyun 	}
1855*4882a593Smuzhiyun 
1856*4882a593Smuzhiyun 	if (ndm->ndm_flags & NTF_PROXY) {
1857*4882a593Smuzhiyun 		err = pneigh_delete(tbl, net, nla_data(dst_attr), dev);
1858*4882a593Smuzhiyun 		goto out;
1859*4882a593Smuzhiyun 	}
1860*4882a593Smuzhiyun 
1861*4882a593Smuzhiyun 	if (dev == NULL)
1862*4882a593Smuzhiyun 		goto out;
1863*4882a593Smuzhiyun 
1864*4882a593Smuzhiyun 	neigh = neigh_lookup(tbl, nla_data(dst_attr), dev);
1865*4882a593Smuzhiyun 	if (neigh == NULL) {
1866*4882a593Smuzhiyun 		err = -ENOENT;
1867*4882a593Smuzhiyun 		goto out;
1868*4882a593Smuzhiyun 	}
1869*4882a593Smuzhiyun 
1870*4882a593Smuzhiyun 	err = __neigh_update(neigh, NULL, NUD_FAILED,
1871*4882a593Smuzhiyun 			     NEIGH_UPDATE_F_OVERRIDE | NEIGH_UPDATE_F_ADMIN,
1872*4882a593Smuzhiyun 			     NETLINK_CB(skb).portid, extack);
1873*4882a593Smuzhiyun 	write_lock_bh(&tbl->lock);
1874*4882a593Smuzhiyun 	neigh_release(neigh);
1875*4882a593Smuzhiyun 	neigh_remove_one(neigh, tbl);
1876*4882a593Smuzhiyun 	write_unlock_bh(&tbl->lock);
1877*4882a593Smuzhiyun 
1878*4882a593Smuzhiyun out:
1879*4882a593Smuzhiyun 	return err;
1880*4882a593Smuzhiyun }
1881*4882a593Smuzhiyun 
neigh_add(struct sk_buff * skb,struct nlmsghdr * nlh,struct netlink_ext_ack * extack)1882*4882a593Smuzhiyun static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh,
1883*4882a593Smuzhiyun 		     struct netlink_ext_ack *extack)
1884*4882a593Smuzhiyun {
1885*4882a593Smuzhiyun 	int flags = NEIGH_UPDATE_F_ADMIN | NEIGH_UPDATE_F_OVERRIDE |
1886*4882a593Smuzhiyun 		NEIGH_UPDATE_F_OVERRIDE_ISROUTER;
1887*4882a593Smuzhiyun 	struct net *net = sock_net(skb->sk);
1888*4882a593Smuzhiyun 	struct ndmsg *ndm;
1889*4882a593Smuzhiyun 	struct nlattr *tb[NDA_MAX+1];
1890*4882a593Smuzhiyun 	struct neigh_table *tbl;
1891*4882a593Smuzhiyun 	struct net_device *dev = NULL;
1892*4882a593Smuzhiyun 	struct neighbour *neigh;
1893*4882a593Smuzhiyun 	void *dst, *lladdr;
1894*4882a593Smuzhiyun 	u8 protocol = 0;
1895*4882a593Smuzhiyun 	int err;
1896*4882a593Smuzhiyun 
1897*4882a593Smuzhiyun 	ASSERT_RTNL();
1898*4882a593Smuzhiyun 	err = nlmsg_parse_deprecated(nlh, sizeof(*ndm), tb, NDA_MAX,
1899*4882a593Smuzhiyun 				     nda_policy, extack);
1900*4882a593Smuzhiyun 	if (err < 0)
1901*4882a593Smuzhiyun 		goto out;
1902*4882a593Smuzhiyun 
1903*4882a593Smuzhiyun 	err = -EINVAL;
1904*4882a593Smuzhiyun 	if (!tb[NDA_DST]) {
1905*4882a593Smuzhiyun 		NL_SET_ERR_MSG(extack, "Network address not specified");
1906*4882a593Smuzhiyun 		goto out;
1907*4882a593Smuzhiyun 	}
1908*4882a593Smuzhiyun 
1909*4882a593Smuzhiyun 	ndm = nlmsg_data(nlh);
1910*4882a593Smuzhiyun 	if (ndm->ndm_ifindex) {
1911*4882a593Smuzhiyun 		dev = __dev_get_by_index(net, ndm->ndm_ifindex);
1912*4882a593Smuzhiyun 		if (dev == NULL) {
1913*4882a593Smuzhiyun 			err = -ENODEV;
1914*4882a593Smuzhiyun 			goto out;
1915*4882a593Smuzhiyun 		}
1916*4882a593Smuzhiyun 
1917*4882a593Smuzhiyun 		if (tb[NDA_LLADDR] && nla_len(tb[NDA_LLADDR]) < dev->addr_len) {
1918*4882a593Smuzhiyun 			NL_SET_ERR_MSG(extack, "Invalid link address");
1919*4882a593Smuzhiyun 			goto out;
1920*4882a593Smuzhiyun 		}
1921*4882a593Smuzhiyun 	}
1922*4882a593Smuzhiyun 
1923*4882a593Smuzhiyun 	tbl = neigh_find_table(ndm->ndm_family);
1924*4882a593Smuzhiyun 	if (tbl == NULL)
1925*4882a593Smuzhiyun 		return -EAFNOSUPPORT;
1926*4882a593Smuzhiyun 
1927*4882a593Smuzhiyun 	if (nla_len(tb[NDA_DST]) < (int)tbl->key_len) {
1928*4882a593Smuzhiyun 		NL_SET_ERR_MSG(extack, "Invalid network address");
1929*4882a593Smuzhiyun 		goto out;
1930*4882a593Smuzhiyun 	}
1931*4882a593Smuzhiyun 
1932*4882a593Smuzhiyun 	dst = nla_data(tb[NDA_DST]);
1933*4882a593Smuzhiyun 	lladdr = tb[NDA_LLADDR] ? nla_data(tb[NDA_LLADDR]) : NULL;
1934*4882a593Smuzhiyun 
1935*4882a593Smuzhiyun 	if (tb[NDA_PROTOCOL])
1936*4882a593Smuzhiyun 		protocol = nla_get_u8(tb[NDA_PROTOCOL]);
1937*4882a593Smuzhiyun 
1938*4882a593Smuzhiyun 	if (ndm->ndm_flags & NTF_PROXY) {
1939*4882a593Smuzhiyun 		struct pneigh_entry *pn;
1940*4882a593Smuzhiyun 
1941*4882a593Smuzhiyun 		err = -ENOBUFS;
1942*4882a593Smuzhiyun 		pn = pneigh_lookup(tbl, net, dst, dev, 1);
1943*4882a593Smuzhiyun 		if (pn) {
1944*4882a593Smuzhiyun 			pn->flags = ndm->ndm_flags;
1945*4882a593Smuzhiyun 			if (protocol)
1946*4882a593Smuzhiyun 				pn->protocol = protocol;
1947*4882a593Smuzhiyun 			err = 0;
1948*4882a593Smuzhiyun 		}
1949*4882a593Smuzhiyun 		goto out;
1950*4882a593Smuzhiyun 	}
1951*4882a593Smuzhiyun 
1952*4882a593Smuzhiyun 	if (!dev) {
1953*4882a593Smuzhiyun 		NL_SET_ERR_MSG(extack, "Device not specified");
1954*4882a593Smuzhiyun 		goto out;
1955*4882a593Smuzhiyun 	}
1956*4882a593Smuzhiyun 
1957*4882a593Smuzhiyun 	if (tbl->allow_add && !tbl->allow_add(dev, extack)) {
1958*4882a593Smuzhiyun 		err = -EINVAL;
1959*4882a593Smuzhiyun 		goto out;
1960*4882a593Smuzhiyun 	}
1961*4882a593Smuzhiyun 
1962*4882a593Smuzhiyun 	neigh = neigh_lookup(tbl, dst, dev);
1963*4882a593Smuzhiyun 	if (neigh == NULL) {
1964*4882a593Smuzhiyun 		bool exempt_from_gc;
1965*4882a593Smuzhiyun 
1966*4882a593Smuzhiyun 		if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
1967*4882a593Smuzhiyun 			err = -ENOENT;
1968*4882a593Smuzhiyun 			goto out;
1969*4882a593Smuzhiyun 		}
1970*4882a593Smuzhiyun 
1971*4882a593Smuzhiyun 		exempt_from_gc = ndm->ndm_state & NUD_PERMANENT ||
1972*4882a593Smuzhiyun 				 ndm->ndm_flags & NTF_EXT_LEARNED;
1973*4882a593Smuzhiyun 		neigh = ___neigh_create(tbl, dst, dev,
1974*4882a593Smuzhiyun 					ndm->ndm_flags & NTF_EXT_LEARNED,
1975*4882a593Smuzhiyun 					exempt_from_gc, true);
1976*4882a593Smuzhiyun 		if (IS_ERR(neigh)) {
1977*4882a593Smuzhiyun 			err = PTR_ERR(neigh);
1978*4882a593Smuzhiyun 			goto out;
1979*4882a593Smuzhiyun 		}
1980*4882a593Smuzhiyun 	} else {
1981*4882a593Smuzhiyun 		if (nlh->nlmsg_flags & NLM_F_EXCL) {
1982*4882a593Smuzhiyun 			err = -EEXIST;
1983*4882a593Smuzhiyun 			neigh_release(neigh);
1984*4882a593Smuzhiyun 			goto out;
1985*4882a593Smuzhiyun 		}
1986*4882a593Smuzhiyun 
1987*4882a593Smuzhiyun 		if (!(nlh->nlmsg_flags & NLM_F_REPLACE))
1988*4882a593Smuzhiyun 			flags &= ~(NEIGH_UPDATE_F_OVERRIDE |
1989*4882a593Smuzhiyun 				   NEIGH_UPDATE_F_OVERRIDE_ISROUTER);
1990*4882a593Smuzhiyun 	}
1991*4882a593Smuzhiyun 
1992*4882a593Smuzhiyun 	if (protocol)
1993*4882a593Smuzhiyun 		neigh->protocol = protocol;
1994*4882a593Smuzhiyun 	if (ndm->ndm_flags & NTF_EXT_LEARNED)
1995*4882a593Smuzhiyun 		flags |= NEIGH_UPDATE_F_EXT_LEARNED;
1996*4882a593Smuzhiyun 	if (ndm->ndm_flags & NTF_ROUTER)
1997*4882a593Smuzhiyun 		flags |= NEIGH_UPDATE_F_ISROUTER;
1998*4882a593Smuzhiyun 	if (ndm->ndm_flags & NTF_USE)
1999*4882a593Smuzhiyun 		flags |= NEIGH_UPDATE_F_USE;
2000*4882a593Smuzhiyun 
2001*4882a593Smuzhiyun 	err = __neigh_update(neigh, lladdr, ndm->ndm_state, flags,
2002*4882a593Smuzhiyun 			     NETLINK_CB(skb).portid, extack);
2003*4882a593Smuzhiyun 	if (!err && ndm->ndm_flags & NTF_USE) {
2004*4882a593Smuzhiyun 		neigh_event_send(neigh, NULL);
2005*4882a593Smuzhiyun 		err = 0;
2006*4882a593Smuzhiyun 	}
2007*4882a593Smuzhiyun 	neigh_release(neigh);
2008*4882a593Smuzhiyun out:
2009*4882a593Smuzhiyun 	return err;
2010*4882a593Smuzhiyun }
2011*4882a593Smuzhiyun 
neightbl_fill_parms(struct sk_buff * skb,struct neigh_parms * parms)2012*4882a593Smuzhiyun static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms)
2013*4882a593Smuzhiyun {
2014*4882a593Smuzhiyun 	struct nlattr *nest;
2015*4882a593Smuzhiyun 
2016*4882a593Smuzhiyun 	nest = nla_nest_start_noflag(skb, NDTA_PARMS);
2017*4882a593Smuzhiyun 	if (nest == NULL)
2018*4882a593Smuzhiyun 		return -ENOBUFS;
2019*4882a593Smuzhiyun 
2020*4882a593Smuzhiyun 	if ((parms->dev &&
2021*4882a593Smuzhiyun 	     nla_put_u32(skb, NDTPA_IFINDEX, parms->dev->ifindex)) ||
2022*4882a593Smuzhiyun 	    nla_put_u32(skb, NDTPA_REFCNT, refcount_read(&parms->refcnt)) ||
2023*4882a593Smuzhiyun 	    nla_put_u32(skb, NDTPA_QUEUE_LENBYTES,
2024*4882a593Smuzhiyun 			NEIGH_VAR(parms, QUEUE_LEN_BYTES)) ||
2025*4882a593Smuzhiyun 	    /* approximative value for deprecated QUEUE_LEN (in packets) */
2026*4882a593Smuzhiyun 	    nla_put_u32(skb, NDTPA_QUEUE_LEN,
2027*4882a593Smuzhiyun 			NEIGH_VAR(parms, QUEUE_LEN_BYTES) / SKB_TRUESIZE(ETH_FRAME_LEN)) ||
2028*4882a593Smuzhiyun 	    nla_put_u32(skb, NDTPA_PROXY_QLEN, NEIGH_VAR(parms, PROXY_QLEN)) ||
2029*4882a593Smuzhiyun 	    nla_put_u32(skb, NDTPA_APP_PROBES, NEIGH_VAR(parms, APP_PROBES)) ||
2030*4882a593Smuzhiyun 	    nla_put_u32(skb, NDTPA_UCAST_PROBES,
2031*4882a593Smuzhiyun 			NEIGH_VAR(parms, UCAST_PROBES)) ||
2032*4882a593Smuzhiyun 	    nla_put_u32(skb, NDTPA_MCAST_PROBES,
2033*4882a593Smuzhiyun 			NEIGH_VAR(parms, MCAST_PROBES)) ||
2034*4882a593Smuzhiyun 	    nla_put_u32(skb, NDTPA_MCAST_REPROBES,
2035*4882a593Smuzhiyun 			NEIGH_VAR(parms, MCAST_REPROBES)) ||
2036*4882a593Smuzhiyun 	    nla_put_msecs(skb, NDTPA_REACHABLE_TIME, parms->reachable_time,
2037*4882a593Smuzhiyun 			  NDTPA_PAD) ||
2038*4882a593Smuzhiyun 	    nla_put_msecs(skb, NDTPA_BASE_REACHABLE_TIME,
2039*4882a593Smuzhiyun 			  NEIGH_VAR(parms, BASE_REACHABLE_TIME), NDTPA_PAD) ||
2040*4882a593Smuzhiyun 	    nla_put_msecs(skb, NDTPA_GC_STALETIME,
2041*4882a593Smuzhiyun 			  NEIGH_VAR(parms, GC_STALETIME), NDTPA_PAD) ||
2042*4882a593Smuzhiyun 	    nla_put_msecs(skb, NDTPA_DELAY_PROBE_TIME,
2043*4882a593Smuzhiyun 			  NEIGH_VAR(parms, DELAY_PROBE_TIME), NDTPA_PAD) ||
2044*4882a593Smuzhiyun 	    nla_put_msecs(skb, NDTPA_RETRANS_TIME,
2045*4882a593Smuzhiyun 			  NEIGH_VAR(parms, RETRANS_TIME), NDTPA_PAD) ||
2046*4882a593Smuzhiyun 	    nla_put_msecs(skb, NDTPA_ANYCAST_DELAY,
2047*4882a593Smuzhiyun 			  NEIGH_VAR(parms, ANYCAST_DELAY), NDTPA_PAD) ||
2048*4882a593Smuzhiyun 	    nla_put_msecs(skb, NDTPA_PROXY_DELAY,
2049*4882a593Smuzhiyun 			  NEIGH_VAR(parms, PROXY_DELAY), NDTPA_PAD) ||
2050*4882a593Smuzhiyun 	    nla_put_msecs(skb, NDTPA_LOCKTIME,
2051*4882a593Smuzhiyun 			  NEIGH_VAR(parms, LOCKTIME), NDTPA_PAD))
2052*4882a593Smuzhiyun 		goto nla_put_failure;
2053*4882a593Smuzhiyun 	return nla_nest_end(skb, nest);
2054*4882a593Smuzhiyun 
2055*4882a593Smuzhiyun nla_put_failure:
2056*4882a593Smuzhiyun 	nla_nest_cancel(skb, nest);
2057*4882a593Smuzhiyun 	return -EMSGSIZE;
2058*4882a593Smuzhiyun }
2059*4882a593Smuzhiyun 
neightbl_fill_info(struct sk_buff * skb,struct neigh_table * tbl,u32 pid,u32 seq,int type,int flags)2060*4882a593Smuzhiyun static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
2061*4882a593Smuzhiyun 			      u32 pid, u32 seq, int type, int flags)
2062*4882a593Smuzhiyun {
2063*4882a593Smuzhiyun 	struct nlmsghdr *nlh;
2064*4882a593Smuzhiyun 	struct ndtmsg *ndtmsg;
2065*4882a593Smuzhiyun 
2066*4882a593Smuzhiyun 	nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags);
2067*4882a593Smuzhiyun 	if (nlh == NULL)
2068*4882a593Smuzhiyun 		return -EMSGSIZE;
2069*4882a593Smuzhiyun 
2070*4882a593Smuzhiyun 	ndtmsg = nlmsg_data(nlh);
2071*4882a593Smuzhiyun 
2072*4882a593Smuzhiyun 	read_lock_bh(&tbl->lock);
2073*4882a593Smuzhiyun 	ndtmsg->ndtm_family = tbl->family;
2074*4882a593Smuzhiyun 	ndtmsg->ndtm_pad1   = 0;
2075*4882a593Smuzhiyun 	ndtmsg->ndtm_pad2   = 0;
2076*4882a593Smuzhiyun 
2077*4882a593Smuzhiyun 	if (nla_put_string(skb, NDTA_NAME, tbl->id) ||
2078*4882a593Smuzhiyun 	    nla_put_msecs(skb, NDTA_GC_INTERVAL, tbl->gc_interval, NDTA_PAD) ||
2079*4882a593Smuzhiyun 	    nla_put_u32(skb, NDTA_THRESH1, tbl->gc_thresh1) ||
2080*4882a593Smuzhiyun 	    nla_put_u32(skb, NDTA_THRESH2, tbl->gc_thresh2) ||
2081*4882a593Smuzhiyun 	    nla_put_u32(skb, NDTA_THRESH3, tbl->gc_thresh3))
2082*4882a593Smuzhiyun 		goto nla_put_failure;
2083*4882a593Smuzhiyun 	{
2084*4882a593Smuzhiyun 		unsigned long now = jiffies;
2085*4882a593Smuzhiyun 		long flush_delta = now - tbl->last_flush;
2086*4882a593Smuzhiyun 		long rand_delta = now - tbl->last_rand;
2087*4882a593Smuzhiyun 		struct neigh_hash_table *nht;
2088*4882a593Smuzhiyun 		struct ndt_config ndc = {
2089*4882a593Smuzhiyun 			.ndtc_key_len		= tbl->key_len,
2090*4882a593Smuzhiyun 			.ndtc_entry_size	= tbl->entry_size,
2091*4882a593Smuzhiyun 			.ndtc_entries		= atomic_read(&tbl->entries),
2092*4882a593Smuzhiyun 			.ndtc_last_flush	= jiffies_to_msecs(flush_delta),
2093*4882a593Smuzhiyun 			.ndtc_last_rand		= jiffies_to_msecs(rand_delta),
2094*4882a593Smuzhiyun 			.ndtc_proxy_qlen	= tbl->proxy_queue.qlen,
2095*4882a593Smuzhiyun 		};
2096*4882a593Smuzhiyun 
2097*4882a593Smuzhiyun 		rcu_read_lock_bh();
2098*4882a593Smuzhiyun 		nht = rcu_dereference_bh(tbl->nht);
2099*4882a593Smuzhiyun 		ndc.ndtc_hash_rnd = nht->hash_rnd[0];
2100*4882a593Smuzhiyun 		ndc.ndtc_hash_mask = ((1 << nht->hash_shift) - 1);
2101*4882a593Smuzhiyun 		rcu_read_unlock_bh();
2102*4882a593Smuzhiyun 
2103*4882a593Smuzhiyun 		if (nla_put(skb, NDTA_CONFIG, sizeof(ndc), &ndc))
2104*4882a593Smuzhiyun 			goto nla_put_failure;
2105*4882a593Smuzhiyun 	}
2106*4882a593Smuzhiyun 
2107*4882a593Smuzhiyun 	{
2108*4882a593Smuzhiyun 		int cpu;
2109*4882a593Smuzhiyun 		struct ndt_stats ndst;
2110*4882a593Smuzhiyun 
2111*4882a593Smuzhiyun 		memset(&ndst, 0, sizeof(ndst));
2112*4882a593Smuzhiyun 
2113*4882a593Smuzhiyun 		for_each_possible_cpu(cpu) {
2114*4882a593Smuzhiyun 			struct neigh_statistics	*st;
2115*4882a593Smuzhiyun 
2116*4882a593Smuzhiyun 			st = per_cpu_ptr(tbl->stats, cpu);
2117*4882a593Smuzhiyun 			ndst.ndts_allocs		+= st->allocs;
2118*4882a593Smuzhiyun 			ndst.ndts_destroys		+= st->destroys;
2119*4882a593Smuzhiyun 			ndst.ndts_hash_grows		+= st->hash_grows;
2120*4882a593Smuzhiyun 			ndst.ndts_res_failed		+= st->res_failed;
2121*4882a593Smuzhiyun 			ndst.ndts_lookups		+= st->lookups;
2122*4882a593Smuzhiyun 			ndst.ndts_hits			+= st->hits;
2123*4882a593Smuzhiyun 			ndst.ndts_rcv_probes_mcast	+= st->rcv_probes_mcast;
2124*4882a593Smuzhiyun 			ndst.ndts_rcv_probes_ucast	+= st->rcv_probes_ucast;
2125*4882a593Smuzhiyun 			ndst.ndts_periodic_gc_runs	+= st->periodic_gc_runs;
2126*4882a593Smuzhiyun 			ndst.ndts_forced_gc_runs	+= st->forced_gc_runs;
2127*4882a593Smuzhiyun 			ndst.ndts_table_fulls		+= st->table_fulls;
2128*4882a593Smuzhiyun 		}
2129*4882a593Smuzhiyun 
2130*4882a593Smuzhiyun 		if (nla_put_64bit(skb, NDTA_STATS, sizeof(ndst), &ndst,
2131*4882a593Smuzhiyun 				  NDTA_PAD))
2132*4882a593Smuzhiyun 			goto nla_put_failure;
2133*4882a593Smuzhiyun 	}
2134*4882a593Smuzhiyun 
2135*4882a593Smuzhiyun 	BUG_ON(tbl->parms.dev);
2136*4882a593Smuzhiyun 	if (neightbl_fill_parms(skb, &tbl->parms) < 0)
2137*4882a593Smuzhiyun 		goto nla_put_failure;
2138*4882a593Smuzhiyun 
2139*4882a593Smuzhiyun 	read_unlock_bh(&tbl->lock);
2140*4882a593Smuzhiyun 	nlmsg_end(skb, nlh);
2141*4882a593Smuzhiyun 	return 0;
2142*4882a593Smuzhiyun 
2143*4882a593Smuzhiyun nla_put_failure:
2144*4882a593Smuzhiyun 	read_unlock_bh(&tbl->lock);
2145*4882a593Smuzhiyun 	nlmsg_cancel(skb, nlh);
2146*4882a593Smuzhiyun 	return -EMSGSIZE;
2147*4882a593Smuzhiyun }
2148*4882a593Smuzhiyun 
neightbl_fill_param_info(struct sk_buff * skb,struct neigh_table * tbl,struct neigh_parms * parms,u32 pid,u32 seq,int type,unsigned int flags)2149*4882a593Smuzhiyun static int neightbl_fill_param_info(struct sk_buff *skb,
2150*4882a593Smuzhiyun 				    struct neigh_table *tbl,
2151*4882a593Smuzhiyun 				    struct neigh_parms *parms,
2152*4882a593Smuzhiyun 				    u32 pid, u32 seq, int type,
2153*4882a593Smuzhiyun 				    unsigned int flags)
2154*4882a593Smuzhiyun {
2155*4882a593Smuzhiyun 	struct ndtmsg *ndtmsg;
2156*4882a593Smuzhiyun 	struct nlmsghdr *nlh;
2157*4882a593Smuzhiyun 
2158*4882a593Smuzhiyun 	nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags);
2159*4882a593Smuzhiyun 	if (nlh == NULL)
2160*4882a593Smuzhiyun 		return -EMSGSIZE;
2161*4882a593Smuzhiyun 
2162*4882a593Smuzhiyun 	ndtmsg = nlmsg_data(nlh);
2163*4882a593Smuzhiyun 
2164*4882a593Smuzhiyun 	read_lock_bh(&tbl->lock);
2165*4882a593Smuzhiyun 	ndtmsg->ndtm_family = tbl->family;
2166*4882a593Smuzhiyun 	ndtmsg->ndtm_pad1   = 0;
2167*4882a593Smuzhiyun 	ndtmsg->ndtm_pad2   = 0;
2168*4882a593Smuzhiyun 
2169*4882a593Smuzhiyun 	if (nla_put_string(skb, NDTA_NAME, tbl->id) < 0 ||
2170*4882a593Smuzhiyun 	    neightbl_fill_parms(skb, parms) < 0)
2171*4882a593Smuzhiyun 		goto errout;
2172*4882a593Smuzhiyun 
2173*4882a593Smuzhiyun 	read_unlock_bh(&tbl->lock);
2174*4882a593Smuzhiyun 	nlmsg_end(skb, nlh);
2175*4882a593Smuzhiyun 	return 0;
2176*4882a593Smuzhiyun errout:
2177*4882a593Smuzhiyun 	read_unlock_bh(&tbl->lock);
2178*4882a593Smuzhiyun 	nlmsg_cancel(skb, nlh);
2179*4882a593Smuzhiyun 	return -EMSGSIZE;
2180*4882a593Smuzhiyun }
2181*4882a593Smuzhiyun 
2182*4882a593Smuzhiyun static const struct nla_policy nl_neightbl_policy[NDTA_MAX+1] = {
2183*4882a593Smuzhiyun 	[NDTA_NAME]		= { .type = NLA_STRING },
2184*4882a593Smuzhiyun 	[NDTA_THRESH1]		= { .type = NLA_U32 },
2185*4882a593Smuzhiyun 	[NDTA_THRESH2]		= { .type = NLA_U32 },
2186*4882a593Smuzhiyun 	[NDTA_THRESH3]		= { .type = NLA_U32 },
2187*4882a593Smuzhiyun 	[NDTA_GC_INTERVAL]	= { .type = NLA_U64 },
2188*4882a593Smuzhiyun 	[NDTA_PARMS]		= { .type = NLA_NESTED },
2189*4882a593Smuzhiyun };
2190*4882a593Smuzhiyun 
2191*4882a593Smuzhiyun static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = {
2192*4882a593Smuzhiyun 	[NDTPA_IFINDEX]			= { .type = NLA_U32 },
2193*4882a593Smuzhiyun 	[NDTPA_QUEUE_LEN]		= { .type = NLA_U32 },
2194*4882a593Smuzhiyun 	[NDTPA_PROXY_QLEN]		= { .type = NLA_U32 },
2195*4882a593Smuzhiyun 	[NDTPA_APP_PROBES]		= { .type = NLA_U32 },
2196*4882a593Smuzhiyun 	[NDTPA_UCAST_PROBES]		= { .type = NLA_U32 },
2197*4882a593Smuzhiyun 	[NDTPA_MCAST_PROBES]		= { .type = NLA_U32 },
2198*4882a593Smuzhiyun 	[NDTPA_MCAST_REPROBES]		= { .type = NLA_U32 },
2199*4882a593Smuzhiyun 	[NDTPA_BASE_REACHABLE_TIME]	= { .type = NLA_U64 },
2200*4882a593Smuzhiyun 	[NDTPA_GC_STALETIME]		= { .type = NLA_U64 },
2201*4882a593Smuzhiyun 	[NDTPA_DELAY_PROBE_TIME]	= { .type = NLA_U64 },
2202*4882a593Smuzhiyun 	[NDTPA_RETRANS_TIME]		= { .type = NLA_U64 },
2203*4882a593Smuzhiyun 	[NDTPA_ANYCAST_DELAY]		= { .type = NLA_U64 },
2204*4882a593Smuzhiyun 	[NDTPA_PROXY_DELAY]		= { .type = NLA_U64 },
2205*4882a593Smuzhiyun 	[NDTPA_LOCKTIME]		= { .type = NLA_U64 },
2206*4882a593Smuzhiyun };
2207*4882a593Smuzhiyun 
neightbl_set(struct sk_buff * skb,struct nlmsghdr * nlh,struct netlink_ext_ack * extack)2208*4882a593Smuzhiyun static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh,
2209*4882a593Smuzhiyun 			struct netlink_ext_ack *extack)
2210*4882a593Smuzhiyun {
2211*4882a593Smuzhiyun 	struct net *net = sock_net(skb->sk);
2212*4882a593Smuzhiyun 	struct neigh_table *tbl;
2213*4882a593Smuzhiyun 	struct ndtmsg *ndtmsg;
2214*4882a593Smuzhiyun 	struct nlattr *tb[NDTA_MAX+1];
2215*4882a593Smuzhiyun 	bool found = false;
2216*4882a593Smuzhiyun 	int err, tidx;
2217*4882a593Smuzhiyun 
2218*4882a593Smuzhiyun 	err = nlmsg_parse_deprecated(nlh, sizeof(*ndtmsg), tb, NDTA_MAX,
2219*4882a593Smuzhiyun 				     nl_neightbl_policy, extack);
2220*4882a593Smuzhiyun 	if (err < 0)
2221*4882a593Smuzhiyun 		goto errout;
2222*4882a593Smuzhiyun 
2223*4882a593Smuzhiyun 	if (tb[NDTA_NAME] == NULL) {
2224*4882a593Smuzhiyun 		err = -EINVAL;
2225*4882a593Smuzhiyun 		goto errout;
2226*4882a593Smuzhiyun 	}
2227*4882a593Smuzhiyun 
2228*4882a593Smuzhiyun 	ndtmsg = nlmsg_data(nlh);
2229*4882a593Smuzhiyun 
2230*4882a593Smuzhiyun 	for (tidx = 0; tidx < NEIGH_NR_TABLES; tidx++) {
2231*4882a593Smuzhiyun 		tbl = neigh_tables[tidx];
2232*4882a593Smuzhiyun 		if (!tbl)
2233*4882a593Smuzhiyun 			continue;
2234*4882a593Smuzhiyun 		if (ndtmsg->ndtm_family && tbl->family != ndtmsg->ndtm_family)
2235*4882a593Smuzhiyun 			continue;
2236*4882a593Smuzhiyun 		if (nla_strcmp(tb[NDTA_NAME], tbl->id) == 0) {
2237*4882a593Smuzhiyun 			found = true;
2238*4882a593Smuzhiyun 			break;
2239*4882a593Smuzhiyun 		}
2240*4882a593Smuzhiyun 	}
2241*4882a593Smuzhiyun 
2242*4882a593Smuzhiyun 	if (!found)
2243*4882a593Smuzhiyun 		return -ENOENT;
2244*4882a593Smuzhiyun 
2245*4882a593Smuzhiyun 	/*
2246*4882a593Smuzhiyun 	 * We acquire tbl->lock to be nice to the periodic timers and
2247*4882a593Smuzhiyun 	 * make sure they always see a consistent set of values.
2248*4882a593Smuzhiyun 	 */
2249*4882a593Smuzhiyun 	write_lock_bh(&tbl->lock);
2250*4882a593Smuzhiyun 
2251*4882a593Smuzhiyun 	if (tb[NDTA_PARMS]) {
2252*4882a593Smuzhiyun 		struct nlattr *tbp[NDTPA_MAX+1];
2253*4882a593Smuzhiyun 		struct neigh_parms *p;
2254*4882a593Smuzhiyun 		int i, ifindex = 0;
2255*4882a593Smuzhiyun 
2256*4882a593Smuzhiyun 		err = nla_parse_nested_deprecated(tbp, NDTPA_MAX,
2257*4882a593Smuzhiyun 						  tb[NDTA_PARMS],
2258*4882a593Smuzhiyun 						  nl_ntbl_parm_policy, extack);
2259*4882a593Smuzhiyun 		if (err < 0)
2260*4882a593Smuzhiyun 			goto errout_tbl_lock;
2261*4882a593Smuzhiyun 
2262*4882a593Smuzhiyun 		if (tbp[NDTPA_IFINDEX])
2263*4882a593Smuzhiyun 			ifindex = nla_get_u32(tbp[NDTPA_IFINDEX]);
2264*4882a593Smuzhiyun 
2265*4882a593Smuzhiyun 		p = lookup_neigh_parms(tbl, net, ifindex);
2266*4882a593Smuzhiyun 		if (p == NULL) {
2267*4882a593Smuzhiyun 			err = -ENOENT;
2268*4882a593Smuzhiyun 			goto errout_tbl_lock;
2269*4882a593Smuzhiyun 		}
2270*4882a593Smuzhiyun 
2271*4882a593Smuzhiyun 		for (i = 1; i <= NDTPA_MAX; i++) {
2272*4882a593Smuzhiyun 			if (tbp[i] == NULL)
2273*4882a593Smuzhiyun 				continue;
2274*4882a593Smuzhiyun 
2275*4882a593Smuzhiyun 			switch (i) {
2276*4882a593Smuzhiyun 			case NDTPA_QUEUE_LEN:
2277*4882a593Smuzhiyun 				NEIGH_VAR_SET(p, QUEUE_LEN_BYTES,
2278*4882a593Smuzhiyun 					      nla_get_u32(tbp[i]) *
2279*4882a593Smuzhiyun 					      SKB_TRUESIZE(ETH_FRAME_LEN));
2280*4882a593Smuzhiyun 				break;
2281*4882a593Smuzhiyun 			case NDTPA_QUEUE_LENBYTES:
2282*4882a593Smuzhiyun 				NEIGH_VAR_SET(p, QUEUE_LEN_BYTES,
2283*4882a593Smuzhiyun 					      nla_get_u32(tbp[i]));
2284*4882a593Smuzhiyun 				break;
2285*4882a593Smuzhiyun 			case NDTPA_PROXY_QLEN:
2286*4882a593Smuzhiyun 				NEIGH_VAR_SET(p, PROXY_QLEN,
2287*4882a593Smuzhiyun 					      nla_get_u32(tbp[i]));
2288*4882a593Smuzhiyun 				break;
2289*4882a593Smuzhiyun 			case NDTPA_APP_PROBES:
2290*4882a593Smuzhiyun 				NEIGH_VAR_SET(p, APP_PROBES,
2291*4882a593Smuzhiyun 					      nla_get_u32(tbp[i]));
2292*4882a593Smuzhiyun 				break;
2293*4882a593Smuzhiyun 			case NDTPA_UCAST_PROBES:
2294*4882a593Smuzhiyun 				NEIGH_VAR_SET(p, UCAST_PROBES,
2295*4882a593Smuzhiyun 					      nla_get_u32(tbp[i]));
2296*4882a593Smuzhiyun 				break;
2297*4882a593Smuzhiyun 			case NDTPA_MCAST_PROBES:
2298*4882a593Smuzhiyun 				NEIGH_VAR_SET(p, MCAST_PROBES,
2299*4882a593Smuzhiyun 					      nla_get_u32(tbp[i]));
2300*4882a593Smuzhiyun 				break;
2301*4882a593Smuzhiyun 			case NDTPA_MCAST_REPROBES:
2302*4882a593Smuzhiyun 				NEIGH_VAR_SET(p, MCAST_REPROBES,
2303*4882a593Smuzhiyun 					      nla_get_u32(tbp[i]));
2304*4882a593Smuzhiyun 				break;
2305*4882a593Smuzhiyun 			case NDTPA_BASE_REACHABLE_TIME:
2306*4882a593Smuzhiyun 				NEIGH_VAR_SET(p, BASE_REACHABLE_TIME,
2307*4882a593Smuzhiyun 					      nla_get_msecs(tbp[i]));
2308*4882a593Smuzhiyun 				/* update reachable_time as well, otherwise, the change will
2309*4882a593Smuzhiyun 				 * only be effective after the next time neigh_periodic_work
2310*4882a593Smuzhiyun 				 * decides to recompute it (can be multiple minutes)
2311*4882a593Smuzhiyun 				 */
2312*4882a593Smuzhiyun 				p->reachable_time =
2313*4882a593Smuzhiyun 					neigh_rand_reach_time(NEIGH_VAR(p, BASE_REACHABLE_TIME));
2314*4882a593Smuzhiyun 				break;
2315*4882a593Smuzhiyun 			case NDTPA_GC_STALETIME:
2316*4882a593Smuzhiyun 				NEIGH_VAR_SET(p, GC_STALETIME,
2317*4882a593Smuzhiyun 					      nla_get_msecs(tbp[i]));
2318*4882a593Smuzhiyun 				break;
2319*4882a593Smuzhiyun 			case NDTPA_DELAY_PROBE_TIME:
2320*4882a593Smuzhiyun 				NEIGH_VAR_SET(p, DELAY_PROBE_TIME,
2321*4882a593Smuzhiyun 					      nla_get_msecs(tbp[i]));
2322*4882a593Smuzhiyun 				call_netevent_notifiers(NETEVENT_DELAY_PROBE_TIME_UPDATE, p);
2323*4882a593Smuzhiyun 				break;
2324*4882a593Smuzhiyun 			case NDTPA_RETRANS_TIME:
2325*4882a593Smuzhiyun 				NEIGH_VAR_SET(p, RETRANS_TIME,
2326*4882a593Smuzhiyun 					      nla_get_msecs(tbp[i]));
2327*4882a593Smuzhiyun 				break;
2328*4882a593Smuzhiyun 			case NDTPA_ANYCAST_DELAY:
2329*4882a593Smuzhiyun 				NEIGH_VAR_SET(p, ANYCAST_DELAY,
2330*4882a593Smuzhiyun 					      nla_get_msecs(tbp[i]));
2331*4882a593Smuzhiyun 				break;
2332*4882a593Smuzhiyun 			case NDTPA_PROXY_DELAY:
2333*4882a593Smuzhiyun 				NEIGH_VAR_SET(p, PROXY_DELAY,
2334*4882a593Smuzhiyun 					      nla_get_msecs(tbp[i]));
2335*4882a593Smuzhiyun 				break;
2336*4882a593Smuzhiyun 			case NDTPA_LOCKTIME:
2337*4882a593Smuzhiyun 				NEIGH_VAR_SET(p, LOCKTIME,
2338*4882a593Smuzhiyun 					      nla_get_msecs(tbp[i]));
2339*4882a593Smuzhiyun 				break;
2340*4882a593Smuzhiyun 			}
2341*4882a593Smuzhiyun 		}
2342*4882a593Smuzhiyun 	}
2343*4882a593Smuzhiyun 
2344*4882a593Smuzhiyun 	err = -ENOENT;
2345*4882a593Smuzhiyun 	if ((tb[NDTA_THRESH1] || tb[NDTA_THRESH2] ||
2346*4882a593Smuzhiyun 	     tb[NDTA_THRESH3] || tb[NDTA_GC_INTERVAL]) &&
2347*4882a593Smuzhiyun 	    !net_eq(net, &init_net))
2348*4882a593Smuzhiyun 		goto errout_tbl_lock;
2349*4882a593Smuzhiyun 
2350*4882a593Smuzhiyun 	if (tb[NDTA_THRESH1])
2351*4882a593Smuzhiyun 		tbl->gc_thresh1 = nla_get_u32(tb[NDTA_THRESH1]);
2352*4882a593Smuzhiyun 
2353*4882a593Smuzhiyun 	if (tb[NDTA_THRESH2])
2354*4882a593Smuzhiyun 		tbl->gc_thresh2 = nla_get_u32(tb[NDTA_THRESH2]);
2355*4882a593Smuzhiyun 
2356*4882a593Smuzhiyun 	if (tb[NDTA_THRESH3])
2357*4882a593Smuzhiyun 		tbl->gc_thresh3 = nla_get_u32(tb[NDTA_THRESH3]);
2358*4882a593Smuzhiyun 
2359*4882a593Smuzhiyun 	if (tb[NDTA_GC_INTERVAL])
2360*4882a593Smuzhiyun 		tbl->gc_interval = nla_get_msecs(tb[NDTA_GC_INTERVAL]);
2361*4882a593Smuzhiyun 
2362*4882a593Smuzhiyun 	err = 0;
2363*4882a593Smuzhiyun 
2364*4882a593Smuzhiyun errout_tbl_lock:
2365*4882a593Smuzhiyun 	write_unlock_bh(&tbl->lock);
2366*4882a593Smuzhiyun errout:
2367*4882a593Smuzhiyun 	return err;
2368*4882a593Smuzhiyun }
2369*4882a593Smuzhiyun 
neightbl_valid_dump_info(const struct nlmsghdr * nlh,struct netlink_ext_ack * extack)2370*4882a593Smuzhiyun static int neightbl_valid_dump_info(const struct nlmsghdr *nlh,
2371*4882a593Smuzhiyun 				    struct netlink_ext_ack *extack)
2372*4882a593Smuzhiyun {
2373*4882a593Smuzhiyun 	struct ndtmsg *ndtm;
2374*4882a593Smuzhiyun 
2375*4882a593Smuzhiyun 	if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ndtm))) {
2376*4882a593Smuzhiyun 		NL_SET_ERR_MSG(extack, "Invalid header for neighbor table dump request");
2377*4882a593Smuzhiyun 		return -EINVAL;
2378*4882a593Smuzhiyun 	}
2379*4882a593Smuzhiyun 
2380*4882a593Smuzhiyun 	ndtm = nlmsg_data(nlh);
2381*4882a593Smuzhiyun 	if (ndtm->ndtm_pad1  || ndtm->ndtm_pad2) {
2382*4882a593Smuzhiyun 		NL_SET_ERR_MSG(extack, "Invalid values in header for neighbor table dump request");
2383*4882a593Smuzhiyun 		return -EINVAL;
2384*4882a593Smuzhiyun 	}
2385*4882a593Smuzhiyun 
2386*4882a593Smuzhiyun 	if (nlmsg_attrlen(nlh, sizeof(*ndtm))) {
2387*4882a593Smuzhiyun 		NL_SET_ERR_MSG(extack, "Invalid data after header in neighbor table dump request");
2388*4882a593Smuzhiyun 		return -EINVAL;
2389*4882a593Smuzhiyun 	}
2390*4882a593Smuzhiyun 
2391*4882a593Smuzhiyun 	return 0;
2392*4882a593Smuzhiyun }
2393*4882a593Smuzhiyun 
neightbl_dump_info(struct sk_buff * skb,struct netlink_callback * cb)2394*4882a593Smuzhiyun static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
2395*4882a593Smuzhiyun {
2396*4882a593Smuzhiyun 	const struct nlmsghdr *nlh = cb->nlh;
2397*4882a593Smuzhiyun 	struct net *net = sock_net(skb->sk);
2398*4882a593Smuzhiyun 	int family, tidx, nidx = 0;
2399*4882a593Smuzhiyun 	int tbl_skip = cb->args[0];
2400*4882a593Smuzhiyun 	int neigh_skip = cb->args[1];
2401*4882a593Smuzhiyun 	struct neigh_table *tbl;
2402*4882a593Smuzhiyun 
2403*4882a593Smuzhiyun 	if (cb->strict_check) {
2404*4882a593Smuzhiyun 		int err = neightbl_valid_dump_info(nlh, cb->extack);
2405*4882a593Smuzhiyun 
2406*4882a593Smuzhiyun 		if (err < 0)
2407*4882a593Smuzhiyun 			return err;
2408*4882a593Smuzhiyun 	}
2409*4882a593Smuzhiyun 
2410*4882a593Smuzhiyun 	family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family;
2411*4882a593Smuzhiyun 
2412*4882a593Smuzhiyun 	for (tidx = 0; tidx < NEIGH_NR_TABLES; tidx++) {
2413*4882a593Smuzhiyun 		struct neigh_parms *p;
2414*4882a593Smuzhiyun 
2415*4882a593Smuzhiyun 		tbl = neigh_tables[tidx];
2416*4882a593Smuzhiyun 		if (!tbl)
2417*4882a593Smuzhiyun 			continue;
2418*4882a593Smuzhiyun 
2419*4882a593Smuzhiyun 		if (tidx < tbl_skip || (family && tbl->family != family))
2420*4882a593Smuzhiyun 			continue;
2421*4882a593Smuzhiyun 
2422*4882a593Smuzhiyun 		if (neightbl_fill_info(skb, tbl, NETLINK_CB(cb->skb).portid,
2423*4882a593Smuzhiyun 				       nlh->nlmsg_seq, RTM_NEWNEIGHTBL,
2424*4882a593Smuzhiyun 				       NLM_F_MULTI) < 0)
2425*4882a593Smuzhiyun 			break;
2426*4882a593Smuzhiyun 
2427*4882a593Smuzhiyun 		nidx = 0;
2428*4882a593Smuzhiyun 		p = list_next_entry(&tbl->parms, list);
2429*4882a593Smuzhiyun 		list_for_each_entry_from(p, &tbl->parms_list, list) {
2430*4882a593Smuzhiyun 			if (!net_eq(neigh_parms_net(p), net))
2431*4882a593Smuzhiyun 				continue;
2432*4882a593Smuzhiyun 
2433*4882a593Smuzhiyun 			if (nidx < neigh_skip)
2434*4882a593Smuzhiyun 				goto next;
2435*4882a593Smuzhiyun 
2436*4882a593Smuzhiyun 			if (neightbl_fill_param_info(skb, tbl, p,
2437*4882a593Smuzhiyun 						     NETLINK_CB(cb->skb).portid,
2438*4882a593Smuzhiyun 						     nlh->nlmsg_seq,
2439*4882a593Smuzhiyun 						     RTM_NEWNEIGHTBL,
2440*4882a593Smuzhiyun 						     NLM_F_MULTI) < 0)
2441*4882a593Smuzhiyun 				goto out;
2442*4882a593Smuzhiyun 		next:
2443*4882a593Smuzhiyun 			nidx++;
2444*4882a593Smuzhiyun 		}
2445*4882a593Smuzhiyun 
2446*4882a593Smuzhiyun 		neigh_skip = 0;
2447*4882a593Smuzhiyun 	}
2448*4882a593Smuzhiyun out:
2449*4882a593Smuzhiyun 	cb->args[0] = tidx;
2450*4882a593Smuzhiyun 	cb->args[1] = nidx;
2451*4882a593Smuzhiyun 
2452*4882a593Smuzhiyun 	return skb->len;
2453*4882a593Smuzhiyun }
2454*4882a593Smuzhiyun 
neigh_fill_info(struct sk_buff * skb,struct neighbour * neigh,u32 pid,u32 seq,int type,unsigned int flags)2455*4882a593Smuzhiyun static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh,
2456*4882a593Smuzhiyun 			   u32 pid, u32 seq, int type, unsigned int flags)
2457*4882a593Smuzhiyun {
2458*4882a593Smuzhiyun 	unsigned long now = jiffies;
2459*4882a593Smuzhiyun 	struct nda_cacheinfo ci;
2460*4882a593Smuzhiyun 	struct nlmsghdr *nlh;
2461*4882a593Smuzhiyun 	struct ndmsg *ndm;
2462*4882a593Smuzhiyun 
2463*4882a593Smuzhiyun 	nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), flags);
2464*4882a593Smuzhiyun 	if (nlh == NULL)
2465*4882a593Smuzhiyun 		return -EMSGSIZE;
2466*4882a593Smuzhiyun 
2467*4882a593Smuzhiyun 	ndm = nlmsg_data(nlh);
2468*4882a593Smuzhiyun 	ndm->ndm_family	 = neigh->ops->family;
2469*4882a593Smuzhiyun 	ndm->ndm_pad1    = 0;
2470*4882a593Smuzhiyun 	ndm->ndm_pad2    = 0;
2471*4882a593Smuzhiyun 	ndm->ndm_flags	 = neigh->flags;
2472*4882a593Smuzhiyun 	ndm->ndm_type	 = neigh->type;
2473*4882a593Smuzhiyun 	ndm->ndm_ifindex = neigh->dev->ifindex;
2474*4882a593Smuzhiyun 
2475*4882a593Smuzhiyun 	if (nla_put(skb, NDA_DST, neigh->tbl->key_len, neigh->primary_key))
2476*4882a593Smuzhiyun 		goto nla_put_failure;
2477*4882a593Smuzhiyun 
2478*4882a593Smuzhiyun 	read_lock_bh(&neigh->lock);
2479*4882a593Smuzhiyun 	ndm->ndm_state	 = neigh->nud_state;
2480*4882a593Smuzhiyun 	if (neigh->nud_state & NUD_VALID) {
2481*4882a593Smuzhiyun 		char haddr[MAX_ADDR_LEN];
2482*4882a593Smuzhiyun 
2483*4882a593Smuzhiyun 		neigh_ha_snapshot(haddr, neigh, neigh->dev);
2484*4882a593Smuzhiyun 		if (nla_put(skb, NDA_LLADDR, neigh->dev->addr_len, haddr) < 0) {
2485*4882a593Smuzhiyun 			read_unlock_bh(&neigh->lock);
2486*4882a593Smuzhiyun 			goto nla_put_failure;
2487*4882a593Smuzhiyun 		}
2488*4882a593Smuzhiyun 	}
2489*4882a593Smuzhiyun 
2490*4882a593Smuzhiyun 	ci.ndm_used	 = jiffies_to_clock_t(now - neigh->used);
2491*4882a593Smuzhiyun 	ci.ndm_confirmed = jiffies_to_clock_t(now - neigh->confirmed);
2492*4882a593Smuzhiyun 	ci.ndm_updated	 = jiffies_to_clock_t(now - neigh->updated);
2493*4882a593Smuzhiyun 	ci.ndm_refcnt	 = refcount_read(&neigh->refcnt) - 1;
2494*4882a593Smuzhiyun 	read_unlock_bh(&neigh->lock);
2495*4882a593Smuzhiyun 
2496*4882a593Smuzhiyun 	if (nla_put_u32(skb, NDA_PROBES, atomic_read(&neigh->probes)) ||
2497*4882a593Smuzhiyun 	    nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci))
2498*4882a593Smuzhiyun 		goto nla_put_failure;
2499*4882a593Smuzhiyun 
2500*4882a593Smuzhiyun 	if (neigh->protocol && nla_put_u8(skb, NDA_PROTOCOL, neigh->protocol))
2501*4882a593Smuzhiyun 		goto nla_put_failure;
2502*4882a593Smuzhiyun 
2503*4882a593Smuzhiyun 	nlmsg_end(skb, nlh);
2504*4882a593Smuzhiyun 	return 0;
2505*4882a593Smuzhiyun 
2506*4882a593Smuzhiyun nla_put_failure:
2507*4882a593Smuzhiyun 	nlmsg_cancel(skb, nlh);
2508*4882a593Smuzhiyun 	return -EMSGSIZE;
2509*4882a593Smuzhiyun }
2510*4882a593Smuzhiyun 
pneigh_fill_info(struct sk_buff * skb,struct pneigh_entry * pn,u32 pid,u32 seq,int type,unsigned int flags,struct neigh_table * tbl)2511*4882a593Smuzhiyun static int pneigh_fill_info(struct sk_buff *skb, struct pneigh_entry *pn,
2512*4882a593Smuzhiyun 			    u32 pid, u32 seq, int type, unsigned int flags,
2513*4882a593Smuzhiyun 			    struct neigh_table *tbl)
2514*4882a593Smuzhiyun {
2515*4882a593Smuzhiyun 	struct nlmsghdr *nlh;
2516*4882a593Smuzhiyun 	struct ndmsg *ndm;
2517*4882a593Smuzhiyun 
2518*4882a593Smuzhiyun 	nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), flags);
2519*4882a593Smuzhiyun 	if (nlh == NULL)
2520*4882a593Smuzhiyun 		return -EMSGSIZE;
2521*4882a593Smuzhiyun 
2522*4882a593Smuzhiyun 	ndm = nlmsg_data(nlh);
2523*4882a593Smuzhiyun 	ndm->ndm_family	 = tbl->family;
2524*4882a593Smuzhiyun 	ndm->ndm_pad1    = 0;
2525*4882a593Smuzhiyun 	ndm->ndm_pad2    = 0;
2526*4882a593Smuzhiyun 	ndm->ndm_flags	 = pn->flags | NTF_PROXY;
2527*4882a593Smuzhiyun 	ndm->ndm_type	 = RTN_UNICAST;
2528*4882a593Smuzhiyun 	ndm->ndm_ifindex = pn->dev ? pn->dev->ifindex : 0;
2529*4882a593Smuzhiyun 	ndm->ndm_state	 = NUD_NONE;
2530*4882a593Smuzhiyun 
2531*4882a593Smuzhiyun 	if (nla_put(skb, NDA_DST, tbl->key_len, pn->key))
2532*4882a593Smuzhiyun 		goto nla_put_failure;
2533*4882a593Smuzhiyun 
2534*4882a593Smuzhiyun 	if (pn->protocol && nla_put_u8(skb, NDA_PROTOCOL, pn->protocol))
2535*4882a593Smuzhiyun 		goto nla_put_failure;
2536*4882a593Smuzhiyun 
2537*4882a593Smuzhiyun 	nlmsg_end(skb, nlh);
2538*4882a593Smuzhiyun 	return 0;
2539*4882a593Smuzhiyun 
2540*4882a593Smuzhiyun nla_put_failure:
2541*4882a593Smuzhiyun 	nlmsg_cancel(skb, nlh);
2542*4882a593Smuzhiyun 	return -EMSGSIZE;
2543*4882a593Smuzhiyun }
2544*4882a593Smuzhiyun 
neigh_update_notify(struct neighbour * neigh,u32 nlmsg_pid)2545*4882a593Smuzhiyun static void neigh_update_notify(struct neighbour *neigh, u32 nlmsg_pid)
2546*4882a593Smuzhiyun {
2547*4882a593Smuzhiyun 	call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
2548*4882a593Smuzhiyun 	__neigh_notify(neigh, RTM_NEWNEIGH, 0, nlmsg_pid);
2549*4882a593Smuzhiyun }
2550*4882a593Smuzhiyun 
neigh_master_filtered(struct net_device * dev,int master_idx)2551*4882a593Smuzhiyun static bool neigh_master_filtered(struct net_device *dev, int master_idx)
2552*4882a593Smuzhiyun {
2553*4882a593Smuzhiyun 	struct net_device *master;
2554*4882a593Smuzhiyun 
2555*4882a593Smuzhiyun 	if (!master_idx)
2556*4882a593Smuzhiyun 		return false;
2557*4882a593Smuzhiyun 
2558*4882a593Smuzhiyun 	master = dev ? netdev_master_upper_dev_get(dev) : NULL;
2559*4882a593Smuzhiyun 	if (!master || master->ifindex != master_idx)
2560*4882a593Smuzhiyun 		return true;
2561*4882a593Smuzhiyun 
2562*4882a593Smuzhiyun 	return false;
2563*4882a593Smuzhiyun }
2564*4882a593Smuzhiyun 
neigh_ifindex_filtered(struct net_device * dev,int filter_idx)2565*4882a593Smuzhiyun static bool neigh_ifindex_filtered(struct net_device *dev, int filter_idx)
2566*4882a593Smuzhiyun {
2567*4882a593Smuzhiyun 	if (filter_idx && (!dev || dev->ifindex != filter_idx))
2568*4882a593Smuzhiyun 		return true;
2569*4882a593Smuzhiyun 
2570*4882a593Smuzhiyun 	return false;
2571*4882a593Smuzhiyun }
2572*4882a593Smuzhiyun 
2573*4882a593Smuzhiyun struct neigh_dump_filter {
2574*4882a593Smuzhiyun 	int master_idx;
2575*4882a593Smuzhiyun 	int dev_idx;
2576*4882a593Smuzhiyun };
2577*4882a593Smuzhiyun 
neigh_dump_table(struct neigh_table * tbl,struct sk_buff * skb,struct netlink_callback * cb,struct neigh_dump_filter * filter)2578*4882a593Smuzhiyun static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
2579*4882a593Smuzhiyun 			    struct netlink_callback *cb,
2580*4882a593Smuzhiyun 			    struct neigh_dump_filter *filter)
2581*4882a593Smuzhiyun {
2582*4882a593Smuzhiyun 	struct net *net = sock_net(skb->sk);
2583*4882a593Smuzhiyun 	struct neighbour *n;
2584*4882a593Smuzhiyun 	int rc, h, s_h = cb->args[1];
2585*4882a593Smuzhiyun 	int idx, s_idx = idx = cb->args[2];
2586*4882a593Smuzhiyun 	struct neigh_hash_table *nht;
2587*4882a593Smuzhiyun 	unsigned int flags = NLM_F_MULTI;
2588*4882a593Smuzhiyun 
2589*4882a593Smuzhiyun 	if (filter->dev_idx || filter->master_idx)
2590*4882a593Smuzhiyun 		flags |= NLM_F_DUMP_FILTERED;
2591*4882a593Smuzhiyun 
2592*4882a593Smuzhiyun 	rcu_read_lock_bh();
2593*4882a593Smuzhiyun 	nht = rcu_dereference_bh(tbl->nht);
2594*4882a593Smuzhiyun 
2595*4882a593Smuzhiyun 	for (h = s_h; h < (1 << nht->hash_shift); h++) {
2596*4882a593Smuzhiyun 		if (h > s_h)
2597*4882a593Smuzhiyun 			s_idx = 0;
2598*4882a593Smuzhiyun 		for (n = rcu_dereference_bh(nht->hash_buckets[h]), idx = 0;
2599*4882a593Smuzhiyun 		     n != NULL;
2600*4882a593Smuzhiyun 		     n = rcu_dereference_bh(n->next)) {
2601*4882a593Smuzhiyun 			if (idx < s_idx || !net_eq(dev_net(n->dev), net))
2602*4882a593Smuzhiyun 				goto next;
2603*4882a593Smuzhiyun 			if (neigh_ifindex_filtered(n->dev, filter->dev_idx) ||
2604*4882a593Smuzhiyun 			    neigh_master_filtered(n->dev, filter->master_idx))
2605*4882a593Smuzhiyun 				goto next;
2606*4882a593Smuzhiyun 			if (neigh_fill_info(skb, n, NETLINK_CB(cb->skb).portid,
2607*4882a593Smuzhiyun 					    cb->nlh->nlmsg_seq,
2608*4882a593Smuzhiyun 					    RTM_NEWNEIGH,
2609*4882a593Smuzhiyun 					    flags) < 0) {
2610*4882a593Smuzhiyun 				rc = -1;
2611*4882a593Smuzhiyun 				goto out;
2612*4882a593Smuzhiyun 			}
2613*4882a593Smuzhiyun next:
2614*4882a593Smuzhiyun 			idx++;
2615*4882a593Smuzhiyun 		}
2616*4882a593Smuzhiyun 	}
2617*4882a593Smuzhiyun 	rc = skb->len;
2618*4882a593Smuzhiyun out:
2619*4882a593Smuzhiyun 	rcu_read_unlock_bh();
2620*4882a593Smuzhiyun 	cb->args[1] = h;
2621*4882a593Smuzhiyun 	cb->args[2] = idx;
2622*4882a593Smuzhiyun 	return rc;
2623*4882a593Smuzhiyun }
2624*4882a593Smuzhiyun 
pneigh_dump_table(struct neigh_table * tbl,struct sk_buff * skb,struct netlink_callback * cb,struct neigh_dump_filter * filter)2625*4882a593Smuzhiyun static int pneigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
2626*4882a593Smuzhiyun 			     struct netlink_callback *cb,
2627*4882a593Smuzhiyun 			     struct neigh_dump_filter *filter)
2628*4882a593Smuzhiyun {
2629*4882a593Smuzhiyun 	struct pneigh_entry *n;
2630*4882a593Smuzhiyun 	struct net *net = sock_net(skb->sk);
2631*4882a593Smuzhiyun 	int rc, h, s_h = cb->args[3];
2632*4882a593Smuzhiyun 	int idx, s_idx = idx = cb->args[4];
2633*4882a593Smuzhiyun 	unsigned int flags = NLM_F_MULTI;
2634*4882a593Smuzhiyun 
2635*4882a593Smuzhiyun 	if (filter->dev_idx || filter->master_idx)
2636*4882a593Smuzhiyun 		flags |= NLM_F_DUMP_FILTERED;
2637*4882a593Smuzhiyun 
2638*4882a593Smuzhiyun 	read_lock_bh(&tbl->lock);
2639*4882a593Smuzhiyun 
2640*4882a593Smuzhiyun 	for (h = s_h; h <= PNEIGH_HASHMASK; h++) {
2641*4882a593Smuzhiyun 		if (h > s_h)
2642*4882a593Smuzhiyun 			s_idx = 0;
2643*4882a593Smuzhiyun 		for (n = tbl->phash_buckets[h], idx = 0; n; n = n->next) {
2644*4882a593Smuzhiyun 			if (idx < s_idx || pneigh_net(n) != net)
2645*4882a593Smuzhiyun 				goto next;
2646*4882a593Smuzhiyun 			if (neigh_ifindex_filtered(n->dev, filter->dev_idx) ||
2647*4882a593Smuzhiyun 			    neigh_master_filtered(n->dev, filter->master_idx))
2648*4882a593Smuzhiyun 				goto next;
2649*4882a593Smuzhiyun 			if (pneigh_fill_info(skb, n, NETLINK_CB(cb->skb).portid,
2650*4882a593Smuzhiyun 					    cb->nlh->nlmsg_seq,
2651*4882a593Smuzhiyun 					    RTM_NEWNEIGH, flags, tbl) < 0) {
2652*4882a593Smuzhiyun 				read_unlock_bh(&tbl->lock);
2653*4882a593Smuzhiyun 				rc = -1;
2654*4882a593Smuzhiyun 				goto out;
2655*4882a593Smuzhiyun 			}
2656*4882a593Smuzhiyun 		next:
2657*4882a593Smuzhiyun 			idx++;
2658*4882a593Smuzhiyun 		}
2659*4882a593Smuzhiyun 	}
2660*4882a593Smuzhiyun 
2661*4882a593Smuzhiyun 	read_unlock_bh(&tbl->lock);
2662*4882a593Smuzhiyun 	rc = skb->len;
2663*4882a593Smuzhiyun out:
2664*4882a593Smuzhiyun 	cb->args[3] = h;
2665*4882a593Smuzhiyun 	cb->args[4] = idx;
2666*4882a593Smuzhiyun 	return rc;
2667*4882a593Smuzhiyun 
2668*4882a593Smuzhiyun }
2669*4882a593Smuzhiyun 
neigh_valid_dump_req(const struct nlmsghdr * nlh,bool strict_check,struct neigh_dump_filter * filter,struct netlink_ext_ack * extack)2670*4882a593Smuzhiyun static int neigh_valid_dump_req(const struct nlmsghdr *nlh,
2671*4882a593Smuzhiyun 				bool strict_check,
2672*4882a593Smuzhiyun 				struct neigh_dump_filter *filter,
2673*4882a593Smuzhiyun 				struct netlink_ext_ack *extack)
2674*4882a593Smuzhiyun {
2675*4882a593Smuzhiyun 	struct nlattr *tb[NDA_MAX + 1];
2676*4882a593Smuzhiyun 	int err, i;
2677*4882a593Smuzhiyun 
2678*4882a593Smuzhiyun 	if (strict_check) {
2679*4882a593Smuzhiyun 		struct ndmsg *ndm;
2680*4882a593Smuzhiyun 
2681*4882a593Smuzhiyun 		if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ndm))) {
2682*4882a593Smuzhiyun 			NL_SET_ERR_MSG(extack, "Invalid header for neighbor dump request");
2683*4882a593Smuzhiyun 			return -EINVAL;
2684*4882a593Smuzhiyun 		}
2685*4882a593Smuzhiyun 
2686*4882a593Smuzhiyun 		ndm = nlmsg_data(nlh);
2687*4882a593Smuzhiyun 		if (ndm->ndm_pad1  || ndm->ndm_pad2  || ndm->ndm_ifindex ||
2688*4882a593Smuzhiyun 		    ndm->ndm_state || ndm->ndm_type) {
2689*4882a593Smuzhiyun 			NL_SET_ERR_MSG(extack, "Invalid values in header for neighbor dump request");
2690*4882a593Smuzhiyun 			return -EINVAL;
2691*4882a593Smuzhiyun 		}
2692*4882a593Smuzhiyun 
2693*4882a593Smuzhiyun 		if (ndm->ndm_flags & ~NTF_PROXY) {
2694*4882a593Smuzhiyun 			NL_SET_ERR_MSG(extack, "Invalid flags in header for neighbor dump request");
2695*4882a593Smuzhiyun 			return -EINVAL;
2696*4882a593Smuzhiyun 		}
2697*4882a593Smuzhiyun 
2698*4882a593Smuzhiyun 		err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct ndmsg),
2699*4882a593Smuzhiyun 						    tb, NDA_MAX, nda_policy,
2700*4882a593Smuzhiyun 						    extack);
2701*4882a593Smuzhiyun 	} else {
2702*4882a593Smuzhiyun 		err = nlmsg_parse_deprecated(nlh, sizeof(struct ndmsg), tb,
2703*4882a593Smuzhiyun 					     NDA_MAX, nda_policy, extack);
2704*4882a593Smuzhiyun 	}
2705*4882a593Smuzhiyun 	if (err < 0)
2706*4882a593Smuzhiyun 		return err;
2707*4882a593Smuzhiyun 
2708*4882a593Smuzhiyun 	for (i = 0; i <= NDA_MAX; ++i) {
2709*4882a593Smuzhiyun 		if (!tb[i])
2710*4882a593Smuzhiyun 			continue;
2711*4882a593Smuzhiyun 
2712*4882a593Smuzhiyun 		/* all new attributes should require strict_check */
2713*4882a593Smuzhiyun 		switch (i) {
2714*4882a593Smuzhiyun 		case NDA_IFINDEX:
2715*4882a593Smuzhiyun 			filter->dev_idx = nla_get_u32(tb[i]);
2716*4882a593Smuzhiyun 			break;
2717*4882a593Smuzhiyun 		case NDA_MASTER:
2718*4882a593Smuzhiyun 			filter->master_idx = nla_get_u32(tb[i]);
2719*4882a593Smuzhiyun 			break;
2720*4882a593Smuzhiyun 		default:
2721*4882a593Smuzhiyun 			if (strict_check) {
2722*4882a593Smuzhiyun 				NL_SET_ERR_MSG(extack, "Unsupported attribute in neighbor dump request");
2723*4882a593Smuzhiyun 				return -EINVAL;
2724*4882a593Smuzhiyun 			}
2725*4882a593Smuzhiyun 		}
2726*4882a593Smuzhiyun 	}
2727*4882a593Smuzhiyun 
2728*4882a593Smuzhiyun 	return 0;
2729*4882a593Smuzhiyun }
2730*4882a593Smuzhiyun 
neigh_dump_info(struct sk_buff * skb,struct netlink_callback * cb)2731*4882a593Smuzhiyun static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
2732*4882a593Smuzhiyun {
2733*4882a593Smuzhiyun 	const struct nlmsghdr *nlh = cb->nlh;
2734*4882a593Smuzhiyun 	struct neigh_dump_filter filter = {};
2735*4882a593Smuzhiyun 	struct neigh_table *tbl;
2736*4882a593Smuzhiyun 	int t, family, s_t;
2737*4882a593Smuzhiyun 	int proxy = 0;
2738*4882a593Smuzhiyun 	int err;
2739*4882a593Smuzhiyun 
2740*4882a593Smuzhiyun 	family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family;
2741*4882a593Smuzhiyun 
2742*4882a593Smuzhiyun 	/* check for full ndmsg structure presence, family member is
2743*4882a593Smuzhiyun 	 * the same for both structures
2744*4882a593Smuzhiyun 	 */
2745*4882a593Smuzhiyun 	if (nlmsg_len(nlh) >= sizeof(struct ndmsg) &&
2746*4882a593Smuzhiyun 	    ((struct ndmsg *)nlmsg_data(nlh))->ndm_flags == NTF_PROXY)
2747*4882a593Smuzhiyun 		proxy = 1;
2748*4882a593Smuzhiyun 
2749*4882a593Smuzhiyun 	err = neigh_valid_dump_req(nlh, cb->strict_check, &filter, cb->extack);
2750*4882a593Smuzhiyun 	if (err < 0 && cb->strict_check)
2751*4882a593Smuzhiyun 		return err;
2752*4882a593Smuzhiyun 
2753*4882a593Smuzhiyun 	s_t = cb->args[0];
2754*4882a593Smuzhiyun 
2755*4882a593Smuzhiyun 	for (t = 0; t < NEIGH_NR_TABLES; t++) {
2756*4882a593Smuzhiyun 		tbl = neigh_tables[t];
2757*4882a593Smuzhiyun 
2758*4882a593Smuzhiyun 		if (!tbl)
2759*4882a593Smuzhiyun 			continue;
2760*4882a593Smuzhiyun 		if (t < s_t || (family && tbl->family != family))
2761*4882a593Smuzhiyun 			continue;
2762*4882a593Smuzhiyun 		if (t > s_t)
2763*4882a593Smuzhiyun 			memset(&cb->args[1], 0, sizeof(cb->args) -
2764*4882a593Smuzhiyun 						sizeof(cb->args[0]));
2765*4882a593Smuzhiyun 		if (proxy)
2766*4882a593Smuzhiyun 			err = pneigh_dump_table(tbl, skb, cb, &filter);
2767*4882a593Smuzhiyun 		else
2768*4882a593Smuzhiyun 			err = neigh_dump_table(tbl, skb, cb, &filter);
2769*4882a593Smuzhiyun 		if (err < 0)
2770*4882a593Smuzhiyun 			break;
2771*4882a593Smuzhiyun 	}
2772*4882a593Smuzhiyun 
2773*4882a593Smuzhiyun 	cb->args[0] = t;
2774*4882a593Smuzhiyun 	return skb->len;
2775*4882a593Smuzhiyun }
2776*4882a593Smuzhiyun 
neigh_valid_get_req(const struct nlmsghdr * nlh,struct neigh_table ** tbl,void ** dst,int * dev_idx,u8 * ndm_flags,struct netlink_ext_ack * extack)2777*4882a593Smuzhiyun static int neigh_valid_get_req(const struct nlmsghdr *nlh,
2778*4882a593Smuzhiyun 			       struct neigh_table **tbl,
2779*4882a593Smuzhiyun 			       void **dst, int *dev_idx, u8 *ndm_flags,
2780*4882a593Smuzhiyun 			       struct netlink_ext_ack *extack)
2781*4882a593Smuzhiyun {
2782*4882a593Smuzhiyun 	struct nlattr *tb[NDA_MAX + 1];
2783*4882a593Smuzhiyun 	struct ndmsg *ndm;
2784*4882a593Smuzhiyun 	int err, i;
2785*4882a593Smuzhiyun 
2786*4882a593Smuzhiyun 	if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ndm))) {
2787*4882a593Smuzhiyun 		NL_SET_ERR_MSG(extack, "Invalid header for neighbor get request");
2788*4882a593Smuzhiyun 		return -EINVAL;
2789*4882a593Smuzhiyun 	}
2790*4882a593Smuzhiyun 
2791*4882a593Smuzhiyun 	ndm = nlmsg_data(nlh);
2792*4882a593Smuzhiyun 	if (ndm->ndm_pad1  || ndm->ndm_pad2  || ndm->ndm_state ||
2793*4882a593Smuzhiyun 	    ndm->ndm_type) {
2794*4882a593Smuzhiyun 		NL_SET_ERR_MSG(extack, "Invalid values in header for neighbor get request");
2795*4882a593Smuzhiyun 		return -EINVAL;
2796*4882a593Smuzhiyun 	}
2797*4882a593Smuzhiyun 
2798*4882a593Smuzhiyun 	if (ndm->ndm_flags & ~NTF_PROXY) {
2799*4882a593Smuzhiyun 		NL_SET_ERR_MSG(extack, "Invalid flags in header for neighbor get request");
2800*4882a593Smuzhiyun 		return -EINVAL;
2801*4882a593Smuzhiyun 	}
2802*4882a593Smuzhiyun 
2803*4882a593Smuzhiyun 	err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct ndmsg), tb,
2804*4882a593Smuzhiyun 					    NDA_MAX, nda_policy, extack);
2805*4882a593Smuzhiyun 	if (err < 0)
2806*4882a593Smuzhiyun 		return err;
2807*4882a593Smuzhiyun 
2808*4882a593Smuzhiyun 	*ndm_flags = ndm->ndm_flags;
2809*4882a593Smuzhiyun 	*dev_idx = ndm->ndm_ifindex;
2810*4882a593Smuzhiyun 	*tbl = neigh_find_table(ndm->ndm_family);
2811*4882a593Smuzhiyun 	if (*tbl == NULL) {
2812*4882a593Smuzhiyun 		NL_SET_ERR_MSG(extack, "Unsupported family in header for neighbor get request");
2813*4882a593Smuzhiyun 		return -EAFNOSUPPORT;
2814*4882a593Smuzhiyun 	}
2815*4882a593Smuzhiyun 
2816*4882a593Smuzhiyun 	for (i = 0; i <= NDA_MAX; ++i) {
2817*4882a593Smuzhiyun 		if (!tb[i])
2818*4882a593Smuzhiyun 			continue;
2819*4882a593Smuzhiyun 
2820*4882a593Smuzhiyun 		switch (i) {
2821*4882a593Smuzhiyun 		case NDA_DST:
2822*4882a593Smuzhiyun 			if (nla_len(tb[i]) != (int)(*tbl)->key_len) {
2823*4882a593Smuzhiyun 				NL_SET_ERR_MSG(extack, "Invalid network address in neighbor get request");
2824*4882a593Smuzhiyun 				return -EINVAL;
2825*4882a593Smuzhiyun 			}
2826*4882a593Smuzhiyun 			*dst = nla_data(tb[i]);
2827*4882a593Smuzhiyun 			break;
2828*4882a593Smuzhiyun 		default:
2829*4882a593Smuzhiyun 			NL_SET_ERR_MSG(extack, "Unsupported attribute in neighbor get request");
2830*4882a593Smuzhiyun 			return -EINVAL;
2831*4882a593Smuzhiyun 		}
2832*4882a593Smuzhiyun 	}
2833*4882a593Smuzhiyun 
2834*4882a593Smuzhiyun 	return 0;
2835*4882a593Smuzhiyun }
2836*4882a593Smuzhiyun 
neigh_nlmsg_size(void)2837*4882a593Smuzhiyun static inline size_t neigh_nlmsg_size(void)
2838*4882a593Smuzhiyun {
2839*4882a593Smuzhiyun 	return NLMSG_ALIGN(sizeof(struct ndmsg))
2840*4882a593Smuzhiyun 	       + nla_total_size(MAX_ADDR_LEN) /* NDA_DST */
2841*4882a593Smuzhiyun 	       + nla_total_size(MAX_ADDR_LEN) /* NDA_LLADDR */
2842*4882a593Smuzhiyun 	       + nla_total_size(sizeof(struct nda_cacheinfo))
2843*4882a593Smuzhiyun 	       + nla_total_size(4)  /* NDA_PROBES */
2844*4882a593Smuzhiyun 	       + nla_total_size(1); /* NDA_PROTOCOL */
2845*4882a593Smuzhiyun }
2846*4882a593Smuzhiyun 
neigh_get_reply(struct net * net,struct neighbour * neigh,u32 pid,u32 seq)2847*4882a593Smuzhiyun static int neigh_get_reply(struct net *net, struct neighbour *neigh,
2848*4882a593Smuzhiyun 			   u32 pid, u32 seq)
2849*4882a593Smuzhiyun {
2850*4882a593Smuzhiyun 	struct sk_buff *skb;
2851*4882a593Smuzhiyun 	int err = 0;
2852*4882a593Smuzhiyun 
2853*4882a593Smuzhiyun 	skb = nlmsg_new(neigh_nlmsg_size(), GFP_KERNEL);
2854*4882a593Smuzhiyun 	if (!skb)
2855*4882a593Smuzhiyun 		return -ENOBUFS;
2856*4882a593Smuzhiyun 
2857*4882a593Smuzhiyun 	err = neigh_fill_info(skb, neigh, pid, seq, RTM_NEWNEIGH, 0);
2858*4882a593Smuzhiyun 	if (err) {
2859*4882a593Smuzhiyun 		kfree_skb(skb);
2860*4882a593Smuzhiyun 		goto errout;
2861*4882a593Smuzhiyun 	}
2862*4882a593Smuzhiyun 
2863*4882a593Smuzhiyun 	err = rtnl_unicast(skb, net, pid);
2864*4882a593Smuzhiyun errout:
2865*4882a593Smuzhiyun 	return err;
2866*4882a593Smuzhiyun }
2867*4882a593Smuzhiyun 
pneigh_nlmsg_size(void)2868*4882a593Smuzhiyun static inline size_t pneigh_nlmsg_size(void)
2869*4882a593Smuzhiyun {
2870*4882a593Smuzhiyun 	return NLMSG_ALIGN(sizeof(struct ndmsg))
2871*4882a593Smuzhiyun 	       + nla_total_size(MAX_ADDR_LEN) /* NDA_DST */
2872*4882a593Smuzhiyun 	       + nla_total_size(1); /* NDA_PROTOCOL */
2873*4882a593Smuzhiyun }
2874*4882a593Smuzhiyun 
pneigh_get_reply(struct net * net,struct pneigh_entry * neigh,u32 pid,u32 seq,struct neigh_table * tbl)2875*4882a593Smuzhiyun static int pneigh_get_reply(struct net *net, struct pneigh_entry *neigh,
2876*4882a593Smuzhiyun 			    u32 pid, u32 seq, struct neigh_table *tbl)
2877*4882a593Smuzhiyun {
2878*4882a593Smuzhiyun 	struct sk_buff *skb;
2879*4882a593Smuzhiyun 	int err = 0;
2880*4882a593Smuzhiyun 
2881*4882a593Smuzhiyun 	skb = nlmsg_new(pneigh_nlmsg_size(), GFP_KERNEL);
2882*4882a593Smuzhiyun 	if (!skb)
2883*4882a593Smuzhiyun 		return -ENOBUFS;
2884*4882a593Smuzhiyun 
2885*4882a593Smuzhiyun 	err = pneigh_fill_info(skb, neigh, pid, seq, RTM_NEWNEIGH, 0, tbl);
2886*4882a593Smuzhiyun 	if (err) {
2887*4882a593Smuzhiyun 		kfree_skb(skb);
2888*4882a593Smuzhiyun 		goto errout;
2889*4882a593Smuzhiyun 	}
2890*4882a593Smuzhiyun 
2891*4882a593Smuzhiyun 	err = rtnl_unicast(skb, net, pid);
2892*4882a593Smuzhiyun errout:
2893*4882a593Smuzhiyun 	return err;
2894*4882a593Smuzhiyun }
2895*4882a593Smuzhiyun 
neigh_get(struct sk_buff * in_skb,struct nlmsghdr * nlh,struct netlink_ext_ack * extack)2896*4882a593Smuzhiyun static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
2897*4882a593Smuzhiyun 		     struct netlink_ext_ack *extack)
2898*4882a593Smuzhiyun {
2899*4882a593Smuzhiyun 	struct net *net = sock_net(in_skb->sk);
2900*4882a593Smuzhiyun 	struct net_device *dev = NULL;
2901*4882a593Smuzhiyun 	struct neigh_table *tbl = NULL;
2902*4882a593Smuzhiyun 	struct neighbour *neigh;
2903*4882a593Smuzhiyun 	void *dst = NULL;
2904*4882a593Smuzhiyun 	u8 ndm_flags = 0;
2905*4882a593Smuzhiyun 	int dev_idx = 0;
2906*4882a593Smuzhiyun 	int err;
2907*4882a593Smuzhiyun 
2908*4882a593Smuzhiyun 	err = neigh_valid_get_req(nlh, &tbl, &dst, &dev_idx, &ndm_flags,
2909*4882a593Smuzhiyun 				  extack);
2910*4882a593Smuzhiyun 	if (err < 0)
2911*4882a593Smuzhiyun 		return err;
2912*4882a593Smuzhiyun 
2913*4882a593Smuzhiyun 	if (dev_idx) {
2914*4882a593Smuzhiyun 		dev = __dev_get_by_index(net, dev_idx);
2915*4882a593Smuzhiyun 		if (!dev) {
2916*4882a593Smuzhiyun 			NL_SET_ERR_MSG(extack, "Unknown device ifindex");
2917*4882a593Smuzhiyun 			return -ENODEV;
2918*4882a593Smuzhiyun 		}
2919*4882a593Smuzhiyun 	}
2920*4882a593Smuzhiyun 
2921*4882a593Smuzhiyun 	if (!dst) {
2922*4882a593Smuzhiyun 		NL_SET_ERR_MSG(extack, "Network address not specified");
2923*4882a593Smuzhiyun 		return -EINVAL;
2924*4882a593Smuzhiyun 	}
2925*4882a593Smuzhiyun 
2926*4882a593Smuzhiyun 	if (ndm_flags & NTF_PROXY) {
2927*4882a593Smuzhiyun 		struct pneigh_entry *pn;
2928*4882a593Smuzhiyun 
2929*4882a593Smuzhiyun 		pn = pneigh_lookup(tbl, net, dst, dev, 0);
2930*4882a593Smuzhiyun 		if (!pn) {
2931*4882a593Smuzhiyun 			NL_SET_ERR_MSG(extack, "Proxy neighbour entry not found");
2932*4882a593Smuzhiyun 			return -ENOENT;
2933*4882a593Smuzhiyun 		}
2934*4882a593Smuzhiyun 		return pneigh_get_reply(net, pn, NETLINK_CB(in_skb).portid,
2935*4882a593Smuzhiyun 					nlh->nlmsg_seq, tbl);
2936*4882a593Smuzhiyun 	}
2937*4882a593Smuzhiyun 
2938*4882a593Smuzhiyun 	if (!dev) {
2939*4882a593Smuzhiyun 		NL_SET_ERR_MSG(extack, "No device specified");
2940*4882a593Smuzhiyun 		return -EINVAL;
2941*4882a593Smuzhiyun 	}
2942*4882a593Smuzhiyun 
2943*4882a593Smuzhiyun 	neigh = neigh_lookup(tbl, dst, dev);
2944*4882a593Smuzhiyun 	if (!neigh) {
2945*4882a593Smuzhiyun 		NL_SET_ERR_MSG(extack, "Neighbour entry not found");
2946*4882a593Smuzhiyun 		return -ENOENT;
2947*4882a593Smuzhiyun 	}
2948*4882a593Smuzhiyun 
2949*4882a593Smuzhiyun 	err = neigh_get_reply(net, neigh, NETLINK_CB(in_skb).portid,
2950*4882a593Smuzhiyun 			      nlh->nlmsg_seq);
2951*4882a593Smuzhiyun 
2952*4882a593Smuzhiyun 	neigh_release(neigh);
2953*4882a593Smuzhiyun 
2954*4882a593Smuzhiyun 	return err;
2955*4882a593Smuzhiyun }
2956*4882a593Smuzhiyun 
neigh_for_each(struct neigh_table * tbl,void (* cb)(struct neighbour *,void *),void * cookie)2957*4882a593Smuzhiyun void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie)
2958*4882a593Smuzhiyun {
2959*4882a593Smuzhiyun 	int chain;
2960*4882a593Smuzhiyun 	struct neigh_hash_table *nht;
2961*4882a593Smuzhiyun 
2962*4882a593Smuzhiyun 	rcu_read_lock_bh();
2963*4882a593Smuzhiyun 	nht = rcu_dereference_bh(tbl->nht);
2964*4882a593Smuzhiyun 
2965*4882a593Smuzhiyun 	read_lock(&tbl->lock); /* avoid resizes */
2966*4882a593Smuzhiyun 	for (chain = 0; chain < (1 << nht->hash_shift); chain++) {
2967*4882a593Smuzhiyun 		struct neighbour *n;
2968*4882a593Smuzhiyun 
2969*4882a593Smuzhiyun 		for (n = rcu_dereference_bh(nht->hash_buckets[chain]);
2970*4882a593Smuzhiyun 		     n != NULL;
2971*4882a593Smuzhiyun 		     n = rcu_dereference_bh(n->next))
2972*4882a593Smuzhiyun 			cb(n, cookie);
2973*4882a593Smuzhiyun 	}
2974*4882a593Smuzhiyun 	read_unlock(&tbl->lock);
2975*4882a593Smuzhiyun 	rcu_read_unlock_bh();
2976*4882a593Smuzhiyun }
2977*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_for_each);
2978*4882a593Smuzhiyun 
2979*4882a593Smuzhiyun /* The tbl->lock must be held as a writer and BH disabled. */
__neigh_for_each_release(struct neigh_table * tbl,int (* cb)(struct neighbour *))2980*4882a593Smuzhiyun void __neigh_for_each_release(struct neigh_table *tbl,
2981*4882a593Smuzhiyun 			      int (*cb)(struct neighbour *))
2982*4882a593Smuzhiyun {
2983*4882a593Smuzhiyun 	int chain;
2984*4882a593Smuzhiyun 	struct neigh_hash_table *nht;
2985*4882a593Smuzhiyun 
2986*4882a593Smuzhiyun 	nht = rcu_dereference_protected(tbl->nht,
2987*4882a593Smuzhiyun 					lockdep_is_held(&tbl->lock));
2988*4882a593Smuzhiyun 	for (chain = 0; chain < (1 << nht->hash_shift); chain++) {
2989*4882a593Smuzhiyun 		struct neighbour *n;
2990*4882a593Smuzhiyun 		struct neighbour __rcu **np;
2991*4882a593Smuzhiyun 
2992*4882a593Smuzhiyun 		np = &nht->hash_buckets[chain];
2993*4882a593Smuzhiyun 		while ((n = rcu_dereference_protected(*np,
2994*4882a593Smuzhiyun 					lockdep_is_held(&tbl->lock))) != NULL) {
2995*4882a593Smuzhiyun 			int release;
2996*4882a593Smuzhiyun 
2997*4882a593Smuzhiyun 			write_lock(&n->lock);
2998*4882a593Smuzhiyun 			release = cb(n);
2999*4882a593Smuzhiyun 			if (release) {
3000*4882a593Smuzhiyun 				rcu_assign_pointer(*np,
3001*4882a593Smuzhiyun 					rcu_dereference_protected(n->next,
3002*4882a593Smuzhiyun 						lockdep_is_held(&tbl->lock)));
3003*4882a593Smuzhiyun 				neigh_mark_dead(n);
3004*4882a593Smuzhiyun 			} else
3005*4882a593Smuzhiyun 				np = &n->next;
3006*4882a593Smuzhiyun 			write_unlock(&n->lock);
3007*4882a593Smuzhiyun 			if (release)
3008*4882a593Smuzhiyun 				neigh_cleanup_and_release(n);
3009*4882a593Smuzhiyun 		}
3010*4882a593Smuzhiyun 	}
3011*4882a593Smuzhiyun }
3012*4882a593Smuzhiyun EXPORT_SYMBOL(__neigh_for_each_release);
3013*4882a593Smuzhiyun 
neigh_xmit(int index,struct net_device * dev,const void * addr,struct sk_buff * skb)3014*4882a593Smuzhiyun int neigh_xmit(int index, struct net_device *dev,
3015*4882a593Smuzhiyun 	       const void *addr, struct sk_buff *skb)
3016*4882a593Smuzhiyun {
3017*4882a593Smuzhiyun 	int err = -EAFNOSUPPORT;
3018*4882a593Smuzhiyun 	if (likely(index < NEIGH_NR_TABLES)) {
3019*4882a593Smuzhiyun 		struct neigh_table *tbl;
3020*4882a593Smuzhiyun 		struct neighbour *neigh;
3021*4882a593Smuzhiyun 
3022*4882a593Smuzhiyun 		tbl = neigh_tables[index];
3023*4882a593Smuzhiyun 		if (!tbl)
3024*4882a593Smuzhiyun 			goto out;
3025*4882a593Smuzhiyun 		rcu_read_lock_bh();
3026*4882a593Smuzhiyun 		if (index == NEIGH_ARP_TABLE) {
3027*4882a593Smuzhiyun 			u32 key = *((u32 *)addr);
3028*4882a593Smuzhiyun 
3029*4882a593Smuzhiyun 			neigh = __ipv4_neigh_lookup_noref(dev, key);
3030*4882a593Smuzhiyun 		} else {
3031*4882a593Smuzhiyun 			neigh = __neigh_lookup_noref(tbl, addr, dev);
3032*4882a593Smuzhiyun 		}
3033*4882a593Smuzhiyun 		if (!neigh)
3034*4882a593Smuzhiyun 			neigh = __neigh_create(tbl, addr, dev, false);
3035*4882a593Smuzhiyun 		err = PTR_ERR(neigh);
3036*4882a593Smuzhiyun 		if (IS_ERR(neigh)) {
3037*4882a593Smuzhiyun 			rcu_read_unlock_bh();
3038*4882a593Smuzhiyun 			goto out_kfree_skb;
3039*4882a593Smuzhiyun 		}
3040*4882a593Smuzhiyun 		err = neigh->output(neigh, skb);
3041*4882a593Smuzhiyun 		rcu_read_unlock_bh();
3042*4882a593Smuzhiyun 	}
3043*4882a593Smuzhiyun 	else if (index == NEIGH_LINK_TABLE) {
3044*4882a593Smuzhiyun 		err = dev_hard_header(skb, dev, ntohs(skb->protocol),
3045*4882a593Smuzhiyun 				      addr, NULL, skb->len);
3046*4882a593Smuzhiyun 		if (err < 0)
3047*4882a593Smuzhiyun 			goto out_kfree_skb;
3048*4882a593Smuzhiyun 		err = dev_queue_xmit(skb);
3049*4882a593Smuzhiyun 	}
3050*4882a593Smuzhiyun out:
3051*4882a593Smuzhiyun 	return err;
3052*4882a593Smuzhiyun out_kfree_skb:
3053*4882a593Smuzhiyun 	kfree_skb(skb);
3054*4882a593Smuzhiyun 	goto out;
3055*4882a593Smuzhiyun }
3056*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_xmit);
3057*4882a593Smuzhiyun 
3058*4882a593Smuzhiyun #ifdef CONFIG_PROC_FS
3059*4882a593Smuzhiyun 
neigh_get_first(struct seq_file * seq)3060*4882a593Smuzhiyun static struct neighbour *neigh_get_first(struct seq_file *seq)
3061*4882a593Smuzhiyun {
3062*4882a593Smuzhiyun 	struct neigh_seq_state *state = seq->private;
3063*4882a593Smuzhiyun 	struct net *net = seq_file_net(seq);
3064*4882a593Smuzhiyun 	struct neigh_hash_table *nht = state->nht;
3065*4882a593Smuzhiyun 	struct neighbour *n = NULL;
3066*4882a593Smuzhiyun 	int bucket;
3067*4882a593Smuzhiyun 
3068*4882a593Smuzhiyun 	state->flags &= ~NEIGH_SEQ_IS_PNEIGH;
3069*4882a593Smuzhiyun 	for (bucket = 0; bucket < (1 << nht->hash_shift); bucket++) {
3070*4882a593Smuzhiyun 		n = rcu_dereference_bh(nht->hash_buckets[bucket]);
3071*4882a593Smuzhiyun 
3072*4882a593Smuzhiyun 		while (n) {
3073*4882a593Smuzhiyun 			if (!net_eq(dev_net(n->dev), net))
3074*4882a593Smuzhiyun 				goto next;
3075*4882a593Smuzhiyun 			if (state->neigh_sub_iter) {
3076*4882a593Smuzhiyun 				loff_t fakep = 0;
3077*4882a593Smuzhiyun 				void *v;
3078*4882a593Smuzhiyun 
3079*4882a593Smuzhiyun 				v = state->neigh_sub_iter(state, n, &fakep);
3080*4882a593Smuzhiyun 				if (!v)
3081*4882a593Smuzhiyun 					goto next;
3082*4882a593Smuzhiyun 			}
3083*4882a593Smuzhiyun 			if (!(state->flags & NEIGH_SEQ_SKIP_NOARP))
3084*4882a593Smuzhiyun 				break;
3085*4882a593Smuzhiyun 			if (n->nud_state & ~NUD_NOARP)
3086*4882a593Smuzhiyun 				break;
3087*4882a593Smuzhiyun next:
3088*4882a593Smuzhiyun 			n = rcu_dereference_bh(n->next);
3089*4882a593Smuzhiyun 		}
3090*4882a593Smuzhiyun 
3091*4882a593Smuzhiyun 		if (n)
3092*4882a593Smuzhiyun 			break;
3093*4882a593Smuzhiyun 	}
3094*4882a593Smuzhiyun 	state->bucket = bucket;
3095*4882a593Smuzhiyun 
3096*4882a593Smuzhiyun 	return n;
3097*4882a593Smuzhiyun }
3098*4882a593Smuzhiyun 
neigh_get_next(struct seq_file * seq,struct neighbour * n,loff_t * pos)3099*4882a593Smuzhiyun static struct neighbour *neigh_get_next(struct seq_file *seq,
3100*4882a593Smuzhiyun 					struct neighbour *n,
3101*4882a593Smuzhiyun 					loff_t *pos)
3102*4882a593Smuzhiyun {
3103*4882a593Smuzhiyun 	struct neigh_seq_state *state = seq->private;
3104*4882a593Smuzhiyun 	struct net *net = seq_file_net(seq);
3105*4882a593Smuzhiyun 	struct neigh_hash_table *nht = state->nht;
3106*4882a593Smuzhiyun 
3107*4882a593Smuzhiyun 	if (state->neigh_sub_iter) {
3108*4882a593Smuzhiyun 		void *v = state->neigh_sub_iter(state, n, pos);
3109*4882a593Smuzhiyun 		if (v)
3110*4882a593Smuzhiyun 			return n;
3111*4882a593Smuzhiyun 	}
3112*4882a593Smuzhiyun 	n = rcu_dereference_bh(n->next);
3113*4882a593Smuzhiyun 
3114*4882a593Smuzhiyun 	while (1) {
3115*4882a593Smuzhiyun 		while (n) {
3116*4882a593Smuzhiyun 			if (!net_eq(dev_net(n->dev), net))
3117*4882a593Smuzhiyun 				goto next;
3118*4882a593Smuzhiyun 			if (state->neigh_sub_iter) {
3119*4882a593Smuzhiyun 				void *v = state->neigh_sub_iter(state, n, pos);
3120*4882a593Smuzhiyun 				if (v)
3121*4882a593Smuzhiyun 					return n;
3122*4882a593Smuzhiyun 				goto next;
3123*4882a593Smuzhiyun 			}
3124*4882a593Smuzhiyun 			if (!(state->flags & NEIGH_SEQ_SKIP_NOARP))
3125*4882a593Smuzhiyun 				break;
3126*4882a593Smuzhiyun 
3127*4882a593Smuzhiyun 			if (n->nud_state & ~NUD_NOARP)
3128*4882a593Smuzhiyun 				break;
3129*4882a593Smuzhiyun next:
3130*4882a593Smuzhiyun 			n = rcu_dereference_bh(n->next);
3131*4882a593Smuzhiyun 		}
3132*4882a593Smuzhiyun 
3133*4882a593Smuzhiyun 		if (n)
3134*4882a593Smuzhiyun 			break;
3135*4882a593Smuzhiyun 
3136*4882a593Smuzhiyun 		if (++state->bucket >= (1 << nht->hash_shift))
3137*4882a593Smuzhiyun 			break;
3138*4882a593Smuzhiyun 
3139*4882a593Smuzhiyun 		n = rcu_dereference_bh(nht->hash_buckets[state->bucket]);
3140*4882a593Smuzhiyun 	}
3141*4882a593Smuzhiyun 
3142*4882a593Smuzhiyun 	if (n && pos)
3143*4882a593Smuzhiyun 		--(*pos);
3144*4882a593Smuzhiyun 	return n;
3145*4882a593Smuzhiyun }
3146*4882a593Smuzhiyun 
neigh_get_idx(struct seq_file * seq,loff_t * pos)3147*4882a593Smuzhiyun static struct neighbour *neigh_get_idx(struct seq_file *seq, loff_t *pos)
3148*4882a593Smuzhiyun {
3149*4882a593Smuzhiyun 	struct neighbour *n = neigh_get_first(seq);
3150*4882a593Smuzhiyun 
3151*4882a593Smuzhiyun 	if (n) {
3152*4882a593Smuzhiyun 		--(*pos);
3153*4882a593Smuzhiyun 		while (*pos) {
3154*4882a593Smuzhiyun 			n = neigh_get_next(seq, n, pos);
3155*4882a593Smuzhiyun 			if (!n)
3156*4882a593Smuzhiyun 				break;
3157*4882a593Smuzhiyun 		}
3158*4882a593Smuzhiyun 	}
3159*4882a593Smuzhiyun 	return *pos ? NULL : n;
3160*4882a593Smuzhiyun }
3161*4882a593Smuzhiyun 
pneigh_get_first(struct seq_file * seq)3162*4882a593Smuzhiyun static struct pneigh_entry *pneigh_get_first(struct seq_file *seq)
3163*4882a593Smuzhiyun {
3164*4882a593Smuzhiyun 	struct neigh_seq_state *state = seq->private;
3165*4882a593Smuzhiyun 	struct net *net = seq_file_net(seq);
3166*4882a593Smuzhiyun 	struct neigh_table *tbl = state->tbl;
3167*4882a593Smuzhiyun 	struct pneigh_entry *pn = NULL;
3168*4882a593Smuzhiyun 	int bucket = state->bucket;
3169*4882a593Smuzhiyun 
3170*4882a593Smuzhiyun 	state->flags |= NEIGH_SEQ_IS_PNEIGH;
3171*4882a593Smuzhiyun 	for (bucket = 0; bucket <= PNEIGH_HASHMASK; bucket++) {
3172*4882a593Smuzhiyun 		pn = tbl->phash_buckets[bucket];
3173*4882a593Smuzhiyun 		while (pn && !net_eq(pneigh_net(pn), net))
3174*4882a593Smuzhiyun 			pn = pn->next;
3175*4882a593Smuzhiyun 		if (pn)
3176*4882a593Smuzhiyun 			break;
3177*4882a593Smuzhiyun 	}
3178*4882a593Smuzhiyun 	state->bucket = bucket;
3179*4882a593Smuzhiyun 
3180*4882a593Smuzhiyun 	return pn;
3181*4882a593Smuzhiyun }
3182*4882a593Smuzhiyun 
pneigh_get_next(struct seq_file * seq,struct pneigh_entry * pn,loff_t * pos)3183*4882a593Smuzhiyun static struct pneigh_entry *pneigh_get_next(struct seq_file *seq,
3184*4882a593Smuzhiyun 					    struct pneigh_entry *pn,
3185*4882a593Smuzhiyun 					    loff_t *pos)
3186*4882a593Smuzhiyun {
3187*4882a593Smuzhiyun 	struct neigh_seq_state *state = seq->private;
3188*4882a593Smuzhiyun 	struct net *net = seq_file_net(seq);
3189*4882a593Smuzhiyun 	struct neigh_table *tbl = state->tbl;
3190*4882a593Smuzhiyun 
3191*4882a593Smuzhiyun 	do {
3192*4882a593Smuzhiyun 		pn = pn->next;
3193*4882a593Smuzhiyun 	} while (pn && !net_eq(pneigh_net(pn), net));
3194*4882a593Smuzhiyun 
3195*4882a593Smuzhiyun 	while (!pn) {
3196*4882a593Smuzhiyun 		if (++state->bucket > PNEIGH_HASHMASK)
3197*4882a593Smuzhiyun 			break;
3198*4882a593Smuzhiyun 		pn = tbl->phash_buckets[state->bucket];
3199*4882a593Smuzhiyun 		while (pn && !net_eq(pneigh_net(pn), net))
3200*4882a593Smuzhiyun 			pn = pn->next;
3201*4882a593Smuzhiyun 		if (pn)
3202*4882a593Smuzhiyun 			break;
3203*4882a593Smuzhiyun 	}
3204*4882a593Smuzhiyun 
3205*4882a593Smuzhiyun 	if (pn && pos)
3206*4882a593Smuzhiyun 		--(*pos);
3207*4882a593Smuzhiyun 
3208*4882a593Smuzhiyun 	return pn;
3209*4882a593Smuzhiyun }
3210*4882a593Smuzhiyun 
pneigh_get_idx(struct seq_file * seq,loff_t * pos)3211*4882a593Smuzhiyun static struct pneigh_entry *pneigh_get_idx(struct seq_file *seq, loff_t *pos)
3212*4882a593Smuzhiyun {
3213*4882a593Smuzhiyun 	struct pneigh_entry *pn = pneigh_get_first(seq);
3214*4882a593Smuzhiyun 
3215*4882a593Smuzhiyun 	if (pn) {
3216*4882a593Smuzhiyun 		--(*pos);
3217*4882a593Smuzhiyun 		while (*pos) {
3218*4882a593Smuzhiyun 			pn = pneigh_get_next(seq, pn, pos);
3219*4882a593Smuzhiyun 			if (!pn)
3220*4882a593Smuzhiyun 				break;
3221*4882a593Smuzhiyun 		}
3222*4882a593Smuzhiyun 	}
3223*4882a593Smuzhiyun 	return *pos ? NULL : pn;
3224*4882a593Smuzhiyun }
3225*4882a593Smuzhiyun 
neigh_get_idx_any(struct seq_file * seq,loff_t * pos)3226*4882a593Smuzhiyun static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos)
3227*4882a593Smuzhiyun {
3228*4882a593Smuzhiyun 	struct neigh_seq_state *state = seq->private;
3229*4882a593Smuzhiyun 	void *rc;
3230*4882a593Smuzhiyun 	loff_t idxpos = *pos;
3231*4882a593Smuzhiyun 
3232*4882a593Smuzhiyun 	rc = neigh_get_idx(seq, &idxpos);
3233*4882a593Smuzhiyun 	if (!rc && !(state->flags & NEIGH_SEQ_NEIGH_ONLY))
3234*4882a593Smuzhiyun 		rc = pneigh_get_idx(seq, &idxpos);
3235*4882a593Smuzhiyun 
3236*4882a593Smuzhiyun 	return rc;
3237*4882a593Smuzhiyun }
3238*4882a593Smuzhiyun 
neigh_seq_start(struct seq_file * seq,loff_t * pos,struct neigh_table * tbl,unsigned int neigh_seq_flags)3239*4882a593Smuzhiyun void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl, unsigned int neigh_seq_flags)
3240*4882a593Smuzhiyun 	__acquires(tbl->lock)
3241*4882a593Smuzhiyun 	__acquires(rcu_bh)
3242*4882a593Smuzhiyun {
3243*4882a593Smuzhiyun 	struct neigh_seq_state *state = seq->private;
3244*4882a593Smuzhiyun 
3245*4882a593Smuzhiyun 	state->tbl = tbl;
3246*4882a593Smuzhiyun 	state->bucket = 0;
3247*4882a593Smuzhiyun 	state->flags = (neigh_seq_flags & ~NEIGH_SEQ_IS_PNEIGH);
3248*4882a593Smuzhiyun 
3249*4882a593Smuzhiyun 	rcu_read_lock_bh();
3250*4882a593Smuzhiyun 	state->nht = rcu_dereference_bh(tbl->nht);
3251*4882a593Smuzhiyun 	read_lock(&tbl->lock);
3252*4882a593Smuzhiyun 
3253*4882a593Smuzhiyun 	return *pos ? neigh_get_idx_any(seq, pos) : SEQ_START_TOKEN;
3254*4882a593Smuzhiyun }
3255*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_seq_start);
3256*4882a593Smuzhiyun 
neigh_seq_next(struct seq_file * seq,void * v,loff_t * pos)3257*4882a593Smuzhiyun void *neigh_seq_next(struct seq_file *seq, void *v, loff_t *pos)
3258*4882a593Smuzhiyun {
3259*4882a593Smuzhiyun 	struct neigh_seq_state *state;
3260*4882a593Smuzhiyun 	void *rc;
3261*4882a593Smuzhiyun 
3262*4882a593Smuzhiyun 	if (v == SEQ_START_TOKEN) {
3263*4882a593Smuzhiyun 		rc = neigh_get_first(seq);
3264*4882a593Smuzhiyun 		goto out;
3265*4882a593Smuzhiyun 	}
3266*4882a593Smuzhiyun 
3267*4882a593Smuzhiyun 	state = seq->private;
3268*4882a593Smuzhiyun 	if (!(state->flags & NEIGH_SEQ_IS_PNEIGH)) {
3269*4882a593Smuzhiyun 		rc = neigh_get_next(seq, v, NULL);
3270*4882a593Smuzhiyun 		if (rc)
3271*4882a593Smuzhiyun 			goto out;
3272*4882a593Smuzhiyun 		if (!(state->flags & NEIGH_SEQ_NEIGH_ONLY))
3273*4882a593Smuzhiyun 			rc = pneigh_get_first(seq);
3274*4882a593Smuzhiyun 	} else {
3275*4882a593Smuzhiyun 		BUG_ON(state->flags & NEIGH_SEQ_NEIGH_ONLY);
3276*4882a593Smuzhiyun 		rc = pneigh_get_next(seq, v, NULL);
3277*4882a593Smuzhiyun 	}
3278*4882a593Smuzhiyun out:
3279*4882a593Smuzhiyun 	++(*pos);
3280*4882a593Smuzhiyun 	return rc;
3281*4882a593Smuzhiyun }
3282*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_seq_next);
3283*4882a593Smuzhiyun 
neigh_seq_stop(struct seq_file * seq,void * v)3284*4882a593Smuzhiyun void neigh_seq_stop(struct seq_file *seq, void *v)
3285*4882a593Smuzhiyun 	__releases(tbl->lock)
3286*4882a593Smuzhiyun 	__releases(rcu_bh)
3287*4882a593Smuzhiyun {
3288*4882a593Smuzhiyun 	struct neigh_seq_state *state = seq->private;
3289*4882a593Smuzhiyun 	struct neigh_table *tbl = state->tbl;
3290*4882a593Smuzhiyun 
3291*4882a593Smuzhiyun 	read_unlock(&tbl->lock);
3292*4882a593Smuzhiyun 	rcu_read_unlock_bh();
3293*4882a593Smuzhiyun }
3294*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_seq_stop);
3295*4882a593Smuzhiyun 
3296*4882a593Smuzhiyun /* statistics via seq_file */
3297*4882a593Smuzhiyun 
neigh_stat_seq_start(struct seq_file * seq,loff_t * pos)3298*4882a593Smuzhiyun static void *neigh_stat_seq_start(struct seq_file *seq, loff_t *pos)
3299*4882a593Smuzhiyun {
3300*4882a593Smuzhiyun 	struct neigh_table *tbl = PDE_DATA(file_inode(seq->file));
3301*4882a593Smuzhiyun 	int cpu;
3302*4882a593Smuzhiyun 
3303*4882a593Smuzhiyun 	if (*pos == 0)
3304*4882a593Smuzhiyun 		return SEQ_START_TOKEN;
3305*4882a593Smuzhiyun 
3306*4882a593Smuzhiyun 	for (cpu = *pos-1; cpu < nr_cpu_ids; ++cpu) {
3307*4882a593Smuzhiyun 		if (!cpu_possible(cpu))
3308*4882a593Smuzhiyun 			continue;
3309*4882a593Smuzhiyun 		*pos = cpu+1;
3310*4882a593Smuzhiyun 		return per_cpu_ptr(tbl->stats, cpu);
3311*4882a593Smuzhiyun 	}
3312*4882a593Smuzhiyun 	return NULL;
3313*4882a593Smuzhiyun }
3314*4882a593Smuzhiyun 
neigh_stat_seq_next(struct seq_file * seq,void * v,loff_t * pos)3315*4882a593Smuzhiyun static void *neigh_stat_seq_next(struct seq_file *seq, void *v, loff_t *pos)
3316*4882a593Smuzhiyun {
3317*4882a593Smuzhiyun 	struct neigh_table *tbl = PDE_DATA(file_inode(seq->file));
3318*4882a593Smuzhiyun 	int cpu;
3319*4882a593Smuzhiyun 
3320*4882a593Smuzhiyun 	for (cpu = *pos; cpu < nr_cpu_ids; ++cpu) {
3321*4882a593Smuzhiyun 		if (!cpu_possible(cpu))
3322*4882a593Smuzhiyun 			continue;
3323*4882a593Smuzhiyun 		*pos = cpu+1;
3324*4882a593Smuzhiyun 		return per_cpu_ptr(tbl->stats, cpu);
3325*4882a593Smuzhiyun 	}
3326*4882a593Smuzhiyun 	(*pos)++;
3327*4882a593Smuzhiyun 	return NULL;
3328*4882a593Smuzhiyun }
3329*4882a593Smuzhiyun 
neigh_stat_seq_stop(struct seq_file * seq,void * v)3330*4882a593Smuzhiyun static void neigh_stat_seq_stop(struct seq_file *seq, void *v)
3331*4882a593Smuzhiyun {
3332*4882a593Smuzhiyun 
3333*4882a593Smuzhiyun }
3334*4882a593Smuzhiyun 
neigh_stat_seq_show(struct seq_file * seq,void * v)3335*4882a593Smuzhiyun static int neigh_stat_seq_show(struct seq_file *seq, void *v)
3336*4882a593Smuzhiyun {
3337*4882a593Smuzhiyun 	struct neigh_table *tbl = PDE_DATA(file_inode(seq->file));
3338*4882a593Smuzhiyun 	struct neigh_statistics *st = v;
3339*4882a593Smuzhiyun 
3340*4882a593Smuzhiyun 	if (v == SEQ_START_TOKEN) {
3341*4882a593Smuzhiyun 		seq_printf(seq, "entries  allocs destroys hash_grows  lookups hits  res_failed  rcv_probes_mcast rcv_probes_ucast  periodic_gc_runs forced_gc_runs unresolved_discards table_fulls\n");
3342*4882a593Smuzhiyun 		return 0;
3343*4882a593Smuzhiyun 	}
3344*4882a593Smuzhiyun 
3345*4882a593Smuzhiyun 	seq_printf(seq, "%08x  %08lx %08lx %08lx  %08lx %08lx  %08lx  "
3346*4882a593Smuzhiyun 			"%08lx %08lx  %08lx %08lx %08lx %08lx\n",
3347*4882a593Smuzhiyun 		   atomic_read(&tbl->entries),
3348*4882a593Smuzhiyun 
3349*4882a593Smuzhiyun 		   st->allocs,
3350*4882a593Smuzhiyun 		   st->destroys,
3351*4882a593Smuzhiyun 		   st->hash_grows,
3352*4882a593Smuzhiyun 
3353*4882a593Smuzhiyun 		   st->lookups,
3354*4882a593Smuzhiyun 		   st->hits,
3355*4882a593Smuzhiyun 
3356*4882a593Smuzhiyun 		   st->res_failed,
3357*4882a593Smuzhiyun 
3358*4882a593Smuzhiyun 		   st->rcv_probes_mcast,
3359*4882a593Smuzhiyun 		   st->rcv_probes_ucast,
3360*4882a593Smuzhiyun 
3361*4882a593Smuzhiyun 		   st->periodic_gc_runs,
3362*4882a593Smuzhiyun 		   st->forced_gc_runs,
3363*4882a593Smuzhiyun 		   st->unres_discards,
3364*4882a593Smuzhiyun 		   st->table_fulls
3365*4882a593Smuzhiyun 		   );
3366*4882a593Smuzhiyun 
3367*4882a593Smuzhiyun 	return 0;
3368*4882a593Smuzhiyun }
3369*4882a593Smuzhiyun 
3370*4882a593Smuzhiyun static const struct seq_operations neigh_stat_seq_ops = {
3371*4882a593Smuzhiyun 	.start	= neigh_stat_seq_start,
3372*4882a593Smuzhiyun 	.next	= neigh_stat_seq_next,
3373*4882a593Smuzhiyun 	.stop	= neigh_stat_seq_stop,
3374*4882a593Smuzhiyun 	.show	= neigh_stat_seq_show,
3375*4882a593Smuzhiyun };
3376*4882a593Smuzhiyun #endif /* CONFIG_PROC_FS */
3377*4882a593Smuzhiyun 
__neigh_notify(struct neighbour * n,int type,int flags,u32 pid)3378*4882a593Smuzhiyun static void __neigh_notify(struct neighbour *n, int type, int flags,
3379*4882a593Smuzhiyun 			   u32 pid)
3380*4882a593Smuzhiyun {
3381*4882a593Smuzhiyun 	struct net *net = dev_net(n->dev);
3382*4882a593Smuzhiyun 	struct sk_buff *skb;
3383*4882a593Smuzhiyun 	int err = -ENOBUFS;
3384*4882a593Smuzhiyun 
3385*4882a593Smuzhiyun 	skb = nlmsg_new(neigh_nlmsg_size(), GFP_ATOMIC);
3386*4882a593Smuzhiyun 	if (skb == NULL)
3387*4882a593Smuzhiyun 		goto errout;
3388*4882a593Smuzhiyun 
3389*4882a593Smuzhiyun 	err = neigh_fill_info(skb, n, pid, 0, type, flags);
3390*4882a593Smuzhiyun 	if (err < 0) {
3391*4882a593Smuzhiyun 		/* -EMSGSIZE implies BUG in neigh_nlmsg_size() */
3392*4882a593Smuzhiyun 		WARN_ON(err == -EMSGSIZE);
3393*4882a593Smuzhiyun 		kfree_skb(skb);
3394*4882a593Smuzhiyun 		goto errout;
3395*4882a593Smuzhiyun 	}
3396*4882a593Smuzhiyun 	rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
3397*4882a593Smuzhiyun 	return;
3398*4882a593Smuzhiyun errout:
3399*4882a593Smuzhiyun 	if (err < 0)
3400*4882a593Smuzhiyun 		rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
3401*4882a593Smuzhiyun }
3402*4882a593Smuzhiyun 
neigh_app_ns(struct neighbour * n)3403*4882a593Smuzhiyun void neigh_app_ns(struct neighbour *n)
3404*4882a593Smuzhiyun {
3405*4882a593Smuzhiyun 	__neigh_notify(n, RTM_GETNEIGH, NLM_F_REQUEST, 0);
3406*4882a593Smuzhiyun }
3407*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_app_ns);
3408*4882a593Smuzhiyun 
3409*4882a593Smuzhiyun #ifdef CONFIG_SYSCTL
3410*4882a593Smuzhiyun static int unres_qlen_max = INT_MAX / SKB_TRUESIZE(ETH_FRAME_LEN);
3411*4882a593Smuzhiyun 
proc_unres_qlen(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)3412*4882a593Smuzhiyun static int proc_unres_qlen(struct ctl_table *ctl, int write,
3413*4882a593Smuzhiyun 			   void *buffer, size_t *lenp, loff_t *ppos)
3414*4882a593Smuzhiyun {
3415*4882a593Smuzhiyun 	int size, ret;
3416*4882a593Smuzhiyun 	struct ctl_table tmp = *ctl;
3417*4882a593Smuzhiyun 
3418*4882a593Smuzhiyun 	tmp.extra1 = SYSCTL_ZERO;
3419*4882a593Smuzhiyun 	tmp.extra2 = &unres_qlen_max;
3420*4882a593Smuzhiyun 	tmp.data = &size;
3421*4882a593Smuzhiyun 
3422*4882a593Smuzhiyun 	size = *(int *)ctl->data / SKB_TRUESIZE(ETH_FRAME_LEN);
3423*4882a593Smuzhiyun 	ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
3424*4882a593Smuzhiyun 
3425*4882a593Smuzhiyun 	if (write && !ret)
3426*4882a593Smuzhiyun 		*(int *)ctl->data = size * SKB_TRUESIZE(ETH_FRAME_LEN);
3427*4882a593Smuzhiyun 	return ret;
3428*4882a593Smuzhiyun }
3429*4882a593Smuzhiyun 
neigh_get_dev_parms_rcu(struct net_device * dev,int family)3430*4882a593Smuzhiyun static struct neigh_parms *neigh_get_dev_parms_rcu(struct net_device *dev,
3431*4882a593Smuzhiyun 						   int family)
3432*4882a593Smuzhiyun {
3433*4882a593Smuzhiyun 	switch (family) {
3434*4882a593Smuzhiyun 	case AF_INET:
3435*4882a593Smuzhiyun 		return __in_dev_arp_parms_get_rcu(dev);
3436*4882a593Smuzhiyun 	case AF_INET6:
3437*4882a593Smuzhiyun 		return __in6_dev_nd_parms_get_rcu(dev);
3438*4882a593Smuzhiyun 	}
3439*4882a593Smuzhiyun 	return NULL;
3440*4882a593Smuzhiyun }
3441*4882a593Smuzhiyun 
neigh_copy_dflt_parms(struct net * net,struct neigh_parms * p,int index)3442*4882a593Smuzhiyun static void neigh_copy_dflt_parms(struct net *net, struct neigh_parms *p,
3443*4882a593Smuzhiyun 				  int index)
3444*4882a593Smuzhiyun {
3445*4882a593Smuzhiyun 	struct net_device *dev;
3446*4882a593Smuzhiyun 	int family = neigh_parms_family(p);
3447*4882a593Smuzhiyun 
3448*4882a593Smuzhiyun 	rcu_read_lock();
3449*4882a593Smuzhiyun 	for_each_netdev_rcu(net, dev) {
3450*4882a593Smuzhiyun 		struct neigh_parms *dst_p =
3451*4882a593Smuzhiyun 				neigh_get_dev_parms_rcu(dev, family);
3452*4882a593Smuzhiyun 
3453*4882a593Smuzhiyun 		if (dst_p && !test_bit(index, dst_p->data_state))
3454*4882a593Smuzhiyun 			dst_p->data[index] = p->data[index];
3455*4882a593Smuzhiyun 	}
3456*4882a593Smuzhiyun 	rcu_read_unlock();
3457*4882a593Smuzhiyun }
3458*4882a593Smuzhiyun 
neigh_proc_update(struct ctl_table * ctl,int write)3459*4882a593Smuzhiyun static void neigh_proc_update(struct ctl_table *ctl, int write)
3460*4882a593Smuzhiyun {
3461*4882a593Smuzhiyun 	struct net_device *dev = ctl->extra1;
3462*4882a593Smuzhiyun 	struct neigh_parms *p = ctl->extra2;
3463*4882a593Smuzhiyun 	struct net *net = neigh_parms_net(p);
3464*4882a593Smuzhiyun 	int index = (int *) ctl->data - p->data;
3465*4882a593Smuzhiyun 
3466*4882a593Smuzhiyun 	if (!write)
3467*4882a593Smuzhiyun 		return;
3468*4882a593Smuzhiyun 
3469*4882a593Smuzhiyun 	set_bit(index, p->data_state);
3470*4882a593Smuzhiyun 	if (index == NEIGH_VAR_DELAY_PROBE_TIME)
3471*4882a593Smuzhiyun 		call_netevent_notifiers(NETEVENT_DELAY_PROBE_TIME_UPDATE, p);
3472*4882a593Smuzhiyun 	if (!dev) /* NULL dev means this is default value */
3473*4882a593Smuzhiyun 		neigh_copy_dflt_parms(net, p, index);
3474*4882a593Smuzhiyun }
3475*4882a593Smuzhiyun 
neigh_proc_dointvec_zero_intmax(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)3476*4882a593Smuzhiyun static int neigh_proc_dointvec_zero_intmax(struct ctl_table *ctl, int write,
3477*4882a593Smuzhiyun 					   void *buffer, size_t *lenp,
3478*4882a593Smuzhiyun 					   loff_t *ppos)
3479*4882a593Smuzhiyun {
3480*4882a593Smuzhiyun 	struct ctl_table tmp = *ctl;
3481*4882a593Smuzhiyun 	int ret;
3482*4882a593Smuzhiyun 
3483*4882a593Smuzhiyun 	tmp.extra1 = SYSCTL_ZERO;
3484*4882a593Smuzhiyun 	tmp.extra2 = SYSCTL_INT_MAX;
3485*4882a593Smuzhiyun 
3486*4882a593Smuzhiyun 	ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
3487*4882a593Smuzhiyun 	neigh_proc_update(ctl, write);
3488*4882a593Smuzhiyun 	return ret;
3489*4882a593Smuzhiyun }
3490*4882a593Smuzhiyun 
neigh_proc_dointvec(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)3491*4882a593Smuzhiyun int neigh_proc_dointvec(struct ctl_table *ctl, int write, void *buffer,
3492*4882a593Smuzhiyun 			size_t *lenp, loff_t *ppos)
3493*4882a593Smuzhiyun {
3494*4882a593Smuzhiyun 	int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
3495*4882a593Smuzhiyun 
3496*4882a593Smuzhiyun 	neigh_proc_update(ctl, write);
3497*4882a593Smuzhiyun 	return ret;
3498*4882a593Smuzhiyun }
3499*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_proc_dointvec);
3500*4882a593Smuzhiyun 
neigh_proc_dointvec_jiffies(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)3501*4882a593Smuzhiyun int neigh_proc_dointvec_jiffies(struct ctl_table *ctl, int write, void *buffer,
3502*4882a593Smuzhiyun 				size_t *lenp, loff_t *ppos)
3503*4882a593Smuzhiyun {
3504*4882a593Smuzhiyun 	int ret = proc_dointvec_jiffies(ctl, write, buffer, lenp, ppos);
3505*4882a593Smuzhiyun 
3506*4882a593Smuzhiyun 	neigh_proc_update(ctl, write);
3507*4882a593Smuzhiyun 	return ret;
3508*4882a593Smuzhiyun }
3509*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_proc_dointvec_jiffies);
3510*4882a593Smuzhiyun 
neigh_proc_dointvec_userhz_jiffies(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)3511*4882a593Smuzhiyun static int neigh_proc_dointvec_userhz_jiffies(struct ctl_table *ctl, int write,
3512*4882a593Smuzhiyun 					      void *buffer, size_t *lenp,
3513*4882a593Smuzhiyun 					      loff_t *ppos)
3514*4882a593Smuzhiyun {
3515*4882a593Smuzhiyun 	int ret = proc_dointvec_userhz_jiffies(ctl, write, buffer, lenp, ppos);
3516*4882a593Smuzhiyun 
3517*4882a593Smuzhiyun 	neigh_proc_update(ctl, write);
3518*4882a593Smuzhiyun 	return ret;
3519*4882a593Smuzhiyun }
3520*4882a593Smuzhiyun 
neigh_proc_dointvec_ms_jiffies(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)3521*4882a593Smuzhiyun int neigh_proc_dointvec_ms_jiffies(struct ctl_table *ctl, int write,
3522*4882a593Smuzhiyun 				   void *buffer, size_t *lenp, loff_t *ppos)
3523*4882a593Smuzhiyun {
3524*4882a593Smuzhiyun 	int ret = proc_dointvec_ms_jiffies(ctl, write, buffer, lenp, ppos);
3525*4882a593Smuzhiyun 
3526*4882a593Smuzhiyun 	neigh_proc_update(ctl, write);
3527*4882a593Smuzhiyun 	return ret;
3528*4882a593Smuzhiyun }
3529*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_proc_dointvec_ms_jiffies);
3530*4882a593Smuzhiyun 
neigh_proc_dointvec_unres_qlen(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)3531*4882a593Smuzhiyun static int neigh_proc_dointvec_unres_qlen(struct ctl_table *ctl, int write,
3532*4882a593Smuzhiyun 					  void *buffer, size_t *lenp,
3533*4882a593Smuzhiyun 					  loff_t *ppos)
3534*4882a593Smuzhiyun {
3535*4882a593Smuzhiyun 	int ret = proc_unres_qlen(ctl, write, buffer, lenp, ppos);
3536*4882a593Smuzhiyun 
3537*4882a593Smuzhiyun 	neigh_proc_update(ctl, write);
3538*4882a593Smuzhiyun 	return ret;
3539*4882a593Smuzhiyun }
3540*4882a593Smuzhiyun 
neigh_proc_base_reachable_time(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)3541*4882a593Smuzhiyun static int neigh_proc_base_reachable_time(struct ctl_table *ctl, int write,
3542*4882a593Smuzhiyun 					  void *buffer, size_t *lenp,
3543*4882a593Smuzhiyun 					  loff_t *ppos)
3544*4882a593Smuzhiyun {
3545*4882a593Smuzhiyun 	struct neigh_parms *p = ctl->extra2;
3546*4882a593Smuzhiyun 	int ret;
3547*4882a593Smuzhiyun 
3548*4882a593Smuzhiyun 	if (strcmp(ctl->procname, "base_reachable_time") == 0)
3549*4882a593Smuzhiyun 		ret = neigh_proc_dointvec_jiffies(ctl, write, buffer, lenp, ppos);
3550*4882a593Smuzhiyun 	else if (strcmp(ctl->procname, "base_reachable_time_ms") == 0)
3551*4882a593Smuzhiyun 		ret = neigh_proc_dointvec_ms_jiffies(ctl, write, buffer, lenp, ppos);
3552*4882a593Smuzhiyun 	else
3553*4882a593Smuzhiyun 		ret = -1;
3554*4882a593Smuzhiyun 
3555*4882a593Smuzhiyun 	if (write && ret == 0) {
3556*4882a593Smuzhiyun 		/* update reachable_time as well, otherwise, the change will
3557*4882a593Smuzhiyun 		 * only be effective after the next time neigh_periodic_work
3558*4882a593Smuzhiyun 		 * decides to recompute it
3559*4882a593Smuzhiyun 		 */
3560*4882a593Smuzhiyun 		p->reachable_time =
3561*4882a593Smuzhiyun 			neigh_rand_reach_time(NEIGH_VAR(p, BASE_REACHABLE_TIME));
3562*4882a593Smuzhiyun 	}
3563*4882a593Smuzhiyun 	return ret;
3564*4882a593Smuzhiyun }
3565*4882a593Smuzhiyun 
3566*4882a593Smuzhiyun #define NEIGH_PARMS_DATA_OFFSET(index)	\
3567*4882a593Smuzhiyun 	(&((struct neigh_parms *) 0)->data[index])
3568*4882a593Smuzhiyun 
3569*4882a593Smuzhiyun #define NEIGH_SYSCTL_ENTRY(attr, data_attr, name, mval, proc) \
3570*4882a593Smuzhiyun 	[NEIGH_VAR_ ## attr] = { \
3571*4882a593Smuzhiyun 		.procname	= name, \
3572*4882a593Smuzhiyun 		.data		= NEIGH_PARMS_DATA_OFFSET(NEIGH_VAR_ ## data_attr), \
3573*4882a593Smuzhiyun 		.maxlen		= sizeof(int), \
3574*4882a593Smuzhiyun 		.mode		= mval, \
3575*4882a593Smuzhiyun 		.proc_handler	= proc, \
3576*4882a593Smuzhiyun 	}
3577*4882a593Smuzhiyun 
3578*4882a593Smuzhiyun #define NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(attr, name) \
3579*4882a593Smuzhiyun 	NEIGH_SYSCTL_ENTRY(attr, attr, name, 0644, neigh_proc_dointvec_zero_intmax)
3580*4882a593Smuzhiyun 
3581*4882a593Smuzhiyun #define NEIGH_SYSCTL_JIFFIES_ENTRY(attr, name) \
3582*4882a593Smuzhiyun 	NEIGH_SYSCTL_ENTRY(attr, attr, name, 0644, neigh_proc_dointvec_jiffies)
3583*4882a593Smuzhiyun 
3584*4882a593Smuzhiyun #define NEIGH_SYSCTL_USERHZ_JIFFIES_ENTRY(attr, name) \
3585*4882a593Smuzhiyun 	NEIGH_SYSCTL_ENTRY(attr, attr, name, 0644, neigh_proc_dointvec_userhz_jiffies)
3586*4882a593Smuzhiyun 
3587*4882a593Smuzhiyun #define NEIGH_SYSCTL_MS_JIFFIES_REUSED_ENTRY(attr, data_attr, name) \
3588*4882a593Smuzhiyun 	NEIGH_SYSCTL_ENTRY(attr, data_attr, name, 0644, neigh_proc_dointvec_ms_jiffies)
3589*4882a593Smuzhiyun 
3590*4882a593Smuzhiyun #define NEIGH_SYSCTL_UNRES_QLEN_REUSED_ENTRY(attr, data_attr, name) \
3591*4882a593Smuzhiyun 	NEIGH_SYSCTL_ENTRY(attr, data_attr, name, 0644, neigh_proc_dointvec_unres_qlen)
3592*4882a593Smuzhiyun 
3593*4882a593Smuzhiyun static struct neigh_sysctl_table {
3594*4882a593Smuzhiyun 	struct ctl_table_header *sysctl_header;
3595*4882a593Smuzhiyun 	struct ctl_table neigh_vars[NEIGH_VAR_MAX + 1];
3596*4882a593Smuzhiyun } neigh_sysctl_template __read_mostly = {
3597*4882a593Smuzhiyun 	.neigh_vars = {
3598*4882a593Smuzhiyun 		NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(MCAST_PROBES, "mcast_solicit"),
3599*4882a593Smuzhiyun 		NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(UCAST_PROBES, "ucast_solicit"),
3600*4882a593Smuzhiyun 		NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(APP_PROBES, "app_solicit"),
3601*4882a593Smuzhiyun 		NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(MCAST_REPROBES, "mcast_resolicit"),
3602*4882a593Smuzhiyun 		NEIGH_SYSCTL_USERHZ_JIFFIES_ENTRY(RETRANS_TIME, "retrans_time"),
3603*4882a593Smuzhiyun 		NEIGH_SYSCTL_JIFFIES_ENTRY(BASE_REACHABLE_TIME, "base_reachable_time"),
3604*4882a593Smuzhiyun 		NEIGH_SYSCTL_JIFFIES_ENTRY(DELAY_PROBE_TIME, "delay_first_probe_time"),
3605*4882a593Smuzhiyun 		NEIGH_SYSCTL_JIFFIES_ENTRY(GC_STALETIME, "gc_stale_time"),
3606*4882a593Smuzhiyun 		NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(QUEUE_LEN_BYTES, "unres_qlen_bytes"),
3607*4882a593Smuzhiyun 		NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(PROXY_QLEN, "proxy_qlen"),
3608*4882a593Smuzhiyun 		NEIGH_SYSCTL_USERHZ_JIFFIES_ENTRY(ANYCAST_DELAY, "anycast_delay"),
3609*4882a593Smuzhiyun 		NEIGH_SYSCTL_USERHZ_JIFFIES_ENTRY(PROXY_DELAY, "proxy_delay"),
3610*4882a593Smuzhiyun 		NEIGH_SYSCTL_USERHZ_JIFFIES_ENTRY(LOCKTIME, "locktime"),
3611*4882a593Smuzhiyun 		NEIGH_SYSCTL_UNRES_QLEN_REUSED_ENTRY(QUEUE_LEN, QUEUE_LEN_BYTES, "unres_qlen"),
3612*4882a593Smuzhiyun 		NEIGH_SYSCTL_MS_JIFFIES_REUSED_ENTRY(RETRANS_TIME_MS, RETRANS_TIME, "retrans_time_ms"),
3613*4882a593Smuzhiyun 		NEIGH_SYSCTL_MS_JIFFIES_REUSED_ENTRY(BASE_REACHABLE_TIME_MS, BASE_REACHABLE_TIME, "base_reachable_time_ms"),
3614*4882a593Smuzhiyun 		[NEIGH_VAR_GC_INTERVAL] = {
3615*4882a593Smuzhiyun 			.procname	= "gc_interval",
3616*4882a593Smuzhiyun 			.maxlen		= sizeof(int),
3617*4882a593Smuzhiyun 			.mode		= 0644,
3618*4882a593Smuzhiyun 			.proc_handler	= proc_dointvec_jiffies,
3619*4882a593Smuzhiyun 		},
3620*4882a593Smuzhiyun 		[NEIGH_VAR_GC_THRESH1] = {
3621*4882a593Smuzhiyun 			.procname	= "gc_thresh1",
3622*4882a593Smuzhiyun 			.maxlen		= sizeof(int),
3623*4882a593Smuzhiyun 			.mode		= 0644,
3624*4882a593Smuzhiyun 			.extra1		= SYSCTL_ZERO,
3625*4882a593Smuzhiyun 			.extra2		= SYSCTL_INT_MAX,
3626*4882a593Smuzhiyun 			.proc_handler	= proc_dointvec_minmax,
3627*4882a593Smuzhiyun 		},
3628*4882a593Smuzhiyun 		[NEIGH_VAR_GC_THRESH2] = {
3629*4882a593Smuzhiyun 			.procname	= "gc_thresh2",
3630*4882a593Smuzhiyun 			.maxlen		= sizeof(int),
3631*4882a593Smuzhiyun 			.mode		= 0644,
3632*4882a593Smuzhiyun 			.extra1		= SYSCTL_ZERO,
3633*4882a593Smuzhiyun 			.extra2		= SYSCTL_INT_MAX,
3634*4882a593Smuzhiyun 			.proc_handler	= proc_dointvec_minmax,
3635*4882a593Smuzhiyun 		},
3636*4882a593Smuzhiyun 		[NEIGH_VAR_GC_THRESH3] = {
3637*4882a593Smuzhiyun 			.procname	= "gc_thresh3",
3638*4882a593Smuzhiyun 			.maxlen		= sizeof(int),
3639*4882a593Smuzhiyun 			.mode		= 0644,
3640*4882a593Smuzhiyun 			.extra1		= SYSCTL_ZERO,
3641*4882a593Smuzhiyun 			.extra2		= SYSCTL_INT_MAX,
3642*4882a593Smuzhiyun 			.proc_handler	= proc_dointvec_minmax,
3643*4882a593Smuzhiyun 		},
3644*4882a593Smuzhiyun 		{},
3645*4882a593Smuzhiyun 	},
3646*4882a593Smuzhiyun };
3647*4882a593Smuzhiyun 
neigh_sysctl_register(struct net_device * dev,struct neigh_parms * p,proc_handler * handler)3648*4882a593Smuzhiyun int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
3649*4882a593Smuzhiyun 			  proc_handler *handler)
3650*4882a593Smuzhiyun {
3651*4882a593Smuzhiyun 	int i;
3652*4882a593Smuzhiyun 	struct neigh_sysctl_table *t;
3653*4882a593Smuzhiyun 	const char *dev_name_source;
3654*4882a593Smuzhiyun 	char neigh_path[ sizeof("net//neigh/") + IFNAMSIZ + IFNAMSIZ ];
3655*4882a593Smuzhiyun 	char *p_name;
3656*4882a593Smuzhiyun 
3657*4882a593Smuzhiyun 	t = kmemdup(&neigh_sysctl_template, sizeof(*t), GFP_KERNEL);
3658*4882a593Smuzhiyun 	if (!t)
3659*4882a593Smuzhiyun 		goto err;
3660*4882a593Smuzhiyun 
3661*4882a593Smuzhiyun 	for (i = 0; i < NEIGH_VAR_GC_INTERVAL; i++) {
3662*4882a593Smuzhiyun 		t->neigh_vars[i].data += (long) p;
3663*4882a593Smuzhiyun 		t->neigh_vars[i].extra1 = dev;
3664*4882a593Smuzhiyun 		t->neigh_vars[i].extra2 = p;
3665*4882a593Smuzhiyun 	}
3666*4882a593Smuzhiyun 
3667*4882a593Smuzhiyun 	if (dev) {
3668*4882a593Smuzhiyun 		dev_name_source = dev->name;
3669*4882a593Smuzhiyun 		/* Terminate the table early */
3670*4882a593Smuzhiyun 		memset(&t->neigh_vars[NEIGH_VAR_GC_INTERVAL], 0,
3671*4882a593Smuzhiyun 		       sizeof(t->neigh_vars[NEIGH_VAR_GC_INTERVAL]));
3672*4882a593Smuzhiyun 	} else {
3673*4882a593Smuzhiyun 		struct neigh_table *tbl = p->tbl;
3674*4882a593Smuzhiyun 		dev_name_source = "default";
3675*4882a593Smuzhiyun 		t->neigh_vars[NEIGH_VAR_GC_INTERVAL].data = &tbl->gc_interval;
3676*4882a593Smuzhiyun 		t->neigh_vars[NEIGH_VAR_GC_THRESH1].data = &tbl->gc_thresh1;
3677*4882a593Smuzhiyun 		t->neigh_vars[NEIGH_VAR_GC_THRESH2].data = &tbl->gc_thresh2;
3678*4882a593Smuzhiyun 		t->neigh_vars[NEIGH_VAR_GC_THRESH3].data = &tbl->gc_thresh3;
3679*4882a593Smuzhiyun 	}
3680*4882a593Smuzhiyun 
3681*4882a593Smuzhiyun 	if (handler) {
3682*4882a593Smuzhiyun 		/* RetransTime */
3683*4882a593Smuzhiyun 		t->neigh_vars[NEIGH_VAR_RETRANS_TIME].proc_handler = handler;
3684*4882a593Smuzhiyun 		/* ReachableTime */
3685*4882a593Smuzhiyun 		t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME].proc_handler = handler;
3686*4882a593Smuzhiyun 		/* RetransTime (in milliseconds)*/
3687*4882a593Smuzhiyun 		t->neigh_vars[NEIGH_VAR_RETRANS_TIME_MS].proc_handler = handler;
3688*4882a593Smuzhiyun 		/* ReachableTime (in milliseconds) */
3689*4882a593Smuzhiyun 		t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].proc_handler = handler;
3690*4882a593Smuzhiyun 	} else {
3691*4882a593Smuzhiyun 		/* Those handlers will update p->reachable_time after
3692*4882a593Smuzhiyun 		 * base_reachable_time(_ms) is set to ensure the new timer starts being
3693*4882a593Smuzhiyun 		 * applied after the next neighbour update instead of waiting for
3694*4882a593Smuzhiyun 		 * neigh_periodic_work to update its value (can be multiple minutes)
3695*4882a593Smuzhiyun 		 * So any handler that replaces them should do this as well
3696*4882a593Smuzhiyun 		 */
3697*4882a593Smuzhiyun 		/* ReachableTime */
3698*4882a593Smuzhiyun 		t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME].proc_handler =
3699*4882a593Smuzhiyun 			neigh_proc_base_reachable_time;
3700*4882a593Smuzhiyun 		/* ReachableTime (in milliseconds) */
3701*4882a593Smuzhiyun 		t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].proc_handler =
3702*4882a593Smuzhiyun 			neigh_proc_base_reachable_time;
3703*4882a593Smuzhiyun 	}
3704*4882a593Smuzhiyun 
3705*4882a593Smuzhiyun 	/* Don't export sysctls to unprivileged users */
3706*4882a593Smuzhiyun 	if (neigh_parms_net(p)->user_ns != &init_user_ns)
3707*4882a593Smuzhiyun 		t->neigh_vars[0].procname = NULL;
3708*4882a593Smuzhiyun 
3709*4882a593Smuzhiyun 	switch (neigh_parms_family(p)) {
3710*4882a593Smuzhiyun 	case AF_INET:
3711*4882a593Smuzhiyun 	      p_name = "ipv4";
3712*4882a593Smuzhiyun 	      break;
3713*4882a593Smuzhiyun 	case AF_INET6:
3714*4882a593Smuzhiyun 	      p_name = "ipv6";
3715*4882a593Smuzhiyun 	      break;
3716*4882a593Smuzhiyun 	default:
3717*4882a593Smuzhiyun 	      BUG();
3718*4882a593Smuzhiyun 	}
3719*4882a593Smuzhiyun 
3720*4882a593Smuzhiyun 	snprintf(neigh_path, sizeof(neigh_path), "net/%s/neigh/%s",
3721*4882a593Smuzhiyun 		p_name, dev_name_source);
3722*4882a593Smuzhiyun 	t->sysctl_header =
3723*4882a593Smuzhiyun 		register_net_sysctl(neigh_parms_net(p), neigh_path, t->neigh_vars);
3724*4882a593Smuzhiyun 	if (!t->sysctl_header)
3725*4882a593Smuzhiyun 		goto free;
3726*4882a593Smuzhiyun 
3727*4882a593Smuzhiyun 	p->sysctl_table = t;
3728*4882a593Smuzhiyun 	return 0;
3729*4882a593Smuzhiyun 
3730*4882a593Smuzhiyun free:
3731*4882a593Smuzhiyun 	kfree(t);
3732*4882a593Smuzhiyun err:
3733*4882a593Smuzhiyun 	return -ENOBUFS;
3734*4882a593Smuzhiyun }
3735*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_sysctl_register);
3736*4882a593Smuzhiyun 
neigh_sysctl_unregister(struct neigh_parms * p)3737*4882a593Smuzhiyun void neigh_sysctl_unregister(struct neigh_parms *p)
3738*4882a593Smuzhiyun {
3739*4882a593Smuzhiyun 	if (p->sysctl_table) {
3740*4882a593Smuzhiyun 		struct neigh_sysctl_table *t = p->sysctl_table;
3741*4882a593Smuzhiyun 		p->sysctl_table = NULL;
3742*4882a593Smuzhiyun 		unregister_net_sysctl_table(t->sysctl_header);
3743*4882a593Smuzhiyun 		kfree(t);
3744*4882a593Smuzhiyun 	}
3745*4882a593Smuzhiyun }
3746*4882a593Smuzhiyun EXPORT_SYMBOL(neigh_sysctl_unregister);
3747*4882a593Smuzhiyun 
3748*4882a593Smuzhiyun #endif	/* CONFIG_SYSCTL */
3749*4882a593Smuzhiyun 
neigh_init(void)3750*4882a593Smuzhiyun static int __init neigh_init(void)
3751*4882a593Smuzhiyun {
3752*4882a593Smuzhiyun 	rtnl_register(PF_UNSPEC, RTM_NEWNEIGH, neigh_add, NULL, 0);
3753*4882a593Smuzhiyun 	rtnl_register(PF_UNSPEC, RTM_DELNEIGH, neigh_delete, NULL, 0);
3754*4882a593Smuzhiyun 	rtnl_register(PF_UNSPEC, RTM_GETNEIGH, neigh_get, neigh_dump_info, 0);
3755*4882a593Smuzhiyun 
3756*4882a593Smuzhiyun 	rtnl_register(PF_UNSPEC, RTM_GETNEIGHTBL, NULL, neightbl_dump_info,
3757*4882a593Smuzhiyun 		      0);
3758*4882a593Smuzhiyun 	rtnl_register(PF_UNSPEC, RTM_SETNEIGHTBL, neightbl_set, NULL, 0);
3759*4882a593Smuzhiyun 
3760*4882a593Smuzhiyun 	return 0;
3761*4882a593Smuzhiyun }
3762*4882a593Smuzhiyun 
3763*4882a593Smuzhiyun subsys_initcall(neigh_init);
3764