aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Pirko <jiri@mellanox.com>2015-08-27 09:31:23 +0200
committerDavid S. Miller <davem@davemloft.net>2015-08-27 16:28:35 -0700
commit686ed3047e8727fe3c7eb5a3c63a5e9b1556bbbb (patch)
tree82a77077f8e86636c91bae0c401ba97ae4415737
parentrocker: use new helper to figure out master kind (diff)
downloadlinux-dev-686ed3047e8727fe3c7eb5a3c63a5e9b1556bbbb.tar.xz
linux-dev-686ed3047e8727fe3c7eb5a3c63a5e9b1556bbbb.zip
rocker: use change upper info
Since now information about changed upper is passed along, benefit from that and use this info directly. This also fixes possible issues that could happen when non-master device is added (current code does not distinguish between master and non-master upper device). Signed-off-by: Jiri Pirko <jiri@mellanox.com> Acked-by: Scott Feldman <sfeldma@gmail.com Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/rocker/rocker.c61
1 files changed, 38 insertions, 23 deletions
diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c
index 62f383c84a66..34ac41ac9e61 100644
--- a/drivers/net/ethernet/rocker/rocker.c
+++ b/drivers/net/ethernet/rocker/rocker.c
@@ -5326,46 +5326,61 @@ static int rocker_port_ovs_changed(struct rocker_port *rocker_port,
return err;
}
-static int rocker_port_master_changed(struct net_device *dev)
+static int rocker_port_master_linked(struct rocker_port *rocker_port,
+ struct net_device *master)
+{
+ int err = 0;
+
+ if (netif_is_bridge_master(master))
+ err = rocker_port_bridge_join(rocker_port, master);
+ else if (netif_is_ovs_master(master))
+ err = rocker_port_ovs_changed(rocker_port, master);
+ return err;
+}
+
+static int rocker_port_master_unlinked(struct rocker_port *rocker_port)
{
- struct rocker_port *rocker_port = netdev_priv(dev);
- struct net_device *master = netdev_master_upper_dev_get(dev);
int err = 0;
- /* N.B: Do nothing if the type of master is not supported */
- if (master) {
- if (netif_is_bridge_master(master))
- err = rocker_port_bridge_join(rocker_port, master);
- else if (netif_is_ovs_master(master))
- err = rocker_port_ovs_changed(rocker_port, master);
- } else if (rocker_port_is_bridged(rocker_port)) {
+ if (rocker_port_is_bridged(rocker_port))
err = rocker_port_bridge_leave(rocker_port);
- } else if (rocker_port_is_ovsed(rocker_port)) {
+ else if (rocker_port_is_ovsed(rocker_port))
err = rocker_port_ovs_changed(rocker_port, NULL);
- }
-
return err;
}
static int rocker_netdevice_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
- struct net_device *dev;
+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+ struct netdev_notifier_changeupper_info *info;
+ struct rocker_port *rocker_port;
int err;
+ if (!rocker_port_dev_check(dev))
+ return NOTIFY_DONE;
+
switch (event) {
case NETDEV_CHANGEUPPER:
- dev = netdev_notifier_info_to_dev(ptr);
- if (!rocker_port_dev_check(dev))
- return NOTIFY_DONE;
- err = rocker_port_master_changed(dev);
- if (err)
- netdev_warn(dev,
- "failed to reflect master change (err %d)\n",
- err);
+ info = ptr;
+ if (!info->master)
+ goto out;
+ rocker_port = netdev_priv(dev);
+ if (info->linking) {
+ err = rocker_port_master_linked(rocker_port,
+ info->upper_dev);
+ if (err)
+ netdev_warn(dev, "failed to reflect master linked (err %d)\n",
+ err);
+ } else {
+ err = rocker_port_master_unlinked(rocker_port);
+ if (err)
+ netdev_warn(dev, "failed to reflect master unlinked (err %d)\n",
+ err);
+ }
break;
}
-
+out:
return NOTIFY_DONE;
}