xref: /OK3568_Linux_fs/kernel/net/8021q/vlan.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * INET		802.1Q VLAN
4*4882a593Smuzhiyun  *		Ethernet-type device handling.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Authors:	Ben Greear <greearb@candelatech.com>
7*4882a593Smuzhiyun  *              Please send support related email to: netdev@vger.kernel.org
8*4882a593Smuzhiyun  *              VLAN Home Page: http://www.candelatech.com/~greear/vlan.html
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  * Fixes:
11*4882a593Smuzhiyun  *              Fix for packet capture - Nick Eggleston <nick@dccinc.com>;
12*4882a593Smuzhiyun  *		Add HW acceleration hooks - David S. Miller <davem@redhat.com>;
13*4882a593Smuzhiyun  *		Correct all the locking - David S. Miller <davem@redhat.com>;
14*4882a593Smuzhiyun  *		Use hash table for VLAN groups - David S. Miller <davem@redhat.com>
15*4882a593Smuzhiyun  */
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #include <linux/capability.h>
20*4882a593Smuzhiyun #include <linux/module.h>
21*4882a593Smuzhiyun #include <linux/netdevice.h>
22*4882a593Smuzhiyun #include <linux/skbuff.h>
23*4882a593Smuzhiyun #include <linux/slab.h>
24*4882a593Smuzhiyun #include <linux/init.h>
25*4882a593Smuzhiyun #include <linux/rculist.h>
26*4882a593Smuzhiyun #include <net/p8022.h>
27*4882a593Smuzhiyun #include <net/arp.h>
28*4882a593Smuzhiyun #include <linux/rtnetlink.h>
29*4882a593Smuzhiyun #include <linux/notifier.h>
30*4882a593Smuzhiyun #include <net/rtnetlink.h>
31*4882a593Smuzhiyun #include <net/net_namespace.h>
32*4882a593Smuzhiyun #include <net/netns/generic.h>
33*4882a593Smuzhiyun #include <linux/uaccess.h>
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #include <linux/if_vlan.h>
36*4882a593Smuzhiyun #include "vlan.h"
37*4882a593Smuzhiyun #include "vlanproc.h"
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #define DRV_VERSION "1.8"
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun /* Global VLAN variables */
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun unsigned int vlan_net_id __read_mostly;
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun const char vlan_fullname[] = "802.1Q VLAN Support";
46*4882a593Smuzhiyun const char vlan_version[] = DRV_VERSION;
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun /* End of global variables definitions. */
49*4882a593Smuzhiyun 
vlan_group_prealloc_vid(struct vlan_group * vg,__be16 vlan_proto,u16 vlan_id)50*4882a593Smuzhiyun static int vlan_group_prealloc_vid(struct vlan_group *vg,
51*4882a593Smuzhiyun 				   __be16 vlan_proto, u16 vlan_id)
52*4882a593Smuzhiyun {
53*4882a593Smuzhiyun 	struct net_device **array;
54*4882a593Smuzhiyun 	unsigned int vidx;
55*4882a593Smuzhiyun 	unsigned int size;
56*4882a593Smuzhiyun 	int pidx;
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun 	ASSERT_RTNL();
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	pidx  = vlan_proto_idx(vlan_proto);
61*4882a593Smuzhiyun 	if (pidx < 0)
62*4882a593Smuzhiyun 		return -EINVAL;
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	vidx  = vlan_id / VLAN_GROUP_ARRAY_PART_LEN;
65*4882a593Smuzhiyun 	array = vg->vlan_devices_arrays[pidx][vidx];
66*4882a593Smuzhiyun 	if (array != NULL)
67*4882a593Smuzhiyun 		return 0;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	size = sizeof(struct net_device *) * VLAN_GROUP_ARRAY_PART_LEN;
70*4882a593Smuzhiyun 	array = kzalloc(size, GFP_KERNEL);
71*4882a593Smuzhiyun 	if (array == NULL)
72*4882a593Smuzhiyun 		return -ENOBUFS;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	vg->vlan_devices_arrays[pidx][vidx] = array;
75*4882a593Smuzhiyun 	return 0;
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun 
vlan_stacked_transfer_operstate(const struct net_device * rootdev,struct net_device * dev,struct vlan_dev_priv * vlan)78*4882a593Smuzhiyun static void vlan_stacked_transfer_operstate(const struct net_device *rootdev,
79*4882a593Smuzhiyun 					    struct net_device *dev,
80*4882a593Smuzhiyun 					    struct vlan_dev_priv *vlan)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun 	if (!(vlan->flags & VLAN_FLAG_BRIDGE_BINDING))
83*4882a593Smuzhiyun 		netif_stacked_transfer_operstate(rootdev, dev);
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun 
unregister_vlan_dev(struct net_device * dev,struct list_head * head)86*4882a593Smuzhiyun void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun 	struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
89*4882a593Smuzhiyun 	struct net_device *real_dev = vlan->real_dev;
90*4882a593Smuzhiyun 	struct vlan_info *vlan_info;
91*4882a593Smuzhiyun 	struct vlan_group *grp;
92*4882a593Smuzhiyun 	u16 vlan_id = vlan->vlan_id;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	ASSERT_RTNL();
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 	vlan_info = rtnl_dereference(real_dev->vlan_info);
97*4882a593Smuzhiyun 	BUG_ON(!vlan_info);
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 	grp = &vlan_info->grp;
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	grp->nr_vlan_devs--;
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	if (vlan->flags & VLAN_FLAG_MVRP)
104*4882a593Smuzhiyun 		vlan_mvrp_request_leave(dev);
105*4882a593Smuzhiyun 	if (vlan->flags & VLAN_FLAG_GVRP)
106*4882a593Smuzhiyun 		vlan_gvrp_request_leave(dev);
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	vlan_group_set_device(grp, vlan->vlan_proto, vlan_id, NULL);
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	netdev_upper_dev_unlink(real_dev, dev);
111*4882a593Smuzhiyun 	/* Because unregister_netdevice_queue() makes sure at least one rcu
112*4882a593Smuzhiyun 	 * grace period is respected before device freeing,
113*4882a593Smuzhiyun 	 * we dont need to call synchronize_net() here.
114*4882a593Smuzhiyun 	 */
115*4882a593Smuzhiyun 	unregister_netdevice_queue(dev, head);
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 	if (grp->nr_vlan_devs == 0) {
118*4882a593Smuzhiyun 		vlan_mvrp_uninit_applicant(real_dev);
119*4882a593Smuzhiyun 		vlan_gvrp_uninit_applicant(real_dev);
120*4882a593Smuzhiyun 	}
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	vlan_vid_del(real_dev, vlan->vlan_proto, vlan_id);
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun 
vlan_check_real_dev(struct net_device * real_dev,__be16 protocol,u16 vlan_id,struct netlink_ext_ack * extack)125*4882a593Smuzhiyun int vlan_check_real_dev(struct net_device *real_dev,
126*4882a593Smuzhiyun 			__be16 protocol, u16 vlan_id,
127*4882a593Smuzhiyun 			struct netlink_ext_ack *extack)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun 	const char *name = real_dev->name;
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	if (real_dev->features & NETIF_F_VLAN_CHALLENGED) {
132*4882a593Smuzhiyun 		pr_info("VLANs not supported on %s\n", name);
133*4882a593Smuzhiyun 		NL_SET_ERR_MSG_MOD(extack, "VLANs not supported on device");
134*4882a593Smuzhiyun 		return -EOPNOTSUPP;
135*4882a593Smuzhiyun 	}
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 	if (vlan_find_dev(real_dev, protocol, vlan_id) != NULL) {
138*4882a593Smuzhiyun 		NL_SET_ERR_MSG_MOD(extack, "VLAN device already exists");
139*4882a593Smuzhiyun 		return -EEXIST;
140*4882a593Smuzhiyun 	}
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	return 0;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun 
register_vlan_dev(struct net_device * dev,struct netlink_ext_ack * extack)145*4882a593Smuzhiyun int register_vlan_dev(struct net_device *dev, struct netlink_ext_ack *extack)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun 	struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
148*4882a593Smuzhiyun 	struct net_device *real_dev = vlan->real_dev;
149*4882a593Smuzhiyun 	u16 vlan_id = vlan->vlan_id;
150*4882a593Smuzhiyun 	struct vlan_info *vlan_info;
151*4882a593Smuzhiyun 	struct vlan_group *grp;
152*4882a593Smuzhiyun 	int err;
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	err = vlan_vid_add(real_dev, vlan->vlan_proto, vlan_id);
155*4882a593Smuzhiyun 	if (err)
156*4882a593Smuzhiyun 		return err;
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	vlan_info = rtnl_dereference(real_dev->vlan_info);
159*4882a593Smuzhiyun 	/* vlan_info should be there now. vlan_vid_add took care of it */
160*4882a593Smuzhiyun 	BUG_ON(!vlan_info);
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	grp = &vlan_info->grp;
163*4882a593Smuzhiyun 	if (grp->nr_vlan_devs == 0) {
164*4882a593Smuzhiyun 		err = vlan_gvrp_init_applicant(real_dev);
165*4882a593Smuzhiyun 		if (err < 0)
166*4882a593Smuzhiyun 			goto out_vid_del;
167*4882a593Smuzhiyun 		err = vlan_mvrp_init_applicant(real_dev);
168*4882a593Smuzhiyun 		if (err < 0)
169*4882a593Smuzhiyun 			goto out_uninit_gvrp;
170*4882a593Smuzhiyun 	}
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	err = vlan_group_prealloc_vid(grp, vlan->vlan_proto, vlan_id);
173*4882a593Smuzhiyun 	if (err < 0)
174*4882a593Smuzhiyun 		goto out_uninit_mvrp;
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	err = register_netdevice(dev);
177*4882a593Smuzhiyun 	if (err < 0)
178*4882a593Smuzhiyun 		goto out_uninit_mvrp;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 	err = netdev_upper_dev_link(real_dev, dev, extack);
181*4882a593Smuzhiyun 	if (err)
182*4882a593Smuzhiyun 		goto out_unregister_netdev;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	vlan_stacked_transfer_operstate(real_dev, dev, vlan);
185*4882a593Smuzhiyun 	linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 	/* So, got the sucker initialized, now lets place
188*4882a593Smuzhiyun 	 * it into our local structure.
189*4882a593Smuzhiyun 	 */
190*4882a593Smuzhiyun 	vlan_group_set_device(grp, vlan->vlan_proto, vlan_id, dev);
191*4882a593Smuzhiyun 	grp->nr_vlan_devs++;
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	return 0;
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun out_unregister_netdev:
196*4882a593Smuzhiyun 	unregister_netdevice(dev);
197*4882a593Smuzhiyun out_uninit_mvrp:
198*4882a593Smuzhiyun 	if (grp->nr_vlan_devs == 0)
199*4882a593Smuzhiyun 		vlan_mvrp_uninit_applicant(real_dev);
200*4882a593Smuzhiyun out_uninit_gvrp:
201*4882a593Smuzhiyun 	if (grp->nr_vlan_devs == 0)
202*4882a593Smuzhiyun 		vlan_gvrp_uninit_applicant(real_dev);
203*4882a593Smuzhiyun out_vid_del:
204*4882a593Smuzhiyun 	vlan_vid_del(real_dev, vlan->vlan_proto, vlan_id);
205*4882a593Smuzhiyun 	return err;
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun /*  Attach a VLAN device to a mac address (ie Ethernet Card).
209*4882a593Smuzhiyun  *  Returns 0 if the device was created or a negative error code otherwise.
210*4882a593Smuzhiyun  */
register_vlan_device(struct net_device * real_dev,u16 vlan_id)211*4882a593Smuzhiyun static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
212*4882a593Smuzhiyun {
213*4882a593Smuzhiyun 	struct net_device *new_dev;
214*4882a593Smuzhiyun 	struct vlan_dev_priv *vlan;
215*4882a593Smuzhiyun 	struct net *net = dev_net(real_dev);
216*4882a593Smuzhiyun 	struct vlan_net *vn = net_generic(net, vlan_net_id);
217*4882a593Smuzhiyun 	char name[IFNAMSIZ];
218*4882a593Smuzhiyun 	int err;
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	if (vlan_id >= VLAN_VID_MASK)
221*4882a593Smuzhiyun 		return -ERANGE;
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	err = vlan_check_real_dev(real_dev, htons(ETH_P_8021Q), vlan_id,
224*4882a593Smuzhiyun 				  NULL);
225*4882a593Smuzhiyun 	if (err < 0)
226*4882a593Smuzhiyun 		return err;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	/* Gotta set up the fields for the device. */
229*4882a593Smuzhiyun 	switch (vn->name_type) {
230*4882a593Smuzhiyun 	case VLAN_NAME_TYPE_RAW_PLUS_VID:
231*4882a593Smuzhiyun 		/* name will look like:	 eth1.0005 */
232*4882a593Smuzhiyun 		snprintf(name, IFNAMSIZ, "%s.%.4i", real_dev->name, vlan_id);
233*4882a593Smuzhiyun 		break;
234*4882a593Smuzhiyun 	case VLAN_NAME_TYPE_PLUS_VID_NO_PAD:
235*4882a593Smuzhiyun 		/* Put our vlan.VID in the name.
236*4882a593Smuzhiyun 		 * Name will look like:	 vlan5
237*4882a593Smuzhiyun 		 */
238*4882a593Smuzhiyun 		snprintf(name, IFNAMSIZ, "vlan%i", vlan_id);
239*4882a593Smuzhiyun 		break;
240*4882a593Smuzhiyun 	case VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD:
241*4882a593Smuzhiyun 		/* Put our vlan.VID in the name.
242*4882a593Smuzhiyun 		 * Name will look like:	 eth0.5
243*4882a593Smuzhiyun 		 */
244*4882a593Smuzhiyun 		snprintf(name, IFNAMSIZ, "%s.%i", real_dev->name, vlan_id);
245*4882a593Smuzhiyun 		break;
246*4882a593Smuzhiyun 	case VLAN_NAME_TYPE_PLUS_VID:
247*4882a593Smuzhiyun 		/* Put our vlan.VID in the name.
248*4882a593Smuzhiyun 		 * Name will look like:	 vlan0005
249*4882a593Smuzhiyun 		 */
250*4882a593Smuzhiyun 	default:
251*4882a593Smuzhiyun 		snprintf(name, IFNAMSIZ, "vlan%.4i", vlan_id);
252*4882a593Smuzhiyun 	}
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	new_dev = alloc_netdev(sizeof(struct vlan_dev_priv), name,
255*4882a593Smuzhiyun 			       NET_NAME_UNKNOWN, vlan_setup);
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 	if (new_dev == NULL)
258*4882a593Smuzhiyun 		return -ENOBUFS;
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 	dev_net_set(new_dev, net);
261*4882a593Smuzhiyun 	/* need 4 bytes for extra VLAN header info,
262*4882a593Smuzhiyun 	 * hope the underlying device can handle it.
263*4882a593Smuzhiyun 	 */
264*4882a593Smuzhiyun 	new_dev->mtu = real_dev->mtu;
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 	vlan = vlan_dev_priv(new_dev);
267*4882a593Smuzhiyun 	vlan->vlan_proto = htons(ETH_P_8021Q);
268*4882a593Smuzhiyun 	vlan->vlan_id = vlan_id;
269*4882a593Smuzhiyun 	vlan->real_dev = real_dev;
270*4882a593Smuzhiyun 	vlan->dent = NULL;
271*4882a593Smuzhiyun 	vlan->flags = VLAN_FLAG_REORDER_HDR;
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	new_dev->rtnl_link_ops = &vlan_link_ops;
274*4882a593Smuzhiyun 	err = register_vlan_dev(new_dev, NULL);
275*4882a593Smuzhiyun 	if (err < 0)
276*4882a593Smuzhiyun 		goto out_free_newdev;
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	return 0;
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun out_free_newdev:
281*4882a593Smuzhiyun 	free_netdev(new_dev);
282*4882a593Smuzhiyun 	return err;
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun 
vlan_sync_address(struct net_device * dev,struct net_device * vlandev)285*4882a593Smuzhiyun static void vlan_sync_address(struct net_device *dev,
286*4882a593Smuzhiyun 			      struct net_device *vlandev)
287*4882a593Smuzhiyun {
288*4882a593Smuzhiyun 	struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	/* May be called without an actual change */
291*4882a593Smuzhiyun 	if (ether_addr_equal(vlan->real_dev_addr, dev->dev_addr))
292*4882a593Smuzhiyun 		return;
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	/* vlan continues to inherit address of lower device */
295*4882a593Smuzhiyun 	if (vlan_dev_inherit_address(vlandev, dev))
296*4882a593Smuzhiyun 		goto out;
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 	/* vlan address was different from the old address and is equal to
299*4882a593Smuzhiyun 	 * the new address */
300*4882a593Smuzhiyun 	if (!ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) &&
301*4882a593Smuzhiyun 	    ether_addr_equal(vlandev->dev_addr, dev->dev_addr))
302*4882a593Smuzhiyun 		dev_uc_del(dev, vlandev->dev_addr);
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun 	/* vlan address was equal to the old address and is different from
305*4882a593Smuzhiyun 	 * the new address */
306*4882a593Smuzhiyun 	if (ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) &&
307*4882a593Smuzhiyun 	    !ether_addr_equal(vlandev->dev_addr, dev->dev_addr))
308*4882a593Smuzhiyun 		dev_uc_add(dev, vlandev->dev_addr);
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun out:
311*4882a593Smuzhiyun 	ether_addr_copy(vlan->real_dev_addr, dev->dev_addr);
312*4882a593Smuzhiyun }
313*4882a593Smuzhiyun 
vlan_transfer_features(struct net_device * dev,struct net_device * vlandev)314*4882a593Smuzhiyun static void vlan_transfer_features(struct net_device *dev,
315*4882a593Smuzhiyun 				   struct net_device *vlandev)
316*4882a593Smuzhiyun {
317*4882a593Smuzhiyun 	struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun 	vlandev->gso_max_size = dev->gso_max_size;
320*4882a593Smuzhiyun 	vlandev->gso_max_segs = dev->gso_max_segs;
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	if (vlan_hw_offload_capable(dev->features, vlan->vlan_proto))
323*4882a593Smuzhiyun 		vlandev->hard_header_len = dev->hard_header_len;
324*4882a593Smuzhiyun 	else
325*4882a593Smuzhiyun 		vlandev->hard_header_len = dev->hard_header_len + VLAN_HLEN;
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_FCOE)
328*4882a593Smuzhiyun 	vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid;
329*4882a593Smuzhiyun #endif
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 	vlandev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
332*4882a593Smuzhiyun 	vlandev->priv_flags |= (vlan->real_dev->priv_flags & IFF_XMIT_DST_RELEASE);
333*4882a593Smuzhiyun 	vlandev->hw_enc_features = vlan_tnl_features(vlan->real_dev);
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 	netdev_update_features(vlandev);
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun 
__vlan_device_event(struct net_device * dev,unsigned long event)338*4882a593Smuzhiyun static int __vlan_device_event(struct net_device *dev, unsigned long event)
339*4882a593Smuzhiyun {
340*4882a593Smuzhiyun 	int err = 0;
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 	switch (event) {
343*4882a593Smuzhiyun 	case NETDEV_CHANGENAME:
344*4882a593Smuzhiyun 		vlan_proc_rem_dev(dev);
345*4882a593Smuzhiyun 		err = vlan_proc_add_dev(dev);
346*4882a593Smuzhiyun 		break;
347*4882a593Smuzhiyun 	case NETDEV_REGISTER:
348*4882a593Smuzhiyun 		err = vlan_proc_add_dev(dev);
349*4882a593Smuzhiyun 		break;
350*4882a593Smuzhiyun 	case NETDEV_UNREGISTER:
351*4882a593Smuzhiyun 		vlan_proc_rem_dev(dev);
352*4882a593Smuzhiyun 		break;
353*4882a593Smuzhiyun 	}
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 	return err;
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun 
vlan_device_event(struct notifier_block * unused,unsigned long event,void * ptr)358*4882a593Smuzhiyun static int vlan_device_event(struct notifier_block *unused, unsigned long event,
359*4882a593Smuzhiyun 			     void *ptr)
360*4882a593Smuzhiyun {
361*4882a593Smuzhiyun 	struct netlink_ext_ack *extack = netdev_notifier_info_to_extack(ptr);
362*4882a593Smuzhiyun 	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
363*4882a593Smuzhiyun 	struct vlan_group *grp;
364*4882a593Smuzhiyun 	struct vlan_info *vlan_info;
365*4882a593Smuzhiyun 	int i, flgs;
366*4882a593Smuzhiyun 	struct net_device *vlandev;
367*4882a593Smuzhiyun 	struct vlan_dev_priv *vlan;
368*4882a593Smuzhiyun 	bool last = false;
369*4882a593Smuzhiyun 	LIST_HEAD(list);
370*4882a593Smuzhiyun 	int err;
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 	if (is_vlan_dev(dev)) {
373*4882a593Smuzhiyun 		int err = __vlan_device_event(dev, event);
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 		if (err)
376*4882a593Smuzhiyun 			return notifier_from_errno(err);
377*4882a593Smuzhiyun 	}
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 	if ((event == NETDEV_UP) &&
380*4882a593Smuzhiyun 	    (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) {
381*4882a593Smuzhiyun 		pr_info("adding VLAN 0 to HW filter on device %s\n",
382*4882a593Smuzhiyun 			dev->name);
383*4882a593Smuzhiyun 		vlan_vid_add(dev, htons(ETH_P_8021Q), 0);
384*4882a593Smuzhiyun 	}
385*4882a593Smuzhiyun 	if (event == NETDEV_DOWN &&
386*4882a593Smuzhiyun 	    (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER))
387*4882a593Smuzhiyun 		vlan_vid_del(dev, htons(ETH_P_8021Q), 0);
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun 	vlan_info = rtnl_dereference(dev->vlan_info);
390*4882a593Smuzhiyun 	if (!vlan_info)
391*4882a593Smuzhiyun 		goto out;
392*4882a593Smuzhiyun 	grp = &vlan_info->grp;
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 	/* It is OK that we do not hold the group lock right now,
395*4882a593Smuzhiyun 	 * as we run under the RTNL lock.
396*4882a593Smuzhiyun 	 */
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 	switch (event) {
399*4882a593Smuzhiyun 	case NETDEV_CHANGE:
400*4882a593Smuzhiyun 		/* Propagate real device state to vlan devices */
401*4882a593Smuzhiyun 		vlan_group_for_each_dev(grp, i, vlandev)
402*4882a593Smuzhiyun 			vlan_stacked_transfer_operstate(dev, vlandev,
403*4882a593Smuzhiyun 							vlan_dev_priv(vlandev));
404*4882a593Smuzhiyun 		break;
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 	case NETDEV_CHANGEADDR:
407*4882a593Smuzhiyun 		/* Adjust unicast filters on underlying device */
408*4882a593Smuzhiyun 		vlan_group_for_each_dev(grp, i, vlandev) {
409*4882a593Smuzhiyun 			flgs = vlandev->flags;
410*4882a593Smuzhiyun 			if (!(flgs & IFF_UP))
411*4882a593Smuzhiyun 				continue;
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 			vlan_sync_address(dev, vlandev);
414*4882a593Smuzhiyun 		}
415*4882a593Smuzhiyun 		break;
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 	case NETDEV_CHANGEMTU:
418*4882a593Smuzhiyun 		vlan_group_for_each_dev(grp, i, vlandev) {
419*4882a593Smuzhiyun 			if (vlandev->mtu <= dev->mtu)
420*4882a593Smuzhiyun 				continue;
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 			dev_set_mtu(vlandev, dev->mtu);
423*4882a593Smuzhiyun 		}
424*4882a593Smuzhiyun 		break;
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 	case NETDEV_FEAT_CHANGE:
427*4882a593Smuzhiyun 		/* Propagate device features to underlying device */
428*4882a593Smuzhiyun 		vlan_group_for_each_dev(grp, i, vlandev)
429*4882a593Smuzhiyun 			vlan_transfer_features(dev, vlandev);
430*4882a593Smuzhiyun 		break;
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun 	case NETDEV_DOWN: {
433*4882a593Smuzhiyun 		struct net_device *tmp;
434*4882a593Smuzhiyun 		LIST_HEAD(close_list);
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 		/* Put all VLANs for this dev in the down state too.  */
437*4882a593Smuzhiyun 		vlan_group_for_each_dev(grp, i, vlandev) {
438*4882a593Smuzhiyun 			flgs = vlandev->flags;
439*4882a593Smuzhiyun 			if (!(flgs & IFF_UP))
440*4882a593Smuzhiyun 				continue;
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun 			vlan = vlan_dev_priv(vlandev);
443*4882a593Smuzhiyun 			if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
444*4882a593Smuzhiyun 				list_add(&vlandev->close_list, &close_list);
445*4882a593Smuzhiyun 		}
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 		dev_close_many(&close_list, false);
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 		list_for_each_entry_safe(vlandev, tmp, &close_list, close_list) {
450*4882a593Smuzhiyun 			vlan_stacked_transfer_operstate(dev, vlandev,
451*4882a593Smuzhiyun 							vlan_dev_priv(vlandev));
452*4882a593Smuzhiyun 			list_del_init(&vlandev->close_list);
453*4882a593Smuzhiyun 		}
454*4882a593Smuzhiyun 		list_del(&close_list);
455*4882a593Smuzhiyun 		break;
456*4882a593Smuzhiyun 	}
457*4882a593Smuzhiyun 	case NETDEV_UP:
458*4882a593Smuzhiyun 		/* Put all VLANs for this dev in the up state too.  */
459*4882a593Smuzhiyun 		vlan_group_for_each_dev(grp, i, vlandev) {
460*4882a593Smuzhiyun 			flgs = dev_get_flags(vlandev);
461*4882a593Smuzhiyun 			if (flgs & IFF_UP)
462*4882a593Smuzhiyun 				continue;
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun 			vlan = vlan_dev_priv(vlandev);
465*4882a593Smuzhiyun 			if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
466*4882a593Smuzhiyun 				dev_change_flags(vlandev, flgs | IFF_UP,
467*4882a593Smuzhiyun 						 extack);
468*4882a593Smuzhiyun 			vlan_stacked_transfer_operstate(dev, vlandev, vlan);
469*4882a593Smuzhiyun 		}
470*4882a593Smuzhiyun 		break;
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun 	case NETDEV_UNREGISTER:
473*4882a593Smuzhiyun 		/* twiddle thumbs on netns device moves */
474*4882a593Smuzhiyun 		if (dev->reg_state != NETREG_UNREGISTERING)
475*4882a593Smuzhiyun 			break;
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 		vlan_group_for_each_dev(grp, i, vlandev) {
478*4882a593Smuzhiyun 			/* removal of last vid destroys vlan_info, abort
479*4882a593Smuzhiyun 			 * afterwards */
480*4882a593Smuzhiyun 			if (vlan_info->nr_vids == 1)
481*4882a593Smuzhiyun 				last = true;
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 			unregister_vlan_dev(vlandev, &list);
484*4882a593Smuzhiyun 			if (last)
485*4882a593Smuzhiyun 				break;
486*4882a593Smuzhiyun 		}
487*4882a593Smuzhiyun 		unregister_netdevice_many(&list);
488*4882a593Smuzhiyun 		break;
489*4882a593Smuzhiyun 
490*4882a593Smuzhiyun 	case NETDEV_PRE_TYPE_CHANGE:
491*4882a593Smuzhiyun 		/* Forbid underlaying device to change its type. */
492*4882a593Smuzhiyun 		if (vlan_uses_dev(dev))
493*4882a593Smuzhiyun 			return NOTIFY_BAD;
494*4882a593Smuzhiyun 		break;
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun 	case NETDEV_NOTIFY_PEERS:
497*4882a593Smuzhiyun 	case NETDEV_BONDING_FAILOVER:
498*4882a593Smuzhiyun 	case NETDEV_RESEND_IGMP:
499*4882a593Smuzhiyun 		/* Propagate to vlan devices */
500*4882a593Smuzhiyun 		vlan_group_for_each_dev(grp, i, vlandev)
501*4882a593Smuzhiyun 			call_netdevice_notifiers(event, vlandev);
502*4882a593Smuzhiyun 		break;
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun 	case NETDEV_CVLAN_FILTER_PUSH_INFO:
505*4882a593Smuzhiyun 		err = vlan_filter_push_vids(vlan_info, htons(ETH_P_8021Q));
506*4882a593Smuzhiyun 		if (err)
507*4882a593Smuzhiyun 			return notifier_from_errno(err);
508*4882a593Smuzhiyun 		break;
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 	case NETDEV_CVLAN_FILTER_DROP_INFO:
511*4882a593Smuzhiyun 		vlan_filter_drop_vids(vlan_info, htons(ETH_P_8021Q));
512*4882a593Smuzhiyun 		break;
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 	case NETDEV_SVLAN_FILTER_PUSH_INFO:
515*4882a593Smuzhiyun 		err = vlan_filter_push_vids(vlan_info, htons(ETH_P_8021AD));
516*4882a593Smuzhiyun 		if (err)
517*4882a593Smuzhiyun 			return notifier_from_errno(err);
518*4882a593Smuzhiyun 		break;
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun 	case NETDEV_SVLAN_FILTER_DROP_INFO:
521*4882a593Smuzhiyun 		vlan_filter_drop_vids(vlan_info, htons(ETH_P_8021AD));
522*4882a593Smuzhiyun 		break;
523*4882a593Smuzhiyun 	}
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun out:
526*4882a593Smuzhiyun 	return NOTIFY_DONE;
527*4882a593Smuzhiyun }
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun static struct notifier_block vlan_notifier_block __read_mostly = {
530*4882a593Smuzhiyun 	.notifier_call = vlan_device_event,
531*4882a593Smuzhiyun };
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun /*
534*4882a593Smuzhiyun  *	VLAN IOCTL handler.
535*4882a593Smuzhiyun  *	o execute requested action or pass command to the device driver
536*4882a593Smuzhiyun  *   arg is really a struct vlan_ioctl_args __user *.
537*4882a593Smuzhiyun  */
vlan_ioctl_handler(struct net * net,void __user * arg)538*4882a593Smuzhiyun static int vlan_ioctl_handler(struct net *net, void __user *arg)
539*4882a593Smuzhiyun {
540*4882a593Smuzhiyun 	int err;
541*4882a593Smuzhiyun 	struct vlan_ioctl_args args;
542*4882a593Smuzhiyun 	struct net_device *dev = NULL;
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 	if (copy_from_user(&args, arg, sizeof(struct vlan_ioctl_args)))
545*4882a593Smuzhiyun 		return -EFAULT;
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun 	/* Null terminate this sucker, just in case. */
548*4882a593Smuzhiyun 	args.device1[sizeof(args.device1) - 1] = 0;
549*4882a593Smuzhiyun 	args.u.device2[sizeof(args.u.device2) - 1] = 0;
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun 	rtnl_lock();
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 	switch (args.cmd) {
554*4882a593Smuzhiyun 	case SET_VLAN_INGRESS_PRIORITY_CMD:
555*4882a593Smuzhiyun 	case SET_VLAN_EGRESS_PRIORITY_CMD:
556*4882a593Smuzhiyun 	case SET_VLAN_FLAG_CMD:
557*4882a593Smuzhiyun 	case ADD_VLAN_CMD:
558*4882a593Smuzhiyun 	case DEL_VLAN_CMD:
559*4882a593Smuzhiyun 	case GET_VLAN_REALDEV_NAME_CMD:
560*4882a593Smuzhiyun 	case GET_VLAN_VID_CMD:
561*4882a593Smuzhiyun 		err = -ENODEV;
562*4882a593Smuzhiyun 		dev = __dev_get_by_name(net, args.device1);
563*4882a593Smuzhiyun 		if (!dev)
564*4882a593Smuzhiyun 			goto out;
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun 		err = -EINVAL;
567*4882a593Smuzhiyun 		if (args.cmd != ADD_VLAN_CMD && !is_vlan_dev(dev))
568*4882a593Smuzhiyun 			goto out;
569*4882a593Smuzhiyun 	}
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun 	switch (args.cmd) {
572*4882a593Smuzhiyun 	case SET_VLAN_INGRESS_PRIORITY_CMD:
573*4882a593Smuzhiyun 		err = -EPERM;
574*4882a593Smuzhiyun 		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
575*4882a593Smuzhiyun 			break;
576*4882a593Smuzhiyun 		vlan_dev_set_ingress_priority(dev,
577*4882a593Smuzhiyun 					      args.u.skb_priority,
578*4882a593Smuzhiyun 					      args.vlan_qos);
579*4882a593Smuzhiyun 		err = 0;
580*4882a593Smuzhiyun 		break;
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun 	case SET_VLAN_EGRESS_PRIORITY_CMD:
583*4882a593Smuzhiyun 		err = -EPERM;
584*4882a593Smuzhiyun 		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
585*4882a593Smuzhiyun 			break;
586*4882a593Smuzhiyun 		err = vlan_dev_set_egress_priority(dev,
587*4882a593Smuzhiyun 						   args.u.skb_priority,
588*4882a593Smuzhiyun 						   args.vlan_qos);
589*4882a593Smuzhiyun 		break;
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun 	case SET_VLAN_FLAG_CMD:
592*4882a593Smuzhiyun 		err = -EPERM;
593*4882a593Smuzhiyun 		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
594*4882a593Smuzhiyun 			break;
595*4882a593Smuzhiyun 		err = vlan_dev_change_flags(dev,
596*4882a593Smuzhiyun 					    args.vlan_qos ? args.u.flag : 0,
597*4882a593Smuzhiyun 					    args.u.flag);
598*4882a593Smuzhiyun 		break;
599*4882a593Smuzhiyun 
600*4882a593Smuzhiyun 	case SET_VLAN_NAME_TYPE_CMD:
601*4882a593Smuzhiyun 		err = -EPERM;
602*4882a593Smuzhiyun 		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
603*4882a593Smuzhiyun 			break;
604*4882a593Smuzhiyun 		if (args.u.name_type < VLAN_NAME_TYPE_HIGHEST) {
605*4882a593Smuzhiyun 			struct vlan_net *vn;
606*4882a593Smuzhiyun 
607*4882a593Smuzhiyun 			vn = net_generic(net, vlan_net_id);
608*4882a593Smuzhiyun 			vn->name_type = args.u.name_type;
609*4882a593Smuzhiyun 			err = 0;
610*4882a593Smuzhiyun 		} else {
611*4882a593Smuzhiyun 			err = -EINVAL;
612*4882a593Smuzhiyun 		}
613*4882a593Smuzhiyun 		break;
614*4882a593Smuzhiyun 
615*4882a593Smuzhiyun 	case ADD_VLAN_CMD:
616*4882a593Smuzhiyun 		err = -EPERM;
617*4882a593Smuzhiyun 		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
618*4882a593Smuzhiyun 			break;
619*4882a593Smuzhiyun 		err = register_vlan_device(dev, args.u.VID);
620*4882a593Smuzhiyun 		break;
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun 	case DEL_VLAN_CMD:
623*4882a593Smuzhiyun 		err = -EPERM;
624*4882a593Smuzhiyun 		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
625*4882a593Smuzhiyun 			break;
626*4882a593Smuzhiyun 		unregister_vlan_dev(dev, NULL);
627*4882a593Smuzhiyun 		err = 0;
628*4882a593Smuzhiyun 		break;
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun 	case GET_VLAN_REALDEV_NAME_CMD:
631*4882a593Smuzhiyun 		err = 0;
632*4882a593Smuzhiyun 		vlan_dev_get_realdev_name(dev, args.u.device2);
633*4882a593Smuzhiyun 		if (copy_to_user(arg, &args,
634*4882a593Smuzhiyun 				 sizeof(struct vlan_ioctl_args)))
635*4882a593Smuzhiyun 			err = -EFAULT;
636*4882a593Smuzhiyun 		break;
637*4882a593Smuzhiyun 
638*4882a593Smuzhiyun 	case GET_VLAN_VID_CMD:
639*4882a593Smuzhiyun 		err = 0;
640*4882a593Smuzhiyun 		args.u.VID = vlan_dev_vlan_id(dev);
641*4882a593Smuzhiyun 		if (copy_to_user(arg, &args,
642*4882a593Smuzhiyun 				 sizeof(struct vlan_ioctl_args)))
643*4882a593Smuzhiyun 		      err = -EFAULT;
644*4882a593Smuzhiyun 		break;
645*4882a593Smuzhiyun 
646*4882a593Smuzhiyun 	default:
647*4882a593Smuzhiyun 		err = -EOPNOTSUPP;
648*4882a593Smuzhiyun 		break;
649*4882a593Smuzhiyun 	}
650*4882a593Smuzhiyun out:
651*4882a593Smuzhiyun 	rtnl_unlock();
652*4882a593Smuzhiyun 	return err;
653*4882a593Smuzhiyun }
654*4882a593Smuzhiyun 
vlan_init_net(struct net * net)655*4882a593Smuzhiyun static int __net_init vlan_init_net(struct net *net)
656*4882a593Smuzhiyun {
657*4882a593Smuzhiyun 	struct vlan_net *vn = net_generic(net, vlan_net_id);
658*4882a593Smuzhiyun 	int err;
659*4882a593Smuzhiyun 
660*4882a593Smuzhiyun 	vn->name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD;
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun 	err = vlan_proc_init(net);
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun 	return err;
665*4882a593Smuzhiyun }
666*4882a593Smuzhiyun 
vlan_exit_net(struct net * net)667*4882a593Smuzhiyun static void __net_exit vlan_exit_net(struct net *net)
668*4882a593Smuzhiyun {
669*4882a593Smuzhiyun 	vlan_proc_cleanup(net);
670*4882a593Smuzhiyun }
671*4882a593Smuzhiyun 
672*4882a593Smuzhiyun static struct pernet_operations vlan_net_ops = {
673*4882a593Smuzhiyun 	.init = vlan_init_net,
674*4882a593Smuzhiyun 	.exit = vlan_exit_net,
675*4882a593Smuzhiyun 	.id   = &vlan_net_id,
676*4882a593Smuzhiyun 	.size = sizeof(struct vlan_net),
677*4882a593Smuzhiyun };
678*4882a593Smuzhiyun 
vlan_proto_init(void)679*4882a593Smuzhiyun static int __init vlan_proto_init(void)
680*4882a593Smuzhiyun {
681*4882a593Smuzhiyun 	int err;
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun 	pr_info("%s v%s\n", vlan_fullname, vlan_version);
684*4882a593Smuzhiyun 
685*4882a593Smuzhiyun 	err = register_pernet_subsys(&vlan_net_ops);
686*4882a593Smuzhiyun 	if (err < 0)
687*4882a593Smuzhiyun 		goto err0;
688*4882a593Smuzhiyun 
689*4882a593Smuzhiyun 	err = register_netdevice_notifier(&vlan_notifier_block);
690*4882a593Smuzhiyun 	if (err < 0)
691*4882a593Smuzhiyun 		goto err2;
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun 	err = vlan_gvrp_init();
694*4882a593Smuzhiyun 	if (err < 0)
695*4882a593Smuzhiyun 		goto err3;
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun 	err = vlan_mvrp_init();
698*4882a593Smuzhiyun 	if (err < 0)
699*4882a593Smuzhiyun 		goto err4;
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 	err = vlan_netlink_init();
702*4882a593Smuzhiyun 	if (err < 0)
703*4882a593Smuzhiyun 		goto err5;
704*4882a593Smuzhiyun 
705*4882a593Smuzhiyun 	vlan_ioctl_set(vlan_ioctl_handler);
706*4882a593Smuzhiyun 	return 0;
707*4882a593Smuzhiyun 
708*4882a593Smuzhiyun err5:
709*4882a593Smuzhiyun 	vlan_mvrp_uninit();
710*4882a593Smuzhiyun err4:
711*4882a593Smuzhiyun 	vlan_gvrp_uninit();
712*4882a593Smuzhiyun err3:
713*4882a593Smuzhiyun 	unregister_netdevice_notifier(&vlan_notifier_block);
714*4882a593Smuzhiyun err2:
715*4882a593Smuzhiyun 	unregister_pernet_subsys(&vlan_net_ops);
716*4882a593Smuzhiyun err0:
717*4882a593Smuzhiyun 	return err;
718*4882a593Smuzhiyun }
719*4882a593Smuzhiyun 
vlan_cleanup_module(void)720*4882a593Smuzhiyun static void __exit vlan_cleanup_module(void)
721*4882a593Smuzhiyun {
722*4882a593Smuzhiyun 	vlan_ioctl_set(NULL);
723*4882a593Smuzhiyun 
724*4882a593Smuzhiyun 	vlan_netlink_fini();
725*4882a593Smuzhiyun 
726*4882a593Smuzhiyun 	unregister_netdevice_notifier(&vlan_notifier_block);
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun 	unregister_pernet_subsys(&vlan_net_ops);
729*4882a593Smuzhiyun 	rcu_barrier(); /* Wait for completion of call_rcu()'s */
730*4882a593Smuzhiyun 
731*4882a593Smuzhiyun 	vlan_mvrp_uninit();
732*4882a593Smuzhiyun 	vlan_gvrp_uninit();
733*4882a593Smuzhiyun }
734*4882a593Smuzhiyun 
735*4882a593Smuzhiyun module_init(vlan_proto_init);
736*4882a593Smuzhiyun module_exit(vlan_cleanup_module);
737*4882a593Smuzhiyun 
738*4882a593Smuzhiyun MODULE_LICENSE("GPL");
739*4882a593Smuzhiyun MODULE_VERSION(DRV_VERSION);
740