br_fdb.c 25.5 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 *	Forwarding database
 *	Linux ethernet bridge
 *
 *	Authors:
 *	Lennert Buytenhek		<buytenh@gnu.org>
 *
 *	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>
16
#include <linux/rculist.h>
Linus Torvalds's avatar
Linus Torvalds committed
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>
22
#include <linux/random.h>
23
#include <linux/slab.h>
Arun Sharma's avatar
Arun Sharma committed
24
#include <linux/atomic.h>
25
#include <asm/unaligned.h>
26
#include <linux/if_vlan.h>
27
#include <net/switchdev.h>
Linus Torvalds's avatar
Linus Torvalds committed
28
29
#include "br_private.h"

30
static struct kmem_cache *br_fdb_cache __read_mostly;
31
32
33
static struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head,
					     const unsigned char *addr,
					     __u16 vid);
Linus Torvalds's avatar
Linus Torvalds committed
34
static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
35
		      const unsigned char *addr, u16 vid);
36
37
static void fdb_notify(struct net_bridge *br,
		       const struct net_bridge_fdb_entry *, int);
Linus Torvalds's avatar
Linus Torvalds committed
38

39
40
static u32 fdb_salt __read_mostly;

41
int __init br_fdb_init(void)
Linus Torvalds's avatar
Linus Torvalds committed
42
43
44
45
{
	br_fdb_cache = kmem_cache_create("bridge_fdb_cache",
					 sizeof(struct net_bridge_fdb_entry),
					 0,
46
					 SLAB_HWCACHE_ALIGN, NULL);
47
48
49
	if (!br_fdb_cache)
		return -ENOMEM;

50
	get_random_bytes(&fdb_salt, sizeof(fdb_salt));
51
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
52
53
}

Andrew Morton's avatar
Andrew Morton committed
54
void br_fdb_fini(void)
Linus Torvalds's avatar
Linus Torvalds committed
55
56
57
58
59
60
61
62
{
	kmem_cache_destroy(br_fdb_cache);
}


/* if topology_changing then use forward_delay (default 15 sec)
 * otherwise keep longer (default 5 minutes)
 */
63
static inline unsigned long hold_time(const struct net_bridge *br)
Linus Torvalds's avatar
Linus Torvalds committed
64
65
66
67
{
	return br->topology_change ? br->forward_delay : br->ageing_time;
}

68
static inline int has_expired(const struct net_bridge *br,
Linus Torvalds's avatar
Linus Torvalds committed
69
70
				  const struct net_bridge_fdb_entry *fdb)
{
71
	return !fdb->is_static &&
72
		time_before_eq(fdb->updated + hold_time(br), jiffies);
Linus Torvalds's avatar
Linus Torvalds committed
73
74
}

75
static inline int br_mac_hash(const unsigned char *mac, __u16 vid)
Linus Torvalds's avatar
Linus Torvalds committed
76
{
77
	/* use 1 byte of OUI and 3 bytes of NIC */
78
	u32 key = get_unaligned((u32 *)(mac + 2));
79
	return jhash_2words(key, vid, fdb_salt) & (BR_HASH_SIZE - 1);
Linus Torvalds's avatar
Linus Torvalds committed
80
81
}

82
83
84
85
86
87
88
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);
}

89
90
91
92
93
/* When a static FDB entry is added, the mac address from the entry is
 * added to the bridge private HW address list and all required ports
 * are then updated with the new information.
 * Called under RTNL.
 */
94
static void fdb_add_hw_addr(struct net_bridge *br, const unsigned char *addr)
95
96
{
	int err;
97
	struct net_bridge_port *p;
98
99
100
101
102
103
104
105
106
107
108
109
110

	ASSERT_RTNL();

	list_for_each_entry(p, &br->port_list, list) {
		if (!br_promisc_port(p)) {
			err = dev_uc_add(p->dev, addr);
			if (err)
				goto undo;
		}
	}

	return;
undo:
111
112
113
	list_for_each_entry_continue_reverse(p, &br->port_list, list) {
		if (!br_promisc_port(p))
			dev_uc_del(p->dev, addr);
114
115
116
117
118
119
120
121
	}
}

/* When a static FDB entry is deleted, the HW address from that entry is
 * also removed from the bridge private HW address list and updates all
 * the ports with needed information.
 * Called under RTNL.
 */
