br.c 8.6 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0-or-later
L
Linus Torvalds 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 *	Generic parts
 *	Linux ethernet bridge
 *
 *	Authors:
 *	Lennert Buytenhek		<buytenh@gnu.org>
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/init.h>
15 16
#include <linux/llc.h>
#include <net/llc.h>
P
Patrick McHardy 已提交
17
#include <net/stp.h>
18
#include <net/switchdev.h>
L
Linus Torvalds 已提交
19 20 21

#include "br_private.h"

22 23 24 25 26 27 28 29
/*
 * Handle changes in state of network devices enslaved to a bridge.
 *
 * Note: don't care about up/down if bridge itself is down, because
 *     port state is checked when bridge is brought up.
 */
static int br_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
{
30 31
	struct netlink_ext_ack *extack = netdev_notifier_info_to_extack(ptr);
	struct netdev_notifier_pre_changeaddr_info *prechaddr_info;
32 33 34
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
	struct net_bridge_port *p;
	struct net_bridge *br;
35
	bool notified = false;
36 37 38
	bool changed_addr;
	int err;

39
	if (dev->priv_flags & IFF_EBRIDGE) {
40 41 42 43
		err = br_vlan_bridge_event(dev, event, ptr);
		if (err)
			return notifier_from_errno(err);

44 45 46 47 48
		if (event == NETDEV_REGISTER) {
			/* register of bridge completed, add sysfs entries */
			br_sysfs_addbr(dev);
			return NOTIFY_DONE;
		}
49 50 51 52 53 54 55 56 57 58 59
	}

	/* not a port of a bridge */
	p = br_port_get_rtnl(dev);
	if (!p)
		return NOTIFY_DONE;

	br = p->br;

	switch (event) {
	case NETDEV_CHANGEMTU:
60
		br_mtu_auto_adjust(br);
61 62
		break;

63 64 65 66 67 68 69 70 71 72 73
	case NETDEV_PRE_CHANGEADDR:
		if (br->dev->addr_assign_type == NET_ADDR_SET)
			break;
		prechaddr_info = ptr;
		err = dev_pre_changeaddr_notify(br->dev,
						prechaddr_info->dev_addr,
						extack);
		if (err)
			return notifier_from_errno(err);
		break;

74 75 76 77 78 79 80 81 82 83 84 85
	case NETDEV_CHANGEADDR:
		spin_lock_bh(&br->lock);
		br_fdb_changeaddr(p, dev->dev_addr);
		changed_addr = br_stp_recalculate_bridge_id(br);
		spin_unlock_bh(&br->lock);

		if (changed_addr)
			call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev);

		break;

	case NETDEV_CHANGE:
86
		br_port_carrier_check(p, &notified);
87 88 89 90 91 92 93 94
		break;

	case NETDEV_FEAT_CHANGE:
		netdev_update_features(br->dev);
		break;

	case NETDEV_DOWN:
		spin_lock_bh(&br->lock);
95
		if (br->dev->flags & IFF_UP) {
96
			br_stp_disable_port(p);
97 98
			notified = true;
		}
99 100 101 102 103 104 105
		spin_unlock_bh(&br->lock);
		break;

	case NETDEV_UP:
		if (netif_running(br->dev) && netif_oper_up(dev)) {
			spin_lock_bh(&br->lock);
			br_stp_enable_port(p);
106
			notified = true;
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
			spin_unlock_bh(&br->lock);
		}
		break;

	case NETDEV_UNREGISTER:
		br_del_if(br, dev);
		break;

	case NETDEV_CHANGENAME:
		err = br_sysfs_renameif(p);
		if (err)
			return notifier_from_errno(err);
		break;

	case NETDEV_PRE_TYPE_CHANGE:
		/* Forbid underlaying device to change its type. */
		return NOTIFY_BAD;

	case NETDEV_RESEND_IGMP:
		/* Propagate to master device */
		call_netdevice_notifiers(event, br->dev);
		break;
	}

131 132
	if (event != NETDEV_UNREGISTER)
		br_vlan_port_event(p, event);
133

134
	/* Events that may cause spanning tree to refresh */
135 136
	if (!notified && (event == NETDEV_CHANGEADDR || event == NETDEV_UP ||
			  event == NETDEV_CHANGE || event == NETDEV_DOWN))
137
		br_ifinfo_notify(RTM_NEWLINK, NULL, p);
138 139 140 141 142 143 144 145

	return NOTIFY_DONE;
}

