datapath: link upper device for port devices
authorJiri Pirko <jiri@resnulli.us>
Tue, 30 Jul 2013 23:27:31 +0000 (16:27 -0700)
committerJesse Gross <jesse@nicira.com>
Tue, 30 Jul 2013 23:29:48 +0000 (16:29 -0700)
Link upper device properly. That will make IFLA_MASTER filled up.
Set the master to port 0 of the datapath under which the port belongs.

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: Jesse Gross <jesse@nicira.com>
datapath/linux/compat/include/linux/netdevice.h
datapath/vport-netdev.c

index ba1fc59..3f66d3a 100644 (file)
@@ -188,4 +188,19 @@ static inline struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
        return skb_gso_segment(skb, features);
 }
 #endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)
+static inline int netdev_master_upper_dev_link(struct net_device *dev,
+                                              struct net_device *upper_dev)
+{
+       return netdev_set_master(dev, upper_dev);
+}
+
+static inline void netdev_upper_dev_unlink(struct net_device *dev,
+                                          struct net_device *upper_dev)
+{
+       netdev_set_master(dev, NULL);
+}
+#endif
+
 #endif
index 06598fa..4bc1617 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/llc.h>
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
+#include <linux/openvswitch.h>
 
 #include <net/llc.h>
 
@@ -136,6 +137,15 @@ static void netdev_exit(void)
 }
 #endif
 
+static struct net_device *get_dpdev(struct datapath *dp)
+{
+       struct vport *local;
+
+       local = ovs_vport_ovsl(dp, OVSP_LOCAL);
+       BUG_ON(!local);
+       return netdev_vport_priv(local)->dev;
+}
+
 static struct vport *netdev_create(const struct vport_parms *parms)
 {
        struct vport *vport;
@@ -165,10 +175,15 @@ static struct vport *netdev_create(const struct vport_parms *parms)
        }
 
        rtnl_lock();
+       err = netdev_master_upper_dev_link(netdev_vport->dev,
+                                          get_dpdev(vport->dp));
+       if (err)
+               goto error_unlock;
+
        err = netdev_rx_handler_register(netdev_vport->dev, netdev_frame_hook,
                                         vport);
        if (err)
-               goto error_unlock;
+               goto error_master_upper_dev_unlink;
 
        dev_set_promiscuity(netdev_vport->dev, 1);
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
@@ -180,6 +195,8 @@ static struct vport *netdev_create(const struct vport_parms *parms)
        netdev_init();
        return vport;
 
+error_master_upper_dev_unlink:
+       netdev_upper_dev_unlink(netdev_vport->dev, get_dpdev(vport->dp));
 error_unlock:
        rtnl_unlock();
 error_put:
@@ -207,6 +224,7 @@ static void netdev_destroy(struct vport *vport)
        rtnl_lock();
        netdev_vport->dev->priv_flags &= ~IFF_OVS_DATAPATH;
        netdev_rx_handler_unregister(netdev_vport->dev);
+       netdev_upper_dev_unlink(netdev_vport->dev, get_dpdev(vport->dp));
        dev_set_promiscuity(netdev_vport->dev, -1);
        rtnl_unlock();