122
static void fdb_del_hw_addr(struct net_bridge *br, const unsigned char *addr)
123
124
125
126
127
128
129
130
131
132
133
{
	struct net_bridge_port *p;

	ASSERT_RTNL();

	list_for_each_entry(p, &br->port_list, list) {
		if (!br_promisc_port(p))
			dev_uc_del(p->dev, addr);
	}
}

134
135
136
137
138
139
140
141
142
143
144
145
146
static void fdb_del_external_learn(struct net_bridge_fdb_entry *f)
{
	struct switchdev_obj obj = {
		.id = SWITCHDEV_OBJ_PORT_FDB,
		.u.fdb = {
			.addr = f->addr.addr,
			.vid = f->vlan_id,
		},
	};

	switchdev_port_obj_del(f->dst->dev, &obj);
}

147
static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f)
Linus Torvalds's avatar
Linus Torvalds committed
148
{
149
	if (f->is_static)
150
		fdb_del_hw_addr(br, f->addr.addr);
151

152
153
154
	if (f->added_by_external_learn)
		fdb_del_external_learn(f);

Linus Torvalds's avatar
Linus Torvalds committed
155
	hlist_del_rcu(&f->hlist);
156
	fdb_notify(br, f, RTM_DELNEIGH);
157
	call_rcu(&f->rcu, fdb_rcu_free);
Linus Torvalds's avatar
Linus Torvalds committed
158
159
}

160
161
162
163
164
165
/* 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;
166
167
	struct net_bridge_vlan_group *vg;
	const struct net_bridge_vlan *v;
168
	struct net_bridge_port *op;
169
	u16 vid = f->vlan_id;
170
171
172

	/* Maybe another port has same hw addr? */
	list_for_each_entry(op, &br->port_list, list) {
173
		vg = nbp_vlan_group(op);
174
		if (op != p && ether_addr_equal(op->dev->dev_addr, addr) &&
175
		    (!vid || br_vlan_find(vg, vid))) {
176
			f->dst = op;
177
			f->added_by_user = 0;
178
179
180
181
			return;
		}
	}

182
183
	vg = br_vlan_group(br);
	v = br_vlan_find(vg, vid);
184
185
	/* Maybe bridge device has same hw addr? */
	if (p && ether_addr_equal(br->dev->dev_addr, addr) &&
186
	    (!vid || (v && br_vlan_should_use(v)))) {
187
		f->dst = NULL;
188
		f->added_by_user = 0;
189
190
191
192
193
194
		return;
	}

	fdb_delete(br, f);
}

195
196
197
198
199
200
201
202
203
204
205
206
207
208
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);
}

Linus Torvalds's avatar
Linus Torvalds committed
209
210
void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr)
{
211
	struct net_bridge_vlan_group *vg;
Linus Torvalds's avatar
Linus Torvalds committed
212
	struct net_bridge *br = p->br;
213
	struct net_bridge_vlan *v;
Linus Torvalds's avatar
Linus Torvalds committed
214
	int i;
215

Linus Torvalds's avatar
Linus Torvalds committed
216
217
	spin_lock_bh(&br->hash_lock);

218
	vg = nbp_vlan_group(p);
Linus Torvalds's avatar
Linus Torvalds committed
219
220
221
222
223
224
225
	/* 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);
226
			if (f->dst == p && f->is_local && !f->added_by_user) {
Linus Torvalds's avatar
Linus Torvalds committed
227
				/* delete old one */
228
229
				fdb_delete_local(br, p, f);

230
231
232
233
				/* if this port has no vlan information
				 * configured, we can safely be done at
				 * this point.
				 */
234
				if (!vg || !vg->num_vlans)
235
					goto insert;
Linus Torvalds's avatar
Linus Torvalds committed
236
237
238
239
			}
		}
	}

240
241
242
243
insert:
	/* insert new address,  may fail if invalid address or dup. */
	fdb_insert(br, p, newaddr, 0);

244
	if (!vg || !vg->num_vlans)
245
246
247
248
249
250
		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.
	 */
251
252
	list_for_each_entry(v, &vg->vlan_list, vlist)
		fdb_insert(br, p, newaddr, v->vid);
253

