aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/team
diff options
context:
space:
mode:
authorJiri Pirko <jpirko@redhat.com>2011-12-07 23:11:17 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-08 19:52:42 -0500
commit87002b03baabd2b8f6281ab6411ed88d24958de1 (patch)
tree0e5730c0d1ba887488ba420d4ea89a230f272c51 /drivers/net/team
parent8e586137e6b63af1e881b328466ab5ffbe562510 (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.c34
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
926unwind:
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
922static int team_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid) 934static 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;