vlan.c 19.3 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 121
int vlan_check_real_dev(struct net_device *real_dev,
			__be16 protocol, u16 vlan_id)
L
Linus Torvalds 已提交
122
{
123
	const char *name = real_dev->name;
124

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

130
	if (vlan_find_dev(real_dev, protocol, vlan_id) != NULL)
P
Patrick McHardy 已提交
131
		return -EEXIST;
L
Linus Torvalds 已提交
132

P
Patrick McHardy 已提交
133 134 135
	return 0;
}

136
int register_vlan_dev(struct net_device *dev, struct netlink_ext_ack *extack)
137
{
138
	struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
139
	struct net_device *real_dev = vlan->real_dev;
140
	u16 vlan_id = vlan->vlan_id;
141 142
	struct vlan_info *vlan_info;
	struct vlan_group *grp;
143 144
	int err;

145
	err = vlan_vid_add(real_dev, vlan->vlan_proto, vlan_id);
146 147 148 149 150 151 152 153 154
	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 已提交
155 156
		err = vlan_gvrp_init_applicant(real_dev);
		if (err < 0)
157
			goto out_vid_del;
158 159 160
		err = vlan_mvrp_init_applicant(real_dev);
		if (err < 0)
			goto out_uninit_gvrp;
161 162
	}

163
	err = vlan_group_prealloc_vid(grp, vlan->vlan_proto, vlan_id);
164
	if (err < 0)
165
		goto out_uninit_mvrp;
166

167
	vlan->nest_level = dev_get_nest_level(real_dev) + 1;
168 169
	err = register_netdevice(dev);
	if (err < 0)
170 171
		goto out_uninit_mvrp;

172
	err = netdev_upper_dev_link(real_dev, dev, extack);
173 174
	if (err)
		goto out_unregister_netdev;
175

176
	/* Account for reference in struct vlan_dev_priv */
177 178
	dev_hold(real_dev);

179
	netif_stacked_transfer_operstate(real_dev, dev);
180 181 182 183 184
	linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */

	/* So, got the sucker initialized, now lets place
	 * it into our local structure.
	 */
185
	vlan_group_set_device(grp, vlan->vlan_proto, vlan_id, dev);
186
	grp->nr_vlan_devs++;
187 188 189

	return 0;

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

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

215
	if (vlan_id >= VLAN_VID_MASK)
216
		return -ERANGE;
P
Patrick McHardy 已提交
217

218
	err = vlan_check_real_dev(real_dev, htons(ETH_P_8021Q), vlan_id);
219 220
	if (err < 0)
		return err;
P
Patrick McHardy 已提交
221

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

248 249
	new_dev = alloc_netdev(sizeof(struct vlan_dev_priv), name,
			       NET_NAME_UNKNOWN, vlan_setup);
250

L
Linus Torvalds 已提交
251
	if (new_dev == NULL)
252
		return -ENOBUFS;
L
Linus Torvalds 已提交
253

254
	dev_net_set(new_dev, net);
L
Linus Torvalds 已提交
255 256 257 258 259
	/* need 4 bytes for extra VLAN header info,
	 * hope the underlying device can handle it.
	 */
	new_dev->mtu = real_dev->mtu;

260 261 262 263 264 265
	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 已提交
266

P
Patrick McHardy 已提交
267
	new_dev->rtnl_link_ops = &vlan_link_ops;
268
	err = register_vlan_dev(new_dev, NULL);
269
	if (err < 0)
270
		goto out_free_newdev;
L
Linus Torvalds 已提交
271

272
	return 0;
L
Linus Torvalds 已提交
273 274

out_free_newdev:
275 276
	if (new_dev->reg_state == NETREG_UNINITIALIZED)
		free_netdev(new_dev);
277
	return err;
L
Linus Torvalds 已提交
278 279
}

280 281 282
static void vlan_sync_address(struct net_device *dev,
			      struct net_device *vlandev)
{
283
	struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
284 285