254
done:
Linus Torvalds's avatar
Linus Torvalds committed
255
256
257
	spin_unlock_bh(&br->hash_lock);
}

258
259
void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr)
{
260
	struct net_bridge_vlan_group *vg;
261
	struct net_bridge_fdb_entry *f;
262
	struct net_bridge_vlan *v;
263

264
265
	spin_lock_bh(&br->hash_lock);

266
	/* If old entry was unassociated with any port, then delete it. */
267
	f = __br_fdb_get(br, br->dev->dev_addr, 0);
268
	if (f && f->is_local && !f->dst)
269
		fdb_delete_local(br, NULL, f);
270

271
	fdb_insert(br, NULL, newaddr, 0);
272
273
274
	vg = br_vlan_group(br);
	if (!vg || !vg->num_vlans)
		goto out;
275
276
277
278
	/* 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.
	 */
279
280
	list_for_each_entry(v, &vg->vlan_list, vlist) {
		f = __br_fdb_get(br, br->dev->dev_addr, v->vid);
281
		if (f && f->is_local && !f->dst)
282
			fdb_delete_local(br, NULL, f);
283
		fdb_insert(br, NULL, newaddr, v->vid);
284
	}
285
286
out:
	spin_unlock_bh(&br->hash_lock);
287
288
}

Linus Torvalds's avatar
Linus Torvalds committed
289
290
291
292
void br_fdb_cleanup(unsigned long _data)
{
	struct net_bridge *br = (struct net_bridge *)_data;
	unsigned long delay = hold_time(br);
293
	unsigned long next_timer = jiffies + br->ageing_time;
Linus Torvalds's avatar
Linus Torvalds committed
294
295
	int i;

296
	spin_lock(&br->hash_lock);
Linus Torvalds's avatar
Linus Torvalds committed
297
298
	for (i = 0; i < BR_HASH_SIZE; i++) {
		struct net_bridge_fdb_entry *f;
299
		struct hlist_node *n;
Linus Torvalds's avatar
Linus Torvalds committed
300

301
		hlist_for_each_entry_safe(f, n, &br->hash[i], hlist) {
302
			unsigned long this_timer;
303
			if (f->is_static)
304
				continue;
305
306
			if (f->added_by_external_learn)
				continue;
307
			this_timer = f->updated + delay;
308
			if (time_before_eq(this_timer, jiffies))
309
				fdb_delete(br, f);
310
			else if (time_before(this_timer, next_timer))
311
				next_timer = this_timer;
Linus Torvalds's avatar
Linus Torvalds committed
312
313
		}
	}
314
	spin_unlock(&br->hash_lock);
Linus Torvalds's avatar
Linus Torvalds committed
315

316
	mod_timer(&br->gc_timer, round_jiffies_up(next_timer));
Linus Torvalds's avatar
Linus Torvalds committed
317
318
}

319
320
321
322
323
324
325
326
/* 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;
327
328
		struct hlist_node *n;
		hlist_for_each_entry_safe(f, n, &br->hash[i], hlist) {
329
			if (!f->is_static)
330
				fdb_delete(br, f);
331
332
333
334
		}
	}
	spin_unlock_bh(&br->hash_lock);
}
335

Lucas De Marchi's avatar
Lucas De Marchi committed
336
/* Flush all entries referring to a specific port.
337
 * if do_all is set also flush static entries
338
 * if vid is set delete all entries that match the vlan_id
339
 */
340
341
void br_fdb_delete_by_port(struct net_bridge *br,
			   const struct net_bridge_port *p,
342
			   u16 vid,
343
			   int do_all)
Linus Torvalds's avatar
Linus Torvalds committed
344
345
346
347
348
349
{
	int i;

	spin_lock_bh(&br->hash_lock);
	for (i = 0; i < BR_HASH_SIZE; i++) {
		struct hlist_node *h, *g;
350

Linus Torvalds's avatar
Linus Torvalds committed
351
352
353
		hlist_for_each_safe(h, g, &br->hash[i]) {
			struct net_bridge_fdb_entry *f
				= hlist_entry(h, struct net_bridge_fdb_entry, hlist);
354
			if (f->dst != p)
Linus Torvalds's avatar
Linus Torvalds committed
355
356
				continue;

357
358
359
			if (!do_all)
				if (f->is_static || (vid && f->vlan_id != vid))
					continue;
Linus Torvalds's avatar
Linus Torvalds committed
360

361
362
363
364
			if (f->is_local)
				fdb_delete_local(br, p, f);
			else
				fdb_delete(br, f);
Linus Torvalds's avatar
Linus Torvalds committed
365
366
367
368
369
		}
	}
	spin_unlock_bh(&br->hash_lock);
}

