diff options
Diffstat (limited to 'net/8021q')
-rw-r--r-- | net/8021q/vlan.c | 19 | ||||
-rw-r--r-- | net/8021q/vlan.h | 31 | ||||
-rw-r--r-- | net/8021q/vlan_core.c | 48 | ||||
-rw-r--r-- | net/8021q/vlan_dev.c | 9 | ||||
-rw-r--r-- | net/8021q/vlanproc.c | 6 |
5 files changed, 71 insertions, 42 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 917ecb93ea2..8970ba139d7 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -18,6 +18,8 @@ | |||
18 | * 2 of the License, or (at your option) any later version. | 18 | * 2 of the License, or (at your option) any later version. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
22 | |||
21 | #include <linux/capability.h> | 23 | #include <linux/capability.h> |
22 | #include <linux/module.h> | 24 | #include <linux/module.h> |
23 | #include <linux/netdevice.h> | 25 | #include <linux/netdevice.h> |
@@ -132,8 +134,6 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) | |||
132 | vlan_gvrp_uninit_applicant(real_dev); | 134 | vlan_gvrp_uninit_applicant(real_dev); |
133 | 135 | ||
134 | rcu_assign_pointer(real_dev->vlgrp, NULL); | 136 | rcu_assign_pointer(real_dev->vlgrp, NULL); |
135 | if (ops->ndo_vlan_rx_register) | ||
136 | ops->ndo_vlan_rx_register(real_dev, NULL); | ||
137 | 137 | ||
138 | /* Free the group, after all cpu's are done. */ | 138 | /* Free the group, after all cpu's are done. */ |
139 | call_rcu(&grp->rcu, vlan_rcu_free); | 139 | call_rcu(&grp->rcu, vlan_rcu_free); |
@@ -149,13 +149,13 @@ int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id) | |||
149 | const struct net_device_ops *ops = real_dev->netdev_ops; | 149 | const struct net_device_ops *ops = real_dev->netdev_ops; |
150 | 150 | ||
151 | if (real_dev->features & NETIF_F_VLAN_CHALLENGED) { | 151 | if (real_dev->features & NETIF_F_VLAN_CHALLENGED) { |
152 | pr_info("8021q: VLANs not supported on %s\n", name); | 152 | pr_info("VLANs not supported on %s\n", name); |
153 | return -EOPNOTSUPP; | 153 | return -EOPNOTSUPP; |
154 | } | 154 | } |
155 | 155 | ||
156 | if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) && | 156 | if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) && |
157 | (!ops->ndo_vlan_rx_add_vid || !ops->ndo_vlan_rx_kill_vid)) { | 157 | (!ops->ndo_vlan_rx_add_vid || !ops->ndo_vlan_rx_kill_vid)) { |
158 | pr_info("8021q: Device %s has buggy VLAN hw accel\n", name); | 158 | pr_info("Device %s has buggy VLAN hw accel\n", name); |
159 | return -EOPNOTSUPP; | 159 | return -EOPNOTSUPP; |
160 | } | 160 | } |
161 | 161 | ||
@@ -205,8 +205,6 @@ int register_vlan_dev(struct net_device *dev) | |||
205 | grp->nr_vlans++; | 205 | grp->nr_vlans++; |
206 | 206 | ||
207 | if (ngrp) { | 207 | if (ngrp) { |
208 | if (ops->ndo_vlan_rx_register && (real_dev->features & NETIF_F_HW_VLAN_RX)) | ||
209 | ops->ndo_vlan_rx_register(real_dev, ngrp); | ||
210 | rcu_assign_pointer(real_dev->vlgrp, ngrp); | 208 | rcu_assign_pointer(real_dev->vlgrp, ngrp); |
211 | } | 209 | } |
212 | if (real_dev->features & NETIF_F_HW_VLAN_FILTER) | 210 | if (real_dev->features & NETIF_F_HW_VLAN_FILTER) |
@@ -344,13 +342,12 @@ static void __vlan_device_event(struct net_device *dev, unsigned long event) | |||
344 | case NETDEV_CHANGENAME: | 342 | case NETDEV_CHANGENAME: |
345 | vlan_proc_rem_dev(dev); | 343 | vlan_proc_rem_dev(dev); |
346 | if (vlan_proc_add_dev(dev) < 0) | 344 | if (vlan_proc_add_dev(dev) < 0) |
347 | pr_warning("8021q: failed to change proc name for %s\n", | 345 | pr_warn("failed to change proc name for %s\n", |
348 | dev->name); | 346 | dev->name); |
349 | break; | 347 | break; |
350 | case NETDEV_REGISTER: | 348 | case NETDEV_REGISTER: |
351 | if (vlan_proc_add_dev(dev) < 0) | 349 | if (vlan_proc_add_dev(dev) < 0) |
352 | pr_warning("8021q: failed to add proc entry for %s\n", | 350 | pr_warn("failed to add proc entry for %s\n", dev->name); |
353 | dev->name); | ||
354 | break; | 351 | break; |
355 | case NETDEV_UNREGISTER: | 352 | case NETDEV_UNREGISTER: |
356 | vlan_proc_rem_dev(dev); | 353 | vlan_proc_rem_dev(dev); |
@@ -374,7 +371,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, | |||
374 | if ((event == NETDEV_UP) && | 371 | if ((event == NETDEV_UP) && |
375 | (dev->features & NETIF_F_HW_VLAN_FILTER) && | 372 | (dev->features & NETIF_F_HW_VLAN_FILTER) && |
376 | dev->netdev_ops->ndo_vlan_rx_add_vid) { | 373 | dev->netdev_ops->ndo_vlan_rx_add_vid) { |
377 | pr_info("8021q: adding VLAN 0 to HW filter on device %s\n", | 374 | pr_info("adding VLAN 0 to HW filter on device %s\n", |
378 | dev->name); | 375 | dev->name); |
379 | dev->netdev_ops->ndo_vlan_rx_add_vid(dev, 0); | 376 | dev->netdev_ops->ndo_vlan_rx_add_vid(dev, 0); |
380 | } | 377 | } |
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index 9da07e30d1a..9fd45f3571f 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h | |||
@@ -74,6 +74,37 @@ static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev) | |||
74 | return netdev_priv(dev); | 74 | return netdev_priv(dev); |
75 | } | 75 | } |
76 | 76 | ||
77 | static inline struct net_device *vlan_group_get_device(struct vlan_group *vg, | ||
78 | u16 vlan_id) | ||
79 | { | ||
80 | struct net_device **array; | ||
81 | array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; | ||
82 | return array ? array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] : NULL; | ||
83 | } | ||
84 | |||
85 | static inline void vlan_group_set_device(struct vlan_group *vg, | ||
86 | u16 vlan_id, | ||
87 | struct net_device *dev) | ||
88 | { | ||
89 | struct net_device **array; | ||
90 | if (!vg) | ||
91 | return; | ||
92 | array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; | ||
93 | array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev; | ||
94 | } | ||
95 | |||
96 | /* Must be invoked with rcu_read_lock or with RTNL. */ | ||
97 | static inline struct net_device *vlan_find_dev(struct net_device *real_dev, | ||
98 | u16 vlan_id) | ||
99 | { | ||
100 | struct vlan_group *grp = rcu_dereference_rtnl(real_dev->vlgrp); | ||
101 | |||
102 | if (grp) | ||
103 | return vlan_group_get_device(grp, vlan_id); | ||
104 | |||
105 | return NULL; | ||
106 | } | ||
107 | |||
77 | /* found in vlan_dev.c */ | 108 | /* found in vlan_dev.c */ |
78 | void vlan_dev_set_ingress_priority(const struct net_device *dev, | 109 | void vlan_dev_set_ingress_priority(const struct net_device *dev, |
79 | u32 skb_prio, u16 vlan_prio); | 110 | u32 skb_prio, u16 vlan_prio); |
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index fcc684678af..f1f2f7bb666 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
@@ -63,6 +63,27 @@ bool vlan_do_receive(struct sk_buff **skbp) | |||
63 | return true; | 63 | return true; |
64 | } | 64 | } |
65 | 65 | ||
66 | /* Must be invoked with rcu_read_lock or with RTNL. */ | ||
67 | struct net_device *__vlan_find_dev_deep(struct net_device *real_dev, | ||
68 | u16 vlan_id) | ||
69 | { | ||
70 | struct vlan_group *grp = rcu_dereference_rtnl(real_dev->vlgrp); | ||
71 | |||
72 | if (grp) { | ||
73 | return vlan_group_get_device(grp, vlan_id); | ||
74 | } else { | ||
75 | /* | ||
76 | * Bonding slaves do not have grp assigned to themselves. | ||
77 | * Grp is assigned to bonding master instead. | ||
78 | */ | ||
79 | if (netif_is_bond_slave(real_dev)) | ||
80 | return __vlan_find_dev_deep(real_dev->master, vlan_id); | ||
81 | } | ||
82 | |||
83 | return NULL; | ||
84 | } | ||
85 | EXPORT_SYMBOL(__vlan_find_dev_deep); | ||
86 | |||
66 | struct net_device *vlan_dev_real_dev(const struct net_device *dev) | 87 | struct net_device *vlan_dev_real_dev(const struct net_device *dev) |
67 | { | 88 | { |
68 | return vlan_dev_info(dev)->real_dev; | 89 | return vlan_dev_info(dev)->real_dev; |
@@ -75,31 +96,6 @@ u16 vlan_dev_vlan_id(const struct net_device *dev) | |||
75 | } | 96 | } |
76 | EXPORT_SYMBOL(vlan_dev_vlan_id); | 97 | EXPORT_SYMBOL(vlan_dev_vlan_id); |
77 | 98 | ||
78 | /* VLAN rx hw acceleration helper. This acts like netif_{rx,receive_skb}(). */ | ||
79 | int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, | ||
80 | u16 vlan_tci, int polling) | ||
81 | { | ||
82 | __vlan_hwaccel_put_tag(skb, vlan_tci); | ||
83 | return polling ? netif_receive_skb(skb) : netif_rx(skb); | ||
84 | } | ||
85 | EXPORT_SYMBOL(__vlan_hwaccel_rx); | ||
86 | |||
87 | gro_result_t vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp, | ||
88 | unsigned int vlan_tci, struct sk_buff *skb) | ||
89 | { | ||
90 | __vlan_hwaccel_put_tag(skb, vlan_tci); | ||
91 | return napi_gro_receive(napi, skb); | ||
92 | } | ||
93 | EXPORT_SYMBOL(vlan_gro_receive); | ||
94 | |||
95 | gro_result_t vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp, | ||
96 | unsigned int vlan_tci) | ||
97 | { | ||
98 | __vlan_hwaccel_put_tag(napi->skb, vlan_tci); | ||
99 | return napi_gro_frags(napi); | ||
100 | } | ||
101 | EXPORT_SYMBOL(vlan_gro_frags); | ||
102 | |||
103 | static struct sk_buff *vlan_reorder_header(struct sk_buff *skb) | 99 | static struct sk_buff *vlan_reorder_header(struct sk_buff *skb) |
104 | { | 100 | { |
105 | if (skb_cow(skb, skb_headroom(skb)) < 0) | 101 | if (skb_cow(skb, skb_headroom(skb)) < 0) |
@@ -171,6 +167,8 @@ struct sk_buff *vlan_untag(struct sk_buff *skb) | |||
171 | if (unlikely(!skb)) | 167 | if (unlikely(!skb)) |
172 | goto err_free; | 168 | goto err_free; |
173 | 169 | ||
170 | skb_reset_network_header(skb); | ||
171 | skb_reset_transport_header(skb); | ||
174 | return skb; | 172 | return skb; |
175 | 173 | ||
176 | err_free: | 174 | err_free: |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 6e82148edfc..9d40a071d03 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -20,6 +20,8 @@ | |||
20 | * 2 of the License, or (at your option) any later version. | 20 | * 2 of the License, or (at your option) any later version. |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
24 | |||
23 | #include <linux/module.h> | 25 | #include <linux/module.h> |
24 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
25 | #include <linux/skbuff.h> | 27 | #include <linux/skbuff.h> |
@@ -55,7 +57,7 @@ static int vlan_dev_rebuild_header(struct sk_buff *skb) | |||
55 | return arp_find(veth->h_dest, skb); | 57 | return arp_find(veth->h_dest, skb); |
56 | #endif | 58 | #endif |
57 | default: | 59 | default: |
58 | pr_debug("%s: unable to resolve type %X addresses.\n", | 60 | pr_debug("%s: unable to resolve type %X addresses\n", |
59 | dev->name, ntohs(veth->h_vlan_encapsulated_proto)); | 61 | dev->name, ntohs(veth->h_vlan_encapsulated_proto)); |
60 | 62 | ||
61 | memcpy(veth->h_source, dev->dev_addr, ETH_ALEN); | 63 | memcpy(veth->h_source, dev->dev_addr, ETH_ALEN); |
@@ -595,8 +597,7 @@ static u32 vlan_dev_fix_features(struct net_device *dev, u32 features) | |||
595 | features &= real_dev->features; | 597 | features &= real_dev->features; |
596 | features &= real_dev->vlan_features; | 598 | features &= real_dev->vlan_features; |
597 | 599 | ||
598 | if (old_features & NETIF_F_SOFT_FEATURES) | 600 | features |= old_features & NETIF_F_SOFT_FEATURES; |
599 | features |= old_features & NETIF_F_SOFT_FEATURES; | ||
600 | 601 | ||
601 | if (dev_ethtool_get_rx_csum(real_dev)) | 602 | if (dev_ethtool_get_rx_csum(real_dev)) |
602 | features |= NETIF_F_RXCSUM; | 603 | features |= NETIF_F_RXCSUM; |
@@ -694,7 +695,7 @@ void vlan_setup(struct net_device *dev) | |||
694 | ether_setup(dev); | 695 | ether_setup(dev); |
695 | 696 | ||
696 | dev->priv_flags |= IFF_802_1Q_VLAN; | 697 | dev->priv_flags |= IFF_802_1Q_VLAN; |
697 | dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; | 698 | dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); |
698 | dev->tx_queue_len = 0; | 699 | dev->tx_queue_len = 0; |
699 | 700 | ||
700 | dev->netdev_ops = &vlan_netdev_ops; | 701 | dev->netdev_ops = &vlan_netdev_ops; |
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c index d940c49d168..d34b6daf893 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c | |||
@@ -17,6 +17,8 @@ | |||
17 | * Jan 20, 1998 Ben Greear Initial Version | 17 | * Jan 20, 1998 Ben Greear Initial Version |
18 | *****************************************************************************/ | 18 | *****************************************************************************/ |
19 | 19 | ||
20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
21 | |||
20 | #include <linux/module.h> | 22 | #include <linux/module.h> |
21 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
22 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
@@ -155,7 +157,7 @@ int __net_init vlan_proc_init(struct net *net) | |||
155 | return 0; | 157 | return 0; |
156 | 158 | ||
157 | err: | 159 | err: |
158 | pr_err("%s: can't create entry in proc filesystem!\n", __func__); | 160 | pr_err("can't create entry in proc filesystem!\n"); |
159 | vlan_proc_cleanup(net); | 161 | vlan_proc_cleanup(net); |
160 | return -ENOBUFS; | 162 | return -ENOBUFS; |
161 | } | 163 | } |
@@ -229,7 +231,7 @@ static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
229 | 231 | ||
230 | ++*pos; | 232 | ++*pos; |
231 | 233 | ||
232 | dev = (struct net_device *)v; | 234 | dev = v; |
233 | if (v == SEQ_START_TOKEN) | 235 | if (v == SEQ_START_TOKEN) |
234 | dev = net_device_entry(&net->dev_base_head); | 236 | dev = net_device_entry(&net->dev_base_head); |
235 | 237 | ||