mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-02 01:45:17 +00:00
nodedev: add RDMA and tx-udp_tnl-segmentation NIC capabilities
Adding functionality to libvirt that will allow it query the interface for the availability of RDMA and tx-udp_tnl-segmentation Offloading NIC capabilities Here is an example of the feature XML definition: <device> <name>net_eth4_90_e2_ba_5e_a5_45</name> <path>/sys/devices/pci0000:00/0000:00:03.0/0000:08:00.1/net/eth4</path> <parent>pci_0000_08_00_1</parent> <capability type='net'> <interface>eth4</interface> <address>90:e2:ba:5e:a5:45</address> <link speed='10000' state='up'/> <feature name='rx'/> <feature name='tx'/> <feature name='sg'/> <feature name='tso'/> <feature name='gso'/> <feature name='gro'/> <feature name='rxvlan'/> <feature name='txvlan'/> <feature name='rxhash'/> <feature name='rdma'/> <feature name='txudptnl'/> <capability type='80203'/> </capability> </device>
This commit is contained in:
parent
e46791e003
commit
ac3ed2085f
@ -390,7 +390,7 @@ AC_CHECK_TYPE([struct ifreq],
|
|||||||
]])
|
]])
|
||||||
|
|
||||||
AC_CHECK_DECLS([ETH_FLAG_TXVLAN, ETH_FLAG_NTUPLE, ETH_FLAG_RXHASH, ETH_FLAG_LRO,
|
AC_CHECK_DECLS([ETH_FLAG_TXVLAN, ETH_FLAG_NTUPLE, ETH_FLAG_RXHASH, ETH_FLAG_LRO,
|
||||||
ETHTOOL_GGSO, ETHTOOL_GGRO, ETHTOOL_GFLAGS],
|
ETHTOOL_GGSO, ETHTOOL_GGRO, ETHTOOL_GFLAGS, ETHTOOL_GFEATURES],
|
||||||
[], [], [[#include <linux/ethtool.h>
|
[], [], [[#include <linux/ethtool.h>
|
||||||
]])
|
]])
|
||||||
|
|
||||||
|
@ -199,6 +199,8 @@
|
|||||||
<dt><code>txvlan</code></dt><dd>tx-vlan-offload</dd>
|
<dt><code>txvlan</code></dt><dd>tx-vlan-offload</dd>
|
||||||
<dt><code>ntuple</code></dt><dd>ntuple-filters</dd>
|
<dt><code>ntuple</code></dt><dd>ntuple-filters</dd>
|
||||||
<dt><code>rxhash</code></dt><dd>receive-hashing</dd>
|
<dt><code>rxhash</code></dt><dd>receive-hashing</dd>
|
||||||
|
<dt><code>rdma</code></dt><dd>remote-direct-memory-access</dd>
|
||||||
|
<dt><code>txudptnl</code></dt><dd>tx-udp-tunnel-segmentation</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</dd>
|
</dd>
|
||||||
<dt><code>capability</code></dt>
|
<dt><code>capability</code></dt>
|
||||||
|
@ -51,7 +51,9 @@ VIR_ENUM_IMPL(virNetDevFeature,
|
|||||||
"rxvlan",
|
"rxvlan",
|
||||||
"txvlan",
|
"txvlan",
|
||||||
"ntuple",
|
"ntuple",
|
||||||
"rxhash")
|
"rxhash",
|
||||||
|
"rdma",
|
||||||
|
"txudptnl")
|
||||||
|
|
||||||
int virDevicePCIAddressIsValid(virDevicePCIAddressPtr addr)
|
int virDevicePCIAddressIsValid(virDevicePCIAddressPtr addr)
|
||||||
{
|
{
|
||||||
|
@ -74,6 +74,8 @@ typedef enum {
|
|||||||
VIR_NET_DEV_FEAT_TXVLAN,
|
VIR_NET_DEV_FEAT_TXVLAN,
|
||||||
VIR_NET_DEV_FEAT_NTUPLE,
|
VIR_NET_DEV_FEAT_NTUPLE,
|
||||||
VIR_NET_DEV_FEAT_RXHASH,
|
VIR_NET_DEV_FEAT_RXHASH,
|
||||||
|
VIR_NET_DEV_FEAT_RDMA,
|
||||||
|
VIR_NET_DEV_FEAT_TXUDPTNL,
|
||||||
VIR_NET_DEV_FEAT_LAST
|
VIR_NET_DEV_FEAT_LAST
|
||||||
} virNetDevFeature;
|
} virNetDevFeature;
|
||||||
|
|
||||||
|
@ -87,6 +87,16 @@ VIR_LOG_INIT("util.netdev");
|
|||||||
# define VIR_IFF_ALLMULTI 0
|
# define VIR_IFF_ALLMULTI 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define RESOURCE_FILE_LEN 4096
|
||||||
|
#if HAVE_DECL_ETHTOOL_GFEATURES
|
||||||
|
# define TX_UDP_TNL 25
|
||||||
|
# define GFEATURES_SIZE 2
|
||||||
|
# define FEATURE_WORD(blocks, index, field) ((blocks)[(index) / 32U].field)
|
||||||
|
# define FEATURE_FIELD_FLAG(index) (1U << (index) % 32U)
|
||||||
|
# define FEATURE_BIT_IS_SET(blocks, index, field) \
|
||||||
|
(FEATURE_WORD(blocks, index, field) & FEATURE_FIELD_FLAG(index))
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
VIR_MCAST_TYPE_INDEX_TOKEN,
|
VIR_MCAST_TYPE_INDEX_TOKEN,
|
||||||
VIR_MCAST_TYPE_NAME_TOKEN,
|
VIR_MCAST_TYPE_NAME_TOKEN,
|
||||||
@ -1868,7 +1878,6 @@ virNetDevReplaceMacAddress(const char *linkdev,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(path);
|
VIR_FREE(path);
|
||||||
return ret;
|
return ret;
|
||||||
@ -2858,9 +2867,9 @@ static int virNetDevGetMulticastTable(const char *ifname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
virNetDevMcastListClear(&mcast);
|
virNetDevMcastListClear(&mcast);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2943,11 +2952,73 @@ int virNetDevGetRxFilter(const char *ifname,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNetDevRDMAFeature
|
||||||
|
* This function checks for the availability of RDMA feature
|
||||||
|
* and add it to bitmap
|
||||||
|
*
|
||||||
|
* @ifname: name of the interface
|
||||||
|
* @out: add RDMA feature if exist to bitmap
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -1 on failure.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
virNetDevRDMAFeature(const char *ifname,
|
||||||
|
virBitmapPtr *out)
|
||||||
|
{
|
||||||
|
char *eth_devpath = NULL;
|
||||||
|
char *ib_devpath = NULL;
|
||||||
|
char *eth_res_buf = NULL;
|
||||||
|
char *ib_res_buf = NULL;
|
||||||
|
DIR *dirp = NULL;
|
||||||
|
struct dirent *dp;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (!(dirp = opendir(SYSFS_INFINIBAND_DIR))) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("Failed to opendir path '%s'"),
|
||||||
|
SYSFS_INFINIBAND_DIR);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virAsprintf(ð_devpath, SYSFS_NET_DIR "%s/device/resource", ifname) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (!virFileExists(eth_devpath))
|
||||||
|
goto cleanup;
|
||||||
|
if (virFileReadAll(eth_devpath, RESOURCE_FILE_LEN, ð_res_buf) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
while (virDirRead(dirp, &dp, SYSFS_INFINIBAND_DIR) > 0) {
|
||||||
|
if (dp->d_name[0] == '.')
|
||||||
|
continue;
|
||||||
|
if (virAsprintf(&ib_devpath, SYSFS_INFINIBAND_DIR "%s/device/resource",
|
||||||
|
dp->d_name) < 0)
|
||||||
|
continue;
|
||||||
|
if (virFileReadAll(ib_devpath, RESOURCE_FILE_LEN, &ib_res_buf) > 0 &&
|
||||||
|
STREQ(eth_res_buf, ib_res_buf)) {
|
||||||
|
ignore_value(virBitmapSetBit(*out, VIR_NET_DEV_FEAT_RDMA));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
VIR_FREE(ib_devpath);
|
||||||
|
VIR_FREE(ib_res_buf);
|
||||||
|
}
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
closedir(dirp);
|
||||||
|
VIR_FREE(eth_devpath);
|
||||||
|
VIR_FREE(ib_devpath);
|
||||||
|
VIR_FREE(eth_res_buf);
|
||||||
|
VIR_FREE(ib_res_buf);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(SIOCETHTOOL) && defined(HAVE_STRUCT_IFREQ)
|
#if defined(SIOCETHTOOL) && defined(HAVE_STRUCT_IFREQ)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virNetDevFeatureAvailable
|
* virNetDevSendEthtoolIoctl
|
||||||
* This function checks for the availability of a network device feature
|
* This function sends ethtool ioctl request
|
||||||
*
|
*
|
||||||
* @ifname: name of the interface
|
* @ifname: name of the interface
|
||||||
* @cmd: reference to an ethtool command structure
|
* @cmd: reference to an ethtool command structure
|
||||||
@ -2955,7 +3026,7 @@ int virNetDevGetRxFilter(const char *ifname,
|
|||||||
* Returns 0 on success, -1 on failure.
|
* Returns 0 on success, -1 on failure.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
virNetDevFeatureAvailable(const char *ifname, struct ethtool_value *cmd)
|
virNetDevSendEthtoolIoctl(const char *ifname, void *cmd)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
int sock = -1;
|
int sock = -1;
|
||||||
@ -2969,9 +3040,9 @@ virNetDevFeatureAvailable(const char *ifname, struct ethtool_value *cmd)
|
|||||||
|
|
||||||
memset(&ifr, 0, sizeof(ifr));
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
strcpy(ifr.ifr_name, ifname);
|
strcpy(ifr.ifr_name, ifname);
|
||||||
ifr.ifr_data = (void*) cmd;
|
ifr.ifr_data = cmd;
|
||||||
|
ret = ioctl(sock, SIOCETHTOOL, &ifr);
|
||||||
if (ioctl(sock, SIOCETHTOOL, &ifr) != 0) {
|
if (ret != 0) {
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
case EPERM:
|
case EPERM:
|
||||||
VIR_DEBUG("ethtool ioctl: permission denied");
|
VIR_DEBUG("ethtool ioctl: permission denied");
|
||||||
@ -2988,15 +3059,57 @@ virNetDevFeatureAvailable(const char *ifname, struct ethtool_value *cmd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = cmd->data > 0 ? 1: 0;
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (sock)
|
if (sock)
|
||||||
VIR_FORCE_CLOSE(sock);
|
VIR_FORCE_CLOSE(sock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNetDevFeatureAvailable
|
||||||
|
* This function checks for the availability of a network device feature
|
||||||
|
*
|
||||||
|
* @ifname: name of the interface
|
||||||
|
* @cmd: reference to an ethtool command structure
|
||||||
|
*
|
||||||
|
* Returns 0 if not found, 1 on success, and -1 on failure.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
virNetDevFeatureAvailable(const char *ifname, struct ethtool_value *cmd)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
cmd = (void*)cmd;
|
||||||
|
if (!virNetDevSendEthtoolIoctl(ifname, cmd))
|
||||||
|
ret = cmd->data > 0 ? 1 : 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# if HAVE_DECL_ETHTOOL_GFEATURES
|
||||||
|
/**
|
||||||
|
* virNetDevGFeatureAvailable
|
||||||
|
* This function checks for the availability of a network device gfeature
|
||||||
|
*
|
||||||
|
* @ifname: name of the interface
|
||||||
|
* @cmd: reference to a gfeatures ethtool command structure
|
||||||
|
*
|
||||||
|
* Returns 0 if not found, 1 on success, and -1 on failure.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
virNetDevGFeatureAvailable(const char *ifname, struct ethtool_gfeatures *cmd)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
cmd = (void*)cmd;
|
||||||
|
if (!virNetDevSendEthtoolIoctl(ifname, cmd))
|
||||||
|
ret = FEATURE_BIT_IS_SET(cmd->features, TX_UDP_TNL, active);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virNetDevGetFeatures:
|
* virNetDevGetFeatures:
|
||||||
* This function gets the nic offloads features available for ifname
|
* This function gets the nic offloads features available for ifname
|
||||||
@ -3013,7 +3126,9 @@ virNetDevGetFeatures(const char *ifname,
|
|||||||
{
|
{
|
||||||
size_t i = -1;
|
size_t i = -1;
|
||||||
struct ethtool_value cmd = { 0 };
|
struct ethtool_value cmd = { 0 };
|
||||||
|
# if HAVE_DECL_ETHTOOL_GFEATURES
|
||||||
|
struct ethtool_gfeatures g_cmd = { 0 };
|
||||||
|
# endif
|
||||||
struct elem{
|
struct elem{
|
||||||
const int cmd;
|
const int cmd;
|
||||||
const virNetDevFeature feat;
|
const virNetDevFeature feat;
|
||||||
@ -3069,6 +3184,15 @@ virNetDevGetFeatures(const char *ifname,
|
|||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# if HAVE_DECL_ETHTOOL_GFEATURES
|
||||||
|
g_cmd.cmd = ETHTOOL_GFEATURES;
|
||||||
|
g_cmd.size = GFEATURES_SIZE;
|
||||||
|
if (virNetDevGFeatureAvailable(ifname, &g_cmd))
|
||||||
|
ignore_value(virBitmapSetBit(*out, VIR_NET_DEV_FEAT_TXUDPTNL));
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if (virNetDevRDMAFeature(ifname, out))
|
||||||
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -210,6 +210,7 @@ int virNetDevGetRcvAllMulti(const char *ifname, bool *receive)
|
|||||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
|
||||||
|
|
||||||
# define SYSFS_NET_DIR "/sys/class/net/"
|
# define SYSFS_NET_DIR "/sys/class/net/"
|
||||||
|
# define SYSFS_INFINIBAND_DIR "/sys/class/infiniband/"
|
||||||
int virNetDevSysfsFile(char **pf_sysfs_device_link,
|
int virNetDevSysfsFile(char **pf_sysfs_device_link,
|
||||||
const char *ifname,
|
const char *ifname,
|
||||||
const char *file)
|
const char *file)
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
<feature name='rxvlan'/>
|
<feature name='rxvlan'/>
|
||||||
<feature name='txvlan'/>
|
<feature name='txvlan'/>
|
||||||
<feature name='rxhash'/>
|
<feature name='rxhash'/>
|
||||||
|
<feature name='rdma'/>
|
||||||
|
<feature name='txudptnl'/>
|
||||||
<capability type='80211'/>
|
<capability type='80211'/>
|
||||||
</capability>
|
</capability>
|
||||||
</device>
|
</device>
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
<feature name='rxvlan'/>
|
<feature name='rxvlan'/>
|
||||||
<feature name='txvlan'/>
|
<feature name='txvlan'/>
|
||||||
<feature name='rxhash'/>
|
<feature name='rxhash'/>
|
||||||
|
<feature name='rdma'/>
|
||||||
|
<feature name='txudptnl'/>
|
||||||
<capability type='80203'/>
|
<capability type='80203'/>
|
||||||
</capability>
|
</capability>
|
||||||
</device>
|
</device>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user