370
/* No locking or refcounting, assumes caller has rcu_read_lock */
Linus Torvalds's avatar
Linus Torvalds committed
371
struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br,
372
373
					  const unsigned char *addr,
					  __u16 vid)
Linus Torvalds's avatar
Linus Torvalds committed
374
375
376
{
	struct net_bridge_fdb_entry *fdb;

377
	hlist_for_each_entry_rcu(fdb,
378
379
380
				&br->hash[br_mac_hash(addr, vid)], hlist) {
		if (ether_addr_equal(fdb->addr.addr, addr) &&
		    fdb->vlan_id == vid) {
Linus Torvalds's avatar
Linus Torvalds committed
381
382
383
384
385
386
387
388
389
			if (unlikely(has_expired(br, fdb)))
				break;
			return fdb;
		}
	}

	return NULL;
}

Igor Maravić's avatar
Igor Maravić committed
390
#if IS_ENABLED(CONFIG_ATM_LANE)
391
392
393
/* 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)
Linus Torvalds's avatar
Linus Torvalds committed
394
395
{
	struct net_bridge_fdb_entry *fdb;
396
	struct net_bridge_port *port;
397
398
	int ret;

Linus Torvalds's avatar
Linus Torvalds committed
399
	rcu_read_lock();
400
401
402
403
	port = br_port_get_rcu(dev);
	if (!port)
		ret = 0;
	else {
404
		fdb = __br_fdb_get(port->br, addr, 0);
405
		ret = fdb && fdb->dst && fdb->dst->dev != dev &&
406
407
			fdb->dst->state == BR_STATE_FORWARDING;
	}
Linus Torvalds's avatar
Linus Torvalds committed
408
409
	rcu_read_unlock();

410
	return ret;
Linus Torvalds's avatar
Linus Torvalds committed
411
}
412
#endif /* CONFIG_ATM_LANE */
Linus Torvalds's avatar
Linus Torvalds committed
413
414

/*
415
 * Fill buffer with forwarding table records in
Linus Torvalds's avatar
Linus Torvalds committed
416
417
418
419
420
421
422
423
424
425
426
427
428
 * 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;
	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++) {
429
		hlist_for_each_entry_rcu(f, &br->hash[i], hlist) {
Linus Torvalds's avatar
Linus Torvalds committed
430
431
432
			if (num >= maxnum)
				goto out;

433
			if (has_expired(br, f))
Linus Torvalds's avatar
Linus Torvalds committed
434
435
				continue;

436
437
438
439
			/* ignore pseudo entry for local MAC address */
			if (!f->dst)
				continue;

Linus Torvalds's avatar
Linus Torvalds committed
440
441
442
443
444
445
446
			if (skip) {
				--skip;
				continue;
			}

			/* convert from internal format to API */
			memcpy(fe->mac_addr, f->addr.addr, ETH_ALEN);
447
448

			/* due to ABI compat need to split into hi/lo */
Linus Torvalds's avatar
Linus Torvalds committed
449
			fe->port_no = f->dst->port_no;
450
451
			fe->port_hi = f->dst->port_no >> 8;

Linus Torvalds's avatar
Linus Torvalds committed
452
453
			fe->is_local = f->is_local;
			if (!f->is_static)
454
				fe->ageing_timer_value = jiffies_delta_to_clock_t(jiffies - f->updated);
Linus Torvalds's avatar
Linus Torvalds committed
455
456
457
458
459
460
461
462
463
464
465
			++fe;
			++num;
		}
	}

 out:
	rcu_read_unlock();

	return num;
}

466
static struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head,
467
468
					     const unsigned char *addr,
					     __u16 vid)
469
470
471
{
	struct net_bridge_fdb_entry *fdb;

472
	hlist_for_each_entry(fdb, head, hlist) {
473
474
		if (ether_addr_equal(fdb->addr.addr, addr) &&
		    fdb->vlan_id == vid)
475
476
477
478
479
480
			return fdb;
	}
	return NULL;
}