static struct notifier_block br_device_notifier = {
	.notifier_call = br_device_event
};

146
/* called with RTNL or RCU */
147 148
static int br_switchdev_event(struct notifier_block *unused,
			      unsigned long event, void *ptr)
149
{
150
	struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
151 152
	struct net_bridge_port *p;
	struct net_bridge *br;
153
	struct switchdev_notifier_fdb_info *fdb_info;
154 155
	int err = NOTIFY_DONE;

156
	p = br_port_get_rtnl_rcu(dev);
157 158 159 160 161 162
	if (!p)
		goto out;

	br = p->br;

	switch (event) {
163
	case SWITCHDEV_FDB_ADD_TO_BRIDGE:
164 165
		fdb_info = ptr;
		err = br_fdb_external_learn_add(br, p, fdb_info->addr,
166
						fdb_info->vid, false);
167
		if (err) {
168
			err = notifier_from_errno(err);
169 170 171
			break;
		}
		br_fdb_offloaded_set(br, p, fdb_info->addr,
172
				     fdb_info->vid, true);
173
		break;
174
	case SWITCHDEV_FDB_DEL_TO_BRIDGE:
175 176
		fdb_info = ptr;
		err = br_fdb_external_learn_del(br, p, fdb_info->addr,
177
						fdb_info->vid, false);
178 179 180
		if (err)
			err = notifier_from_errno(err);
		break;
181 182 183
	case SWITCHDEV_FDB_OFFLOADED:
		fdb_info = ptr;
		br_fdb_offloaded_set(br, p, fdb_info->addr,
184
				     fdb_info->vid, fdb_info->offloaded);
185
		break;
186 187 188 189 190 191
	}

out:
	return err;
}

192 193
static struct notifier_block br_switchdev_notifier = {
	.notifier_call = br_switchdev_event,
194 195
};

196 197 198 199 200 201 202 203 204 205 206 207 208 209
/* br_boolopt_toggle - change user-controlled boolean option
 *
 * @br: bridge device
 * @opt: id of the option to change
 * @on: new option value
 * @extack: extack for error messages
 *
 * Changes the value of the respective boolean option to @on taking care of
 * any internal option value mapping and configuration.
 */
int br_boolopt_toggle(struct net_bridge *br, enum br_boolopt_id opt, bool on,
		      struct netlink_ext_ack *extack)
{
	switch (opt) {
210 211 212
	case BR_BOOLOPT_NO_LL_LEARN:
		br_opt_toggle(br, BROPT_NO_LL_LEARN, on);
		break;
213 214 215 216 217 218 219 220 221 222 223 224
	default:
		/* shouldn't be called with unsupported options */
		WARN_ON(1);
		break;
	}

	return 0;
}

int br_boolopt_get(const struct net_bridge *br, enum br_boolopt_id opt)
{
	switch (opt) {
225 226
	case BR_BOOLOPT_NO_LL_LEARN:
		return br_opt_get(br, BROPT_NO_LL_LEARN);
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
	default:
		/* shouldn't be called with unsupported options */
		WARN_ON(1);
		break;
	}

	return 0;
}

int br_boolopt_multi_toggle(struct net_bridge *br,
			    struct br_boolopt_multi *bm,
			    struct netlink_ext_ack *extack)
{
	unsigned long bitmap = bm->optmask;
	int err = 0;
	int opt_id;

	for_each_set_bit(opt_id, &bitmap, BR_BOOLOPT_MAX) {
		bool on = !!(bm->optval & BIT(opt_id));

		err = br_boolopt_toggle(br, opt_id, on, extack);
		if (err) {
			br_debug(br, "boolopt multi-toggle error: option: %d current: %d new: %d error: %d\n",
				 opt_id, br_boolopt_get(br, opt_id), on, err);
			break;
		}
	}

	return err;
}

void br_boolopt_multi_get(const struct net_bridge *br,
			  struct br_boolopt_multi *bm)
{
	u32 optval = 0;
	int opt_id;

	for (opt_id = 0; opt_id < BR_BOOLOPT_MAX; opt_id++)
		optval |= (br_boolopt_get(br, opt_id) << opt_id);

	bm->optval = optval;
268
	bm->optmask = GENMASK((BR_BOOLOPT_MAX - 1), 0);
269 270 271
}

/* private bridge options, controlled by the kernel */
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
void br_opt_toggle(struct net_bridge *br, enum net_bridge_opts opt, bool on)
{
	bool cur = !!br_opt_get(br, opt);

	br_debug(br, "toggle option: %d state: %d -> %d\n",
		 opt, cur, on);

	if (cur == on)
		return;

	if (on)
		set_bit(opt, &br->options);
	else
		clear_bit(opt, &br->options);
}

