Blame view

net/bridge/br_fdb.c 20.9 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
  /*
   *	Forwarding database
   *	Linux ethernet bridge
   *
   *	Authors:
   *	Lennert Buytenhek		<buytenh@gnu.org>
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
10
11
12
13
14
15
   *	This program is free software; you can redistribute it and/or
   *	modify it under the terms of the GNU General Public License
   *	as published by the Free Software Foundation; either version
   *	2 of the License, or (at your option) any later version.
   */
  
  #include <linux/kernel.h>
  #include <linux/init.h>
82524746c   Franck Bui-Huu   rcu: split list.h...
16
  #include <linux/rculist.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
18
19
20
21
  #include <linux/spinlock.h>
  #include <linux/times.h>
  #include <linux/netdevice.h>
  #include <linux/etherdevice.h>
  #include <linux/jhash.h>
3f8909231   Stephen Hemminger   bridge: simpler h...
22
  #include <linux/random.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
23
  #include <linux/slab.h>
60063497a   Arun Sharma   atomic: use <linu...
24
  #include <linux/atomic.h>
3f8909231   Stephen Hemminger   bridge: simpler h...
25
  #include <asm/unaligned.h>
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
26
  #include <linux/if_vlan.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
  #include "br_private.h"
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
28
  static struct kmem_cache *br_fdb_cache __read_mostly;
424bb9c97   Toshiaki Makita   bridge: Properly ...
29
30
31
  static struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head,
  					     const unsigned char *addr,
  					     __u16 vid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
  static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
bc9a25d21   Vlad Yasevich   bridge: Add vlan ...
33
  		      const unsigned char *addr, u16 vid);
31e8a49c1   stephen hemminger   bridge: rearrange...
34
35
  static void fdb_notify(struct net_bridge *br,
  		       const struct net_bridge_fdb_entry *, int);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36

3f8909231   Stephen Hemminger   bridge: simpler h...
37
  static u32 fdb_salt __read_mostly;
87a596e0b   Akinobu Mita   bridge: check kme...
38
  int __init br_fdb_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
40
41
42
  {
  	br_fdb_cache = kmem_cache_create("bridge_fdb_cache",
  					 sizeof(struct net_bridge_fdb_entry),
  					 0,
20c2df83d   Paul Mundt   mm: Remove slab d...
43
  					 SLAB_HWCACHE_ALIGN, NULL);
87a596e0b   Akinobu Mita   bridge: check kme...
44
45
  	if (!br_fdb_cache)
  		return -ENOMEM;
3f8909231   Stephen Hemminger   bridge: simpler h...
46
  	get_random_bytes(&fdb_salt, sizeof(fdb_salt));
87a596e0b   Akinobu Mita   bridge: check kme...
47
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
  }
