vlan.c 19.5 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5
/*
 * INET		802.1Q VLAN
 *		Ethernet-type device handling.
 *
 * Authors:	Ben Greear <greearb@candelatech.com>
P
Patrick McHardy 已提交
6
 *              Please send support related email to: netdev@vger.kernel.org
L
Linus Torvalds 已提交
7
 *              VLAN Home Page: http://www.candelatech.com/~greear/vlan.html
8
 *
L
Linus Torvalds 已提交
9 10 11 12 13 14 15 16 17 18 19 20
 * Fixes:
 *              Fix for packet capture - Nick Eggleston <nick@dccinc.com>;
 *		Add HW acceleration hooks - David S. Miller <davem@redhat.com>;
 *		Correct all the locking - David S. Miller <davem@redhat.com>;
 *		Use hash table for VLAN groups - David S. Miller <davem@redhat.com>
 *
 *		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.
 */

J
Joe Perches 已提交
21 22
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

23
#include <linux/capability.h>
L
Linus Torvalds 已提交
24 25 26
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
27
#include <linux/slab.h>
L
Linus Torvalds 已提交
28
#include <linux/init.h>
29
#include <linux/rculist.h>
L
Linus Torvalds 已提交
30 31 32 33
#include <net/p8022.h>
#include <net/arp.h>
#include <linux/rtnetlink.h>
#include <linux/notifier.h>
34
#include <net/rtnetlink.h>
35
#include <net/net_namespace.h>
36
#include <net/netns/generic.h>
37
#include <linux/uaccess.h>
L
Linus Torvalds 已提交
38 39 40 41 42 43 44 45 46

#include <linux/if_vlan.h>
#include "vlan.h"
#include "vlanproc.h"

#define DRV_VERSION "1.8"

/* Global VLAN variables */

47
unsigned int vlan_net_id __read_mostly;
48

49 50
const char vlan_fullname[] = "802.1Q VLAN Support";
const char vlan_version[] = DRV_VERSION;
L
Linus Torvalds 已提交
51 52 53

/* End of global variables definitions. */

54 55
static int vlan_group_prealloc_vid(struct vlan_group *vg,
				   __be16 vlan_proto, u16 vlan_id)
56 57
{
	struct net_device **array;
58
	unsigned int pidx, vidx;
59 60 61 62
	unsigned int size;

	ASSERT_RTNL();

63 64 65
	pidx  = vlan_proto_idx(vlan_proto);
	vidx  = vlan_id / VLAN_GROUP_ARRAY_PART_LEN;
	array = vg->vlan_devices_arrays[pidx][vidx];
66 67 68 69 70 71 72 73
	if (array != NULL)
		return 0;

	size = sizeof(struct net_device *) * VLAN_GROUP_ARRAY_PART_LEN;
	array = kzalloc(size, GFP_KERNEL);
	if (array == NULL)
		return -ENOBUFS;

74
	vg->vlan_devices_arrays[pidx][vidx] = array;
75
	return 0;
76 77
}

78
void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
L
Linus Torvalds 已提交
79
{
80
	struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
81
	struct net_device *real_dev = vlan->real_dev;
82
	struct vlan_info *vlan_info;
L
Linus Torvalds 已提交
83
	struct vlan_group *grp;
84
	u16 vlan_id = vlan->vlan_id;
L
Linus Torvalds 已提交
85 86

	ASSERT_RTNL();
87

88 89 90 91
	vlan_info = rtnl_dereference(real_dev->vlan_info);
	BUG_ON(!vlan_info);

	grp = &vlan_info->grp;
92

93
	grp->nr_vlan_devs--;
94

95 96
	if (vlan->flags & VLAN_FLAG_MVRP)
		vlan_mvrp_request_leave(dev);
E
Eric Dumazet 已提交
97 98 99
	if (vlan->flags & VLAN_FLAG_GVRP)
		vlan_gvrp_request_leave(dev);

100
	vlan_group_set_device(grp, vlan->vlan_proto, vlan_id, NULL);
101 102

	netdev_upper_dev_unlink(real_dev, dev);
103 104 105 106
	/* Because unregister_netdevice_queue() makes sure at least one rcu
	 * grace period is respected before device freeing,
	 * we dont need to call synchronize_net() here.
	 */
107
	unregister_netdevice_queue(dev, head);
108

109 110
	if (grp->nr_vlan_devs == 0) {
		vlan_mvrp_uninit_applicant(real_dev);
P
Patrick McHardy 已提交
111
		vlan_gvrp_uninit_applicant(real_dev);
112
	}
P
Patrick McHardy 已提交
113

114
	vlan_vid_del(real_dev, vlan->vlan_proto, vlan_id);
115

116 117
	/* Get rid of the vlan's reference to real_dev */
	dev_put(real_dev);
L
Linus Torvalds 已提交
118 119
}