static struct net_bridge_fdb_entry *fdb_find_rcu(struct hlist_head *head,
481
482
						 const unsigned char *addr,
						 __u16 vid)
Linus Torvalds's avatar
Linus Torvalds committed
483
484
485
{
	struct net_bridge_fdb_entry *fdb;

486
	hlist_for_each_entry_rcu(fdb, head, hlist) {
487
488
		if (ether_addr_equal(fdb->addr.addr, addr) &&
		    fdb->vlan_id == vid)
Linus Torvalds's avatar
Linus Torvalds committed
489
490
491
492
493
494
495
			return fdb;
	}
	return NULL;
}

static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head,
					       struct net_bridge_port *source,
496
497
					       const unsigned char *addr,
					       __u16 vid)
Linus Torvalds's avatar
Linus Torvalds committed
498
499
500
501
502
503
504
{
	struct net_bridge_fdb_entry *fdb;

	fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC);
	if (fdb) {
		memcpy(fdb->addr.addr, addr, ETH_ALEN);
		fdb->dst = source;
505
		fdb->vlan_id = vid;
506
507
		fdb->is_local = 0;
		fdb->is_static = 0;
508
		fdb->added_by_user = 0;
509
		fdb->added_by_external_learn = 0;
510
		fdb->updated = fdb->used = jiffies;
511
		hlist_add_head_rcu(&fdb->hlist, head);
Linus Torvalds's avatar
Linus Torvalds committed
512
513
514
515
516
	}
	return fdb;
}

static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
517
		  const unsigned char *addr, u16 vid)
Linus Torvalds's avatar
Linus Torvalds committed
518
{
519
	struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)];
Linus Torvalds's avatar
Linus Torvalds committed
520
521
522
523
524
	struct net_bridge_fdb_entry *fdb;

	if (!is_valid_ether_addr(addr))
		return -EINVAL;

525
	fdb = fdb_find(head, addr, vid);
Linus Torvalds's avatar
Linus Torvalds committed
526
	if (fdb) {
527
		/* it is okay to have multiple ports with same
Linus Torvalds's avatar
Linus Torvalds committed
528
529
		 * address, just use the first one.
		 */
530
		if (fdb->is_local)
Linus Torvalds's avatar
Linus Torvalds committed
531
			return 0;
532
		br_warn(br, "adding interface %s with same address "
Linus Torvalds's avatar
Linus Torvalds committed
533
		       "as a received packet\n",
534
		       source ? source->dev->name : br->dev->name);
535
		fdb_delete(br, fdb);
536
	}
Linus Torvalds's avatar
Linus Torvalds committed
537

538
	fdb = fdb_create(head, source, addr, vid);
539
	if (!fdb)
Linus Torvalds's avatar
Linus Torvalds committed
540
541
		return -ENOMEM;

542
	fdb->is_local = fdb->is_static = 1;
543
	fdb_add_hw_addr(br, addr);
544
	fdb_notify(br, fdb, RTM_NEWNEIGH);
Linus Torvalds's avatar
Linus Torvalds committed
545
546
547
	return 0;
}

548
/* Add entry for local address of interface */
Linus Torvalds's avatar
Linus Torvalds committed
549
int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
550
		  const unsigned char *addr, u16 vid)
Linus Torvalds's avatar
Linus Torvalds committed
551
552
553
554
{
	int ret;

	spin_lock_bh(&br->hash_lock);
555
	ret = fdb_insert(br, source, addr, vid);
Linus Torvalds's avatar
Linus Torvalds committed
556
557
558
559
560
	spin_unlock_bh(&br->hash_lock);
	return ret;
}

void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
561
		   const unsigned char *addr, u16 vid, bool added_by_user)
Linus Torvalds's avatar
Linus Torvalds committed
562
{
563
	struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)];
Linus Torvalds's avatar
Linus Torvalds committed
564
	struct net_bridge_fdb_entry *fdb;
565
	bool fdb_modified = false;
Linus Torvalds's avatar
Linus Torvalds committed
566
567
568
569
570

	/* some users want to always flood. */
	if (hold_time(br) == 0)
		return;

571
572
573
574
575
	/* ignore packets unless we are using this port */
	if (!(source->state == BR_STATE_LEARNING ||
	      source->state == BR_STATE_FORWARDING))
		return;

