aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Cohen <eli@mellanox.com>2016-03-11 15:58:34 -0500
committerDoug Ledford <dledford@redhat.com>2016-03-21 16:34:06 -0400
commitcc8e27cc97318471b7e707932d5b93b0d5f70830 (patch)
tree7334c9bc203d3a49f9ddfec39afaa5890321d845
parentfb532d6a79b96a4c8f678024d7ed3549ff0ca916 (diff)
net/core: Add support for configuring VF GUIDs
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>
-rw-r--r--include/linux/netdevice.h3
-rw-r--r--include/uapi/linux/if_link.h7
-rw-r--r--net/core/rtnetlink.c36
3 files changed, 46 insertions, 0 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 5440b7b705eb..7b4ae218b90b 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1147,6 +1147,9 @@ struct net_device_ops {
1147 struct nlattr *port[]); 1147 struct nlattr *port[]);
1148 int (*ndo_get_vf_port)(struct net_device *dev, 1148 int (*ndo_get_vf_port)(struct net_device *dev,
1149 int vf, struct sk_buff *skb); 1149 int vf, struct sk_buff *skb);
1150 int (*ndo_set_vf_guid)(struct net_device *dev,
1151 int vf, u64 guid,
1152 int guid_type);
1150 int (*ndo_set_vf_rss_query_en)( 1153 int (*ndo_set_vf_rss_query_en)(
1151 struct net_device *dev, 1154 struct net_device *dev,
1152 int vf, bool setting); 1155 int vf, bool setting);
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index a30b78090594..1d01e8a4e5dd 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -556,6 +556,8 @@ enum {
556 */ 556 */
557 IFLA_VF_STATS, /* network device statistics */ 557 IFLA_VF_STATS, /* network device statistics */
558 IFLA_VF_TRUST, /* Trust VF */ 558 IFLA_VF_TRUST, /* Trust VF */
559 IFLA_VF_IB_NODE_GUID, /* VF Infiniband node GUID */
560 IFLA_VF_IB_PORT_GUID, /* VF Infiniband port GUID */
559 __IFLA_VF_MAX, 561 __IFLA_VF_MAX,
560}; 562};
561 563
@@ -588,6 +590,11 @@ struct ifla_vf_spoofchk {
588 __u32 setting; 590 __u32 setting;
589}; 591};
590 592
593struct ifla_vf_guid {
594 __u32 vf;
595 __u64 guid;
596};
597
591enum { 598enum {
592 IFLA_VF_LINK_STATE_AUTO, /* link state of the uplink */ 599 IFLA_VF_LINK_STATE_AUTO, /* link state of the uplink */
593 IFLA_VF_LINK_STATE_ENABLE, /* link always up */ 600 IFLA_VF_LINK_STATE_ENABLE, /* link always up */
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index d735e854f916..4b6f3db9f8af 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1387,6 +1387,8 @@ static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
1387 [IFLA_VF_RSS_QUERY_EN] = { .len = sizeof(struct ifla_vf_rss_query_en) }, 1387 [IFLA_VF_RSS_QUERY_EN] = { .len = sizeof(struct ifla_vf_rss_query_en) },
1388 [IFLA_VF_STATS] = { .type = NLA_NESTED }, 1388 [IFLA_VF_STATS] = { .type = NLA_NESTED },
1389 [IFLA_VF_TRUST] = { .len = sizeof(struct ifla_vf_trust) }, 1389 [IFLA_VF_TRUST] = { .len = sizeof(struct ifla_vf_trust) },
1390 [IFLA_VF_IB_NODE_GUID] = { .len = sizeof(struct ifla_vf_guid) },
1391 [IFLA_VF_IB_PORT_GUID] = { .len = sizeof(struct ifla_vf_guid) },
1390}; 1392};
1391 1393
1392static const struct nla_policy ifla_vf_stats_policy[IFLA_VF_STATS_MAX + 1] = { 1394static 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[])
1534 return 0; 1536 return 0;
1535} 1537}
1536 1538
1539static int handle_infiniband_guid(struct net_device *dev, struct ifla_vf_guid *ivt,
1540 int guid_type)
1541{
1542 const struct net_device_ops *ops = dev->netdev_ops;
1543
1544 return ops->ndo_set_vf_guid(dev, ivt->vf, ivt->guid, guid_type);
1545}
1546
1547static int handle_vf_guid(struct net_device *dev, struct ifla_vf_guid *ivt, int guid_type)
1548{
1549 if (dev->type != ARPHRD_INFINIBAND)
1550 return -EOPNOTSUPP;
1551
1552 return handle_infiniband_guid(dev, ivt, guid_type);
1553}
1554
1537static int do_setvfinfo(struct net_device *dev, struct nlattr **tb) 1555static int do_setvfinfo(struct net_device *dev, struct nlattr **tb)
1538{ 1556{
1539 const struct net_device_ops *ops = dev->netdev_ops; 1557 const struct net_device_ops *ops = dev->netdev_ops;
@@ -1636,6 +1654,24 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr **tb)
1636 return err; 1654 return err;
1637 } 1655 }
1638 1656
1657 if (tb[IFLA_VF_IB_NODE_GUID]) {
1658 struct ifla_vf_guid *ivt = nla_data(tb[IFLA_VF_IB_NODE_GUID]);
1659
1660 if (!ops->ndo_set_vf_guid)
1661 return -EOPNOTSUPP;
1662
1663 return handle_vf_guid(dev, ivt, IFLA_VF_IB_NODE_GUID);
1664 }
1665
1666 if (tb[IFLA_VF_IB_PORT_GUID]) {
1667 struct ifla_vf_guid *ivt = nla_data(tb[IFLA_VF_IB_PORT_GUID]);
1668
1669 if (!ops->ndo_set_vf_guid)
1670 return -EOPNOTSUPP;
1671
1672 return handle_vf_guid(dev, ivt, IFLA_VF_IB_PORT_GUID);
1673 }
1674
1639 return err; 1675 return err;
1640} 1676}
1641 1677