diff options
Diffstat (limited to 'net/8021q/vlan_dev.c')
-rw-r--r-- | net/8021q/vlan_dev.c | 86 |
1 files changed, 76 insertions, 10 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 9e83272fc5b0..b5249c5fd4d3 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> |
@@ -361,6 +362,14 @@ static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, | |||
361 | return ret; | 362 | return ret; |
362 | } | 363 | } |
363 | 364 | ||
365 | static 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); | ||
371 | } | ||
372 | |||
364 | static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) | 373 | static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) |
365 | { | 374 | { |
366 | /* TODO: gotta make sure the underlying layer can handle it, | 375 | /* TODO: gotta make sure the underlying layer can handle it, |
@@ -461,7 +470,7 @@ static int vlan_dev_open(struct net_device *dev) | |||
461 | return -ENETDOWN; | 470 | return -ENETDOWN; |
462 | 471 | ||
463 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) { | 472 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) { |
464 | err = dev_unicast_add(real_dev, dev->dev_addr); | 473 | err = dev_uc_add(real_dev, dev->dev_addr); |
465 | if (err < 0) | 474 | if (err < 0) |
466 | goto out; | 475 | goto out; |
467 | } | 476 | } |
@@ -490,7 +499,7 @@ clear_allmulti: | |||
490 | dev_set_allmulti(real_dev, -1); | 499 | dev_set_allmulti(real_dev, -1); |
491 | del_unicast: | 500 | del_unicast: |
492 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) | 501 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) |
493 | dev_unicast_delete(real_dev, dev->dev_addr); | 502 | dev_uc_del(real_dev, dev->dev_addr); |
494 | out: | 503 | out: |
495 | netif_carrier_off(dev); | 504 | netif_carrier_off(dev); |
496 | return err; | 505 | return err; |
@@ -505,14 +514,14 @@ static int vlan_dev_stop(struct net_device *dev) | |||
505 | vlan_gvrp_request_leave(dev); | 514 | vlan_gvrp_request_leave(dev); |
506 | 515 | ||
507 | dev_mc_unsync(real_dev, dev); | 516 | dev_mc_unsync(real_dev, dev); |
508 | dev_unicast_unsync(real_dev, dev); | 517 | dev_uc_unsync(real_dev, dev); |
509 | if (dev->flags & IFF_ALLMULTI) | 518 | if (dev->flags & IFF_ALLMULTI) |
510 | dev_set_allmulti(real_dev, -1); | 519 | dev_set_allmulti(real_dev, -1); |
511 | if (dev->flags & IFF_PROMISC) | 520 | if (dev->flags & IFF_PROMISC) |
512 | dev_set_promiscuity(real_dev, -1); | 521 | dev_set_promiscuity(real_dev, -1); |
513 | 522 | ||
514 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) | 523 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) |
515 | dev_unicast_delete(real_dev, dev->dev_addr); | 524 | dev_uc_del(real_dev, dev->dev_addr); |
516 | 525 | ||
517 | netif_carrier_off(dev); | 526 | netif_carrier_off(dev); |
518 | return 0; | 527 | return 0; |
@@ -531,13 +540,13 @@ static int vlan_dev_set_mac_address(struct net_device *dev, void *p) | |||
531 | goto out; | 540 | goto out; |
532 | 541 | ||
533 | if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) { | 542 | if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) { |
534 | err = dev_unicast_add(real_dev, addr->sa_data); | 543 | err = dev_uc_add(real_dev, addr->sa_data); |
535 | if (err < 0) | 544 | if (err < 0) |
536 | return err; | 545 | return err; |
537 | } | 546 | } |
538 | 547 | ||
539 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) | 548 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) |
540 | dev_unicast_delete(real_dev, dev->dev_addr); | 549 | dev_uc_del(real_dev, dev->dev_addr); |
541 | 550 | ||
542 | out: | 551 | out: |
543 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); | 552 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); |
@@ -654,7 +663,7 @@ static void vlan_dev_change_rx_flags(struct net_device *dev, int change) | |||
654 | static void vlan_dev_set_rx_mode(struct net_device *vlan_dev) | 663 | static void vlan_dev_set_rx_mode(struct net_device *vlan_dev) |
655 | { | 664 | { |
656 | dev_mc_sync(vlan_dev_info(vlan_dev)->real_dev, vlan_dev); | 665 | dev_mc_sync(vlan_dev_info(vlan_dev)->real_dev, vlan_dev); |
657 | dev_unicast_sync(vlan_dev_info(vlan_dev)->real_dev, vlan_dev); | 666 | dev_uc_sync(vlan_dev_info(vlan_dev)->real_dev, vlan_dev); |
658 | } | 667 | } |
659 | 668 | ||
660 | /* | 669 | /* |
@@ -688,7 +697,8 @@ static const struct header_ops vlan_header_ops = { | |||
688 | .parse = eth_header_parse, | 697 | .parse = eth_header_parse, |
689 | }; | 698 | }; |
690 | 699 | ||
691 | static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops; | 700 | static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops, |
701 | vlan_netdev_ops_sq, vlan_netdev_accel_ops_sq; | ||
692 | 702 | ||
693 | static int vlan_dev_init(struct net_device *dev) | 703 | static int vlan_dev_init(struct net_device *dev) |
694 | { | 704 | { |
@@ -722,11 +732,17 @@ static int vlan_dev_init(struct net_device *dev) | |||
722 | if (real_dev->features & NETIF_F_HW_VLAN_TX) { | 732 | if (real_dev->features & NETIF_F_HW_VLAN_TX) { |
723 | dev->header_ops = real_dev->header_ops; | 733 | dev->header_ops = real_dev->header_ops; |
724 | dev->hard_header_len = real_dev->hard_header_len; | 734 | dev->hard_header_len = real_dev->hard_header_len; |
725 | 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; | ||
726 | } else { | 739 | } else { |
727 | dev->header_ops = &vlan_header_ops; | 740 | dev->header_ops = &vlan_header_ops; |
728 | dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; | 741 | dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; |
729 | 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; | ||
730 | } | 746 | } |
731 | 747 | ||
732 | if (is_vlan_dev(real_dev)) | 748 | if (is_vlan_dev(real_dev)) |
@@ -865,6 +881,56 @@ static const struct net_device_ops vlan_netdev_accel_ops = { | |||
865 | #endif | 881 | #endif |
866 | }; | 882 | }; |
867 | 883 | ||
884 | static 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 | |||
909 | static 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, | ||
925 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) | ||
926 | .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, | ||
927 | .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, | ||
928 | .ndo_fcoe_enable = vlan_dev_fcoe_enable, | ||
929 | .ndo_fcoe_disable = vlan_dev_fcoe_disable, | ||
930 | .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, | ||
931 | #endif | ||
932 | }; | ||
933 | |||
868 | void vlan_setup(struct net_device *dev) | 934 | void vlan_setup(struct net_device *dev) |
869 | { | 935 | { |
870 | ether_setup(dev); | 936 | ether_setup(dev); |