From: Kamal Heib <kamalhe...@gmail.com>

[ Upstream commit 5ce2dced8e95e76ff7439863a118a053a7fc6f91 ]

Report the "ipoib pkey", "mode" and "umcast" netlink attributes for every
IPoiB interface type, not just children created with 'ip link add'.

After setting the rtnl_link_ops for the parent interface, implement the
dellink() callback to block users from trying to remove it.

Fixes: 862096a8bbf8 ("IB/ipoib: Add more rtnl_link_ops callbacks")
Link: https://lore.kernel.org/r/20201004132948.26669-1-kamalhe...@gmail.com
Signed-off-by: Kamal Heib <kamalhe...@gmail.com>
Signed-off-by: Jason Gunthorpe <j...@nvidia.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 drivers/infiniband/ulp/ipoib/ipoib_main.c    |  2 ++
 drivers/infiniband/ulp/ipoib/ipoib_netlink.c | 11 +++++++++++
 drivers/infiniband/ulp/ipoib/ipoib_vlan.c    |  2 ++
 3 files changed, 15 insertions(+)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c 
b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index ef60e8e4ae67b..7c0bb2642d232 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -2470,6 +2470,8 @@ static struct net_device *ipoib_add_port(const char 
*format,
        /* call event handler to ensure pkey in sync */
        queue_work(ipoib_workqueue, &priv->flush_heavy);
 
+       ndev->rtnl_link_ops = ipoib_get_link_ops();
+
        result = register_netdev(ndev);
        if (result) {
                pr_warn("%s: couldn't register ipoib port %d; error %d\n",
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c 
b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
index 38c984d16996d..d5a90a66b45cf 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
@@ -144,6 +144,16 @@ static int ipoib_new_child_link(struct net *src_net, 
struct net_device *dev,
        return 0;
 }
 
+static void ipoib_del_child_link(struct net_device *dev, struct list_head 
*head)
+{
+       struct ipoib_dev_priv *priv = ipoib_priv(dev);
+
+       if (!priv->parent)
+               return;
+
+       unregister_netdevice_queue(dev, head);
+}
+
 static size_t ipoib_get_size(const struct net_device *dev)
 {
        return nla_total_size(2) +      /* IFLA_IPOIB_PKEY   */
@@ -158,6 +168,7 @@ static struct rtnl_link_ops ipoib_link_ops __read_mostly = {
        .priv_size      = sizeof(struct ipoib_dev_priv),
        .setup          = ipoib_setup_common,
        .newlink        = ipoib_new_child_link,
+       .dellink        = ipoib_del_child_link,
        .changelink     = ipoib_changelink,
        .get_size       = ipoib_get_size,
        .fill_info      = ipoib_fill_info,
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c 
b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 30865605e0980..4c50a87ed7cc2 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -195,6 +195,8 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short 
pkey)
        }
        priv = ipoib_priv(ndev);
 
+       ndev->rtnl_link_ops = ipoib_get_link_ops();
+
        result = __ipoib_vlan_add(ppriv, priv, pkey, IPOIB_LEGACY_CHILD);
 
        if (result && ndev->reg_state == NETREG_UNINITIALIZED)
-- 
2.25.1



Reply via email to