br_netlink.c 12.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 *	Bridge netlink control interface
 *
 *	Authors:
 *	Stephen Hemminger		<shemminger@osdl.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>
14
#include <linux/slab.h>
15
#include <linux/etherdevice.h>
16
#include <net/rtnetlink.h>
17
#include <net/net_namespace.h>
18
#include <net/sock.h>
19
#include <uapi/linux/if_bridge.h>
20

21
#include "br_private.h"
22
#include "br_private_stp.h"
23

24 25 26 27 28 29
static inline size_t br_port_info_size(void)
{
	return nla_total_size(1)	/* IFLA_BRPORT_STATE  */
		+ nla_total_size(2)	/* IFLA_BRPORT_PRIORITY */
		+ nla_total_size(4)	/* IFLA_BRPORT_COST */
		+ nla_total_size(1)	/* IFLA_BRPORT_MODE */
30
		+ nla_total_size(1)	/* IFLA_BRPORT_GUARD */
S
stephen hemminger 已提交
31
		+ nla_total_size(1)	/* IFLA_BRPORT_PROTECT */
32 33 34
		+ 0;
}

35 36 37
static inline size_t br_nlmsg_size(void)
{
	return NLMSG_ALIGN(sizeof(struct ifinfomsg))
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
		+ nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
		+ nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
		+ nla_total_size(4) /* IFLA_MASTER */
		+ nla_total_size(4) /* IFLA_MTU */
		+ nla_total_size(4) /* IFLA_LINK */
		+ nla_total_size(1) /* IFLA_OPERSTATE */
		+ nla_total_size(br_port_info_size()); /* IFLA_PROTINFO */
}

static int br_port_fill_attrs(struct sk_buff *skb,
			      const struct net_bridge_port *p)
{
	u8 mode = !!(p->flags & BR_HAIRPIN_MODE);

	if (nla_put_u8(skb, IFLA_BRPORT_STATE, p->state) ||
	    nla_put_u16(skb, IFLA_BRPORT_PRIORITY, p->priority) ||
	    nla_put_u32(skb, IFLA_BRPORT_COST, p->path_cost) ||
55
	    nla_put_u8(skb, IFLA_BRPORT_MODE, mode) ||
S
stephen hemminger 已提交
56
	    nla_put_u8(skb, IFLA_BRPORT_GUARD, !!(p->flags & BR_BPDU_GUARD)) ||
57 58
	    nla_put_u8(skb, IFLA_BRPORT_PROTECT, !!(p->flags & BR_ROOT_BLOCK)) ||
	    nla_put_u8(skb, IFLA_BRPORT_FAST_LEAVE, !!(p->flags & BR_MULTICAST_FAST_LEAVE)))
59 60 61
		return -EMSGSIZE;

	return 0;
62 63
}

64 65 66 67
/*
 * Create one netlink message for one interface
 * Contains port and master info as well as carrier and bridge state.
 */
68 69 70 71
static int br_fill_ifinfo(struct sk_buff *skb,
			  const struct net_bridge_port *port,
			  u32 pid, u32 seq, int event, unsigned int flags,
			  u32 filter_mask, const struct net_device *dev)
72
{
73
	const struct net_bridge *br;
74
	struct ifinfomsg *hdr;
75 76 77
	struct nlmsghdr *nlh;
	u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN;

78 79 80 81 82
	if (port)
		br = port->br;
	else
		br = netdev_priv(dev);

83 84
	br_debug(br, "br_fill_info event %d port %s master %s\n",
		     event, dev->name, br->dev->name);
85

86 87
	nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
	if (nlh == NULL)
88
		return -EMSGSIZE;
89

90 91 92 93 94 95 96
	hdr = nlmsg_data(nlh);
	hdr->ifi_family = AF_BRIDGE;
	hdr->__ifi_pad = 0;
	hdr->ifi_type = dev->type;
	hdr->ifi_index = dev->ifindex;
	hdr->ifi_flags = dev_get_flags(dev);
	hdr->ifi_change = 0;
97

D
David S. Miller 已提交
98 99 100 101 102 103 104
	if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
	    nla_put_u32(skb, IFLA_MASTER, br->dev->ifindex) ||
	    nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
	    nla_put_u8(skb, IFLA_OPERSTATE, operstate) ||
	    (dev->addr_len &&
	     nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) ||
	    (dev->ifindex != dev->iflink &&
105
	     nla_put_u32(skb, IFLA_LINK, dev->iflink)))
D
David S. Miller 已提交
106
		goto nla_put_failure;
107