	/* May be called without an actual change */
286
	if (ether_addr_equal(vlan->real_dev_addr, dev->dev_addr))
287 288
		return;

289 290 291 292
	/* vlan continues to inherit address of lower device */
	if (vlan_dev_inherit_address(vlandev, dev))
		goto out;

293 294
	/* vlan address was different from the old address and is equal to
	 * the new address */
295 296
	if (!ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) &&
	    ether_addr_equal(vlandev->dev_addr, dev->dev_addr))
297
		dev_uc_del(dev, vlandev->dev_addr);
298 299 300

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

305
out:
J
Joe Perches 已提交
306
	ether_addr_copy(vlan->real_dev_addr, dev->dev_addr);
307 308
}

309 310 311
static void vlan_transfer_features(struct net_device *dev,
				   struct net_device *vlandev)
{
312 313
	struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);

314
	vlandev->gso_max_size = dev->gso_max_size;
E
Eric Dumazet 已提交
315
	vlandev->gso_max_segs = dev->gso_max_segs;
316

317
	if (vlan_hw_offload_capable(dev->features, vlan->vlan_proto))
318 319 320 321
		vlandev->hard_header_len = dev->hard_header_len;
	else
		vlandev->hard_header_len = dev->hard_header_len + VLAN_HLEN;

A
Amerigo Wang 已提交
322
#if IS_ENABLED(CONFIG_FCOE)
323 324
	vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid;
#endif
325

326 327 328
	vlandev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
	vlandev->priv_flags |= (vlan->real_dev->priv_flags & IFF_XMIT_DST_RELEASE);

329
	netdev_update_features(vlandev);
330 331
}

332
static int __vlan_device_event(struct net_device *dev, unsigned long event)
333
{
334 335
	int err = 0;

336 337 338
	switch (event) {
	case NETDEV_CHANGENAME:
		vlan_proc_rem_dev(dev);
339
		err = vlan_proc_add_dev(dev);
340
		break;
341
	case NETDEV_REGISTER:
342
		err = vlan_proc_add_dev(dev);
343 344 345 346
		break;
	case NETDEV_UNREGISTER:
		vlan_proc_rem_dev(dev);
		break;
347
	}
348 349

	return err;
350 351
}

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

365 366 367 368 369 370
	if (is_vlan_dev(dev)) {
		int err = __vlan_device_event(dev, event);

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

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

382 383
	vlan_info = rtnl_dereference(dev->vlan_info);
	if (!vlan_info)
L
Linus Torvalds 已提交
384
		goto out;
385
	grp = &vlan_info->grp;
L
Linus Torvalds 已提交
386 387 388 389 390 391 392 393

	/* 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 */
394
		vlan_group_for_each_dev(grp, i, vlandev)
395
			netif_stacked_transfer_operstate(dev, vlandev);
L
Linus Torvalds 已提交
396 397
		break;

398 399
	case NETDEV_CHANGEADDR:
		/* Adjust unicast filters on underlying device */
400
		vlan_group_for_each_dev(grp, i, vlandev) {
401 402 403 404
			flgs = vlandev->flags;
			if (!(flgs & IFF_UP))
				continue;

405 406
			vlan_sync_address(dev, vlandev);
		}
407 408 409
		break;

	case NETDEV_CHANGEMTU:
410
		vlan_group_for_each_dev(grp, i, vlandev) {
411 412 413 414 415
			if (vlandev->mtu <= dev->mtu)
				continue;

			dev_set_mtu(vlandev, dev->mtu);
		}
416 417
		break;

418 419
	case NETDEV_FEAT_CHANGE:
		/* Propagate device features to underlying device */
420
		vlan_group_for_each_dev(grp, i, vlandev)
421 422 423
			vlan_transfer_features(dev, vlandev);
		break;

424 425 426 427
	case NETDEV_DOWN: {
		struct net_device *tmp;
		LIST_HEAD(close_list);

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

434
			vlan = vlan_dev_priv(vlandev);
435
			if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
436 437 438 439 440 441
				list_add(&vlandev->close_list, &close_list);
		}

		dev_close_many(&close_list, false);

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

455
			vlan = vlan_dev_priv(vlandev);
456 457
			if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
				dev_change_flags(vlandev, flgs | IFF_UP);
458
			netif_stacked_transfer_operstate(dev, vlandev);
L
Linus Torvalds 已提交
459 460
		}
		break;
