net/core: Add support for configuring VF GUIDs
authorEli Cohen <eli@mellanox.com>
Fri, 11 Mar 2016 20:58:34 +0000 (22:58 +0200)
committerDoug Ledford <dledford@redhat.com>
Mon, 21 Mar 2016 20:34:06 +0000 (16:34 -0400)
Add two new NLAs to support configuration of Infiniband node or port
GUIDs. New applications can choose to use this interface to configure
GUIDs with iproute2 with commands such as:

ip link set dev ib0 vf 0 node_guid 00:02:c9:03:00:21:6e:70
ip link set dev ib0 vf 0 port_guid 00:02:c9:03:00:21:6e:78

A new ndo, ndo_sef_vf_guid is introduced to notify the net device of the
request to change the GUID.

Signed-off-by: Eli Cohen <eli@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
include/linux/netdevice.h
include/uapi/linux/if_link.h
net/core/rtnetlink.c

index 5440b7b705eb1756f4d095e6eab3518893245568..7b4ae218b90bcfe6eeef660fe34972a3bddc3800 100644 (file)
@@ -1147,6 +1147,9 @@ struct net_device_ops {
                                                   struct nlattr *port[]);
        int                     (*ndo_get_vf_port)(struct net_device *dev,
                                                   int vf, struct sk_buff *skb);
+       int                     (*ndo_set_vf_guid)(struct net_device *dev,
+                                                  int vf, u64 guid,
+                                                  int guid_type);
        int                     (*ndo_set_vf_rss_query_en)(
                                                   struct net_device *dev,
                                                   int vf, bool setting);
index a30b78090594d500df10aa91f9f1b6628ae88593..1d01e8a4e5dd3ab4d052f234a541c7d7bc778c02 100644 (file)
@@ -556,6 +556,8 @@ enum {
                                 */
        IFLA_VF_STATS,          /* network device statistics */
        IFLA_VF_TRUST,          /* Trust VF */
+       IFLA_VF_IB_NODE_GUID,   /* VF Infiniband node GUID */
+       IFLA_VF_IB_PORT_GUID,   /* VF Infiniband port GUID */
        __IFLA_VF_MAX,
 };
 
@@ -588,6 +590,11 @@ struct ifla_vf_spoofchk {
        __u32 setting;
 };
 
+struct ifla_vf_guid {
+       __u32 vf;
+       __u64 guid;
+};
+
 enum {
        IFLA_VF_LINK_STATE_AUTO,        /* link state of the uplink */
        IFLA_VF_LINK_STATE_ENABLE,      /* link always up */
index d735e854f916040912fb12930cbc6a7950ace942..4b6f3db9f8afb8589be7ec4363911d6770abae2c 100644 (file)
@@ -1387,6 +1387,8 @@ static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
        [IFLA_VF_RSS_QUERY_EN]  = { .len = sizeof(struct ifla_vf_rss_query_en) },
        [IFLA_VF_STATS]         = { .type = NLA_NESTED },
        [IFLA_VF_TRUST]         = { .len = sizeof(struct ifla_vf_trust) },
+       [IFLA_VF_IB_NODE_GUID]  = { .len = sizeof(struct ifla_vf_guid) },
+       [IFLA_VF_IB_PORT_GUID]  = { .len = sizeof(struct ifla_vf_guid) },
 };
 
 static const struct nla_policy ifla_vf_stats_policy[IFLA_VF_STATS_MAX + 1] = {
@@ -1534,6 +1536,22 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
        return 0;
 }
 
+static int handle_infiniband_guid(struct net_device *dev, struct ifla_vf_guid *ivt,
+                                 int guid_type)
+{
+       const struct net_device_ops *ops = dev->netdev_ops;
+
+       return ops->ndo_set_vf_guid(dev, ivt->vf, ivt->guid, guid_type);
+}
+
+static int handle_vf_guid(struct net_device *dev, struct ifla_vf_guid *ivt, int guid_type)
+{
+       if (dev->type != ARPHRD_INFINIBAND)
+               return -EOPNOTSUPP;
+
+       return handle_infiniband_guid(dev, ivt, guid_type);
+}
+
 static int do_setvfinfo(struct net_device *dev, struct nlattr **tb)
 {
        const struct net_device_ops *ops = dev->netdev_ops;
@@ -1636,6 +1654,24 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr **tb)
                        return err;
        }
 
+       if (tb[IFLA_VF_IB_NODE_GUID]) {
+               struct ifla_vf_guid *ivt = nla_data(tb[IFLA_VF_IB_NODE_GUID]);
+
+               if (!ops->ndo_set_vf_guid)
+                       return -EOPNOTSUPP;
+
+               return handle_vf_guid(dev, ivt, IFLA_VF_IB_NODE_GUID);
+       }
+
+       if (tb[IFLA_VF_IB_PORT_GUID]) {
+               struct ifla_vf_guid *ivt = nla_data(tb[IFLA_VF_IB_PORT_GUID]);
+
+               if (!ops->ndo_set_vf_guid)
+                       return -EOPNOTSUPP;
+
+               return handle_vf_guid(dev, ivt, IFLA_VF_IB_PORT_GUID);
+       }
+
        return err;
 }