120
int vlan_check_real_dev(struct net_device *real_dev,
121 122
			__be16 protocol, u16 vlan_id,
			struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
123
{
124
	const char *name = real_dev->name;
125

L
Linus Torvalds 已提交
126
	if (real_dev->features & NETIF_F_VLAN_CHALLENGED) {
J
Joe Perches 已提交
127
		pr_info("VLANs not supported on %s\n", name);
128
		NL_SET_ERR_MSG_MOD(extack, "VLANs not supported on device");
P
Patrick McHardy 已提交
129
		return -EOPNOTSUPP;
L
Linus Torvalds 已提交
130 131
	}

132 133
	if (vlan_find_dev(real_dev, protocol, vlan_id) != NULL) {
		NL_SET_ERR_MSG_MOD(extack, "VLAN device already exists");
P
Patrick McHardy 已提交
134
		return -EEXIST;
135
	}
L
Linus Torvalds 已提交
136

P
Patrick McHardy 已提交
137 138 139
	return 0;
}

140
int register_vlan_dev(struct net_device *dev, struct netlink_ext_ack *extack)
141
{
142
	struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
143
	struct net_device *real_dev = vlan->real_dev;
144
	u16 vlan_id = vlan->vlan_id;
145 146
	struct vlan_info *vlan_info;
	struct vlan_group *grp;
147 148
	int err;

149
	err = vlan_vid_add(real_dev, vlan->vlan_proto, vlan_id);
150 151 152 153 154 155 156 157 158
	if (err)
		return err;

	vlan_info = rtnl_dereference(real_dev->vlan_info);
	/* vlan_info should be there now. vlan_vid_add took care of it */
	BUG_ON(!vlan_info);

	grp = &vlan_info->grp;
	if (grp->nr_vlan_devs == 0) {
P
Patrick McHardy 已提交
159 160
		err = vlan_gvrp_init_applicant(real_dev);
		if (err < 0)
161
			goto out_vid_del;
162 163 164
		err = vlan_mvrp_init_applicant(real_dev);
		if (err < 0)
			goto out_uninit_gvrp;
165 166
	}

167
	err = vlan_group_prealloc_vid(grp, vlan->vlan_proto, vlan_id);
168
	if (err < 0)
169
		goto out_uninit_mvrp;
170

171
	vlan->nest_level = dev_get_nest_level(real_dev) + 1;
172 173
	err = register_netdevice(dev);
	if (err < 0)
174 175
		goto out_uninit_mvrp;

176
	err = netdev_upper_dev_link(real_dev, dev, extack);
177 178
	if (err)
		goto out_unregister_netdev;
179

180
	/* Account for reference in struct vlan_dev_priv */
181 182
	dev_hold(real_dev);

183
	netif_stacked_transfer_operstate(real_dev, dev);
184 185 186 187 188
	linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */

	/* So, got the sucker initialized, now lets place
	 * it into our local structure.
	 */
189
	vlan_group_set_device(grp, vlan->vlan_proto, vlan_id, dev);
190
	grp->nr_vlan_devs++;
191 192 193

	return 0;

194 195
out_unregister_netdev:
	unregister_netdevice(dev);
196 197 198 199
out_uninit_mvrp:
	if (grp->nr_vlan_devs == 0)
		vlan_mvrp_uninit_applicant(real_dev);
out_uninit_gvrp:
200
	if (grp->nr_vlan_devs == 0)
P
Patrick McHardy 已提交
201
		vlan_gvrp_uninit_applicant(real_dev);
202
out_vid_del:
203
	vlan_vid_del(real_dev, vlan->vlan_proto, vlan_id);
204 205 206
	return err;
}

P
Patrick McHardy 已提交
207
/*  Attach a VLAN device to a mac address (ie Ethernet Card).
208
 *  Returns 0 if the device was created or a negative error code otherwise.
P
Patrick McHardy 已提交
209
 */
210
static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
P
Patrick McHardy 已提交
211 212
{
	struct net_device *new_dev;
213
	struct vlan_dev_priv *vlan;
214 215
	struct net *net = dev_net(real_dev);
	struct vlan_net *vn = net_generic(net, vlan_net_id);
P
Patrick McHardy 已提交
216
	char name[IFNAMSIZ];
217
	int err;
P
Patrick McHardy 已提交
218

219
	if (vlan_id >= VLAN_VID_MASK)
220
		return -ERANGE;
P
Patrick McHardy 已提交
221

222 223
	err = vlan_check_real_dev(real_dev, htons(ETH_P_8021Q), vlan_id,
				  NULL);
224 225
	if (err < 0)
		return err;
P
Patrick McHardy 已提交
226

L
Linus Torvalds 已提交
227
	/* Gotta set up the fields for the device. */
228
	switch (vn->name_type) {
L
Linus Torvalds 已提交
229 230
	case VLAN_NAME_TYPE_RAW_PLUS_VID:
		/* name will look like:	 eth1.0005 */
231
		snprintf(name, IFNAMSIZ, "%s.%.4i", real_dev->name, vlan_id);
L
Linus Torvalds 已提交
232 233 234 235 236
		break;
	case VLAN_NAME_TYPE_PLUS_VID_NO_PAD:
		/* Put our vlan.VID in the name.
		 * Name will look like:	 vlan5
		 */
237
		snprintf(name, IFNAMSIZ, "vlan%i", vlan_id);
L
Linus Torvalds 已提交
238 239 240 241 242
		break;
	case VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD:
		/* Put our vlan.VID in the name.
		 * Name will look like:	 eth0.5
		 */
243
		snprintf(name, IFNAMSIZ, "%s.%i", real_dev->name, vlan_id);
L
Linus Torvalds 已提交
244 245 246 247 248 249
		break;
	case VLAN_NAME_TYPE_PLUS_VID:
		/* Put our vlan.VID in the name.
		 * Name will look like:	 vlan0005
		 */
	default:
250
		snprintf(name, IFNAMSIZ, "vlan%.4i", vlan_id);
251
	}
252

253 254
	new_dev = alloc_netdev(sizeof(struct vlan_dev_priv), name,
			       NET_NAME_UNKNOWN, vlan_setup);
255

L
Linus Torvalds 已提交
256
	if (new_dev == NULL)
257
		return -ENOBUFS;
L
Linus Torvalds 已提交
258

259
	dev_net_set(new_dev, net);
L
Linus Torvalds 已提交
260 261 262 263 264
	/* need 4 bytes for extra VLAN header info,
	 * hope the underlying device can handle it.
	 */
	new_dev->mtu = real_dev->mtu;

265 266 267 268 269 270
	vlan = vlan_dev_priv(new_dev);
	vlan->vlan_proto = htons(ETH_P_8021Q);
	vlan->vlan_id = vlan_id;
	vlan->real_dev = real_dev;
	vlan->dent = NULL;
	vlan->flags = VLAN_FLAG_REORDER_HDR;
L
Linus Torvalds 已提交
271

P
Patrick McHardy 已提交
272
	new_dev->rtnl_link_ops = &vlan_link_ops;
273
	err = register_vlan_dev(new_dev, NULL);
274
	if (err < 0)
275
		goto out_free_newdev;
L
Linus Torvalds 已提交
276

277
	return 0;
L
Linus Torvalds 已提交
278 279

out_free_newdev:
280 281
	if (new_dev->reg_state == NETREG_UNINITIALIZED)
		free_netdev(new_dev);
282
	return err;
L
Linus Torvalds 已提交
283 284
}

285 286 287
static void vlan_sync_address(struct net_device *dev,
			      struct net_device *vlandev)
{
288
	struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
289 290

	/* May be called without an actual change */
291
	if (ether_addr_equal(vlan->real_dev_addr, dev->dev_addr))
292 293
		return;

294 295 296 297
	/* vlan continues to inherit address of lower device */
	if (vlan_dev_inherit_address(vlandev, dev))
		goto out;

298 299
	/* vlan address was different from the old address and is equal to
	 * the new address */
300 301
	if (!ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) &&
	    ether_addr_equal(vlandev->dev_addr, dev->dev_addr))
302
		dev_uc_del(dev, vlandev->dev_addr);
303 304 305

	/* vlan address was equal to the old address and is different from
	 * the new address */
306 307
	if (ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) &&
	    !ether_addr_equal(vlandev->dev_addr, dev->dev_addr))