108
	if (event == RTM_NEWLINK && port) {
109 110 111 112 113 114 115 116
		struct nlattr *nest
			= nla_nest_start(skb, IFLA_PROTINFO | NLA_F_NESTED);

		if (nest == NULL || br_port_fill_attrs(skb, port) < 0)
			goto nla_put_failure;
		nla_nest_end(skb, nest);
	}

117 118 119 120 121 122
	/* Check if  the VID information is requested */
	if (filter_mask & RTEXT_FILTER_BRVLAN) {
		struct nlattr *af;
		const struct net_port_vlans *pv;
		struct bridge_vlan_info vinfo;
		u16 vid;
123
		u16 pvid;
124 125 126 127 128 129 130 131 132 133 134 135 136

		if (port)
			pv = nbp_get_vlan_info(port);
		else
			pv = br_get_vlan_info(br);

		if (!pv || bitmap_empty(pv->vlan_bitmap, BR_VLAN_BITMAP_LEN))
			goto done;

		af = nla_nest_start(skb, IFLA_AF_SPEC);
		if (!af)
			goto nla_put_failure;

137
		pvid = br_get_pvid(pv);
138 139 140 141 142 143
		for (vid = find_first_bit(pv->vlan_bitmap, BR_VLAN_BITMAP_LEN);
		     vid < BR_VLAN_BITMAP_LEN;
		     vid = find_next_bit(pv->vlan_bitmap,
					 BR_VLAN_BITMAP_LEN, vid+1)) {
			vinfo.vid = vid;
			vinfo.flags = 0;
144 145
			if (vid == pvid)
				vinfo.flags |= BRIDGE_VLAN_INFO_PVID;
146 147 148 149 150 151 152 153 154
			if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO,
				    sizeof(vinfo), &vinfo))
				goto nla_put_failure;
		}

		nla_nest_end(skb, af);
	}

done:
155
	return nlmsg_end(skb, nlh);
156

157
nla_put_failure:
158 159
	nlmsg_cancel(skb, nlh);
	return -EMSGSIZE;
160 161 162 163 164 165 166
}

/*
 * Notify listeners of a change in port information
 */
void br_ifinfo_notify(int event, struct net_bridge_port *port)
{
167
	struct net *net;
168
	struct sk_buff *skb;
169
	int err = -ENOBUFS;
170

171 172 173 174
	if (!port)
		return;

	net = dev_net(port->dev);
175
	br_debug(port->br, "port %u(%s) event %d\n",
176
		 (unsigned int)port->port_no, port->dev->name, event);
177

178
	skb = nlmsg_new(br_nlmsg_size(), GFP_ATOMIC);
179 180 181
	if (skb == NULL)
		goto errout;

182
	err = br_fill_ifinfo(skb, port, 0, 0, event, 0, 0, port->dev);
183 184 185 186 187 188
	if (err < 0) {
		/* -EMSGSIZE implies BUG in br_nlmsg_size() */
		WARN_ON(err == -EMSGSIZE);
		kfree_skb(skb);
		goto errout;
	}
189 190
	rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
	return;
191
errout:
S
Stephen Hemminger 已提交
192
	if (err < 0)
193
		rtnl_set_sk_err(net, RTNLGRP_LINK, err);
194 195
}

196

197 198 199
/*
 * Dump information about all ports, in response to GETLINK
 */
J
John Fastabend 已提交
200
int br_getlink(struct sk_buff *skb, u32 pid, u32 seq,
201
	       struct net_device *dev, u32 filter_mask)
202
{
J
John Fastabend 已提交
203 204 205
	int err = 0;
	struct net_bridge_port *port = br_port_get_rcu(dev);

206 207
	/* not a bridge port and  */
	if (!port && !(filter_mask & RTEXT_FILTER_BRVLAN))
J
John Fastabend 已提交
208
		goto out;
209

210 211
	err = br_fill_ifinfo(skb, port, pid, seq, RTM_NEWLINK, NLM_F_MULTI,
			     filter_mask, dev);
J
John Fastabend 已提交
212 213
out:
	return err;
214 215
}

216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
const struct nla_policy ifla_br_policy[IFLA_MAX+1] = {
	[IFLA_BRIDGE_FLAGS]	= { .type = NLA_U16 },
	[IFLA_BRIDGE_MODE]	= { .type = NLA_U16 },
	[IFLA_BRIDGE_VLAN_INFO]	= { .type = NLA_BINARY,
				    .len = sizeof(struct bridge_vlan_info), },
};

