aboutsummaryrefslogtreecommitdiffstats
path: root/net/8021q/vlan_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/8021q/vlan_dev.c')
-rw-r--r--net/8021q/vlan_dev.c153
1 files changed, 134 insertions, 19 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 4198ec5c8abc..29b6348c8d4d 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -21,6 +21,7 @@
21 */ 21 */
22 22
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/slab.h>
24#include <linux/skbuff.h> 25#include <linux/skbuff.h>
25#include <linux/netdevice.h> 26#include <linux/netdevice.h>
26#include <linux/etherdevice.h> 27#include <linux/etherdevice.h>
@@ -140,7 +141,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
140 struct packet_type *ptype, struct net_device *orig_dev) 141 struct packet_type *ptype, struct net_device *orig_dev)
141{ 142{
142 struct vlan_hdr *vhdr; 143 struct vlan_hdr *vhdr;
143 struct net_device_stats *stats; 144 struct vlan_rx_stats *rx_stats;
144 u16 vlan_id; 145 u16 vlan_id;
145 u16 vlan_tci; 146 u16 vlan_tci;
146 147
@@ -163,9 +164,10 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
163 goto err_unlock; 164 goto err_unlock;
164 } 165 }
165 166
166 stats = &skb->dev->stats; 167 rx_stats = per_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats,
167 stats->rx_packets++; 168 smp_processor_id());
168 stats->rx_bytes += skb->len; 169 rx_stats->rx_packets++;
170 rx_stats->rx_bytes += skb->len;
169 171
170 skb_pull_rcsum(skb, VLAN_HLEN); 172 skb_pull_rcsum(skb, VLAN_HLEN);
171 173
@@ -180,7 +182,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
180 break; 182 break;
181 183
182 case PACKET_MULTICAST: 184 case PACKET_MULTICAST:
183 stats->multicast++; 185 rx_stats->multicast++;
184 break; 186 break;
185 187
186 case PACKET_OTHERHOST: 188 case PACKET_OTHERHOST:
@@ -200,7 +202,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
200 202
201 skb = vlan_check_reorder_header(skb); 203 skb = vlan_check_reorder_header(skb);
202 if (!skb) { 204 if (!skb) {
203 stats->rx_errors++; 205 rx_stats->rx_errors++;
204 goto err_unlock; 206 goto err_unlock;
205 } 207 }
206 208
@@ -262,11 +264,10 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
262 vhdr->h_vlan_TCI = htons(vlan_tci); 264 vhdr->h_vlan_TCI = htons(vlan_tci);
263 265
264 /* 266 /*
265 * Set the protocol type. For a packet of type ETH_P_802_3 we 267 * Set the protocol type. For a packet of type ETH_P_802_3/2 we
266 * put the length in here instead. It is up to the 802.2 268 * put the length in here instead.
267 * layer to carry protocol information.
268 */ 269 */
269 if (type != ETH_P_802_3) 270 if (type != ETH_P_802_3 && type != ETH_P_802_2)
270 vhdr->h_vlan_encapsulated_proto = htons(type); 271 vhdr->h_vlan_encapsulated_proto = htons(type);
271 else 272 else
272 vhdr->h_vlan_encapsulated_proto = htons(len); 273 vhdr->h_vlan_encapsulated_proto = htons(len);
@@ -322,7 +323,7 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
322 } 323 }
323 324
324 325
325 skb->dev = vlan_dev_info(dev)->real_dev; 326 skb_set_dev(skb, vlan_dev_info(dev)->real_dev);
326 len = skb->len; 327 len = skb->len;
327 ret = dev_queue_xmit(skb); 328 ret = dev_queue_xmit(skb);
328 329
@@ -332,7 +333,7 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
332 } else 333 } else
333 txq->tx_dropped++; 334 txq->tx_dropped++;
334 335
335 return NETDEV_TX_OK; 336 return ret;
336} 337}
337 338
338static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, 339static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb,
@@ -358,7 +359,15 @@ static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb,
358 } else 359 } else
359 txq->tx_dropped++; 360 txq->tx_dropped++;
360 361
361 return NETDEV_TX_OK; 362 return ret;
363}
364
365static u16 vlan_dev_select_queue(struct net_device *dev, struct sk_buff *skb)
366{
367 struct net_device *rdev = vlan_dev_info(dev)->real_dev;
368 const struct net_device_ops *ops = rdev->netdev_ops;
369
370 return ops->ndo_select_queue(rdev, skb);
362} 371}
363 372
364static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) 373static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
@@ -393,7 +402,7 @@ int vlan_dev_set_egress_priority(const struct net_device *dev,
393 struct vlan_dev_info *vlan = vlan_dev_info(dev); 402 struct vlan_dev_info *vlan = vlan_dev_info(dev);
394 struct vlan_priority_tci_mapping *mp = NULL; 403 struct vlan_priority_tci_mapping *mp = NULL;
395 struct vlan_priority_tci_mapping *np; 404 struct vlan_priority_tci_mapping *np;
396 u32 vlan_qos = (vlan_prio << 13) & 0xE000; 405 u32 vlan_qos = (vlan_prio << VLAN_PRIO_SHIFT) & VLAN_PRIO_MASK;
397 406
398 /* See if a priority mapping exists.. */ 407 /* See if a priority mapping exists.. */
399 mp = vlan->egress_priority_map[skb_prio & 0xF]; 408 mp = vlan->egress_priority_map[skb_prio & 0xF];
@@ -430,7 +439,8 @@ int vlan_dev_change_flags(const struct net_device *dev, u32 flags, u32 mask)
430 struct vlan_dev_info *vlan = vlan_dev_info(dev); 439 struct vlan_dev_info *vlan = vlan_dev_info(dev);
431 u32 old_flags = vlan->flags; 440 u32 old_flags = vlan->flags;
432 441
433 if (mask & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP)) 442 if (mask & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP |
443 VLAN_FLAG_LOOSE_BINDING))
434 return -EINVAL; 444 return -EINVAL;
435 445
436 vlan->flags = (old_flags & ~mask) | (flags & mask); 446 vlan->flags = (old_flags & ~mask) | (flags & mask);
@@ -455,7 +465,8 @@ static int vlan_dev_open(struct net_device *dev)
455 struct net_device *real_dev = vlan->real_dev; 465 struct net_device *real_dev = vlan->real_dev;
456 int err; 466 int err;
457 467
458 if (!(real_dev->flags & IFF_UP)) 468 if (!(real_dev->flags & IFF_UP) &&
469 !(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
459 return -ENETDOWN; 470 return -ENETDOWN;
460 471
461 if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) { 472 if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) {
@@ -626,6 +637,17 @@ static int vlan_dev_fcoe_disable(struct net_device *dev)
626 rc = ops->ndo_fcoe_disable(real_dev); 637 rc = ops->ndo_fcoe_disable(real_dev);
627 return rc; 638 return rc;
628} 639}
640
641static int vlan_dev_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type)
642{
643 struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
644 const struct net_device_ops *ops = real_dev->netdev_ops;
645 int rc = -EINVAL;
646
647 if (ops->ndo_fcoe_get_wwn)
648 rc = ops->ndo_fcoe_get_wwn(real_dev, wwn, type);
649 return rc;
650}
629#endif 651#endif
630 652
631static void vlan_dev_change_rx_flags(struct net_device *dev, int change) 653static void vlan_dev_change_rx_flags(struct net_device *dev, int change)
@@ -675,7 +697,8 @@ static const struct header_ops vlan_header_ops = {
675 .parse = eth_header_parse, 697 .parse = eth_header_parse,
676}; 698};
677 699
678static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops; 700static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops,
701 vlan_netdev_ops_sq, vlan_netdev_accel_ops_sq;
679 702
680static int vlan_dev_init(struct net_device *dev) 703static int vlan_dev_init(struct net_device *dev)
681{ 704{
@@ -709,17 +732,28 @@ static int vlan_dev_init(struct net_device *dev)
709 if (real_dev->features & NETIF_F_HW_VLAN_TX) { 732 if (real_dev->features & NETIF_F_HW_VLAN_TX) {
710 dev->header_ops = real_dev->header_ops; 733 dev->header_ops = real_dev->header_ops;
711 dev->hard_header_len = real_dev->hard_header_len; 734 dev->hard_header_len = real_dev->hard_header_len;
712 dev->netdev_ops = &vlan_netdev_accel_ops; 735 if (real_dev->netdev_ops->ndo_select_queue)
736 dev->netdev_ops = &vlan_netdev_accel_ops_sq;
737 else
738 dev->netdev_ops = &vlan_netdev_accel_ops;
713 } else { 739 } else {
714 dev->header_ops = &vlan_header_ops; 740 dev->header_ops = &vlan_header_ops;
715 dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; 741 dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN;
716 dev->netdev_ops = &vlan_netdev_ops; 742 if (real_dev->netdev_ops->ndo_select_queue)
743 dev->netdev_ops = &vlan_netdev_ops_sq;
744 else
745 dev->netdev_ops = &vlan_netdev_ops;
717 } 746 }
718 747
719 if (is_vlan_dev(real_dev)) 748 if (is_vlan_dev(real_dev))
720 subclass = 1; 749 subclass = 1;
721 750
722 vlan_dev_set_lockdep_class(dev, subclass); 751 vlan_dev_set_lockdep_class(dev, subclass);
752
753 vlan_dev_info(dev)->vlan_rx_stats = alloc_percpu(struct vlan_rx_stats);
754 if (!vlan_dev_info(dev)->vlan_rx_stats)
755 return -ENOMEM;
756
723 return 0; 757 return 0;
724} 758}
725 759
@@ -729,6 +763,8 @@ static void vlan_dev_uninit(struct net_device *dev)
729 struct vlan_dev_info *vlan = vlan_dev_info(dev); 763 struct vlan_dev_info *vlan = vlan_dev_info(dev);
730 int i; 764 int i;
731 765
766 free_percpu(vlan->vlan_rx_stats);
767 vlan->vlan_rx_stats = NULL;
732 for (i = 0; i < ARRAY_SIZE(vlan->egress_priority_map); i++) { 768 for (i = 0; i < ARRAY_SIZE(vlan->egress_priority_map); i++) {
733 while ((pm = vlan->egress_priority_map[i]) != NULL) { 769 while ((pm = vlan->egress_priority_map[i]) != NULL) {
734 vlan->egress_priority_map[i] = pm->next; 770 vlan->egress_priority_map[i] = pm->next;
@@ -764,6 +800,31 @@ static u32 vlan_ethtool_get_flags(struct net_device *dev)
764 return dev_ethtool_get_flags(vlan->real_dev); 800 return dev_ethtool_get_flags(vlan->real_dev);
765} 801}
766 802
803static struct net_device_stats *vlan_dev_get_stats(struct net_device *dev)
804{
805 struct net_device_stats *stats = &dev->stats;
806
807 dev_txq_stats_fold(dev, stats);
808
809 if (vlan_dev_info(dev)->vlan_rx_stats) {
810 struct vlan_rx_stats *p, rx = {0};
811 int i;
812
813 for_each_possible_cpu(i) {
814 p = per_cpu_ptr(vlan_dev_info(dev)->vlan_rx_stats, i);
815 rx.rx_packets += p->rx_packets;
816 rx.rx_bytes += p->rx_bytes;
817 rx.rx_errors += p->rx_errors;
818 rx.multicast += p->multicast;
819 }
820 stats->rx_packets = rx.rx_packets;
821 stats->rx_bytes = rx.rx_bytes;
822 stats->rx_errors = rx.rx_errors;
823 stats->multicast = rx.multicast;
824 }
825 return stats;
826}
827
767static const struct ethtool_ops vlan_ethtool_ops = { 828static const struct ethtool_ops vlan_ethtool_ops = {
768 .get_settings = vlan_ethtool_get_settings, 829 .get_settings = vlan_ethtool_get_settings,
769 .get_drvinfo = vlan_ethtool_get_drvinfo, 830 .get_drvinfo = vlan_ethtool_get_drvinfo,
@@ -786,11 +847,13 @@ static const struct net_device_ops vlan_netdev_ops = {
786 .ndo_change_rx_flags = vlan_dev_change_rx_flags, 847 .ndo_change_rx_flags = vlan_dev_change_rx_flags,
787 .ndo_do_ioctl = vlan_dev_ioctl, 848 .ndo_do_ioctl = vlan_dev_ioctl,
788 .ndo_neigh_setup = vlan_dev_neigh_setup, 849 .ndo_neigh_setup = vlan_dev_neigh_setup,
850 .ndo_get_stats = vlan_dev_get_stats,
789#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) 851#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
790 .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, 852 .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup,
791 .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, 853 .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done,
792 .ndo_fcoe_enable = vlan_dev_fcoe_enable, 854 .ndo_fcoe_enable = vlan_dev_fcoe_enable,
793 .ndo_fcoe_disable = vlan_dev_fcoe_disable, 855 .ndo_fcoe_disable = vlan_dev_fcoe_disable,
856 .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn,
794#endif 857#endif
795}; 858};
796 859
@@ -808,11 +871,63 @@ static const struct net_device_ops vlan_netdev_accel_ops = {
808 .ndo_change_rx_flags = vlan_dev_change_rx_flags, 871 .ndo_change_rx_flags = vlan_dev_change_rx_flags,
809 .ndo_do_ioctl = vlan_dev_ioctl, 872 .ndo_do_ioctl = vlan_dev_ioctl,
810 .ndo_neigh_setup = vlan_dev_neigh_setup, 873 .ndo_neigh_setup = vlan_dev_neigh_setup,
874 .ndo_get_stats = vlan_dev_get_stats,
875#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
876 .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup,
877 .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done,
878 .ndo_fcoe_enable = vlan_dev_fcoe_enable,
879 .ndo_fcoe_disable = vlan_dev_fcoe_disable,
880 .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn,
881#endif
882};
883
884static const struct net_device_ops vlan_netdev_ops_sq = {
885 .ndo_select_queue = vlan_dev_select_queue,
886 .ndo_change_mtu = vlan_dev_change_mtu,
887 .ndo_init = vlan_dev_init,
888 .ndo_uninit = vlan_dev_uninit,
889 .ndo_open = vlan_dev_open,
890 .ndo_stop = vlan_dev_stop,
891 .ndo_start_xmit = vlan_dev_hard_start_xmit,
892 .ndo_validate_addr = eth_validate_addr,
893 .ndo_set_mac_address = vlan_dev_set_mac_address,
894 .ndo_set_rx_mode = vlan_dev_set_rx_mode,
895 .ndo_set_multicast_list = vlan_dev_set_rx_mode,
896 .ndo_change_rx_flags = vlan_dev_change_rx_flags,
897 .ndo_do_ioctl = vlan_dev_ioctl,
898 .ndo_neigh_setup = vlan_dev_neigh_setup,
899 .ndo_get_stats = vlan_dev_get_stats,
900#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
901 .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup,
902 .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done,
903 .ndo_fcoe_enable = vlan_dev_fcoe_enable,
904 .ndo_fcoe_disable = vlan_dev_fcoe_disable,
905 .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn,
906#endif
907};
908
909static const struct net_device_ops vlan_netdev_accel_ops_sq = {
910 .ndo_select_queue = vlan_dev_select_queue,
911 .ndo_change_mtu = vlan_dev_change_mtu,
912 .ndo_init = vlan_dev_init,
913 .ndo_uninit = vlan_dev_uninit,
914 .ndo_open = vlan_dev_open,
915 .ndo_stop = vlan_dev_stop,
916 .ndo_start_xmit = vlan_dev_hwaccel_hard_start_xmit,
917 .ndo_validate_addr = eth_validate_addr,
918 .ndo_set_mac_address = vlan_dev_set_mac_address,
919 .ndo_set_rx_mode = vlan_dev_set_rx_mode,
920 .ndo_set_multicast_list = vlan_dev_set_rx_mode,
921 .ndo_change_rx_flags = vlan_dev_change_rx_flags,
922 .ndo_do_ioctl = vlan_dev_ioctl,
923 .ndo_neigh_setup = vlan_dev_neigh_setup,
924 .ndo_get_stats = vlan_dev_get_stats,
811#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) 925#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
812 .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, 926 .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup,
813 .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, 927 .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done,
814 .ndo_fcoe_enable = vlan_dev_fcoe_enable, 928 .ndo_fcoe_enable = vlan_dev_fcoe_enable,
815 .ndo_fcoe_disable = vlan_dev_fcoe_disable, 929 .ndo_fcoe_disable = vlan_dev_fcoe_disable,
930 .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn,
816#endif 931#endif
817}; 932};
818 933