diff options
| -rw-r--r-- | include/uapi/linux/if_ether.h | 1 | ||||
| -rw-r--r-- | include/uapi/linux/if_vlan.h | 1 | ||||
| -rw-r--r-- | net/8021q/Kconfig | 11 | ||||
| -rw-r--r-- | net/8021q/Makefile | 1 | ||||
| -rw-r--r-- | net/8021q/vlan.c | 27 | ||||
| -rw-r--r-- | net/8021q/vlan.h | 16 | ||||
| -rw-r--r-- | net/8021q/vlan_dev.c | 12 | ||||
| -rw-r--r-- | net/8021q/vlan_mvrp.c | 72 | ||||
| -rw-r--r-- | net/8021q/vlan_netlink.c | 2 |
9 files changed, 136 insertions, 7 deletions
diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h index 67fb87ca1094..798032d01112 100644 --- a/include/uapi/linux/if_ether.h +++ b/include/uapi/linux/if_ether.h | |||
| @@ -83,6 +83,7 @@ | |||
| 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 */ |
diff --git a/include/uapi/linux/if_vlan.h b/include/uapi/linux/if_vlan.h index 0744f8e65d15..7e5e6b397332 100644 --- a/include/uapi/linux/if_vlan.h +++ b/include/uapi/linux/if_vlan.h | |||
| @@ -34,6 +34,7 @@ enum vlan_flags { | |||
| 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 | ||
| 39 | enum vlan_name_types { | 40 | enum vlan_name_types { |
diff --git a/net/8021q/Kconfig b/net/8021q/Kconfig index fa073a54963e..8f7517df41a5 100644 --- a/net/8021q/Kconfig +++ b/net/8021q/Kconfig | |||
| @@ -27,3 +27,14 @@ config VLAN_8021Q_GVRP | |||
| 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 | |||
| 31 | config 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. | ||
diff --git a/net/8021q/Makefile b/net/8021q/Makefile index 9f4f174ead1c..7bc8db08d7ef 100644 --- a/net/8021q/Makefile +++ b/net/8021q/Makefile | |||
| @@ -6,5 +6,6 @@ obj-$(CONFIG_VLAN_8021Q) += 8021q.o | |||
| 6 | 6 | ||
| 7 | 8021q-y := vlan.o vlan_dev.o vlan_netlink.o | 7 | 8021q-y := vlan.o vlan_dev.o vlan_netlink.o |
| 8 | 8021q-$(CONFIG_VLAN_8021Q_GVRP) += vlan_gvrp.o | 8 | 8021q-$(CONFIG_VLAN_8021Q_GVRP) += vlan_gvrp.o |
| 9 | 8021q-$(CONFIG_VLAN_8021Q_MVRP) += vlan_mvrp.o | ||
| 9 | 8021q-$(CONFIG_PROC_FS) += vlanproc.o | 10 | 8021q-$(CONFIG_PROC_FS) += vlanproc.o |
| 10 | 11 | ||
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index addc578d5443..a18714469bf7 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
| @@ -95,6 +95,8 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) | |||
| 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) | |||
| 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) | |||
| 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) | |||
| 181 | 188 | ||
| 182 | out_upper_dev_unlink: | 189 | out_upper_dev_unlink: |
| 183 | netdev_upper_dev_unlink(real_dev, dev); | 190 | netdev_upper_dev_unlink(real_dev, dev); |
| 184 | out_uninit_applicant: | 191 | out_uninit_mvrp: |
| 192 | if (grp->nr_vlan_devs == 0) | ||
| 193 | vlan_mvrp_uninit_applicant(real_dev); | ||
| 194 | out_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); |
| 187 | out_vid_del: | 197 | out_vid_del: |
| @@ -655,13 +665,19 @@ static int __init vlan_proto_init(void) | |||
| 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 | ||
| 679 | err5: | ||
| 680 | vlan_mvrp_uninit(); | ||
| 665 | err4: | 681 | err4: |
| 666 | vlan_gvrp_uninit(); | 682 | vlan_gvrp_uninit(); |
| 667 | err3: | 683 | err3: |
| @@ -682,6 +698,7 @@ static void __exit vlan_cleanup_module(void) | |||
| 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 | ||
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index a4886d94c40c..670f1e8cfc0f 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h | |||
| @@ -171,6 +171,22 @@ static inline int vlan_gvrp_init(void) { return 0; } | |||
| 171 | static inline void vlan_gvrp_uninit(void) {} | 171 | static inline void vlan_gvrp_uninit(void) {} |
| 172 | #endif | 172 | #endif |
| 173 | 173 | ||
| 174 | #ifdef CONFIG_VLAN_8021Q_MVRP | ||
| 175 | extern int vlan_mvrp_request_join(const struct net_device *dev); | ||
| 176 | extern void vlan_mvrp_request_leave(const struct net_device *dev); | ||
| 177 | extern int vlan_mvrp_init_applicant(struct net_device *dev); | ||
| 178 | extern void vlan_mvrp_uninit_applicant(struct net_device *dev); | ||
| 179 | extern int vlan_mvrp_init(void); | ||
| 180 | extern void vlan_mvrp_uninit(void); | ||
| 181 | #else | ||
| 182 | static inline int vlan_mvrp_request_join(const struct net_device *dev) { return 0; } | ||
| 183 | static inline void vlan_mvrp_request_leave(const struct net_device *dev) {} | ||
| 184 | static inline int vlan_mvrp_init_applicant(struct net_device *dev) { return 0; } | ||
| 185 | static inline void vlan_mvrp_uninit_applicant(struct net_device *dev) {} | ||
| 186 | static inline int vlan_mvrp_init(void) { return 0; } | ||
| 187 | static inline void vlan_mvrp_uninit(void) {} | ||
| 188 | #endif | ||
| 189 | |||
| 174 | extern const char vlan_fullname[]; | 190 | extern const char vlan_fullname[]; |
| 175 | extern const char vlan_version[]; | 191 | extern const char vlan_version[]; |
| 176 | extern int vlan_netlink_init(void); | 192 | extern int vlan_netlink_init(void); |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 09f9108d4688..34df5b3c9b75 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
| @@ -261,7 +261,7 @@ int vlan_dev_change_flags(const struct net_device *dev, u32 flags, u32 mask) | |||
| 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)) | ||
