br.c 8.5 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 40 41 42 43 44 45
	if (dev->priv_flags & IFF_EBRIDGE) {
		if (event == NETDEV_REGISTER) {
			/* register of bridge completed, add sysfs entries */
			br_sysfs_addbr(dev);
			return NOTIFY_DONE;
		}
		br_vlan_bridge_event(dev, event, ptr);
46 47 48 49 50 51 52 53 54 55 56
	}

	/* 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:
57
		br_mtu_auto_adjust(br);
58 59
		break;

60 61 62 63 64 65 66 67 68 69 70
	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;

71 72 73 74 75 76 77 78 79 80 81 82
	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:
83
		br_port_carrier_check(p, &notified);
84 85 86 87 88 89 90 91
		break;

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

	case NETDEV_DOWN:
		spin_lock_bh(&br->lock);
92
		if (br->dev->flags & IFF_UP) {
93
			br_stp_disable_port(p);
94 95
			notified = true;
		}
96 97 98 99 100 101 102
		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);
103
			notified = true;
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
			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;
	}

128 129
	if (event != NETDEV_UNREGISTER)
		br_vlan_port_event(p, event);
130

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

	return NOTIFY_DONE;
}

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

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

153
	p = br_port_get_rtnl_rcu(dev);
154 155 156 157 158 159
	if (!p)
		goto out;

	br = p->br;

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

out:
	return err;
}

189 190
static struct notifier_block br_switchdev_notifier = {
	.notifier_call = br_switchdev_event,
191 192
};

193 194 195 196 197 198 199 200 201 202 203 204 205 206
/* 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) {
207 208 209
	case BR_BOOLOPT_NO_LL_LEARN:
		br_opt_toggle(br, BROPT_NO_LL_LEARN, on);
		break;
210 211 212 213 214 215 216 217 218 219 220 221
	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) {
222 223
	case BR_BOOLOPT_NO_LL_LEARN:
		return br_opt_get(br, BROPT_NO_LL_LEARN);
224 225 226 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
	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;
265
	bm->optmask = GENMASK((BR_BOOLOPT_MAX - 1), 0);
266 267 268
}

/* private bridge options, controlled by the kernel */
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
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 已提交
285 286 287 288 289 290 291 292 293 294 295 296 297 298
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();

}
299

300 301 302 303
static struct pernet_operations br_net_ops = {
	.exit	= br_net_exit,
};

W
WANG Cong 已提交
304 305 306 307
static const struct stp_proto br_stp_proto = {
	.rcv	= br_stp_rcv,
};

L
Linus Torvalds 已提交
308 309
static int __init br_init(void)
{
310 311
	int err;

312 313
	BUILD_BUG_ON(sizeof(struct br_input_skb_cb) > FIELD_SIZEOF(struct sk_buff, cb));

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

320 321
	err = br_fdb_init();
	if (err)
322
		goto err_out;
L
Linus Torvalds 已提交
323

324
	err = register_pernet_subsys(&br_net_ops);
325 326 327
	if (err)
		goto err_out1;

328
	err = br_nf_core_init();
329 330 331
	if (err)
		goto err_out2;

332
	err = register_netdevice_notifier(&br_device_notifier);
333 334 335
	if (err)
		goto err_out3;

336
	err = register_switchdev_notifier(&br_switchdev_notifier);
337 338 339
	if (err)
		goto err_out4;

340 341 342 343
	err = br_netlink_init();
	if (err)
		goto err_out5;

L
Linus Torvalds 已提交
344 345
	brioctl_set(br_ioctl_deviceless_stub);

I
Igor Maravić 已提交
346
#if IS_ENABLED(CONFIG_ATM_LANE)
347 348
	br_fdb_test_addr_hook = br_fdb_test_addr;
#endif
L
Linus Torvalds 已提交
349

350 351 352
#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 "
353
		"need this.\n");
354
#endif
355

L
Linus Torvalds 已提交
356
	return 0;
357

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

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

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

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

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