461

L
Linus Torvalds 已提交
462
	case NETDEV_UNREGISTER:
463 464 465 466
		/* twiddle thumbs on netns device moves */
		if (dev->reg_state != NETREG_UNREGISTERING)
			break;

467
		vlan_group_for_each_dev(grp, i, vlandev) {
468
			/* removal of last vid destroys vlan_info, abort
469
			 * afterwards */
470
			if (vlan_info->nr_vids == 1)
471
				last = true;
472 473

			unregister_vlan_dev(vlandev, &list);
474 475
			if (last)
				break;
476 477
		}
		unregister_netdevice_many(&list);
L
Linus Torvalds 已提交
478
		break;
479 480 481

	case NETDEV_PRE_TYPE_CHANGE:
		/* Forbid underlaying device to change its type. */
482 483 484
		if (vlan_uses_dev(dev))
			return NOTIFY_BAD;
		break;
485 486

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

	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;
513
	}
L
Linus Torvalds 已提交
514 515 516 517 518

out:
	return NOTIFY_DONE;
}

519 520 521 522
static struct notifier_block vlan_notifier_block __read_mostly = {
	.notifier_call = vlan_device_event,
};

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

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

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

541 542
	rtnl_lock();

L
Linus Torvalds 已提交
543 544
	switch (args.cmd) {
	case SET_VLAN_INGRESS_PRIORITY_CMD:
545 546 547 548 549 550 551
	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;
552
		dev = __dev_get_by_name(net, args.device1);
553 554 555 556
		if (!dev)
			goto out;

		err = -EINVAL;
J
Joonwoo Park 已提交
557
		if (args.cmd != ADD_VLAN_CMD && !is_vlan_dev(dev))
558 559 560 561 562 563
			goto out;
	}

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

	case SET_VLAN_EGRESS_PRIORITY_CMD:
573
		err = -EPERM;
574
		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
575 576
			break;
		err = vlan_dev_set_egress_priority(dev,
L
Linus Torvalds 已提交
577 578 579 580 581
						   args.u.skb_priority,
						   args.vlan_qos);
		break;

	case SET_VLAN_FLAG_CMD:
582
		err = -EPERM;
583
		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
584
			break;
585 586 587
		err = vlan_dev_change_flags(dev,
					    args.vlan_qos ? args.u.flag : 0,
					    args.u.flag);
L
Linus Torvalds 已提交
588 589 590
		break;

	case SET_VLAN_NAME_TYPE_CMD:
591
		err = -EPERM;
592
		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
593
			break;
594
		if (args.u.name_type < VLAN_NAME_TYPE_HIGHEST) {
595 596 597 598
			struct vlan_net *vn;

			vn = net_generic(net, vlan_net_id);
			vn->name_type = args.u.name_type;
L
Linus Torvalds 已提交
599 600 601 602 603 604 605
			err = 0;
		} else {
			err = -EINVAL;
		}
		break;

	case ADD_VLAN_CMD:
606
		err = -EPERM;
607
		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
608
			break;
609
		err = register_vlan_device(dev, args.u.VID);
L
Linus Torvalds 已提交
610 611 612
		break;

	case DEL_VLAN_CMD:
613
		err = -EPERM;
614
		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
615
			break;
616
		unregister_vlan_dev(dev, NULL);
617
		err = 0;
L
Linus Torvalds 已提交
618 619 620
		break;

	case GET_VLAN_REALDEV_NAME_CMD:
621
		err = 0;
622
		vlan_dev_get_realdev_name(dev, args.u.device2);
L
Linus Torvalds 已提交
623
		if (copy_to_user(arg, &args,
P
Patrick McHardy 已提交
624
				 sizeof(struct vlan_ioctl_args)))
