IB/ipoib: Fix ndo_get_iflink
authorErez Shitrit <erezsh@mellanox.com>
Thu, 16 Apr 2015 13:34:34 +0000 (16:34 +0300)
committerDavid S. Miller <davem@davemloft.net>
Fri, 17 Apr 2015 19:21:04 +0000 (15:21 -0400)
Currently, iflink of the parent interface was always accessed, even
when interface didn't have a parent and hence we crashed there.

Handle the interface types properly: for a child interface, return
the ifindex of the parent, for parent interface, return its ifindex.

For child devices, make sure to set the parent pointer prior to
invoking register_netdevice(), this allows the new ndo to be called
by the stack immediately after the child device is registered.

Fixes: 5aa7add8f14b ('infiniband/ipoib: implement ndo_get_iflink')
Reported-by: Honggang Li <honli@redhat.com>
Signed-off-by: Erez Shitrit <erezsh@mellanox.com>
Signed-off-by: Honggang Li <honli@redhat.com>
Reviewed-By: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>+
Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_vlan.c

index 657b89b..915ad04 100644 (file)
@@ -846,6 +846,11 @@ static int ipoib_get_iflink(const struct net_device *dev)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
 
+       /* parent interface */
+       if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags))
+               return dev->ifindex;
+
+       /* child/vlan interface */
        return priv->parent->ifindex;
 }
 
index 4dd1313..fca1a88 100644 (file)
@@ -58,6 +58,7 @@ int __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv,
        /* MTU will be reset when mcast join happens */
        priv->dev->mtu   = IPOIB_UD_MTU(priv->max_ib_mtu);
        priv->mcast_mtu  = priv->admin_mtu = priv->dev->mtu;
+       priv->parent = ppriv->dev;
        set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags);
 
        result = ipoib_set_dev_features(priv, ppriv->ca);
@@ -84,8 +85,6 @@ int __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv,
                goto register_failed;
        }
 
-       priv->parent = ppriv->dev;
-
        ipoib_create_debug_files(priv->dev);
 
        /* RTNL childs don't need proprietary sysfs entries */