73afc9069   Andrew Morton   [BRIDGE]: Section...
49
  void br_fdb_fini(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
52
53
54
55
56
57
  {
  	kmem_cache_destroy(br_fdb_cache);
  }
  
  
  /* if topology_changing then use forward_delay (default 15 sec)
   * otherwise keep longer (default 5 minutes)
   */
3f8909231   Stephen Hemminger   bridge: simpler h...
58
  static inline unsigned long hold_time(const struct net_bridge *br)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
61
  {
  	return br->topology_change ? br->forward_delay : br->ageing_time;
  }
3f8909231   Stephen Hemminger   bridge: simpler h...
62
  static inline int has_expired(const struct net_bridge *br,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
64
  				  const struct net_bridge_fdb_entry *fdb)
  {
f64f9e719   Joe Perches   net: Move && and ...
65
  	return !fdb->is_static &&
7cd8861ab   stephen hemminger   bridge: track las...
66
  		time_before_eq(fdb->updated + hold_time(br), jiffies);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
  }
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
68
  static inline int br_mac_hash(const unsigned char *mac, __u16 vid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
  {
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
70
  	/* use 1 byte of OUI and 3 bytes of NIC */
3f8909231   Stephen Hemminger   bridge: simpler h...
71
  	u32 key = get_unaligned((u32 *)(mac + 2));
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
72
  	return jhash_2words(key, vid, fdb_salt) & (BR_HASH_SIZE - 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
  }
da6782927   Michał Mirosław   bridge: Simplify ...
74
75
76
77
78
79
  static void fdb_rcu_free(struct rcu_head *head)
  {
  	struct net_bridge_fdb_entry *ent
  		= container_of(head, struct net_bridge_fdb_entry, rcu);
  	kmem_cache_free(br_fdb_cache, ent);
  }
31e8a49c1   stephen hemminger   bridge: rearrange...
80
  static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
82
  {
  	hlist_del_rcu(&f->hlist);
31e8a49c1   stephen hemminger   bridge: rearrange...
83
  	fdb_notify(br, f, RTM_DELNEIGH);
da6782927   Michał Mirosław   bridge: Simplify ...
84
  	call_rcu(&f->rcu, fdb_rcu_free);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
  }
960b589f8   Toshiaki Makita   bridge: Properly ...
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  /* Delete a local entry if no other port had the same address. */
  static void fdb_delete_local(struct net_bridge *br,
  			     const struct net_bridge_port *p,
  			     struct net_bridge_fdb_entry *f)
  {
  	const unsigned char *addr = f->addr.addr;
  	u16 vid = f->vlan_id;
  	struct net_bridge_port *op;
  
  	/* Maybe another port has same hw addr? */
  	list_for_each_entry(op, &br->port_list, list) {
  		if (op != p && ether_addr_equal(op->dev->dev_addr, addr) &&
  		    (!vid || nbp_vlan_find(op, vid))) {
  			f->dst = op;
a778e6d1a   Toshiaki Makita   bridge: Properly ...
100
  			f->added_by_user = 0;
960b589f8   Toshiaki Makita   bridge: Properly ...
101
102
103
104
105
106
107
108
  			return;
  		}
  	}
  
  	/* Maybe bridge device has same hw addr? */
  	if (p && ether_addr_equal(br->dev->dev_addr, addr) &&
  	    (!vid || br_vlan_find(br, vid))) {
  		f->dst = NULL;
a778e6d1a   Toshiaki Makita   bridge: Properly ...
109
  		f->added_by_user = 0;
960b589f8   Toshiaki Makita   bridge: Properly ...
110
111
112
113
114
  		return;
  	}
  
  	fdb_delete(br, f);
  }
424bb9c97   Toshiaki Makita   bridge: Properly ...
115
116
117
118
119
120
121
122
123
124
125
126
127
  void br_fdb_find_delete_local(struct net_bridge *br,
  			      const struct net_bridge_port *p,
  			      const unsigned char *addr, u16 vid)
  {
  	struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)];
  	struct net_bridge_fdb_entry *f;
  
  	spin_lock_bh(&br->hash_lock);
  	f = fdb_find(head, addr, vid);
  	if (f && f->is_local && !f->added_by_user && f->dst == p)
  		fdb_delete_local(br, p, f);
  	spin_unlock_bh(&br->hash_lock);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
130
  void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr)
  {
  	struct net_bridge *br = p->br;
2836882fe   Toshiaki Makita   bridge: Fix the w...
131
132
  	struct net_port_vlans *pv = nbp_get_vlan_info(p);
  	bool no_vlan = !pv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
  	int i;
2836882fe   Toshiaki Makita   bridge: Fix the w...
134
  	u16 vid;
9d6f229fc   YOSHIFUJI Hideaki   [NET] BRIDGE: Fix...
135

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
136
137
138
139
140
141
142
143
144
  	spin_lock_bh(&br->hash_lock);
  
  	/* Search all chains since old address/hash is unknown */
  	for (i = 0; i < BR_HASH_SIZE; i++) {
  		struct hlist_node *h;
  		hlist_for_each(h, &br->hash[i]) {
  			struct net_bridge_fdb_entry *f;
  
  			f = hlist_entry(h, struct net_bridge_fdb_entry, hlist);
a5642ab47   Toshiaki Makita   bridge: Fix the w...
145
  			if (f->dst == p && f->is_local && !f->added_by_user) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146
  				/* delete old one */
960b589f8   Toshiaki Makita   bridge: Properly ...
147
  				fdb_delete_local(br, p, f);
bc9a25d21   Vlad Yasevich   bridge: Add vlan ...
148
149
150
151
152
  				/* if this port has no vlan information
  				 * configured, we can safely be done at
  				 * this point.
  				 */
  				if (no_vlan)
2836882fe   Toshiaki Makita   bridge: Fix the w...
153
  					goto insert;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
155
156
  			}
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157

2836882fe   Toshiaki Makita   bridge: Fix the w...
158
159
160
161
162
163
164
165
166
167
168
169
170
  insert:
  	/* insert new address,  may fail if invalid address or dup. */
  	fdb_insert(br, p, newaddr, 0);
  
  	if (no_vlan)
  		goto done;
  
  	/* Now add entries for every VLAN configured on the port.
  	 * This function runs under RTNL so the bitmap will not change
  	 * from under us.
  	 */
  	for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID)
  		fdb_insert(br, p, newaddr, vid);
bc9a25d21   Vlad Yasevich   bridge: Add vlan ...
171
  done:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
173
  	spin_unlock_bh(&br->hash_lock);
  }
435988133   stephen hemminger   bridge: add local...
174
175
176
  void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr)
  {
  	struct net_bridge_fdb_entry *f;
bc9a25d21   Vlad Yasevich   bridge: Add vlan ...
177
178
  	struct net_port_vlans *pv;
  	u16 vid = 0;
435988133   stephen hemminger   bridge: add local...
179

ac4c88688   Toshiaki Makita   bridge: Prevent p...
180
  	spin_lock_bh(&br->hash_lock);
435988133   stephen hemminger   bridge: add local...
181
  	/* If old entry was unassociated with any port, then delete it. */
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
182
  	f = __br_fdb_get(br, br->dev->dev_addr, 0);
435988133   stephen hemminger   bridge: add local...
183
  	if (f && f->is_local && !f->dst)
960b589f8   Toshiaki Makita   bridge: Properly ...
184
  		fdb_delete_local(br, NULL, f);
435988133   stephen hemminger   bridge: add local...
185

bc9a25d21   Vlad Yasevich   bridge: Add vlan ...
186
187
188
189
190
191
192
193
  	fdb_insert(br, NULL, newaddr, 0);
  
  	/* Now remove and add entries for every VLAN configured on the
  	 * bridge.  This function runs under RTNL so the bitmap will not
  	 * change from under us.
  	 */
  	pv = br_get_vlan_info(br);
  	if (!pv)
ac4c88688   Toshiaki Makita   bridge: Prevent p...
194
  		goto out;
bc9a25d21   Vlad Yasevich   bridge: Add vlan ...
195

ef40b7ef1   Toshiaki Makita   bridge: Use the c...
196
  	for_each_set_bit_from(vid, pv->vlan_bitmap, VLAN_N_VID) {
bc9a25d21   Vlad Yasevich   bridge: Add vlan ...
197
198
  		f = __br_fdb_get(br, br->dev->dev_addr, vid);
  		if (f && f->is_local && !f->dst)
960b589f8   Toshiaki Makita   bridge: Properly ...
199
  			fdb_delete_local(br, NULL, f);
bc9a25d21   Vlad Yasevich   bridge: Add vlan ...
200
201
  		fdb_insert(br, NULL, newaddr, vid);
  	}
ac4c88688   Toshiaki Makita   bridge: Prevent p...
202
203
  out:
  	spin_unlock_bh(&br->hash_lock);
435988133   stephen hemminger   bridge: add local...
204
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
205
206
207
208
  void br_fdb_cleanup(unsigned long _data)
  {
  	struct net_bridge *br = (struct net_bridge *)_data;
  	unsigned long delay = hold_time(br);
25442e06d   stephen hemminger   bridge: fdb clean...
209
  	unsigned long next_timer = jiffies + br->ageing_time;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
  	int i;
27a429383   Eric Dumazet   bridge: BH alread...
211
  	spin_lock(&br->hash_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
212
213
  	for (i = 0; i < BR_HASH_SIZE; i++) {
  		struct net_bridge_fdb_entry *f;
b67bfe0d4   Sasha Levin   hlist: drop the n...
214
  		struct hlist_node *n;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
215

b67bfe0d4   Sasha Levin   hlist: drop the n...
216
  		hlist_for_each_entry_safe(f, n, &br->hash[i], hlist) {
071f77226   Baruch Even   [BRIDGE]: Reduce ...
217
218
219
  			unsigned long this_timer;
  			if (f->is_static)
  				continue;
7cd8861ab   stephen hemminger   bridge: track las...
220
  			this_timer = f->updated + delay;
071f77226   Baruch Even   [BRIDGE]: Reduce ...
221
  			if (time_before_eq(this_timer, jiffies))
31e8a49c1   stephen hemminger   bridge: rearrange...
222
  				fdb_delete(br, f);
2bec008ca   Fabio Checconi   bridge: use time_...
223
  			else if (time_before(this_timer, next_timer))
071f77226   Baruch Even   [BRIDGE]: Reduce ...
224
  				next_timer = this_timer;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225
226
  		}
  	}
27a429383   Eric Dumazet   bridge: BH alread...
227
  	spin_unlock(&br->hash_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228

25442e06d   stephen hemminger   bridge: fdb clean...
229
  	mod_timer(&br->gc_timer, round_jiffies_up(next_timer));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
  }
9cf637473   Stephen Hemminger   bridge: add sysfs...
231
232
233
234
235
236
237
238
  /* Completely flush all dynamic entries in forwarding database.*/
  void br_fdb_flush(struct net_bridge *br)
  {
  	int i;
  
  	spin_lock_bh(&br->hash_lock);
  	for (i = 0; i < BR_HASH_SIZE; i++) {
  		struct net_bridge_fdb_entry *f;
b67bfe0d4   Sasha Levin   hlist: drop the n...
239
240
  		struct hlist_node *n;
  		hlist_for_each_entry_safe(f, n, &br->hash[i], hlist) {
9cf637473   Stephen Hemminger   bridge: add sysfs...
241
  			if (!f->is_static)
31e8a49c1   stephen hemminger   bridge: rearrange...
242
  				fdb_delete(br, f);
9cf637473   Stephen Hemminger   bridge: add sysfs...
243
244
245
246
  		}
  	}
  	spin_unlock_bh(&br->hash_lock);
  }
1a620698c   Stephen Hemminger   [BRIDGE]: flush f...
247

25985edce   Lucas De Marchi   Fix common misspe...
248
  /* Flush all entries referring to a specific port.
9cf637473   Stephen Hemminger   bridge: add sysfs...
249
250
   * if do_all is set also flush static entries
   */
1a620698c   Stephen Hemminger   [BRIDGE]: flush f...
251
252
253
  void br_fdb_delete_by_port(struct net_bridge *br,
  			   const struct net_bridge_port *p,
  			   int do_all)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
254
255
256
257
258
259
  {
  	int i;
  
  	spin_lock_bh(&br->hash_lock);
  	for (i = 0; i < BR_HASH_SIZE; i++) {
  		struct hlist_node *h, *g;
9d6f229fc   YOSHIFUJI Hideaki   [NET] BRIDGE: Fix...
260

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
261
262
263
  		hlist_for_each_safe(h, g, &br->hash[i]) {
  			struct net_bridge_fdb_entry *f
  				= hlist_entry(h, struct net_bridge_fdb_entry, hlist);
9d6f229fc   YOSHIFUJI Hideaki   [NET] BRIDGE: Fix...
264
  			if (f->dst != p)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
  				continue;
1a620698c   Stephen Hemminger   [BRIDGE]: flush f...
266
267
  			if (f->is_static && !do_all)
  				continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
268

a778e6d1a   Toshiaki Makita   bridge: Properly ...
269
270
271
272
  			if (f->is_local)
  				fdb_delete_local(br, p, f);
  			else
  				fdb_delete(br, f);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
273
274
275
276
  		}
  	}
  	spin_unlock_bh(&br->hash_lock);
  }
eeaf61d88   stephen hemminger   bridge: add rcu_r...
277
  /* No locking or refcounting, assumes caller has rcu_read_lock */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
278
  struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br,
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
279
280
  					  const unsigned char *addr,
  					  __u16 vid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
281
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
  	struct net_bridge_fdb_entry *fdb;
b67bfe0d4   Sasha Levin   hlist: drop the n...
283
  	hlist_for_each_entry_rcu(fdb,
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
284
285
286
  				&br->hash[br_mac_hash(addr, vid)], hlist) {
  		if (ether_addr_equal(fdb->addr.addr, addr) &&
  		    fdb->vlan_id == vid) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
287
288
289
290
291
292
293
294
  			if (unlikely(has_expired(br, fdb)))
  				break;
  			return fdb;
  		}
  	}
  
  	return NULL;
  }
e6373c4c0   Igor Maravić   net:bridge: use I...
295
  #if IS_ENABLED(CONFIG_ATM_LANE)
da6782927   Michał Mirosław   bridge: Simplify ...
296
297
298
  /* Interface used by ATM LANE hook to test
   * if an addr is on some other bridge port */
  int br_fdb_test_addr(struct net_device *dev, unsigned char *addr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299
300
  {
  	struct net_bridge_fdb_entry *fdb;
b5ed54e94   stephen hemminger   bridge: fix RCU r...
301
  	struct net_bridge_port *port;
da6782927   Michał Mirosław   bridge: Simplify ...
302
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
  	rcu_read_lock();
b5ed54e94   stephen hemminger   bridge: fix RCU r...
304
305
306
307
  	port = br_port_get_rcu(dev);
  	if (!port)
  		ret = 0;
  	else {
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
308
  		fdb = __br_fdb_get(port->br, addr, 0);
435988133   stephen hemminger   bridge: add local...
309
  		ret = fdb && fdb->dst && fdb->dst->dev != dev &&
b5ed54e94   stephen hemminger   bridge: fix RCU r...
310
311
  			fdb->dst->state == BR_STATE_FORWARDING;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
312
  	rcu_read_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
313

da6782927   Michał Mirosław   bridge: Simplify ...
314
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
  }
da6782927   Michał Mirosław   bridge: Simplify ...
316
  #endif /* CONFIG_ATM_LANE */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317
318
  
  /*
9d6f229fc   YOSHIFUJI Hideaki   [NET] BRIDGE: Fix...
319
   * Fill buffer with forwarding table records in
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
321
322
323
324
325
326
   * the API format.
   */
  int br_fdb_fillbuf(struct net_bridge *br, void *buf,
  		   unsigned long maxnum, unsigned long skip)
  {
  	struct __fdb_entry *fe = buf;
  	int i, num = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
328
329
330
331
332
  	struct net_bridge_fdb_entry *f;
  
  	memset(buf, 0, maxnum*sizeof(struct __fdb_entry));
  
  	rcu_read_lock();
  	for (i = 0; i < BR_HASH_SIZE; i++) {
b67bfe0d4   Sasha Levin   hlist: drop the n...
333
  		hlist_for_each_entry_rcu(f, &br->hash[i], hlist) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334
335
  			if (num >= maxnum)
  				goto out;
9d6f229fc   YOSHIFUJI Hideaki   [NET] BRIDGE: Fix...
336
  			if (has_expired(br, f))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
337
  				continue;
435988133   stephen hemminger   bridge: add local...
338
339
340
  			/* ignore pseudo entry for local MAC address */
  			if (!f->dst)
  				continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
341
342
343
344
345
346
347
  			if (skip) {
  				--skip;
  				continue;
  			}
  
  			/* convert from internal format to API */
  			memcpy(fe->mac_addr, f->addr.addr, ETH_ALEN);
ae4f8fca4   Stephen Hemminger   bridge: forwardin...
348
349
  
  			/* due to ABI compat need to split into hi/lo */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350
  			fe->port_no = f->dst->port_no;
ae4f8fca4   Stephen Hemminger   bridge: forwardin...
351
  			fe->port_hi = f->dst->port_no >> 8;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352
353
  			fe->is_local = f->is_local;
  			if (!f->is_static)
a399a8053   Eric Dumazet   time: jiffies_del...
354
  				fe->ageing_timer_value = jiffies_delta_to_clock_t(jiffies - f->updated);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
355
356
357
358
359
360
361
362
363
364
  			++fe;
  			++num;
  		}
  	}
  
   out:
  	rcu_read_unlock();
  
  	return num;
  }
664de48bb   stephen hemminger   bridge: split rcu...
365
  static struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head,
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
366
367
  					     const unsigned char *addr,
  					     __u16 vid)
664de48bb   stephen hemminger   bridge: split rcu...
368
  {
664de48bb   stephen hemminger   bridge: split rcu...
369
  	struct net_bridge_fdb_entry *fdb;
b67bfe0d4   Sasha Levin   hlist: drop the n...
370
  	hlist_for_each_entry(fdb, head, hlist) {
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
371
372
  		if (ether_addr_equal(fdb->addr.addr, addr) &&
  		    fdb->vlan_id == vid)
664de48bb   stephen hemminger   bridge: split rcu...
373
374
375
376
377
378
  			return fdb;
  	}
  	return NULL;
  }
  
  static struct net_bridge_fdb_entry *fdb_find_rcu(struct hlist_head *head,
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
379
380
  						 const unsigned char *addr,
  						 __u16 vid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
381
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
382
  	struct net_bridge_fdb_entry *fdb;
b67bfe0d4   Sasha Levin   hlist: drop the n...
383
  	hlist_for_each_entry_rcu(fdb, head, hlist) {
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
384
385
  		if (ether_addr_equal(fdb->addr.addr, addr) &&
  		    fdb->vlan_id == vid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
386
387
388
389
390
391
392
  			return fdb;
  	}
  	return NULL;
  }
  
  static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head,
  					       struct net_bridge_port *source,
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
393
394
  					       const unsigned char *addr,
  					       __u16 vid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
396
397
398
399
400
  {
  	struct net_bridge_fdb_entry *fdb;
  
  	fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC);
  	if (fdb) {
  		memcpy(fdb->addr.addr, addr, ETH_ALEN);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
  		fdb->dst = source;
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
402
  		fdb->vlan_id = vid;
03e9b64b8   stephen hemminger   bridge: change ar...
403
404
  		fdb->is_local = 0;
  		fdb->is_static = 0;
a5642ab47   Toshiaki Makita   bridge: Fix the w...
405
  		fdb->added_by_user = 0;
7cd8861ab   stephen hemminger   bridge: track las...
406
  		fdb->updated = fdb->used = jiffies;
1158f762e   Pavel Emelyanov   bridge: Don't put...
407
  		hlist_add_head_rcu(&fdb->hlist, head);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
408
409
410
411
412
  	}
  	return fdb;
  }
  
  static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
bc9a25d21   Vlad Yasevich   bridge: Add vlan ...
413
  		  const unsigned char *addr, u16 vid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
414
  {
bc9a25d21   Vlad Yasevich   bridge: Add vlan ...
415
  	struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
416
417
418
419
  	struct net_bridge_fdb_entry *fdb;
  
  	if (!is_valid_ether_addr(addr))
  		return -EINVAL;
bc9a25d21   Vlad Yasevich   bridge: Add vlan ...
420
  	fdb = fdb_find(head, addr, vid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
421
  	if (fdb) {
9d6f229fc   YOSHIFUJI Hideaki   [NET] BRIDGE: Fix...
422
  		/* it is okay to have multiple ports with same
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
424
  		 * address, just use the first one.
  		 */
9d6f229fc   YOSHIFUJI Hideaki   [NET] BRIDGE: Fix...
425
  		if (fdb->is_local)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
426
  			return 0;
28a16c979   stephen hemminger   bridge: change co...
427
  		br_warn(br, "adding interface %s with same address "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
428
429
  		       "as a received packet
  ",
9b46922e1   Hong zhi guo   bridge: fix crash...
430
  		       source ? source->dev->name : br->dev->name);
31e8a49c1   stephen hemminger   bridge: rearrange...
431
  		fdb_delete(br, fdb);
9d6f229fc   YOSHIFUJI Hideaki   [NET] BRIDGE: Fix...
432
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
433

bc9a25d21   Vlad Yasevich   bridge: Add vlan ...
434
  	fdb = fdb_create(head, source, addr, vid);
03e9b64b8   stephen hemminger   bridge: change ar...
435
  	if (!fdb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436
  		return -ENOMEM;
03e9b64b8   stephen hemminger   bridge: change ar...
437
  	fdb->is_local = fdb->is_static = 1;
31e8a49c1   stephen hemminger   bridge: rearrange...
438
  	fdb_notify(br, fdb, RTM_NEWNEIGH);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
439
440
  	return 0;
  }
03e9b64b8   stephen hemminger   bridge: change ar...
441
  /* Add entry for local address of interface */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
442
  int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
bc9a25d21   Vlad Yasevich   bridge: Add vlan ...
443
  		  const unsigned char *addr, u16 vid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444
445
446
447
  {
  	int ret;
  
  	spin_lock_bh(&br->hash_lock);
bc9a25d21   Vlad Yasevich   bridge: Add vlan ...
448
  	ret = fdb_insert(br, source, addr, vid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
449
450
451
452
453
  	spin_unlock_bh(&br->hash_lock);
  	return ret;
  }
  
  void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
a5642ab47   Toshiaki Makita   bridge: Fix the w...
454
  		   const unsigned char *addr, u16 vid, bool added_by_user)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
455
  {
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
456
  	struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
457
  	struct net_bridge_fdb_entry *fdb;
c65c7a306   Jon Maxwell   bridge: notify us...
458
  	bool fdb_modified = false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459
460
461
462
  
  	/* some users want to always flood. */
  	if (hold_time(br) == 0)
  		return;
df1c0b846   Stephen Hemminger   [BRIDGE]: Packets...
463
464
465
466
  	/* ignore packets unless we are using this port */
  	if (!(source->state == BR_STATE_LEARNING ||
  	      source->state == BR_STATE_FORWARDING))
  		return;
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
467
  	fdb = fdb_find_rcu(head, addr, vid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
468
469
470
  	if (likely(fdb)) {
  		/* attempt to update an entry for a local interface */
  		if (unlikely(fdb->is_local)) {
9d6f229fc   YOSHIFUJI Hideaki   [NET] BRIDGE: Fix...
471
  			if (net_ratelimit())
28a16c979   stephen hemminger   bridge: change co...
472
473
474
475
  				br_warn(br, "received packet on %s with "
  					"own address as source address
  ",
  					source->dev->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
476
477
  		} else {
  			/* fastpath: update of existing entry */
c65c7a306   Jon Maxwell   bridge: notify us...
478
479
480
481
  			if (unlikely(source != fdb->dst)) {
  				fdb->dst = source;
  				fdb_modified = true;
  			}
7cd8861ab   stephen hemminger   bridge: track las...
482
  			fdb->updated = jiffies;
a5642ab47   Toshiaki Makita   bridge: Fix the w...
483
484
  			if (unlikely(added_by_user))
  				fdb->added_by_user = 1;
c65c7a306   Jon Maxwell   bridge: notify us...
485
486
  			if (unlikely(fdb_modified))
  				fdb_notify(br, fdb, RTM_NEWNEIGH);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
487
488
  		}
  	} else {
f8ae737de   Stephen Hemminger   [BRIDGE]: forward...
489
  		spin_lock(&br->hash_lock);
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
490
491
  		if (likely(!fdb_find(head, addr, vid))) {
  			fdb = fdb_create(head, source, addr, vid);
a5642ab47   Toshiaki Makita   bridge: Fix the w...
492
493
494
  			if (fdb) {
  				if (unlikely(added_by_user))
  					fdb->added_by_user = 1;
31e8a49c1   stephen hemminger   bridge: rearrange...
495
  				fdb_notify(br, fdb, RTM_NEWNEIGH);
a5642ab47   Toshiaki Makita   bridge: Fix the w...
496
  			}
f58ee4e1a   stephen hemminger   bridge: refactor ...
497
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
498
499
500
  		/* else  we lose race and someone else inserts
  		 * it first, don't bother updating
  		 */
f8ae737de   Stephen Hemminger   [BRIDGE]: forward...
501
  		spin_unlock(&br->hash_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
502
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
503
  }
b078f0df6   stephen hemminger   bridge: add netli...
504
505
506
507
508
509
510
511
512
513
514
515
  
  static int fdb_to_nud(const struct net_bridge_fdb_entry *fdb)
  {
  	if (fdb->is_local)
  		return NUD_PERMANENT;
  	else if (fdb->is_static)
  		return NUD_NOARP;
  	else if (has_expired(fdb->dst->br, fdb))
  		return NUD_STALE;
  	else
  		return NUD_REACHABLE;
  }
31e8a49c1   stephen hemminger   bridge: rearrange...
516
  static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br,
b078f0df6   stephen hemminger   bridge: add netli...
517
  			 const struct net_bridge_fdb_entry *fdb,
15e473046   Eric W. Biederman   netlink: Rename p...
518
  			 u32 portid, u32 seq, int type, unsigned int flags)
b078f0df6   stephen hemminger   bridge: add netli...
519
520
521
522
523
  {
  	unsigned long now = jiffies;
  	struct nda_cacheinfo ci;
  	struct nlmsghdr *nlh;
  	struct ndmsg *ndm;
15e473046   Eric W. Biederman   netlink: Rename p...
524
  	nlh = nlmsg_put(skb, portid, seq, type, sizeof(*ndm), flags);
b078f0df6   stephen hemminger   bridge: add netli...
525
526
  	if (nlh == NULL)
  		return -EMSGSIZE;
b078f0df6   stephen hemminger   bridge: add netli...
527
528
529
530
531
532
  	ndm = nlmsg_data(nlh);
  	ndm->ndm_family	 = AF_BRIDGE;
  	ndm->ndm_pad1    = 0;
  	ndm->ndm_pad2    = 0;
  	ndm->ndm_flags	 = 0;
  	ndm->ndm_type	 = 0;
435988133   stephen hemminger   bridge: add local...
533
  	ndm->ndm_ifindex = fdb->dst ? fdb->dst->dev->ifindex : br->dev->ifindex;
b078f0df6   stephen hemminger   bridge: add netli...
534
  	ndm->ndm_state   = fdb_to_nud(fdb);
2eb812e65   David S. Miller   bridge: Stop usin...
535
536
  	if (nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->addr))
  		goto nla_put_failure;
b078f0df6   stephen hemminger   bridge: add netli...
537
538
539
540
  	ci.ndm_used	 = jiffies_to_clock_t(now - fdb->used);
  	ci.ndm_confirmed = 0;
  	ci.ndm_updated	 = jiffies_to_clock_t(now - fdb->updated);
  	ci.ndm_refcnt	 = 0;
2eb812e65   David S. Miller   bridge: Stop usin...
541
542
  	if (nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci))
  		goto nla_put_failure;
1690be63a   Vlad Yasevich   bridge: Add vlan ...
543
544
545
  
  	if (nla_put(skb, NDA_VLAN, sizeof(u16), &fdb->vlan_id))
  		goto nla_put_failure;
b078f0df6   stephen hemminger   bridge: add netli...
546
547
548
549
550
551
552
553
554
555
556
  	return nlmsg_end(skb, nlh);
  
  nla_put_failure:
  	nlmsg_cancel(skb, nlh);
  	return -EMSGSIZE;
  }
  
  static inline size_t fdb_nlmsg_size(void)
  {
  	return NLMSG_ALIGN(sizeof(struct ndmsg))
  		+ nla_total_size(ETH_ALEN) /* NDA_LLADDR */
1690be63a   Vlad Yasevich   bridge: Add vlan ...
557
  		+ nla_total_size(sizeof(u16)) /* NDA_VLAN */
b078f0df6   stephen hemminger   bridge: add netli...
558
559
  		+ nla_total_size(sizeof(struct nda_cacheinfo));
  }
31e8a49c1   stephen hemminger   bridge: rearrange...
560
561
  static void fdb_notify(struct net_bridge *br,
  		       const struct net_bridge_fdb_entry *fdb, int type)
b078f0df6   stephen hemminger   bridge: add netli...
562
  {
31e8a49c1   stephen hemminger   bridge: rearrange...
563
  	struct net *net = dev_net(br->dev);
b078f0df6   stephen hemminger   bridge: add netli...
564
565
566
567
568
569
  	struct sk_buff *skb;
  	int err = -ENOBUFS;
  
  	skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC);
  	if (skb == NULL)
  		goto errout;
31e8a49c1   stephen hemminger   bridge: rearrange...
570
  	err = fdb_fill_info(skb, br, fdb, 0, 0, type, 0);
b078f0df6   stephen hemminger   bridge: add netli...
571
572
573
574
575
576
577
578
579
  	if (err < 0) {
  		/* -EMSGSIZE implies BUG in fdb_nlmsg_size() */
  		WARN_ON(err == -EMSGSIZE);
  		kfree_skb(skb);
  		goto errout;
  	}
  	rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
  	return;
  errout:
87e823b3d   tanxiaojun   bridge: remove un...
580
  	rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
b078f0df6   stephen hemminger   bridge: add netli...
581
582
583
  }
  
  /* Dump information about entries, in response to GETNEIGH */
77162022a   John Fastabend   net: add generic ...
584
585
586
587
  int br_fdb_dump(struct sk_buff *skb,
  		struct netlink_callback *cb,
  		struct net_device *dev,
  		int idx)
b078f0df6   stephen hemminger   bridge: add netli...
588
  {
77162022a   John Fastabend   net: add generic ...
589
590
  	struct net_bridge *br = netdev_priv(dev);
  	int i;
b078f0df6   stephen hemminger   bridge: add netli...
591

77162022a   John Fastabend   net: add generic ...
592
593
  	if (!(dev->priv_flags & IFF_EBRIDGE))
  		goto out;
b078f0df6   stephen hemminger   bridge: add netli...
594

77162022a   John Fastabend   net: add generic ...
595
  	for (i = 0; i < BR_HASH_SIZE; i++) {
77162022a   John Fastabend   net: add generic ...
596
  		struct net_bridge_fdb_entry *f;
b078f0df6   stephen hemminger   bridge: add netli...
597

b67bfe0d4   Sasha Levin   hlist: drop the n...
598
  		hlist_for_each_entry_rcu(f, &br->hash[i], hlist) {
77162022a   John Fastabend   net: add generic ...
599
600
601
602
  			if (idx < cb->args[0])
  				goto skip;
  
  			if (fdb_fill_info(skb, br, f,
15e473046   Eric W. Biederman   netlink: Rename p...
603
  					  NETLINK_CB(cb->skb).portid,
77162022a   John Fastabend   net: add generic ...
604
605
606
607
  					  cb->nlh->nlmsg_seq,
  					  RTM_NEWNEIGH,
  					  NLM_F_MULTI) < 0)
  				break;
b078f0df6   stephen hemminger   bridge: add netli...
608
  skip:
77162022a   John Fastabend   net: add generic ...
609
  			++idx;
b078f0df6   stephen hemminger   bridge: add netli...
610
611
  		}
  	}
b078f0df6   stephen hemminger   bridge: add netli...
612

77162022a   John Fastabend   net: add generic ...
613
614
  out:
  	return idx;
b078f0df6   stephen hemminger   bridge: add netli...
615
  }
36fd2b63e   stephen hemminger   bridge: allow cre...
616

292d13989   stephen hemminger   bridge: add NTF_U...
617
  /* Update (create or replace) forwarding database entry */
36fd2b63e   stephen hemminger   bridge: allow cre...
618
  static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr,
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
619
  			 __u16 state, __u16 flags, __u16 vid)
36fd2b63e   stephen hemminger   bridge: allow cre...
620
621
  {
  	struct net_bridge *br = source->br;
2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
622
  	struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)];
36fd2b63e   stephen hemminger   bridge: allow cre...
623
  	struct net_bridge_fdb_entry *fdb;
b0a397fb3   roopa   bridge: Add fdb d...
624
  	bool modified = false;
36fd2b63e   stephen hemminger   bridge: allow cre...
625

2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
626
  	fdb = fdb_find(head, addr, vid);
64af1bac9   stephen hemminger   bridge: allow upd...
627
628
629
  	if (fdb == NULL) {
  		if (!(flags & NLM_F_CREATE))
  			return -ENOENT;
36fd2b63e   stephen hemminger   bridge: allow cre...
630

2ba071ecb   Vlad Yasevich   bridge: Add vlan ...
631
  		fdb = fdb_create(head, source, addr, vid);
64af1bac9   stephen hemminger   bridge: allow upd...
632
633
  		if (!fdb)
  			return -ENOMEM;
b0a397fb3   roopa   bridge: Add fdb d...
634
635
  
  		modified = true;
64af1bac9   stephen hemminger   bridge: allow upd...
636
637
638
  	} else {
  		if (flags & NLM_F_EXCL)
  			return -EEXIST;
b0a397fb3   roopa   bridge: Add fdb d...
639
640
641
642
643
  
  		if (fdb->dst != source) {
  			fdb->dst = source;
  			modified = true;
  		}
292d13989   stephen hemminger   bridge: add NTF_U...
644
645
646
647
648
649
650
651
652
653
  	}
  
  	if (fdb_to_nud(fdb) != state) {
  		if (state & NUD_PERMANENT)
  			fdb->is_local = fdb->is_static = 1;
  		else if (state & NUD_NOARP) {
  			fdb->is_local = 0;
  			fdb->is_static = 1;
  		} else
  			fdb->is_local = fdb->is_static = 0;
64af1bac9   stephen hemminger   bridge: allow upd...
654

b0a397fb3   roopa   bridge: Add fdb d...
655
656
  		modified = true;
  	}
a5642ab47   Toshiaki Makita   bridge: Fix the w...
657
  	fdb->added_by_user = 1;
b0a397fb3   roopa   bridge: Add fdb d...
658
659
660
661
  
  	fdb->used = jiffies;
  	if (modified) {
  		fdb->updated = jiffies;
31e8a49c1   stephen hemminger   bridge: rearrange...
662
  		fdb_notify(br, fdb, RTM_NEWNEIGH);
64af1bac9   stephen hemminger   bridge: allow upd...
663
  	}
36fd2b63e   stephen hemminger   bridge: allow cre...
664

36fd2b63e   stephen hemminger   bridge: allow cre...
665
666
  	return 0;
  }
1690be63a   Vlad Yasevich   bridge: Add vlan ...
667
668
669
670
671
672
673
  static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge_port *p,
  	       const unsigned char *addr, u16 nlh_flags, u16 vid)
  {
  	int err = 0;
  
  	if (ndm->ndm_flags & NTF_USE) {
  		rcu_read_lock();
a5642ab47   Toshiaki Makita   bridge: Fix the w...
674
  		br_fdb_update(p->br, p, addr, vid, true);
1690be63a   Vlad Yasevich   bridge: Add vlan ...
675
676
677
678
679
680
681
682
683
684
  		rcu_read_unlock();
  	} else {
  		spin_lock_bh(&p->br->hash_lock);
  		err = fdb_add_entry(p, addr, ndm->ndm_state,
  				    nlh_flags, vid);
  		spin_unlock_bh(&p->br->hash_lock);
  	}
  
  	return err;
  }
36fd2b63e   stephen hemminger   bridge: allow cre...
685
  /* Add new permanent fdb entry with RTM_NEWNEIGH */
edc7d5732   stephen hemminger   netlink: add attr...
686
687
  int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
  	       struct net_device *dev,
6b6e27255   stephen hemminger   netdev: make addr...
688
  	       const unsigned char *addr, u16 nlh_flags)