static int br_afspec(struct net_bridge *br,
		     struct net_bridge_port *p,
		     struct nlattr *af_spec,
		     int cmd)
{
	struct nlattr *tb[IFLA_BRIDGE_MAX+1];
	int err = 0;

	err = nla_parse_nested(tb, IFLA_BRIDGE_MAX, af_spec, ifla_br_policy);
	if (err)
		return err;

	if (tb[IFLA_BRIDGE_VLAN_INFO]) {
		struct bridge_vlan_info *vinfo;

		vinfo = nla_data(tb[IFLA_BRIDGE_VLAN_INFO]);

		if (vinfo->vid >= VLAN_N_VID)
			return -EINVAL;

		switch (cmd) {
		case RTM_SETLINK:
			if (p) {
246
				err = nbp_vlan_add(p, vinfo->vid, vinfo->flags);
247 248 249 250
				if (err)
					break;

				if (vinfo->flags & BRIDGE_VLAN_INFO_MASTER)
251 252
					err = br_vlan_add(p->br, vinfo->vid,
							  vinfo->flags);
253
			} else
254
				err = br_vlan_add(br, vinfo->vid, vinfo->flags);
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274

			if (err)
				break;

			break;

		case RTM_DELLINK:
			if (p) {
				nbp_vlan_delete(p, vinfo->vid);
				if (vinfo->flags & BRIDGE_VLAN_INFO_MASTER)
					br_vlan_delete(p->br, vinfo->vid);
			} else
				br_vlan_delete(br, vinfo->vid);
			break;
		}
	}

	return err;
}

275 276 277 278 279
static const struct nla_policy ifla_brport_policy[IFLA_BRPORT_MAX + 1] = {
	[IFLA_BRPORT_STATE]	= { .type = NLA_U8 },
	[IFLA_BRPORT_COST]	= { .type = NLA_U32 },
	[IFLA_BRPORT_PRIORITY]	= { .type = NLA_U16 },
	[IFLA_BRPORT_MODE]	= { .type = NLA_U8 },
280
	[IFLA_BRPORT_GUARD]	= { .type = NLA_U8 },
S
stephen hemminger 已提交
281
	[IFLA_BRPORT_PROTECT]	= { .type = NLA_U8 },
282 283 284 285 286 287 288 289 290 291 292 293
};

/* Change the state of the port and notify spanning tree */
static int br_set_port_state(struct net_bridge_port *p, u8 state)
{
	if (state > BR_STATE_BLOCKING)
		return -EINVAL;

	/* if kernel STP is running, don't allow changes */
	if (p->br->stp_enabled == BR_KERNEL_STP)
		return -EBUSY;

294 295 296
	/* if device is not up, change is not allowed
	 * if link is not present, only allowable state is disabled
	 */
297
	if (!netif_running(p->dev) ||
298
	    (!netif_oper_up(p->dev) && state != BR_STATE_DISABLED))
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
		return -ENETDOWN;

	p->state = state;
	br_log_state(p);
	br_port_state_selection(p->br);
	return 0;
}

/* Set/clear or port flags based on attribute */
static void br_set_port_flag(struct net_bridge_port *p, struct nlattr *tb[],
			   int attrtype, unsigned long mask)
{
	if (tb[attrtype]) {
		u8 flag = nla_get_u8(tb[attrtype]);
		if (flag)
			p->flags |= mask;
		else
			p->flags &= ~mask;
	}
}

/* Process bridge protocol info on port */
static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
{
	int err;

	br_set_port_flag(p, tb, IFLA_BRPORT_MODE, BR_HAIRPIN_MODE);
326
	br_set_port_flag(p, tb, IFLA_BRPORT_GUARD, BR_BPDU_GUARD);
327
	br_set_port_flag(p, tb, IFLA_BRPORT_FAST_LEAVE, BR_MULTICAST_FAST_LEAVE);
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349

	if (tb[IFLA_BRPORT_COST]) {
		err = br_stp_set_path_cost(p, nla_get_u32(tb[IFLA_BRPORT_COST]));
		if (err)
			return err;
	}

	if (tb[IFLA_BRPORT_PRIORITY]) {
		err = br_stp_set_port_priority(p, nla_get_u16(tb[IFLA_BRPORT_PRIORITY]));
		if (err)
			return err;
	}

	if (tb[IFLA_BRPORT_STATE]) {
		err = br_set_port_state(p, nla_get_u8(tb[IFLA_BRPORT_STATE]));
		if (err)
			return err;
	}
	return 0;
}