576
	fdb = fdb_find_rcu(head, addr, vid);
Linus Torvalds's avatar
Linus Torvalds committed
577
578
579
	if (likely(fdb)) {
		/* attempt to update an entry for a local interface */
		if (unlikely(fdb->is_local)) {
580
			if (net_ratelimit())
581
582
583
				br_warn(br, "received packet on %s with "
					"own address as source address\n",
					source->dev->name);
Linus Torvalds's avatar
Linus Torvalds committed
584
585
		} else {
			/* fastpath: update of existing entry */
586
587
588
589
			if (unlikely(source != fdb->dst)) {
				fdb->dst = source;
				fdb_modified = true;
			}
590
			fdb->updated = jiffies;
591
592
			if (unlikely(added_by_user))
				fdb->added_by_user = 1;
593
594
			if (unlikely(fdb_modified))
				fdb_notify(br, fdb, RTM_NEWNEIGH);
Linus Torvalds's avatar
Linus Torvalds committed
595
596
		}
	} else {
597
		spin_lock(&br->hash_lock);
598
599
		if (likely(!fdb_find(head, addr, vid))) {
			fdb = fdb_create(head, source, addr, vid);
600
601
602
			if (fdb) {
				if (unlikely(added_by_user))
					fdb->added_by_user = 1;
603
				fdb_notify(br, fdb, RTM_NEWNEIGH);
604
			}
605
		}
Linus Torvalds's avatar
Linus Torvalds committed
606
607
608
		/* else  we lose race and someone else inserts
		 * it first, don't bother updating
		 */
609
		spin_unlock(&br->hash_lock);
Linus Torvalds's avatar
Linus Torvalds committed
610
611
	}
}
612
613
614
615
616
617
618
619
620
621
622
623
624

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;
}

625
static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br,
626
			 const struct net_bridge_fdb_entry *fdb,
627
			 u32 portid, u32 seq, int type, unsigned int flags)
628
629
630
631
632
633
{
	unsigned long now = jiffies;
	struct nda_cacheinfo ci;
	struct nlmsghdr *nlh;
	struct ndmsg *ndm;

634
	nlh = nlmsg_put(skb, portid, seq, type, sizeof(*ndm), flags);
635
636
637
638
639
640
641
	if (nlh == NULL)
		return -EMSGSIZE;

	ndm = nlmsg_data(nlh);
	ndm->ndm_family	 = AF_BRIDGE;
	ndm->ndm_pad1    = 0;
	ndm->ndm_pad2    = 0;
642
	ndm->ndm_flags	 = fdb->added_by_external_learn ? NTF_EXT_LEARNED : 0;
643
	ndm->ndm_type	 = 0;
644
	ndm->ndm_ifindex = fdb->dst ? fdb->dst->dev->ifindex : br->dev->ifindex;
645
646
	ndm->ndm_state   = fdb_to_nud(fdb);

647
648
	if (nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->addr))
		goto nla_put_failure;
649
650
	if (nla_put_u32(skb, NDA_MASTER, br->dev->ifindex))
		goto nla_put_failure;
651
652
653
654
	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;
655
656
	if (nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci))
		goto nla_put_failure;
657

658
	if (fdb->vlan_id && nla_put(skb, NDA_VLAN, sizeof(u16), &fdb->vlan_id))
659
660
		goto nla_put_failure;

661
662
	nlmsg_end(skb, nlh);
	return 0;
663
664
665
666
667
668
669
670
671
672

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 */
673
		+ nla_total_size(sizeof(u32)) /* NDA_MASTER */
674
		+ nla_total_size(sizeof(u16)) /* NDA_VLAN */
675
676
677
		+ nla_total_size(sizeof(struct nda_cacheinfo));
}

678
679
static void fdb_notify(struct net_bridge *br,
		       const struct net_bridge_fdb_entry *fdb, int type)
680
{
681
	struct net *net = dev_net(br->dev);
682
683
684
685
686
687
688
	struct sk_buff *skb;
	int err = -ENOBUFS;

	skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC);
	if (skb == NULL)
		goto errout;

689
	err = fdb_fill_info(skb, br, fdb, 0, 0, type, 0);
