diff options
author | Jiri Pirko <jpirko@redhat.com> | 2011-12-07 23:11:17 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-08 19:52:42 -0500 |
commit | 87002b03baabd2b8f6281ab6411ed88d24958de1 (patch) | |
tree | 0e5730c0d1ba887488ba420d4ea89a230f272c51 /drivers/net/team | |
parent | 8e586137e6b63af1e881b328466ab5ffbe562510 (diff) |
net: introduce vlan_vid_[add/del] and use them instead of direct [add/kill]_vid ndo calls
This patch adds wrapper for ndo_vlan_rx_add_vid/ndo_vlan_rx_kill_vid
functions. Check for NETIF_F_HW_VLAN_FILTER feature is done in this
wrapper.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/team')
-rw-r--r-- | drivers/net/team/team.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 8e8bf958539e..79c2d1b52eb6 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/ctype.h> | 18 | #include <linux/ctype.h> |
19 | #include <linux/notifier.h> | 19 | #include <linux/notifier.h> |
20 | #include <linux/netdevice.h> | 20 | #include <linux/netdevice.h> |
21 | #include <linux/if_vlan.h> | ||
21 | #include <linux/if_arp.h> | 22 | #include <linux/if_arp.h> |
22 | #include <linux/socket.h> | 23 | #include <linux/socket.h> |
23 | #include <linux/etherdevice.h> | 24 | #include <linux/etherdevice.h> |
@@ -906,17 +907,28 @@ static int team_vlan_rx_add_vid(struct net_device *dev, uint16_t vid) | |||
906 | { | 907 | { |
907 | struct team *team = netdev_priv(dev); | 908 | struct team *team = netdev_priv(dev); |
908 | struct team_port *port; | 909 | struct team_port *port; |
910 | int err; | ||
909 | 911 | ||
910 | rcu_read_lock(); | 912 | /* |
911 | list_for_each_entry_rcu(port, &team->port_list, list) { | 913 | * Alhough this is reader, it's guarded by team lock. It's not possible |
912 | const struct net_device_ops *ops = port->dev->netdev_ops; | 914 | * to traverse list in reverse under rcu_read_lock |
913 | 915 | */ | |
914 | if (ops->ndo_vlan_rx_add_vid) | 916 | mutex_lock(&team->lock); |
915 | ops->ndo_vlan_rx_add_vid(port->dev, vid); | 917 | list_for_each_entry(port, &team->port_list, list) { |
918 | err = vlan_vid_add(port->dev, vid); | ||
919 | if (err) | ||
920 | goto unwind; | ||
916 | } | 921 | } |
917 | rcu_read_unlock(); | 922 | mutex_unlock(&team->lock); |
918 | 923 | ||
919 | return 0; | 924 | return 0; |
925 | |||
926 | unwind: | ||
927 | list_for_each_entry_continue_reverse(port, &team->port_list, list) | ||
928 | vlan_vid_del(port->dev, vid); | ||
929 | mutex_unlock(&team->lock); | ||
930 | |||
931 | return err; | ||
920 | } | 932 | } |
921 | 933 | ||
922 | static int team_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid) | 934 | static int team_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid) |
@@ -925,12 +937,8 @@ static int team_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid) | |||
925 | struct team_port *port; | 937 | struct team_port *port; |
926 | 938 | ||
927 | rcu_read_lock(); | 939 | rcu_read_lock(); |
928 | list_for_each_entry_rcu(port, &team->port_list, list) { | 940 | list_for_each_entry_rcu(port, &team->port_list, list) |
929 | const struct net_device_ops *ops = port->dev->netdev_ops; | 941 | vlan_vid_del(port->dev, vid); |
930 | |||
931 | if (ops->ndo_vlan_rx_kill_vid) | ||
932 | ops->ndo_vlan_rx_kill_vid(port->dev, vid); | ||
933 | } | ||
934 | rcu_read_unlock(); | 942 | rcu_read_unlock(); |
935 | 943 | ||
936 | return 0; | 944 | return 0; |