History

net/8021q: Implement Multiple VLAN Registration Protocol (MVRP)

Initial implementation of the Multiple VLAN Registration Protocol (MVRP) from IEEE 802.1Q-2011, based on the existing implementation of the GARP VLAN Registration Protocol (GVRP).

David Ward committed 13 years ago

Commit 86fbe9b1 parent febf0189 files · +136 −7Browse files

Unified · Split

9 files
  1. include/uapi/linux/if_ether.h +1 −0
  2. include/uapi/linux/if_vlan.h +1 −0
  3. net/8021q/Kconfig +11 −0
  4. net/8021q/Makefile +1 −0
  5. net/8021q/vlan.c +22 −5
  6. net/8021q/vlan.h +16 −0
  7. net/8021q/vlan_dev.c +11 −1
  8. net/8021q/vlan_mvrp.c +72 −0
  9. net/8021q/vlan_netlink.c +1 −1
include/uapi/linux/if_ether.h+1−0
@@ -83,6 +83,7 @@ · 82 unmodified lines
83#define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */83#define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */
84#define ETH_P_TIPC 0x88CA /* TIPC */84#define ETH_P_TIPC 0x88CA /* TIPC */
85#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */85#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */
86#define ETH_P_MVRP 0x88F5 /* 802.1Q MVRP */
86#define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */87#define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */
87#define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */88#define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */
88#define ETH_P_TDLS 0x890D /* TDLS */89#define ETH_P_TDLS 0x890D /* TDLS */
include/uapi/linux/if_vlan.h+1−0
@@ -34,6 +34,7 @@ enum vlan_flags { · 33 unmodified lines
34 VLAN_FLAG_REORDER_HDR = 0x1,34 VLAN_FLAG_REORDER_HDR = 0x1,
35 VLAN_FLAG_GVRP = 0x2,35 VLAN_FLAG_GVRP = 0x2,
36 VLAN_FLAG_LOOSE_BINDING = 0x4,36 VLAN_FLAG_LOOSE_BINDING = 0x4,
37 VLAN_FLAG_MVRP = 0x8,
37};38};
38 39
39enum vlan_name_types {40enum vlan_name_types {
net/8021q/Kconfig+11−0
@@ -27,3 +27,14 @@ config VLAN_8021Q_GVRP · 26 unmodified lines
27 automatic propagation of registered VLANs to switches.27 automatic propagation of registered VLANs to switches.
28 28
29 If unsure, say N.29 If unsure, say N.
30
31config VLAN_8021Q_MVRP
32 bool "MVRP (Multiple VLAN Registration Protocol) support"
33 depends on VLAN_8021Q
34 select MRP
35 help
36 Select this to enable MVRP end-system support. MVRP is used for
37 automatic propagation of registered VLANs to switches; it
38 supersedes GVRP and is not backwards-compatible.
39
40 If unsure, say N.
net/8021q/Makefile+1−0
@@ -6,5 +6,6 @@ obj-$(CONFIG_VLAN_8021Q) += 8021q.o · 5 unmodified lines
6 6
78021q-y := vlan.o vlan_dev.o vlan_netlink.o78021q-y := vlan.o vlan_dev.o vlan_netlink.o
88021q-$(CONFIG_VLAN_8021Q_GVRP) += vlan_gvrp.o88021q-$(CONFIG_VLAN_8021Q_GVRP) += vlan_gvrp.o
98021q-$(CONFIG_VLAN_8021Q_MVRP) += vlan_mvrp.o
98021q-$(CONFIG_PROC_FS) += vlanproc.o108021q-$(CONFIG_PROC_FS) += vlanproc.o
10 11
net/8021q/vlan.c+22−5
@@ -95,6 +95,8 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) · 94 unmodified lines
95 95
96 grp->nr_vlan_devs--;96 grp->nr_vlan_devs--;
97 97
98 if (vlan->flags & VLAN_FLAG_MVRP)
99 vlan_mvrp_request_leave(dev);
98 if (vlan->flags & VLAN_FLAG_GVRP)100 if (vlan->flags & VLAN_FLAG_GVRP)
99 vlan_gvrp_request_leave(dev);101 vlan_gvrp_request_leave(dev);
100 102
@@ -107,8 +109,10 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) · 6 unmodified lines
107 109
108 netdev_upper_dev_unlink(real_dev, dev);110 netdev_upper_dev_unlink(real_dev, dev);
109 111
110 if (grp->nr_vlan_devs == 0)112 if (grp->nr_vlan_devs == 0) {
113 vlan_mvrp_uninit_applicant(real_dev);
111 vlan_gvrp_uninit_applicant(real_dev);114 vlan_gvrp_uninit_applicant(real_dev);
115 }
112 116
113 /* Get rid of the vlan's reference to real_dev */117 /* Get rid of the vlan's reference to real_dev */
114 dev_put(real_dev);118 dev_put(real_dev);
@@ -151,15 +155,18 @@ int register_vlan_dev(struct net_device *dev) · 36 unmodified lines
151 err = vlan_gvrp_init_applicant(real_dev);155 err = vlan_gvrp_init_applicant(real_dev);
152 if (err < 0)156 if (err < 0)
153 goto out_vid_del;157 goto out_vid_del;
158 err = vlan_mvrp_init_applicant(real_dev);
159 if (err < 0)
160 goto out_uninit_gvrp;
154 }161 }
155 162
156 err = vlan_group_prealloc_vid(grp, vlan_id);163 err = vlan_group_prealloc_vid(grp, vlan_id);
157 if (err < 0)164 if (err < 0)
158 goto out_uninit_applicant;165 goto out_uninit_mvrp;
159 166
160 err = netdev_upper_dev_link(real_dev, dev);167 err = netdev_upper_dev_link(real_dev, dev);
161 if (err)168 if (err)
162 goto out_uninit_applicant;169 goto out_uninit_mvrp;
163 170
164 err = register_netdevice(dev);171 err = register_netdevice(dev);
165 if (err < 0)172 if (err < 0)
@@ -181,7 +188,10 @@ int register_vlan_dev(struct net_device *dev) · 15 unmodified lines
181 188
182out_upper_dev_unlink:189out_upper_dev_unlink:
183 netdev_upper_dev_unlink(real_dev, dev);190 netdev_upper_dev_unlink(real_dev, dev);
184out_uninit_applicant:191out_uninit_mvrp:
192 if (grp->nr_vlan_devs == 0)
193 vlan_mvrp_uninit_applicant(real_dev);
194out_uninit_gvrp:
185 if (grp->nr_vlan_devs == 0)195 if (grp->nr_vlan_devs == 0)
186 vlan_gvrp_uninit_applicant(real_dev);196 vlan_gvrp_uninit_applicant(real_dev);
187out_vid_del:197out_vid_del:
@@ -655,13 +665,19 @@ static int __init vlan_proto_init(void) · 467 unmodified lines
655 if (err < 0)665 if (err < 0)
656 goto err3;666 goto err3;
657 667
658 err = vlan_netlink_init();668 err = vlan_mvrp_init();
659 if (err < 0)669 if (err < 0)
660 goto err4;670 goto err4;
661 671
672 err = vlan_netlink_init();
673 if (err < 0)
674 goto err5;
675
662 vlan_ioctl_set(vlan_ioctl_handler);676 vlan_ioctl_set(vlan_ioctl_handler);
663 return 0;677 return 0;
664 678
679err5:
680 vlan_mvrp_uninit();
665err4:681err4:
666 vlan_gvrp_uninit();682 vlan_gvrp_uninit();
667err3:683err3:
@@ -682,6 +698,7 @@ static void __exit vlan_cleanup_module(void) · 14 unmodified lines
682 unregister_pernet_subsys(&vlan_net_ops);698 unregister_pernet_subsys(&vlan_net_ops);
683 rcu_barrier(); /* Wait for completion of call_rcu()'s */699 rcu_barrier(); /* Wait for completion of call_rcu()'s */
684 700
701 vlan_mvrp_uninit();
685 vlan_gvrp_uninit();702 vlan_gvrp_uninit();
686}703}
687 704
net/8021q/vlan.h+16−0
@@ -171,6 +171,22 @@ static inline int vlan_gvrp_init(void) { return 0; } · 170 unmodified lines
171static inline void vlan_gvrp_uninit(void) {}171static inline void vlan_gvrp_uninit(void) {}
172#endif172#endif
173 173
174#ifdef CONFIG_VLAN_8021Q_MVRP
175extern int vlan_mvrp_request_join(const struct net_device *dev);
176extern void vlan_mvrp_request_leave(const struct net_device *dev);
177extern int vlan_mvrp_init_applicant(struct net_device *dev);
178extern void vlan_mvrp_uninit_applicant(struct net_device *dev);
179extern int vlan_mvrp_init(void);
180extern void vlan_mvrp_uninit(void);
181#else
182static inline int vlan_mvrp_request_join(const struct net_device *dev) { return 0; }
183static inline void vlan_mvrp_request_leave(const struct net_device *dev) {}
184static inline int vlan_mvrp_init_applicant(struct net_device *dev) { return 0; }
185static inline void vlan_mvrp_uninit_applicant(struct net_device *dev) {}
186static inline int vlan_mvrp_init(void) { return 0; }
187static inline void vlan_mvrp_uninit(void) {}
188#endif
189
174extern const char vlan_fullname[];190extern const char vlan_fullname[];
175extern const char vlan_version[];191extern const char vlan_version[];
176extern int vlan_netlink_init(void);192extern int vlan_netlink_init(void);
net/8021q/vlan_dev.c+11−1
@@ -261,7 +261,7 @@ int vlan_dev_change_flags(const struct net_device *dev, u32 flags, u32 mask) · 260 unmodified lines
261 u32 old_flags = vlan->flags;261 u32 old_flags = vlan->flags;
262 262
263 if (mask & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP |263 if (mask & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP |
264 VLAN_FLAG_LOOSE_BINDING))264 VLAN_FLAG_LOOSE_BINDING | VLAN_FLAG_MVRP))
265 return -EINVAL;265 return -EINVAL;
266 266
267 vlan->flags = (old_flags & ~mask) | (flags & mask);267 vlan->flags = (old_flags & ~mask) | (flags & mask);
@@ -272,6 +272,13 @@ int vlan_dev_change_flags(const struct net_device *dev, u32 flags, u32 mask) · 4 unmodified lines
272 else272 else
273 vlan_gvrp_request_leave(dev);273 vlan_gvrp_request_leave(dev);
274 }274 }
275
276 if (netif_running(dev) && (vlan->flags ^ old_flags) & VLAN_FLAG_MVRP) {
277 if (vlan->flags & VLAN_FLAG_MVRP)
278 vlan_mvrp_request_join(dev);
279 else
280 vlan_mvrp_request_leave(dev);
281 }
275 return 0;282 return 0;
276}283}
277 284
@@ -312,6 +319,9 @@ static int vlan_dev_open(struct net_device *dev) · 34 unmodified lines
312 if (vlan->flags & VLAN_FLAG_GVRP)319 if (vlan->flags & VLAN_FLAG_GVRP)
313 vlan_gvrp_request_join(dev);320 vlan_gvrp_request_join(dev);
314 321
322 if (vlan->flags & VLAN_FLAG_MVRP)
323 vlan_mvrp_request_join(dev);
324
315 if (netif_carrier_ok(real_dev))325 if (netif_carrier_ok(real_dev))
316 netif_carrier_on(dev);326 netif_carrier_on(dev);
317 return 0;327 return 0;
net/8021q/vlan_mvrp.c+72−0
@@ -0,0 +1,72 @@
1/*
2 * IEEE 802.1Q Multiple VLAN Registration Protocol (MVRP)
3 *
4 * Copyright (c) 2012 Massachusetts Institute of Technology
5 *
6 * Adapted from code in net/8021q/vlan_gvrp.c
7 * Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 */
13#include <linux/types.h>
14#include <linux/if_ether.h>
15#include <linux/if_vlan.h>
16#include <net/mrp.h>
17#include "vlan.h"
18
19#define MRP_MVRP_ADDRESS { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x21 }
20
21enum mvrp_attributes {
22 MVRP_ATTR_INVALID,
23 MVRP_ATTR_VID,
24 __MVRP_ATTR_MAX
25};
26#define MVRP_ATTR_MAX (__MVRP_ATTR_MAX - 1)
27
28static struct mrp_application vlan_mrp_app __read_mostly = {
29 .type = MRP_APPLICATION_MVRP,
30 .maxattr = MVRP_ATTR_MAX,
31 .pkttype.type = htons(ETH_P_MVRP),
32 .group_address = MRP_MVRP_ADDRESS,
33 .version = 0,
34};
35
36int vlan_mvrp_request_join(const struct net_device *dev)
37{
38 const struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
39 __be16 vlan_id = htons(vlan->vlan_id);
40
41 return mrp_request_join(vlan->real_dev, &vlan_mrp_app,
42 &vlan_id, sizeof(vlan_id), MVRP_ATTR_VID);
43}
44
45void vlan_mvrp_request_leave(const struct net_device *dev)
46{
47 const struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
48 __be16 vlan_id = htons(vlan->vlan_id);
49
50 mrp_request_leave(vlan->real_dev, &vlan_mrp_app,
51 &vlan_id, sizeof(vlan_id), MVRP_ATTR_VID);
52}
53
54int vlan_mvrp_init_applicant(struct net_device *dev)
55{
56 return mrp_init_applicant(dev, &vlan_mrp_app);
57}
58
59void vlan_mvrp_uninit_applicant(struct net_device *dev)
60{
61 mrp_uninit_applicant(dev, &vlan_mrp_app);
62}
63
64int __init vlan_mvrp_init(void)
65{
66 return mrp_register_application(&vlan_mrp_app);
67}
68
69void vlan_mvrp_uninit(void)
70{
71 mrp_unregister_application(&vlan_mrp_app);
72}
net/8021q/vlan_netlink.c+1−1
@@ -62,7 +62,7 @@ static int vlan_validate(struct nlattr *tb[], struct nlattr *data[]) · 61 unmodified lines
62 flags = nla_data(data[IFLA_VLAN_FLAGS]);62 flags = nla_data(data[IFLA_VLAN_FLAGS]);
63 if ((flags->flags & flags->mask) &63 if ((flags->flags & flags->mask) &
64 ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP |64 ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP |
65 VLAN_FLAG_LOOSE_BINDING))65 VLAN_FLAG_LOOSE_BINDING | VLAN_FLAG_MVRP))
66 return -EINVAL;66 return -EINVAL;
67 }67 }
68 68

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t