diff options
Diffstat (limited to 'net/8021q')
| -rw-r--r-- | net/8021q/Kconfig | 11 | ||||
| -rw-r--r-- | net/8021q/Makefile | 1 | ||||
| -rw-r--r-- | net/8021q/vlan.c | 42 | ||||
| -rw-r--r-- | net/8021q/vlan.h | 16 | ||||
| -rw-r--r-- | net/8021q/vlan_core.c | 25 | ||||
| -rw-r--r-- | net/8021q/vlan_dev.c | 20 | ||||
| -rw-r--r-- | net/8021q/vlan_mvrp.c | 72 | ||||
| -rw-r--r-- | net/8021q/vlan_netlink.c | 2 | ||||
| -rw-r--r-- | net/8021q/vlanproc.c | 2 |
9 files changed, 161 insertions, 30 deletions
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 a292e8050ef2..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 | ||
| @@ -105,8 +107,12 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) | |||
| 105 | */ | 107 | */ |
| 106 | unregister_netdevice_queue(dev, head); | 108 | unregister_netdevice_queue(dev, head); |
| 107 | 109 | ||
| 108 | if (grp->nr_vlan_devs == 0) | 110 | netdev_upper_dev_unlink(real_dev, dev); |
| 111 | |||
| 112 | if (grp->nr_vlan_devs == 0) { | ||
| 113 | vlan_mvrp_uninit_applicant(real_dev); | ||
| 109 | vlan_gvrp_uninit_applicant(real_dev); | 114 | vlan_gvrp_uninit_applicant(real_dev); |
| 115 | } | ||
| 110 | 116 | ||
| 111 | /* Get rid of the vlan's reference to real_dev */ | 117 | /* Get rid of the vlan's reference to real_dev */ |
| 112 | dev_put(real_dev); | 118 | dev_put(real_dev); |
| @@ -115,19 +121,12 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) | |||
| 115 | int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id) | 121 | int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id) |
| 116 | { | 122 | { |
| 117 | const char *name = real_dev->name; | 123 | const char *name = real_dev->name; |
| 118 | const struct net_device_ops *ops = real_dev->netdev_ops; | ||
| 119 | 124 | ||
| 120 | if (real_dev->features & NETIF_F_VLAN_CHALLENGED) { | 125 | if (real_dev->features & NETIF_F_VLAN_CHALLENGED) { |
| 121 | pr_info("VLANs not supported on %s\n", name); | 126 | pr_info("VLANs not supported on %s\n", name); |
| 122 | return -EOPNOTSUPP; | 127 | return -EOPNOTSUPP; |
| 123 | } | 128 | } |
| 124 | 129 | ||
| 125 | if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) && | ||
| 126 | (!ops->ndo_vlan_rx_add_vid || !ops->ndo_vlan_rx_kill_vid)) { | ||
| 127 | pr_info("Device %s has buggy VLAN hw accel\n", name); | ||
| 128 | return -EOPNOTSUPP; | ||
| 129 | } | ||
| 130 | |||
| 131 | if (vlan_find_dev(real_dev, vlan_id) != NULL) | 130 | if (vlan_find_dev(real_dev, vlan_id) != NULL) |
| 132 | return -EEXIST; | 131 | return -EEXIST; |
| 133 | 132 | ||
| @@ -156,15 +155,22 @@ int register_vlan_dev(struct net_device *dev) | |||
| 156 | err = vlan_gvrp_init_applicant(real_dev); | 155 | err = vlan_gvrp_init_applicant(real_dev); |
| 157 | if (err < 0) | 156 | if (err < 0) |
| 158 | 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; | ||
| 159 | } | 161 | } |
| 160 | 162 | ||
| 161 | err = vlan_group_prealloc_vid(grp, vlan_id); | 163 | err = vlan_group_prealloc_vid(grp, vlan_id); |
| 162 | if (err < 0) | 164 | if (err < 0) |
| 163 | goto out_uninit_applicant; | 165 | goto out_uninit_mvrp; |
| 166 | |||
| 167 | err = netdev_upper_dev_link(real_dev, dev); | ||
| 168 | if (err) | ||
| 169 | goto out_uninit_mvrp; | ||
| 164 | 170 | ||
| 165 | err = register_netdevice(dev); | 171 | err = register_netdevice(dev); |
| 166 | if (err < 0) | 172 | if (err < 0) |
| 167 | goto out_uninit_applicant; | 173 | goto out_upper_dev_unlink; |
| 168 | 174 | ||
| 169 | /* Account for reference in struct vlan_dev_priv */ | 175 | /* Account for reference in struct vlan_dev_priv */ |
| 170 | dev_hold(real_dev); | 176 | dev_hold(real_dev); |
| @@ -180,7 +186,12 @@ int register_vlan_dev(struct net_device *dev) | |||
| 180 | 186 | ||
| 181 | return 0; | 187 | return 0; |
| 182 | 188 | ||
| 183 | out_uninit_applicant: | 189 | out_upper_dev_unlink: |
| 190 | netdev_upper_dev_unlink(real_dev, dev); | ||
| 191 | out_uninit_mvrp: | ||
| 192 | if (grp->nr_vlan_devs == 0) | ||
| 193 | vlan_mvrp_uninit_applicant(real_dev); | ||
| 194 | out_uninit_gvrp: | ||
| 184 | if (grp->nr_vlan_devs == 0) | 195 | if (grp->nr_vlan_devs == 0) |
| 185 | vlan_gvrp_uninit_applicant(real_dev); | 196 | vlan_gvrp_uninit_applicant(real_dev); |
| 186 | out_vid_del: | 197 | out_vid_del: |
| @@ -654,13 +665,19 @@ static int __init vlan_proto_init(void) | |||
| 654 | if (err < 0) | 665 | if (err < 0) |
| 655 | goto err3; | 666 | goto err3; |
| 656 | 667 | ||
| 657 | err = vlan_netlink_init(); | 668 | err = vlan_mvrp_init(); |
| 658 | if (err < 0) | 669 | if (err < 0) |
| 659 | goto err4; | 670 | goto err4; |
| 660 | 671 | ||
| 672 | err = vlan_netlink_init(); | ||
| 673 | if (err < 0) | ||
| 674 | goto err5; | ||
| 675 | |||
| 661 | vlan_ioctl_set(vlan_ioctl_handler); | 676 | vlan_ioctl_set(vlan_ioctl_handler); |
| 662 | return 0; | 677 | return 0; |
| 663 | 678 | ||
| 679 | err5: | ||
| 680 | vlan_mvrp_uninit(); | ||
| 664 | err4: | 681 | err4: |
| 665 | vlan_gvrp_uninit(); | 682 | vlan_gvrp_uninit(); |
| 666 | err3: | 683 | err3: |
| @@ -681,6 +698,7 @@ static void __exit vlan_cleanup_module(void) | |||
| 681 | unregister_pernet_subsys(&vlan_net_ops); | 698 | unregister_pernet_subsys(&vlan_net_ops); |
| 682 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ | 699 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ |
| 683 | 700 | ||
| 701 | vlan_mvrp_uninit(); | ||
| 684 | vlan_gvrp_uninit(); | 702 | vlan_gvrp_uninit(); |
| 685 | } | 703 | } |
| 686 | 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_core.c b/net/8021q/vlan_core.c index 65e06abe023f..f3b6f515eba6 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
| @@ -60,21 +60,25 @@ bool vlan_do_receive(struct sk_buff **skbp) | |||
| 60 | return true; | 60 | return true; |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | /* Must be invoked with rcu_read_lock or with RTNL. */ | 63 | /* Must be invoked with rcu_read_lock. */ |
| 64 | struct net_device *__vlan_find_dev_deep(struct net_device *real_dev, | 64 | struct net_device *__vlan_find_dev_deep(struct net_device *dev, |
| 65 | u16 vlan_id) | 65 | u16 vlan_id) |
| 66 | { | 66 | { |
| 67 | struct vlan_info *vlan_info = rcu_dereference_rtnl(real_dev->vlan_info); | 67 | struct vlan_info *vlan_info = rcu_dereference(dev->vlan_info); |
| 68 | 68 | ||
| 69 | if (vlan_info) { | 69 | if (vlan_info) { |
| 70 | return vlan_group_get_device(&vlan_info->grp, vlan_id); | 70 | return vlan_group_get_device(&vlan_info->grp, vlan_id); |
| 71 | } else { | 71 | } else { |
| 72 | /* | 72 | /* |
| 73 | * Bonding slaves do not have grp assigned to themselves. | 73 | * Lower devices of master uppers (bonding, team) do not have |
| 74 | * Grp is assigned to bonding master instead. | 74 | * grp assigned to themselves. Grp is assigned to upper device |
| 75 | * instead. | ||
| 75 | */ | 76 | */ |
| 76 | if (netif_is_bond_slave(real_dev)) | 77 | struct net_device *upper_dev; |
| 77 | return __vlan_find_dev_deep(real_dev->master, vlan_id); | 78 | |
| 79 | upper_dev = netdev_master_upper_dev_get_rcu(dev); | ||
| 80 | if (upper_dev) | ||
| 81 | return __vlan_find_dev_deep(upper_dev, vlan_id); | ||
| 78 | } | 82 | } |
| 79 | 83 | ||
| 80 | return NULL; | 84 | return NULL; |
| @@ -140,6 +144,7 @@ err_free: | |||
| 140 | kfree_skb(skb); | 144 | kfree_skb(skb); |
| 141 | return NULL; | 145 | return NULL; |
| 142 | } | 146 | } |
| 147 | EXPORT_SYMBOL(vlan_untag); | ||
| 143 | 148 | ||
| 144 | 149 | ||
| 145 | /* | 150 | /* |
| @@ -220,8 +225,7 @@ static int __vlan_vid_add(struct vlan_info *vlan_info, unsigned short vid, | |||
| 220 | if (!vid_info) | 225 | if (!vid_info) |
| 221 | return -ENOMEM; | 226 | return -ENOMEM; |
| 222 | 227 | ||
| 223 | if ((dev->features & NETIF_F_HW_VLAN_FILTER) && | 228 | if (dev->features & NETIF_F_HW_VLAN_FILTER) { |
| 224 | ops->ndo_vlan_rx_add_vid) { | ||
| 225 | err = ops->ndo_vlan_rx_add_vid(dev, vid); | 229 | err = ops->ndo_vlan_rx_add_vid(dev, vid); |
| 226 | if (err) { | 230 | if (err) { |
| 227 | kfree(vid_info); | 231 | kfree(vid_info); |
| @@ -278,8 +282,7 @@ static void __vlan_vid_del(struct vlan_info *vlan_info, | |||
| 278 | unsigned short vid = vid_info->vid; | 282 | unsigned short vid = vid_info->vid; |
| 279 | int err; | 283 | int err; |
| 280 | 284 | ||
| 281 | if ((dev->features & NETIF_F_HW_VLAN_FILTER) && | 285 | if (dev->features & NETIF_F_HW_VLAN_FILTER) { |
| 282 | ops->ndo_vlan_rx_kill_vid) { | ||
| 283 | err = ops->ndo_vlan_rx_kill_vid(dev, vid); | 286 | err = ops->ndo_vlan_rx_kill_vid(dev, vid); |
| 284 | if (err) { | 287 | if (err) { |
| 285 | pr_warn("failed to kill vid %d for device %s\n", | 288 | pr_warn("failed to kill vid %d for device %s\n", |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 4a6d31a082b9..19cf81bf9f69 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)) | 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) | |||
| 272 | else | 272 | 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) | |||
| 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; |
| @@ -640,9 +650,9 @@ static int vlan_ethtool_get_settings(struct net_device *dev, | |||
| 640 | static void vlan_ethtool_get_drvinfo(struct net_device *dev, | 650 | static void vlan_ethtool_get_drvinfo(struct net_device *dev, |
| 641 | struct ethtool_drvinfo *info) | 651 | struct ethtool_drvinfo *info) |
| 642 | { | 652 | { |
| 643 | strcpy(info->driver, vlan_fullname); | 653 | strlcpy(info->driver, vlan_fullname, sizeof(info->driver)); |
| 644 | strcpy(info->version, vlan_version); | 654 | strlcpy(info->version, vlan_version, sizeof(info->version)); |
| 645 | strcpy(info->fw_version, "N/A"); | 655 | strlcpy(info->fw_version, "N/A", sizeof(info->fw_version)); |
| 646 | } | 656 | } |
| 647 | 657 | ||
| 648 | static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) | 658 | static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) |
| @@ -723,7 +733,7 @@ static void vlan_dev_netpoll_cleanup(struct net_device *dev) | |||
| 723 | 733 | ||
| 724 | vlan->netpoll = NULL; | 734 | vlan->netpoll = NULL; |
| 725 | 735 | ||
| 726 | __netpoll_free_rcu(netpoll); | 736 | __netpoll_free_async(netpoll); |
| 727 | } | 737 | } |
| 728 | #endif /* CONFIG_NET_POLL_CONTROLLER */ | 738 | #endif /* CONFIG_NET_POLL_CONTROLLER */ |
| 729 | 739 | ||
diff --git a/net/8021q/vlan_mvrp.c b/net/8021q/vlan_mvrp.c new file mode 100644 index 000000000000..d9ec1d5964aa --- /dev/null +++ b/net/8021q/vlan_mvrp.c | |||
| @@ -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 | |||
| 21 | enum 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 | |||
| 28 | static 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 | |||
| 36 | int 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 | |||
| 45 | void 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 | |||
| 54 | int vlan_mvrp_init_applicant(struct net_device *dev) | ||
| 55 | { | ||
| 56 | return mrp_init_applicant(dev, &vlan_mrp_app); | ||
| 57 | } | ||
| 58 | |||
| 59 | void vlan_mvrp_uninit_applicant(struct net_device *dev) | ||
| 60 | { | ||
| 61 | mrp_uninit_applicant(dev, &vlan_mrp_app); | ||
| 62 | } | ||
| 63 | |||
| 64 | int __init vlan_mvrp_init(void) | ||
| 65 | { | ||
| 66 | return mrp_register_application(&vlan_mrp_app); | ||
| 67 | } | ||
| 68 | |||
| 69 | void vlan_mvrp_uninit(void) | ||
| 70 | { | ||
| 71 | mrp_unregister_application(&vlan_mrp_app); | ||
| 72 | } | ||
diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c index 708c80ea1874..1789658b7cd7 100644 --- a/net/8021q/vlan_netlink.c +++ b/net/8021q/vlan_netlink.c | |||
| @@ -62,7 +62,7 @@ static int vlan_validate(struct nlattr *tb[], struct nlattr *data[]) | |||
| 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 | ||
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c index 4de77ea5fa37..dc526ec965e4 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c | |||
| @@ -131,7 +131,7 @@ void vlan_proc_cleanup(struct net *net) | |||
| 131 | remove_proc_entry(name_conf, vn->proc_vlan_dir); | 131 | remove_proc_entry(name_conf, vn->proc_vlan_dir); |
| 132 | 132 | ||
| 133 | if (vn->proc_vlan_dir) | 133 | if (vn->proc_vlan_dir) |
| 134 | proc_net_remove(net, name_root); | 134 | remove_proc_entry(name_root, net->proc_net); |
| 135 | 135 | ||
| 136 | /* Dynamically added entries should be cleaned up as their vlan_device | 136 | /* Dynamically added entries should be cleaned up as their vlan_device |
| 137 | * is removed, so we should not have to take care of it here... | 137 | * is removed, so we should not have to take care of it here... |
