br.c 9.0 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
		if (event == NETDEV_REGISTER) {
			/* register of bridge completed, add sysfs entries */
46 47 48 49
			err = br_sysfs_addbr(dev);
			if (err)
				return notifier_from_errno(err);

50 51
			return NOTIFY_DONE;
		}
52 53 54 55 56 57 58 59 60 61 62
	}

	/* 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:
63
		br_mtu_auto_adjust(br);
64 65
		break;

66 67 68 69 70 71 72 73 74 75 76
	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;

77 78 79 80 81 82 83 84 85 86 87 88
	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:
89
		br_port_carrier_check(p, &notified);
90 91 92 93 94 95 96 97
		break;

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

	case NETDEV_DOWN:
		spin_lock_bh(&br->lock);
98
		if (br->dev->flags & IFF_UP) {
99
			br_stp_disable_port(p);
100 101
			notified = true;
		}
102 103 104 105 106 107 108
		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);
109
			notified = true;
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
			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:
125
		/* Forbid underlying device to change its type. */
126 127 128 129 130 131 132 133
		return NOTIFY_BAD;

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

134 135
	if (event != NETDEV_UNREGISTER)
		br_vlan_port_event(p, event);
136

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

	return NOTIFY_DONE;
}

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

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

159
	p = br_port_get_rtnl_rcu(dev);
160 161 162 163 164 165
	if (!p)
		goto out;

	br = p->br;

	switch (event) {
166
	case SWITCHDEV_FDB_ADD_TO_BRIDGE:
167 168
		fdb_info = ptr;
		err = br_fdb_external_learn_add(br, p, fdb_info->addr,
169
						fdb_info->vid, false);
170
		if (err) {
171
			err = notifier_from_errno(err);
172 173 174
			break;
		}
		br_fdb_offloaded_set(br, p, fdb_info->addr,
175
				     fdb_info->vid, true);
176
		break;
177
	case SWITCHDEV_FDB_DEL_TO_BRIDGE:
178 179
		fdb_info = ptr;
		err = br_fdb_external_learn_del(br, p, fdb_info->addr,
180
						fdb_info->vid, false);
181 182 183
		if (err)
			err = notifier_from_errno(err);
		break;
184 185 186
	case SWITCHDEV_FDB_OFFLOADED:
		fdb_info = ptr;
		br_fdb_offloaded_set(br, p, fdb_info->addr,
187
				     fdb_info->vid, fdb_info->offloaded);
188
		break;
189 190 191 192 193
	case SWITCHDEV_FDB_FLUSH_TO_BRIDGE:
		fdb_info = ptr;
		/* Don't delete static entries */
		br_fdb_delete_by_port(br, p, fdb_info->vid, 0);
		break;
194 195 196 197 198 199
	}

out:
	return err;
}

200 201
static struct notifier_block br_switchdev_notifier = {
	.notifier_call = br_switchdev_event,
202 203
};

204 205 206 207 208 209 210 211 212 213 214 215 216
/* 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)
{
217 218
	int err = 0;

219
	switch (opt) {
220 221 222
	case BR_BOOLOPT_NO_LL_LEARN:
		br_opt_toggle(br, BROPT_NO_LL_LEARN, on);
		break;
223 224 225
	case BR_BOOLOPT_MCAST_VLAN_SNOOPING:
		err = br_multicast_toggle_vlan_snooping(br, on, extack);
		break;
226 227 228 229 230 231
	default:
		/* shouldn't be called with unsupported options */
		WARN_ON(1);
		break;
	}

232
	return err;
233 234 235 236 237
}

int br_boolopt_get(const struct net_bridge *br, enum br_boolopt_id opt)
{
	switch (opt) {
238 239
	case BR_BOOLOPT_NO_LL_LEARN:
		return br_opt_get(br, BROPT_NO_LL_LEARN);
240 241
	case BR_BOOLOPT_MCAST_VLAN_SNOOPING:
		return br_opt_get(br, BROPT_MCAST_VLAN_SNOOPING_ENABLED);
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 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
	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;
283
	bm->optmask = GENMASK((BR_BOOLOPT_MAX - 1), 0);
284 285 286
}

/* private bridge options, controlled by the kernel */
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
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 已提交
303 304 305 306 307 308 309 310 311 312 313 314 315 316
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();

}
317

318 319 320 321
static struct pernet_operations br_net_ops = {
	.exit	= br_net_exit,
};

W
WANG Cong 已提交
322 323 324 325
static const struct stp_proto br_stp_proto = {
	.rcv	= br_stp_rcv,
};

L
Linus Torvalds 已提交
326 327
static int __init br_init(void)
{
328 329
	int err;

330
	BUILD_BUG_ON(sizeof(struct br_input_skb_cb) > sizeof_field(struct sk_buff, cb));
331

P
Patrick McHardy 已提交
332 333
	err = stp_proto_register(&br_stp_proto);
	if (err < 0) {
334
		pr_err("bridge: can't register sap for STP\n");
P
Patrick McHardy 已提交
335
		return err;
336 337
	}

338 339
	err = br_fdb_init();
	if (err)
340
		goto err_out;
L
Linus Torvalds 已提交
341

342
	err = register_pernet_subsys(&br_net_ops);
343 344 345
	if (err)
		goto err_out1;

346
	err = br_nf_core_init();
347 348 349
	if (err)
		goto err_out2;

350
	err = register_netdevice_notifier(&br_device_notifier);
351 352 353
	if (err)
		goto err_out3;

354
	err = register_switchdev_notifier(&br_switchdev_notifier);
355 356 357
	if (err)
		goto err_out4;

358 359 360 361
	err = br_netlink_init();
	if (err)
		goto err_out5;

L
Linus Torvalds 已提交
362 363
	brioctl_set(br_ioctl_deviceless_stub);

I
Igor Maravić 已提交
364
#if IS_ENABLED(CONFIG_ATM_LANE)
365 366
	br_fdb_test_addr_hook = br_fdb_test_addr;
#endif
L
Linus Torvalds 已提交
367

368 369 370
#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 "
371
		"need this.\n");
372
#endif
373

L
Linus Torvalds 已提交
374
	return 0;
375

376
err_out5:
377
	unregister_switchdev_notifier(&br_switchdev_notifier);
378
err_out4:
379
	unregister_netdevice_notifier(&br_device_notifier);
380
err_out3:
381
	br_nf_core_fini();
382 383
err_out2:
	unregister_pernet_subsys(&br_net_ops);
384
err_out1:
385 386
	br_fdb_fini();
err_out:
P
Patrick McHardy 已提交
387
	stp_proto_unregister(&br_stp_proto);
388
	return err;
L
Linus Torvalds 已提交
389 390 391 392
}

static void __exit br_deinit(void)
{
P
Patrick McHardy 已提交
393
	stp_proto_unregister(&br_stp_proto);
394
	br_netlink_fini();
395
	unregister_switchdev_notifier(&br_switchdev_notifier);
L
Linus Torvalds 已提交
396 397
	unregister_netdevice_notifier(&br_device_notifier);
	brioctl_set(NULL);
398
	unregister_pernet_subsys(&br_net_ops);
L
Linus Torvalds 已提交
399

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

402
	br_nf_core_fini();
I
Igor Maravić 已提交
403
#if IS_ENABLED(CONFIG_ATM_LANE)
404 405
	br_fdb_test_addr_hook = NULL;
#endif
L
Linus Torvalds 已提交
406 407 408 409 410 411
	br_fdb_fini();
}

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