308
		dev_uc_add(dev, vlandev->dev_addr);
309

310
out:
J
Joe Perches 已提交
311
	ether_addr_copy(vlan->real_dev_addr, dev->dev_addr);
312 313
}

314 315 316
static void vlan_transfer_features(struct net_device *dev,
				   struct net_device *vlandev)
{
317 318
	struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);

319
	vlandev->gso_max_size = dev->gso_max_size;
E
Eric Dumazet 已提交
320
	vlandev->gso_max_segs = dev->gso_max_segs;
321

322
	if (vlan_hw_offload_capable(dev->features, vlan->vlan_proto))
323 324 325 326
		vlandev->hard_header_len = dev->hard_header_len;
	else
		vlandev->hard_header_len = dev->hard_header_len + VLAN_HLEN;

A
Amerigo Wang 已提交
327
#if IS_ENABLED(CONFIG_FCOE)
328 329
	vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid;
#endif
330

331 332 333
	vlandev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
	vlandev->priv_flags |= (vlan->real_dev->priv_flags & IFF_XMIT_DST_RELEASE);

334
	netdev_update_features(vlandev);
335 336
}

337
static int __vlan_device_event(struct net_device *dev, unsigned long event)
338
{
339 340
	int err = 0;

341 342 343
	switch (event) {
	case NETDEV_CHANGENAME:
		vlan_proc_rem_dev(dev);
344
		err = vlan_proc_add_dev(dev);
345
		break;
346
	case NETDEV_REGISTER:
347
		err = vlan_proc_add_dev(dev);
348 349 350 351
		break;
	case NETDEV_UNREGISTER:
		vlan_proc_rem_dev(dev);
		break;
352
	}
353 354

	return err;
355 356
}