690
691
692
693
694
695
696
697
698
	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:
699
	rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
700
701
702
}

/* Dump information about entries, in response to GETNEIGH */
703
704
705
int br_fdb_dump(struct sk_buff *skb,
		struct netlink_callback *cb,
		struct net_device *dev,
706
		struct net_device *filter_dev,
707
		int idx)
708
{
709
710
	struct net_bridge *br = netdev_priv(dev);
	int i;
711

712
713
	if (!(dev->priv_flags & IFF_EBRIDGE))
		goto out;
714

715
716
717
	if (!filter_dev)
		idx = ndo_dflt_fdb_dump(skb, cb, dev, NULL, idx);

718
719
	for (i = 0; i < BR_HASH_SIZE; i++) {
		struct net_bridge_fdb_entry *f;
720

721
		hlist_for_each_entry_rcu(f, &br->hash[i], hlist) {
722
723
724
			if (idx < cb->args[0])
				goto skip;

725
726
727
728
			if (filter_dev &&
			    (!f->dst || f->dst->dev != filter_dev)) {
				if (filter_dev != dev)
					goto skip;
729
				/* !f->dst is a special case for bridge
730
731
732
733
734
735
736
				 * It means the MAC belongs to the bridge
				 * Therefore need a little more filtering
				 * we only want to dump the !f->dst case
				 */
				if (f->dst)
					goto skip;
			}
737
738
			if (!filter_dev && f->dst)
				goto skip;
739

740
			if (fdb_fill_info(skb, br, f,
741
					  NETLINK_CB(cb->skb).portid,
742
743
744
745
					  cb->nlh->nlmsg_seq,
					  RTM_NEWNEIGH,
					  NLM_F_MULTI) < 0)
				break;
746
skip:
747
			++idx;
748
749
750
		}
	}

751
752
out:
	return idx;
753
}
754

755
/* Update (create or replace) forwarding database entry */
756
static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr,
757
			 __u16 state, __u16 flags, __u16 vid)
758
759
{
	struct net_bridge *br = source->br;
760
	struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)];
761
	struct net_bridge_fdb_entry *fdb;
762
	bool modified = false;
763

764
765
766
767
768
769
	/* If the port cannot learn allow only local and static entries */
	if (!(state & NUD_PERMANENT) && !(state & NUD_NOARP) &&
	    !(source->state == BR_STATE_LEARNING ||
	      source->state == BR_STATE_FORWARDING))
		return -EPERM;

770
	fdb = fdb_find(head, addr, vid);
771
772
773
	if (fdb == NULL) {
		if (!(flags & NLM_F_CREATE))
			return -ENOENT;
774

775
		fdb = fdb_create(head, source, addr, vid);
776
777
		if (!fdb)
			return -ENOMEM;
778
779

		modified = true;
780
781
782
	} else {
		if (flags & NLM_F_EXCL)
			return -EEXIST;
783
784
785
786
787

		if (fdb->dst != source) {
			fdb->dst = source;
			modified = true;
		}
788
789
790
	}

	if (fdb_to_nud(fdb) != state) {
791
792
793
794
		if (state & NUD_PERMANENT) {
			fdb->is_local = 1;
			if (!fdb->is_static) {
				fdb->is_static = 1;
795
				fdb_add_hw_addr(br, addr);
796
797
798
799
800
			}
		} else if (state & NUD_NOARP) {
			fdb->is_local = 0;
			if (!fdb->is_static) {
				fdb->is_static = 1;
801
				fdb_add_hw_addr(br, addr);
802
803
			}
		} else {
804
			fdb->is_local = 0;
805
806
			if (fdb->is_static) {
				fdb->is_static = 0;
807
				fdb_del_hw_addr(br, addr);
808
809
			}
		}
810

811
812
		modified = true;
	}
813
	fdb->added_by_user = 1;
814
815
816
817

	fdb->used = jiffies;
	if (modified) {
		fdb->updated = jiffies;
818
		fdb_notify(br, fdb, RTM_NEWNEIGH);
819
	}
820
821
822
823

	return 0;
}

824
825
826
827
828
829
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) {
830
		local_bh_disable();
831
		rcu_read_lock();
832
		br_fdb_update(p->br, p, addr, vid, true);
833
		rcu_read_unlock();
834
		local_bh_enable();
835
836
837
838
839
840
841
842
843
844
	} 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;
}