W
WANG Cong 已提交
288 289 290 291 292 293 294 295 296 297 298 299 300 301
static void __net_exit br_net_exit(struct net *net)
{
	struct net_device *dev;
	LIST_HEAD(list);

	rtnl_lock();
	for_each_netdev(net, dev)
		if (dev->priv_flags & IFF_EBRIDGE)
			br_dev_delete(dev, &list);

	unregister_netdevice_many(&list);
	rtnl_unlock();

}
302

303 304 305 306
static struct pernet_operations br_net_ops = {
	.exit	= br_net_exit,
};

W
WANG Cong 已提交
307 308 309 310
static const struct stp_proto br_stp_proto = {
	.rcv	= br_stp_rcv,
};

L
Linus Torvalds 已提交
311 312
static int __init br_init(void)
{
313 314
	int err;

315
	BUILD_BUG_ON(sizeof(struct br_input_skb_cb) > sizeof_field(struct sk_buff, cb));
316

P
Patrick McHardy 已提交
317 318
	err = stp_proto_register(&br_stp_proto);
	if (err < 0) {
319
		pr_err("bridge: can't register sap for STP\n");
P
Patrick McHardy 已提交
320
		return err;
321 322
	}

323 324
	err = br_fdb_init();
	if (err)
325
		goto err_out;
L
Linus Torvalds 已提交
326

327
	err = register_pernet_subsys(&br_net_ops);
328 329 330
	if (err)
		goto err_out1;

331
	err = br_nf_core_init();
332 333 334
	if (err)
		goto err_out2;

335
	err = register_netdevice_notifier(&br_device_notifier);
336 337 338
	if (err)
		goto err_out3;

339
	err = register_switchdev_notifier(&br_switchdev_notifier);
340 341 342
	if (err)
		goto err_out4;

343 344 345 346
	err = br_netlink_init();
	if (err)
		goto err_out5;

L
Linus Torvalds 已提交
347 348
	brioctl_set(br_ioctl_deviceless_stub);

I
Igor Maravić 已提交
349
#if IS_ENABLED(CONFIG_ATM_LANE)
350 351
	br_fdb_test_addr_hook = br_fdb_test_addr;
#endif
L
Linus Torvalds 已提交
352

353 354 355
#if IS_MODULE(CONFIG_BRIDGE_NETFILTER)
	pr_info("bridge: filtering via arp/ip/ip6tables is no longer available "
		"by default. Update your scripts to load br_netfilter if you "
356
		"need this.\n");
357
#endif
358

L
Linus Torvalds 已提交
359
	return 0;
360

361
err_out5:
362
	unregister_switchdev_notifier(&br_switchdev_notifier);
363
err_out4:
364
	unregister_netdevice_notifier(&br_device_notifier);
365
err_out3:
366
	br_nf_core_fini();
367 368
err_out2:
	unregister_pernet_subsys(&br_net_ops);
369
err_out1:
370 371
	br_fdb_fini();
err_out:
P
Patrick McHardy 已提交
372
	stp_proto_unregister(&br_stp_proto);
373
	return err;
L
Linus Torvalds 已提交
374 375 376 377
}

static void __exit br_deinit(void)
{
P
Patrick McHardy 已提交
378
	stp_proto_unregister(&br_stp_proto);
379
	br_netlink_fini();
380
	unregister_switchdev_notifier(&br_switchdev_notifier);
L
Linus Torvalds 已提交
381 382
	unregister_netdevice_notifier(&br_device_notifier);
	brioctl_set(NULL);
383
	unregister_pernet_subsys(&br_net_ops);
L
Linus Torvalds 已提交
384

385
	rcu_barrier(); /* Wait for completion of call_rcu()'s */
L
Linus Torvalds 已提交
386

387
	br_nf_core_fini();
I
Igor Maravić 已提交
388
#if IS_ENABLED(CONFIG_ATM_LANE)
389 390
	br_fdb_test_addr_hook = NULL;
#endif
L
Linus Torvalds 已提交
391 392 393 394 395 396
	br_fdb_fini();
}

module_init(br_init)
module_exit(br_deinit)
MODULE_LICENSE("GPL");
S
Stephen Hemminger 已提交
397
MODULE_VERSION(BR_VERSION);
398
MODULE_ALIAS_RTNL_LINK("bridge");