L
Linus Torvalds 已提交
625 626 627 628
			err = -EFAULT;
		break;

	case GET_VLAN_VID_CMD:
629
		err = 0;
630
		args.u.VID = vlan_dev_vlan_id(dev);
L
Linus Torvalds 已提交
631
		if (copy_to_user(arg, &args,
P
Patrick McHardy 已提交
632
				 sizeof(struct vlan_ioctl_args)))
633
		      err = -EFAULT;
L
Linus Torvalds 已提交
634 635 636
		break;

	default:
637
		err = -EOPNOTSUPP;
638
		break;
639
	}
640
out:
641
	rtnl_unlock();
L
Linus Torvalds 已提交
642 643 644
	return err;
}

645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685
static struct sk_buff **vlan_gro_receive(struct sk_buff **head,
					 struct sk_buff *skb)
{
	struct sk_buff *p, **pp = NULL;
	struct vlan_hdr *vhdr;
	unsigned int hlen, off_vlan;
	const struct packet_offload *ptype;
	__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;

	for (p = *head; p; p = p->next) {
		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 已提交
686
	pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
687 688 689 690 691 692 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

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,
		},
	},
};

731
static int __net_init vlan_init_net(struct net *net)
732
{
733
	struct vlan_net *vn = net_generic(net, vlan_net_id);
734 735
	int err;

736 737
	vn->name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD;

738 739
	err = vlan_proc_init(net);

740 741 742
	return err;
}

743
static void __net_exit vlan_exit_net(struct net *net)
744
{
745
	vlan_proc_cleanup(net);
746 747 748 749 750
}

static struct pernet_operations vlan_net_ops = {
	.init = vlan_init_net,
	.exit = vlan_exit_net,
751 752
	.id   = &vlan_net_id,
	.size = sizeof(struct vlan_net),
753 754
};

755 756 757
static int __init vlan_proto_init(void)
{
	int err;
758
	unsigned int i;
759

760
	pr_info("%s v%s\n", vlan_fullname, vlan_version);
761

762
	err = register_pernet_subsys(&vlan_net_ops);
763 764 765
	if (err < 0)
		goto err0;

766 767 768 769
	err = register_netdevice_notifier(&vlan_notifier_block);
	if (err < 0)
		goto err2;

P
Patrick McHardy 已提交
770
	err = vlan_gvrp_init();
771 772 773
	if (err < 0)
		goto err3;

774
	err = vlan_mvrp_init();
P
Patrick McHardy 已提交
775 776 777
	if (err < 0)
		goto err4;

778 779 780 781
	err = vlan_netlink_init();
	if (err < 0)
		goto err5;

782 783 784
	for (i = 0; i < ARRAY_SIZE(vlan_packet_offloads); i++)
		dev_add_offload(&vlan_packet_offloads[i]);

785 786 787
	vlan_ioctl_set(vlan_ioctl_handler);
	return 0;

788 789
err5:
	vlan_mvrp_uninit();
P
Patrick McHardy 已提交
790 791
err4:
	vlan_gvrp_uninit();
792 793 794
err3:
	unregister_netdevice_notifier(&vlan_notifier_block);
err2:
795
	unregister_pernet_subsys(&vlan_net_ops);
796
err0:
797 798 799 800 801
	return err;
}

static void __exit vlan_cleanup_module(void)
{
802 803
	unsigned int i;

804
	vlan_ioctl_set(NULL);
805 806 807 808

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

809 810 811 812
	vlan_netlink_fini();

	unregister_netdevice_notifier(&vlan_notifier_block);

813
	unregister_pernet_subsys(&vlan_net_ops);
814
	rcu_barrier(); /* Wait for completion of call_rcu()'s */
P
Patrick McHardy 已提交
815

816
	vlan_mvrp_uninit();
P
Patrick McHardy 已提交
817
	vlan_gvrp_uninit();
818 819 820 821 822
}

module_init(vlan_proto_init);
module_exit(vlan_cleanup_module);

L
Linus Torvalds 已提交
823 824
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);