845
/* Add new permanent fdb entry with RTM_NEWNEIGH */
846
847
int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
	       struct net_device *dev,
848
	       const unsigned char *addr, u16 vid, u16 nlh_flags)
849
{
850
	struct net_bridge_vlan_group *vg;
851
	struct net_bridge_port *p;
852
	struct net_bridge_vlan *v;
853
	int err = 0;
854

855
856
857
858
859
	if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE))) {
		pr_info("bridge: RTM_NEWNEIGH with invalid state %#x\n", ndm->ndm_state);
		return -EINVAL;
	}

860
861
862
863
864
	if (is_zero_ether_addr(addr)) {
		pr_info("bridge: RTM_NEWNEIGH with invalid ether address\n");
		return -EINVAL;
	}

865
866
867
868
869
870
871
	p = br_port_get_rtnl(dev);
	if (p == NULL) {
		pr_info("bridge: RTM_NEWNEIGH %s not a bridge port\n",
			dev->name);
		return -EINVAL;
	}

872
	vg = nbp_vlan_group(p);
873
	if (vid) {
874
875
		v = br_vlan_find(vg, vid);
		if (!v) {
876
877
878
879
880
881
882
			pr_info("bridge: RTM_NEWNEIGH with unconfigured "
				"vlan %d on port %s\n", vid, dev->name);
			return -EINVAL;
		}

		/* VID was specified, so use it. */
		err = __br_fdb_add(ndm, p, addr, nlh_flags, vid);
883
	} else {
884
		err = __br_fdb_add(ndm, p, addr, nlh_flags, 0);
885
		if (err || !vg || !vg->num_vlans)
886
887
888
889
890
891
			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.
		 */
892
893
		list_for_each_entry(v, &vg->vlan_list, vlist) {
			err = __br_fdb_add(ndm, p, addr, nlh_flags, v->vid);
894
895
896
			if (err)
				goto out;
		}
897
	}
898

899
out:
900
901
902
	return err;
}

903
904
static int fdb_delete_by_addr_and_port(struct net_bridge_port *p,
				       const u8 *addr, u16 vlan)
905
{
906
	struct net_bridge *br = p->br;
907
	struct hlist_head *head = &br->hash[br_mac_hash(addr, vlan)];
908
909
	struct net_bridge_fdb_entry *fdb;

910
	fdb = fdb_find(head, addr, vlan);
911
	if (!fdb || fdb->dst != p)
912
913
		return -ENOENT;

914
	fdb_delete(br, fdb);
915
916
917
	return 0;
}

918
919
920
921
922
923
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);
924
	err = fdb_delete_by_addr_and_port(p, addr, vid);
925
926
927
928
929
	spin_unlock_bh(&p->br->hash_lock);

	return err;
}

930
/* Remove neighbor entry with RTM_DELNEIGH */
931
932
int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
		  struct net_device *dev,
933
		  const unsigned char *addr, u16 vid)
934
{
935
	struct net_bridge_vlan_group *vg;
936
	struct net_bridge_port *p;
937
	struct net_bridge_vlan *v;
938
	int err;
939

940
941
942
943
944
945
946
	p = br_port_get_rtnl(dev);
	if (p == NULL) {
		pr_info("bridge: RTM_DELNEIGH %s not a bridge port\n",
			dev->name);
		return -EINVAL;
	}

947
	vg = nbp_vlan_group(p);
948
	if (vid) {
949
950
		v = br_vlan_find(vg, vid);
		if (!v) {
951
952
953
954
			pr_info("bridge: RTM_DELNEIGH with unconfigured "
				"vlan %d on port %s\n", vid, dev->name);
			return -EINVAL;
		}
955

956
957
		err = __br_fdb_delete(p, addr, vid);
	} else {
958
959
		err = -ENOENT;
		err &= __br_fdb_delete(p, addr, 0);
960
		if (!vg || !vg->num_vlans)
961
962
			goto out;

963
964
		list_for_each_entry(v, &vg->vlan_list, vlist)
			err &= __br_fdb_delete(p, addr, v->vid);
965
966
	}
out:
967
968
	return err;
}
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000

int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p)
{
	struct net_bridge_fdb_entry *fdb, *tmp;
	int i;