P
Patrick McHardy 已提交
357 358
static int vlan_device_event(struct notifier_block *unused, unsigned long event,
			     void *ptr)
L
Linus Torvalds 已提交
359
{
360
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
361
	struct vlan_group *grp;
362
	struct vlan_info *vlan_info;
L
Linus Torvalds 已提交
363 364
	int i, flgs;
	struct net_device *vlandev;
365
	struct vlan_dev_priv *vlan;
366
	bool last = false;
367
	LIST_HEAD(list);
368
	int err;
L
Linus Torvalds 已提交
369

370 371 372 373 374 375
	if (is_vlan_dev(dev)) {
		int err = __vlan_device_event(dev, event);

		if (err)
			return notifier_from_errno(err);
	}
376

377
	if ((event == NETDEV_UP) &&
378
	    (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) {
J
Joe Perches 已提交
379
		pr_info("adding VLAN 0 to HW filter on device %s\n",
380
			dev->name);
381
		vlan_vid_add(dev, htons(ETH_P_8021Q), 0);
382
	}
383 384 385
	if (event == NETDEV_DOWN &&
	    (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER))
		vlan_vid_del(dev, htons(ETH_P_8021Q), 0);
386

387 388
	vlan_info = rtnl_dereference(dev->vlan_info);
	if (!vlan_info)
L
Linus Torvalds 已提交
389
		goto out;
390
	grp = &vlan_info->grp;
L
Linus Torvalds 已提交
391 392 393 394 395 396 397 398

	/* It is OK that we do not hold the group lock right now,
	 * as we run under the RTNL lock.
	 */

	switch (event) {
	case NETDEV_CHANGE:
		/* Propagate real device state to vlan devices */
399
		vlan_group_for_each_dev(grp, i, vlandev)
400
			netif_stacked_transfer_operstate(dev, vlandev);
L
Linus Torvalds 已提交
401 402
		break;

403 404
	case NETDEV_CHANGEADDR:
		/* Adjust unicast filters on underlying device */
405
		vlan_group_for_each_dev(grp, i, vlandev) {
406 407 408 409
			flgs = vlandev->flags;
			if (!(flgs & IFF_UP))
				continue;

410 411
			vlan_sync_address(dev, vlandev);
		}
412 413 414
		break;

	case NETDEV_CHANGEMTU:
415
		vlan_group_for_each_dev(grp, i, vlandev) {
416 417 418 419 420
			if (vlandev->mtu <= dev->mtu)
				continue;

			dev_set_mtu(vlandev, dev->mtu);
		}
421 422
		break;

423 424
	case NETDEV_FEAT_CHANGE:
		/* Propagate device features to underlying device */
425
		vlan_group_for_each_dev(grp, i, vlandev)
426 427 428
			vlan_transfer_features(dev, vlandev);
		break;

429 430 431 432
	case NETDEV_DOWN: {
		struct net_device *tmp;
		LIST_HEAD(close_list);

L
Linus Torvalds 已提交
433
		/* Put all VLANs for this dev in the down state too.  */
434
		vlan_group_for_each_dev(grp, i, vlandev) {
L
Linus Torvalds 已提交
435 436 437 438
			flgs = vlandev->flags;
			if (!(flgs & IFF_UP))
				continue;

439
			vlan = vlan_dev_priv(vlandev);
440
			if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
441 442 443 444 445 446
				list_add(&vlandev->close_list, &close_list);
		}

		dev_close_many(&close_list, false);

		list_for_each_entry_safe(vlandev, tmp, &close_list, close_list) {
447
			netif_stacked_transfer_operstate(dev, vlandev);
448
			list_del_init(&vlandev->close_list);
L
Linus Torvalds 已提交
449
		}
450
		list_del(&close_list);
L
Linus Torvalds 已提交
451
		break;
452
	}
L
Linus Torvalds 已提交
453 454
	case NETDEV_UP:
		/* Put all VLANs for this dev in the up state too.  */
455
		vlan_group_for_each_dev(grp, i, vlandev) {
456
			flgs = dev_get_flags(vlandev);
L
Linus Torvalds 已提交
457 458 459
			if (flgs & IFF_UP)
				continue;

460
			vlan = vlan_dev_priv(vlandev);
461 462
			if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
				dev_change_flags(vlandev, flgs | IFF_UP);
463
			netif_stacked_transfer_operstate(dev, vlandev);
L
Linus Torvalds 已提交
464 465
		}
		break;
466

L
Linus Torvalds 已提交
467
	case NETDEV_UNREGISTER:
468 469 470 471
		/* twiddle thumbs on netns device moves */
		if (dev->reg_state != NETREG_UNREGISTERING)
			break;

472
		vlan_group_for_each_dev(grp, i, vlandev) {
473
			/* removal of last vid destroys vlan_info, abort
474
			 * afterwards */
475
			if (vlan_info->nr_vids == 1)
476
				last = true;
477 478

			unregister_vlan_dev(vlandev, &list);
479 480
			if (last)
				break;
481 482
		}
		unregister_netdevice_many(&list);
L
Linus Torvalds 已提交
483
		break;
484 485 486

	case NETDEV_PRE_TYPE_CHANGE:
		/* Forbid underlaying device to change its type. */
487 488 489
		if (vlan_uses_dev(dev))
			return NOTIFY_BAD;
		break;
490 491

	case NETDEV_NOTIFY_PEERS:
492
	case NETDEV_BONDING_FAILOVER:
493
	case NETDEV_RESEND_IGMP:
494
		/* Propagate to vlan devices */
495
		vlan_group_for_each_dev(grp, i, vlandev)
496
			call_netdevice_notifiers(event, vlandev);
497
		break;
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517

	case NETDEV_CVLAN_FILTER_PUSH_INFO:
		err = vlan_filter_push_vids(vlan_info, htons(ETH_P_8021Q));
		if (err)
			return notifier_from_errno(err);
		break;

	case NETDEV_CVLAN_FILTER_DROP_INFO:
		vlan_filter_drop_vids(vlan_info, htons(ETH_P_8021Q));
		break;

	case NETDEV_SVLAN_FILTER_PUSH_INFO:
		err = vlan_filter_push_vids(vlan_info, htons(ETH_P_8021AD));
		if (err)
			return notifier_from_errno(err);
		break;

	case NETDEV_SVLAN_FILTER_DROP_INFO:
		vlan_filter_drop_vids(vlan_info, htons(ETH_P_8021AD));
		break;
518
	}
L
Linus Torvalds 已提交
519 520 521 522 523

out:
	return NOTIFY_DONE;
}

524 525 526 527
static struct notifier_block vlan_notifier_block __read_mostly = {
	.notifier_call = vlan_device_event,
};

L
Linus Torvalds 已提交
528 529 530 531 532
/*
 *	VLAN IOCTL handler.
 *	o execute requested action or pass command to the device driver
 *   arg is really a struct vlan_ioctl_args __user *.
 */
533
static int vlan_ioctl_handler(struct net *net, void __user *arg)
L
Linus Torvalds 已提交
534
{
535
	int err;
L
Linus Torvalds 已提交
536
	struct vlan_ioctl_args args;
537
	struct net_device *dev = NULL;
L
Linus Torvalds 已提交
538 539 540 541 542

	if (copy_from_user(&args, arg, sizeof(struct vlan_ioctl_args)))
		return -EFAULT;

	/* Null terminate this sucker, just in case. */
543 544
	args.device1[sizeof(args.device1) - 1] = 0;
	args.u.device2[sizeof(args.u.device2) - 1] = 0;
L
Linus Torvalds 已提交
545

546 547
	rtnl_lock();

L
Linus Torvalds 已提交
548 549
	switch (args.cmd) {
	case SET_VLAN_INGRESS_PRIORITY_CMD:
550 551 552 553 554 555 556
	case SET_VLAN_EGRESS_PRIORITY_CMD:
	case SET_VLAN_FLAG_CMD:
	case ADD_VLAN_CMD:
	case DEL_VLAN_CMD:
	case GET_VLAN_REALDEV_NAME_CMD:
	case GET_VLAN_VID_CMD:
		err = -ENODEV;
557
		dev = __dev_get_by_name(net, args.device1);
558 559 560 561
		if (!dev)
			goto out;

		err = -EINVAL;
J
Joonwoo Park 已提交
562
		if (args.cmd != ADD_VLAN_CMD && !is_vlan_dev(dev))
563 564 565 566 567 568
			goto out;
	}

	switch (args.cmd) {
	case SET_VLAN_INGRESS_PRIORITY_CMD:
		err = -EPERM;
569
		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
570 571 572 573
			break;
		vlan_dev_set_ingress_priority(dev,
					      args.u.skb_priority,
					      args.vlan_qos);
574
		err = 0;
L
Linus Torvalds 已提交
575 576 577
		break;

	case SET_VLAN_EGRESS_PRIORITY_CMD:
578
		err = -EPERM;
579
		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
580 581
			break;
		err = vlan_dev_set_egress_priority(dev,
L
Linus Torvalds 已提交
582 583 584 585 586
						   args.u.skb_priority,
						   args.vlan_qos);
		break;

	case SET_VLAN_FLAG_CMD:
587
		err = -EPERM;
588
		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
589
			break;
590 591 592
		err = vlan_dev_change_flags(dev,
					    args.vlan_qos ? args.u.flag : 0,
					    args.u.flag);
L
Linus Torvalds 已提交
593 594 595
		break;

	case SET_VLAN_NAME_TYPE_CMD:
596
		err = -EPERM;
597
		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
598
			break;
599
		if (args.u.name_type < VLAN_NAME_TYPE_HIGHEST) {
600 601 602 603
			struct vlan_net *vn;

			vn = net_generic(net, vlan_net_id);
			vn->name_type = args.u.name_type;
L
Linus Torvalds 已提交
604 605 606 607 608 609 610
			err = 0;
		} else {
			err = -EINVAL;
		}
		break;

	case ADD_VLAN_CMD:
611
		err = -EPERM;
612
		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
613
			break;
614
		err = register_vlan_device(dev, args.u.VID);
L
Linus Torvalds 已提交
615 616 617
		break;

	case DEL_VLAN_CMD:
618
		err = -EPERM;
619
		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
620
			break;
621
		unregister_vlan_dev(dev, NULL);
622
		err = 0;
L
Linus Torvalds 已提交
623 624 625
		break;

	case GET_VLAN_REALDEV_NAME_CMD:
626
		err = 0;
627
		vlan_dev_get_realdev_name(dev, args.u.device2);
L
Linus Torvalds 已提交
628
		if (copy_to_user(arg, &args,
P
Patrick McHardy 已提交
629
				 sizeof(struct vlan_ioctl_args)))
L
Linus Torvalds 已提交
630 631 632 633
			err = -EFAULT;
		break;

	case GET_VLAN_VID_CMD:
634
		err = 0;
635
		args.u.VID = vlan_dev_vlan_id(dev);
L
Linus Torvalds 已提交
636
		if (copy_to_user(arg, &args,
P
Patrick McHardy 已提交
637
				 sizeof(struct vlan_ioctl_args)))
638
		      err = -EFAULT;
L
Linus Torvalds 已提交
639 640 641
		break;

	default:
642
		err = -EOPNOTSUPP;
643
		break;
644
	}
645
out:
646
	rtnl_unlock();
L
Linus Torvalds 已提交
647 648 649
	return err;
}

650 651
static struct sk_buff *vlan_gro_receive(struct list_head *head,
					struct sk_buff *skb)
652 653
{
	const struct packet_offload *ptype;
654 655 656 657
	unsigned int hlen, off_vlan;
	struct sk_buff *pp = NULL;
	struct vlan_hdr *vhdr;
	struct sk_buff *p;
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678
	__be16 type;
	int flush = 1;

	off_vlan = skb_gro_offset(skb);
	hlen = off_vlan + sizeof(*vhdr);
	vhdr = skb_gro_header_fast(skb, off_vlan);
	if (skb_gro_header_hard(skb, hlen)) {
		vhdr = skb_gro_header_slow(skb, hlen, off_vlan);
		if (unlikely(!vhdr))
			goto out;
	}

	type = vhdr->h_vlan_encapsulated_proto;

	rcu_read_lock();
	ptype = gro_find_receive_by_type(type);
	if (!ptype)
		goto out_unlock;

	flush = 0;

679
	list_for_each_entry(p, head, list) {
680 681 682 683 684 685 686 687 688 689 690 691
		struct vlan_hdr *vhdr2;

		if (!NAPI_GRO_CB(p)->same_flow)
			continue;

		vhdr2 = (struct vlan_hdr *)(p->data + off_vlan);
		if (compare_vlan_header(vhdr, vhdr2))
			NAPI_GRO_CB(p)->same_flow = 0;
	}

	skb_gro_pull(skb, sizeof(*vhdr));
	skb_gro_postpull_rcsum(skb, vhdr, sizeof(*vhdr));
S
Sabrina Dubroca 已提交
692
	pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736

out_unlock:
	rcu_read_unlock();
out:
	NAPI_GRO_CB(skb)->flush |= flush;

	return pp;
}

static int vlan_gro_complete(struct sk_buff *skb, int nhoff)
{
	struct vlan_hdr *vhdr = (struct vlan_hdr *)(skb->data + nhoff);
	__be16 type = vhdr->h_vlan_encapsulated_proto;
	struct packet_offload *ptype;
	int err = -ENOENT;

	rcu_read_lock();
	ptype = gro_find_complete_by_type(type);
	if (ptype)
		err = ptype->callbacks.gro_complete(skb, nhoff + sizeof(*vhdr));

	rcu_read_unlock();
	return err;
}

static struct packet_offload vlan_packet_offloads[] __read_mostly = {
	{
		.type = cpu_to_be16(ETH_P_8021Q),
		.priority = 10,
		.callbacks = {
			.gro_receive = vlan_gro_receive,
			.gro_complete = vlan_gro_complete,
		},
	},
	{
		.type = cpu_to_be16(ETH_P_8021AD),
		.priority = 10,
		.callbacks = {
			.gro_receive = vlan_gro_receive,
			.gro_complete = vlan_gro_complete,
		},
	},
};

737
static int __net_init vlan_init_net(struct net *net)
738
{
739
	struct vlan_net *vn = net_generic(net, vlan_net_id);
740 741
	int err;

742 743
	vn->name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD;

744 745
	err = vlan_proc_init(net);

746 747 748
	return err;
}

749
static void __net_exit vlan_exit_net(struct net *net)
750
{
751
	vlan_proc_cleanup(net);
752 753 754 755 756
}

static struct pernet_operations vlan_net_ops = {
	.init = vlan_init_net,
	.exit = vlan_exit_net,
757 758
	.id   = &vlan_net_id,
	.size = sizeof(struct vlan_net),
759 760
};

761 762 763
static int __init vlan_proto_init(void)
{
	int err;
764
	unsigned int i;
765

766
	pr_info("%s v%s\n", vlan_fullname, vlan_version);
767

768
	err = register_pernet_subsys(&vlan_net_ops);
769 770 771
	if (err < 0)
		goto err0;

772 773 774 775
	err = register_netdevice_notifier(&vlan_notifier_block);
	if (err < 0)
		goto err2;

P
Patrick McHardy 已提交
776
	err = vlan_gvrp_init();
777 778 779
	if (err < 0)
		goto err3;

780
	err = vlan_mvrp_init();
P
Patrick McHardy 已提交
781 782 783
	if (err < 0)
		goto err4;

784 785 786 787
	err = vlan_netlink_init();
	if (err < 0)
		goto err5;

788 789 790
	for (i = 0; i < ARRAY_SIZE(vlan_packet_offloads); i++)
		dev_add_offload(&vlan_packet_offloads[i]);

791 792 793
	vlan_ioctl_set(vlan_ioctl_handler);
	return 0;

794 795
err5:
	vlan_mvrp_uninit();
P
Patrick McHardy 已提交
796 797
err4:
	vlan_gvrp_uninit();
798 799 800
err3:
	unregister_netdevice_notifier(&vlan_notifier_block);
err2:
801
	unregister_pernet_subsys(&vlan_net_ops);
802
err0:
803 804 805 806 807
	return err;
}

static void __exit vlan_cleanup_module(void)
{
808 809
	unsigned int i;

810
	vlan_ioctl_set(NULL);
811 812 813 814

	for (i = 0; i < ARRAY_SIZE(vlan_packet_offloads); i++)
		dev_remove_offload(&vlan_packet_offloads[i]);

815 816 817 818
	vlan_netlink_fini();

	unregister_netdevice_notifier(&vlan_notifier_block);

819
	unregister_pernet_subsys(&vlan_net_ops);
820
	rcu_barrier(); /* Wait for completion of call_rcu()'s */
P
Patrick McHardy 已提交
821

822
	vlan_mvrp_uninit();
P
Patrick McHardy 已提交
823
	vlan_gvrp_uninit();
824 825 826 827 828
}

module_init(vlan_proto_init);
module_exit(vlan_cleanup_module);

L
Linus Torvalds 已提交
829 830
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);