/* Change state and parameters on port. */
J
John Fastabend 已提交
350
int br_setlink(struct net_device *dev, struct nlmsghdr *nlh)
351
{
352 353
	struct ifinfomsg *ifm;
	struct nlattr *protinfo;
354
	struct nlattr *afspec;
355
	struct net_bridge_port *p;
356
	struct nlattr *tb[IFLA_BRPORT_MAX + 1];
357
	int err;
358

359
	ifm = nlmsg_data(nlh);
360

361
	protinfo = nlmsg_find_attr(nlh, sizeof(*ifm), IFLA_PROTINFO);
362 363
	afspec = nlmsg_find_attr(nlh, sizeof(*ifm), IFLA_AF_SPEC);
	if (!protinfo && !afspec)
364
		return 0;
365

366
	p = br_port_get_rtnl(dev);
367 368 369 370
	/* We want to accept dev as bridge itself if the AF_SPEC
	 * is set to see if someone is setting vlan info on the brigde
	 */
	if (!p && ((dev->priv_flags & IFF_EBRIDGE) && !afspec))
371
		return -EINVAL;
372

373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
	if (p && protinfo) {
		if (protinfo->nla_type & NLA_F_NESTED) {
			err = nla_parse_nested(tb, IFLA_BRPORT_MAX,
					       protinfo, ifla_brport_policy);
			if (err)
				return err;

			spin_lock_bh(&p->br->lock);
			err = br_setport(p, tb);
			spin_unlock_bh(&p->br->lock);
		} else {
			/* Binary compatability with old RSTP */
			if (nla_len(protinfo) < sizeof(u8))
				return -EINVAL;

			spin_lock_bh(&p->br->lock);
			err = br_set_port_state(p, nla_get_u8(protinfo));
			spin_unlock_bh(&p->br->lock);
		}
392
		if (err)
393 394
			goto out;
	}
395

396 397 398
	if (afspec) {
		err = br_afspec((struct net_bridge *)netdev_priv(dev), p,
				afspec, RTM_SETLINK);
399
	}
400

401 402
	if (err == 0)
		br_ifinfo_notify(RTM_NEWLINK, p);
403

404
out:
405
	return err;
406 407
}

408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
/* Delete port information */
int br_dellink(struct net_device *dev, struct nlmsghdr *nlh)
{
	struct ifinfomsg *ifm;
	struct nlattr *afspec;
	struct net_bridge_port *p;
	int err;

	ifm = nlmsg_data(nlh);

	afspec = nlmsg_find_attr(nlh, sizeof(*ifm), IFLA_AF_SPEC);
	if (!afspec)
		return 0;

	p = br_port_get_rtnl(dev);
	/* We want to accept dev as bridge itself as well */
	if (!p && !(dev->priv_flags & IFF_EBRIDGE))
		return -EINVAL;

	err = br_afspec((struct net_bridge *)netdev_priv(dev), p,
			afspec, RTM_DELLINK);

	return err;
}
432 433 434 435 436 437 438 439 440 441 442 443
static int br_validate(struct nlattr *tb[], struct nlattr *data[])
{
	if (tb[IFLA_ADDRESS]) {
		if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
			return -EINVAL;
		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
			return -EADDRNOTAVAIL;
	}

	return 0;
}

444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
static size_t br_get_link_af_size(const struct net_device *dev)
{
	struct net_port_vlans *pv;

	if (br_port_exists(dev))
		pv = nbp_get_vlan_info(br_port_get_rcu(dev));
	else if (dev->priv_flags & IFF_EBRIDGE)
		pv = br_get_vlan_info((struct net_bridge *)netdev_priv(dev));
	else
		return 0;

	if (!pv)
		return 0;

	/* Each VLAN is returned in bridge_vlan_info along with flags */
	return pv->num_vlans * nla_total_size(sizeof(struct bridge_vlan_info));
}

struct rtnl_af_ops br_af_ops = {
	.family			= AF_BRIDGE,
	.get_link_af_size	= br_get_link_af_size,
};

467
struct rtnl_link_ops br_link_ops __read_mostly = {
468 469 470 471
	.kind		= "bridge",
	.priv_size	= sizeof(struct net_bridge),
	.setup		= br_dev_setup,
	.validate	= br_validate,
472
	.dellink	= br_dev_delete,
473
};
474

475
int __init br_netlink_init(void)
476
{
477 478 479
	int err;

	br_mdb_init();
480
	err = rtnl_af_register(&br_af_ops);
481 482 483
	if (err)
		goto out;

484 485 486 487
	err = rtnl_link_register(&br_link_ops);
	if (err)
		goto out_af;

488
	return 0;
489 490 491

out_af:
	rtnl_af_unregister(&br_af_ops);
492 493 494
out:
	br_mdb_uninit();
	return err;
495 496 497 498
}

void __exit br_netlink_fini(void)
{
499
	br_mdb_uninit();
500
	rtnl_af_unregister(&br_af_ops);
501
	rtnl_link_unregister(&br_link_ops);
502
}