36fd2b63e   stephen hemminger   bridge: allow cre...
689
  {
36fd2b63e   stephen hemminger   bridge: allow cre...
690
  	struct net_bridge_port *p;
77162022a   John Fastabend   net: add generic ...
691
  	int err = 0;
1690be63a   Vlad Yasevich   bridge: Add vlan ...
692
693
  	struct net_port_vlans *pv;
  	unsigned short vid = VLAN_N_VID;
36fd2b63e   stephen hemminger   bridge: allow cre...
694

292d13989   stephen hemminger   bridge: add NTF_U...
695
696
697
698
699
  	if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE))) {
  		pr_info("bridge: RTM_NEWNEIGH with invalid state %#x
  ", ndm->ndm_state);
  		return -EINVAL;
  	}
1690be63a   Vlad Yasevich   bridge: Add vlan ...
700
701
702
703
704
705
706
707
  	if (tb[NDA_VLAN]) {
  		if (nla_len(tb[NDA_VLAN]) != sizeof(unsigned short)) {
  			pr_info("bridge: RTM_NEWNEIGH with invalid vlan
  ");
  			return -EINVAL;
  		}
  
  		vid = nla_get_u16(tb[NDA_VLAN]);
8adff41c3   Toshiaki Makita   bridge: Don't use...
708
  		if (!vid || vid >= VLAN_VID_MASK) {
1690be63a   Vlad Yasevich   bridge: Add vlan ...
709
710
711
712
713
714
  			pr_info("bridge: RTM_NEWNEIGH with invalid vlan id %d
  ",
  				vid);
  			return -EINVAL;
  		}
  	}
537f7f849   Stephen Hemminger   bridge: check for...
715
716
717
718
719
  	if (is_zero_ether_addr(addr)) {
  		pr_info("bridge: RTM_NEWNEIGH with invalid ether address
  ");
  		return -EINVAL;
  	}
36fd2b63e   stephen hemminger   bridge: allow cre...
720
721
722
723
724
725
726
  	p = br_port_get_rtnl(dev);
  	if (p == NULL) {
  		pr_info("bridge: RTM_NEWNEIGH %s not a bridge port
  ",
  			dev->name);
  		return -EINVAL;
  	}
1690be63a   Vlad Yasevich   bridge: Add vlan ...
727
728
729
730
731
732
733
734
735
736
737
  	pv = nbp_get_vlan_info(p);
  	if (vid != VLAN_N_VID) {
  		if (!pv || !test_bit(vid, pv->vlan_bitmap)) {
  			pr_info("bridge: RTM_NEWNEIGH with unconfigured "
  				"vlan %d on port %s
  ", vid, dev->name);
  			return -EINVAL;
  		}
  
  		/* VID was specified, so use it. */
  		err = __br_fdb_add(ndm, p, addr, nlh_flags, vid);
292d13989   stephen hemminger   bridge: add NTF_U...
738
  	} else {
ef40b7ef1   Toshiaki Makita   bridge: Use the c...
739
  		if (!pv || bitmap_empty(pv->vlan_bitmap, VLAN_N_VID)) {
1690be63a   Vlad Yasevich   bridge: Add vlan ...
740
741
742
743
744
745
746
747
  			err = __br_fdb_add(ndm, p, addr, nlh_flags, 0);
  			goto out;
  		}
  
  		/* We have vlans configured on this port and user didn't
  		 * specify a VLAN.  To be nice, add/update entry for every
  		 * vlan on this port.
  		 */
ef40b7ef1   Toshiaki Makita   bridge: Use the c...
748
  		for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) {
1690be63a   Vlad Yasevich   bridge: Add vlan ...
749
750
751
  			err = __br_fdb_add(ndm, p, addr, nlh_flags, vid);
  			if (err)
  				goto out;
1690be63a   Vlad Yasevich   bridge: Add vlan ...
752
  		}
292d13989   stephen hemminger   bridge: add NTF_U...
753
  	}
36fd2b63e   stephen hemminger   bridge: allow cre...
754

1690be63a   Vlad Yasevich   bridge: Add vlan ...
755
  out:
36fd2b63e   stephen hemminger   bridge: allow cre...
756
757
  	return err;
  }
424bb9c97   Toshiaki Makita   bridge: Properly ...
758
  static int fdb_delete_by_addr(struct net_bridge *br, const u8 *addr, u16 vlan)
36fd2b63e   stephen hemminger   bridge: allow cre...
759
  {
1690be63a   Vlad Yasevich   bridge: Add vlan ...
760
  	struct hlist_head *head = &br->hash[br_mac_hash(addr, vlan)];
36fd2b63e   stephen hemminger   bridge: allow cre...
761
  	struct net_bridge_fdb_entry *fdb;
1690be63a   Vlad Yasevich   bridge: Add vlan ...
762
  	fdb = fdb_find(head, addr, vlan);
36fd2b63e   stephen hemminger   bridge: allow cre...
763
764
  	if (!fdb)
  		return -ENOENT;
1690be63a   Vlad Yasevich   bridge: Add vlan ...
765
  	fdb_delete(br, fdb);
36fd2b63e   stephen hemminger   bridge: allow cre...
766
767
  	return 0;
  }
1690be63a   Vlad Yasevich   bridge: Add vlan ...
768
769
770
771
772
773
774
775
776
777
778
  static int __br_fdb_delete(struct net_bridge_port *p,
  			   const unsigned char *addr, u16 vid)
  {
  	int err;
  
  	spin_lock_bh(&p->br->hash_lock);
  	err = fdb_delete_by_addr(p->br, addr, vid);
  	spin_unlock_bh(&p->br->hash_lock);
  
  	return err;
  }
36fd2b63e   stephen hemminger   bridge: allow cre...
779
  /* Remove neighbor entry with RTM_DELNEIGH */
1690be63a   Vlad Yasevich   bridge: Add vlan ...
780
781
  int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
  		  struct net_device *dev,
6b6e27255   stephen hemminger   netdev: make addr...
782
  		  const unsigned char *addr)
36fd2b63e   stephen hemminger   bridge: allow cre...
783
  {
36fd2b63e   stephen hemminger   bridge: allow cre...
784
  	struct net_bridge_port *p;
36fd2b63e   stephen hemminger   bridge: allow cre...
785
  	int err;
1690be63a   Vlad Yasevich   bridge: Add vlan ...
786
787
  	struct net_port_vlans *pv;
  	unsigned short vid = VLAN_N_VID;
36fd2b63e   stephen hemminger   bridge: allow cre...
788

1690be63a   Vlad Yasevich   bridge: Add vlan ...
789
790
791
792
793
794
795
796
  	if (tb[NDA_VLAN]) {
  		if (nla_len(tb[NDA_VLAN]) != sizeof(unsigned short)) {
  			pr_info("bridge: RTM_NEWNEIGH with invalid vlan
  ");
  			return -EINVAL;
  		}
  
  		vid = nla_get_u16(tb[NDA_VLAN]);
8adff41c3   Toshiaki Makita   bridge: Don't use...
797
  		if (!vid || vid >= VLAN_VID_MASK) {
1690be63a   Vlad Yasevich   bridge: Add vlan ...
798
799
800
801
802
803
  			pr_info("bridge: RTM_NEWNEIGH with invalid vlan id %d
  ",
  				vid);
  			return -EINVAL;
  		}
  	}
36fd2b63e   stephen hemminger   bridge: allow cre...
804
805
806
807
808
809
810
  	p = br_port_get_rtnl(dev);
  	if (p == NULL) {
  		pr_info("bridge: RTM_DELNEIGH %s not a bridge port
  ",
  			dev->name);
  		return -EINVAL;
  	}
1690be63a   Vlad Yasevich   bridge: Add vlan ...
811
812
813
814
815
816
817
818
  	pv = nbp_get_vlan_info(p);
  	if (vid != VLAN_N_VID) {
  		if (!pv || !test_bit(vid, pv->vlan_bitmap)) {
  			pr_info("bridge: RTM_DELNEIGH with unconfigured "
  				"vlan %d on port %s
  ", vid, dev->name);
  			return -EINVAL;
  		}
36fd2b63e   stephen hemminger   bridge: allow cre...
819

1690be63a   Vlad Yasevich   bridge: Add vlan ...
820
821
  		err = __br_fdb_delete(p, addr, vid);
  	} else {
ef40b7ef1   Toshiaki Makita   bridge: Use the c...
822
  		if (!pv || bitmap_empty(pv->vlan_bitmap, VLAN_N_VID)) {
1690be63a   Vlad Yasevich   bridge: Add vlan ...
823
824
825
826
827
828
829
830
831
  			err = __br_fdb_delete(p, addr, 0);
  			goto out;
  		}
  
  		/* We have vlans configured on this port and user didn't
  		 * specify a VLAN.  To be nice, add/update entry for every
  		 * vlan on this port.
  		 */
  		err = -ENOENT;
ef40b7ef1   Toshiaki Makita   bridge: Use the c...
832
  		for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) {
1690be63a   Vlad Yasevich   bridge: Add vlan ...
833
  			err &= __br_fdb_delete(p, addr, vid);
1690be63a   Vlad Yasevich   bridge: Add vlan ...
834
835
836
  		}
  	}
  out:
36fd2b63e   stephen hemminger   bridge: allow cre...
837
838
  	return err;
  }