platform: detect SR-IOV support and allow changing the number of VFs
(cherry picked from commit 0a7694cf81
)
This commit is contained in:
@@ -573,6 +573,12 @@ link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu)
|
|||||||
return !!device;
|
return !!device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
link_set_sriov_num_vfs (NMPlatform *platform, int ifindex, guint num_vfs)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
link_get_udi (NMPlatform *platform, int ifindex)
|
link_get_udi (NMPlatform *platform, int ifindex)
|
||||||
{
|
{
|
||||||
@@ -632,6 +638,22 @@ link_supports_vlans (NMPlatform *platform, int ifindex)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
link_supports_sriov (NMPlatform *platform, int ifindex)
|
||||||
|
{
|
||||||
|
NMFakePlatformLink *device = link_get (platform, ifindex);
|
||||||
|
|
||||||
|
if (!device)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
switch (device->link.type) {
|
||||||
|
case NM_LINK_TYPE_LOOPBACK:
|
||||||
|
return FALSE;
|
||||||
|
default:
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
link_enslave (NMPlatform *platform, int master, int slave)
|
link_enslave (NMPlatform *platform, int master, int slave)
|
||||||
{
|
{
|
||||||
@@ -1470,11 +1492,13 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass)
|
|||||||
|
|
||||||
platform_class->link_set_address = link_set_address;
|
platform_class->link_set_address = link_set_address;
|
||||||
platform_class->link_set_mtu = link_set_mtu;
|
platform_class->link_set_mtu = link_set_mtu;
|
||||||
|
platform_class->link_set_sriov_num_vfs = link_set_sriov_num_vfs;
|
||||||
|
|
||||||
platform_class->link_get_driver_info = link_get_driver_info;
|
platform_class->link_get_driver_info = link_get_driver_info;
|
||||||
|
|
||||||
platform_class->link_supports_carrier_detect = link_supports_carrier_detect;
|
platform_class->link_supports_carrier_detect = link_supports_carrier_detect;
|
||||||
platform_class->link_supports_vlans = link_supports_vlans;
|
platform_class->link_supports_vlans = link_supports_vlans;
|
||||||
|
platform_class->link_supports_sriov = link_supports_sriov;
|
||||||
|
|
||||||
platform_class->link_enslave = link_enslave;
|
platform_class->link_enslave = link_enslave;
|
||||||
platform_class->link_release = link_release;
|
platform_class->link_release = link_release;
|
||||||
|
@@ -4604,6 +4604,30 @@ link_supports_vlans (NMPlatform *platform, int ifindex)
|
|||||||
return nmp_utils_ethtool_supports_vlans (ifindex);
|
return nmp_utils_ethtool_supports_vlans (ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
link_supports_sriov (NMPlatform *platform, int ifindex)
|
||||||
|
{
|
||||||
|
nm_auto_pop_netns NMPNetns *netns = NULL;
|
||||||
|
nm_auto_close int dirfd = -1;
|
||||||
|
char ifname[IFNAMSIZ];
|
||||||
|
int total = -1;
|
||||||
|
|
||||||
|
if (!nm_platform_netns_push (platform, &netns))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
dirfd = nm_platform_sysctl_open_netdir (platform, ifindex, ifname);
|
||||||
|
if (dirfd < 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
total = nm_platform_sysctl_get_int32 (platform,
|
||||||
|
NMP_SYSCTL_PATHID_NETDIR (dirfd,
|
||||||
|
ifname,
|
||||||
|
"device/sriov_totalvfs"),
|
||||||
|
-1);
|
||||||
|
|
||||||
|
return total > 0;
|
||||||
|
}
|
||||||
|
|
||||||
static NMPlatformError
|
static NMPlatformError
|
||||||
link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size_t length)
|
link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size_t length)
|
||||||
{
|
{
|
||||||
@@ -4695,6 +4719,71 @@ nla_put_failure:
|
|||||||
g_return_val_if_reached (FALSE);
|
g_return_val_if_reached (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
link_set_sriov_num_vfs (NMPlatform *platform, int ifindex, guint num_vfs)
|
||||||
|
{
|
||||||
|
nm_auto_pop_netns NMPNetns *netns = NULL;
|
||||||
|
nm_auto_close int dirfd = -1;
|
||||||
|
int total, current;
|
||||||
|
char ifname[IFNAMSIZ];
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
_LOGD ("link: change %d: num VFs: %u", ifindex, num_vfs);
|
||||||
|
|
||||||
|
if (!nm_platform_netns_push (platform, &netns))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
dirfd = nm_platform_sysctl_open_netdir (platform, ifindex, ifname);
|
||||||
|
if (!dirfd)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
total = nm_platform_sysctl_get_int32 (platform,
|
||||||
|
NMP_SYSCTL_PATHID_NETDIR (dirfd,
|
||||||
|
ifname,
|
||||||
|
"device/sriov_totalvfs"),
|
||||||
|
-1);
|
||||||
|
if (total < 1)
|
||||||
|
return FALSE;
|
||||||
|
if (num_vfs > total) {
|
||||||
|
_LOGW ("link: %d only supports %u VFs (requested %u)", ifindex, total, num_vfs);
|
||||||
|
num_vfs = total;
|
||||||
|
}
|
||||||
|
|
||||||
|
current = nm_platform_sysctl_get_int32 (platform,
|
||||||
|
NMP_SYSCTL_PATHID_NETDIR (dirfd,
|
||||||
|
ifname,
|
||||||
|
"device/sriov_numvfs"),
|
||||||
|
-1);
|
||||||
|
if (current == num_vfs)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (current != 0) {
|
||||||
|
/* We need to destroy all other VFs before changing the value */
|
||||||
|
if (!nm_platform_sysctl_set (NM_PLATFORM_GET,
|
||||||
|
NMP_SYSCTL_PATHID_NETDIR (dirfd,
|
||||||
|
ifname,
|
||||||
|
"device/sriov_numvfs"),
|
||||||
|
"0")) {
|
||||||
|
_LOGW ("link: couldn't set SR-IOV num_vfs to %d: %s", 0, strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (num_vfs == 0)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finally, set the desired value */
|
||||||
|
if (!nm_platform_sysctl_set (NM_PLATFORM_GET,
|
||||||
|
NMP_SYSCTL_PATHID_NETDIR (dirfd,
|
||||||
|
ifname,
|
||||||
|
"device/sriov_numvfs"),
|
||||||
|
nm_sprintf_buf (buf, "%d", num_vfs))) {
|
||||||
|
_LOGW ("link: couldn't set SR-IOV num_vfs to %d: %s", num_vfs, strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
link_get_physical_port_id (NMPlatform *platform, int ifindex)
|
link_get_physical_port_id (NMPlatform *platform, int ifindex)
|
||||||
{
|
{
|
||||||
@@ -6845,6 +6934,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
|
|||||||
platform_class->link_set_address = link_set_address;
|
platform_class->link_set_address = link_set_address;
|
||||||
platform_class->link_get_permanent_address = link_get_permanent_address;
|
platform_class->link_get_permanent_address = link_get_permanent_address;
|
||||||
platform_class->link_set_mtu = link_set_mtu;
|
platform_class->link_set_mtu = link_set_mtu;
|
||||||
|
platform_class->link_set_sriov_num_vfs = link_set_sriov_num_vfs;
|
||||||
|
|
||||||
platform_class->link_get_physical_port_id = link_get_physical_port_id;
|
platform_class->link_get_physical_port_id = link_get_physical_port_id;
|
||||||
platform_class->link_get_dev_id = link_get_dev_id;
|
platform_class->link_get_dev_id = link_get_dev_id;
|
||||||
@@ -6853,6 +6943,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
|
|||||||
|
|
||||||
platform_class->link_supports_carrier_detect = link_supports_carrier_detect;
|
platform_class->link_supports_carrier_detect = link_supports_carrier_detect;
|
||||||
platform_class->link_supports_vlans = link_supports_vlans;
|
platform_class->link_supports_vlans = link_supports_vlans;
|
||||||
|
platform_class->link_supports_sriov = link_supports_sriov;
|
||||||
|
|
||||||
platform_class->link_enslave = link_enslave;
|
platform_class->link_enslave = link_enslave;
|
||||||
platform_class->link_release = link_release;
|
platform_class->link_release = link_release;
|
||||||
|
@@ -1179,6 +1179,30 @@ nm_platform_link_supports_vlans (NMPlatform *self, int ifindex)
|
|||||||
return klass->link_supports_vlans (self, ifindex);
|
return klass->link_supports_vlans (self, ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
nm_platform_link_supports_sriov (NMPlatform *self, int ifindex)
|
||||||
|
{
|
||||||
|
_CHECK_SELF (self, klass, FALSE);
|
||||||
|
|
||||||
|
g_return_val_if_fail (ifindex >= 0, FALSE);
|
||||||
|
|
||||||
|
return klass->link_supports_sriov (self, ifindex);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
nm_platform_link_set_sriov_num_vfs (NMPlatform *self, int ifindex, guint num_vfs)
|
||||||
|
{
|
||||||
|
_CHECK_SELF (self, klass, FALSE);
|
||||||
|
|
||||||
|
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||||
|
|
||||||
|
_LOGD ("link: setting %u VFs for %s (%d)",
|
||||||
|
num_vfs,
|
||||||
|
nm_strquote_a (25, nm_platform_link_get_name (self, ifindex)),
|
||||||
|
ifindex);
|
||||||
|
return klass->link_set_sriov_num_vfs (self, ifindex, num_vfs);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_platform_link_set_up:
|
* nm_platform_link_set_up:
|
||||||
* @self: platform instance
|
* @self: platform instance
|
||||||
|
@@ -575,6 +575,7 @@ typedef struct {
|
|||||||
size_t *length);
|
size_t *length);
|
||||||
NMPlatformError (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length);
|
NMPlatformError (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length);
|
||||||
gboolean (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu);
|
gboolean (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu);
|
||||||
|
gboolean (*link_set_sriov_num_vfs) (NMPlatform *, int ifindex, guint num_vfs);
|
||||||
|
|
||||||
char * (*link_get_physical_port_id) (NMPlatform *, int ifindex);
|
char * (*link_get_physical_port_id) (NMPlatform *, int ifindex);
|
||||||
guint (*link_get_dev_id) (NMPlatform *, int ifindex);
|
guint (*link_get_dev_id) (NMPlatform *, int ifindex);
|
||||||
@@ -587,6 +588,7 @@ typedef struct {
|
|||||||
|
|
||||||
gboolean (*link_supports_carrier_detect) (NMPlatform *, int ifindex);
|
gboolean (*link_supports_carrier_detect) (NMPlatform *, int ifindex);
|
||||||
gboolean (*link_supports_vlans) (NMPlatform *, int ifindex);
|
gboolean (*link_supports_vlans) (NMPlatform *, int ifindex);
|
||||||
|
gboolean (*link_supports_sriov) (NMPlatform *, int ifindex);
|
||||||
|
|
||||||
gboolean (*link_enslave) (NMPlatform *, int master, int slave);
|
gboolean (*link_enslave) (NMPlatform *, int master, int slave);
|
||||||
gboolean (*link_release) (NMPlatform *, int master, int slave);
|
gboolean (*link_release) (NMPlatform *, int master, int slave);
|
||||||
@@ -825,6 +827,7 @@ gboolean nm_platform_link_set_ipv6_token (NMPlatform *self, int ifindex, NMUtils
|
|||||||
gboolean nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex, guint8 *buf, size_t *length);
|
gboolean nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex, guint8 *buf, size_t *length);
|
||||||
NMPlatformError nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length);
|
NMPlatformError nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length);
|
||||||
gboolean nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu);
|
gboolean nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu);
|
||||||
|
gboolean nm_platform_link_set_sriov_num_vfs (NMPlatform *self, int ifindex, guint num_vfs);
|
||||||
|
|
||||||
char *nm_platform_link_get_physical_port_id (NMPlatform *self, int ifindex);
|
char *nm_platform_link_get_physical_port_id (NMPlatform *self, int ifindex);
|
||||||
guint nm_platform_link_get_dev_id (NMPlatform *self, int ifindex);
|
guint nm_platform_link_get_dev_id (NMPlatform *self, int ifindex);
|
||||||
@@ -837,6 +840,7 @@ gboolean nm_platform_link_get_driver_info (NMPlatform *self,
|
|||||||
|
|
||||||
gboolean nm_platform_link_supports_carrier_detect (NMPlatform *self, int ifindex);
|
gboolean nm_platform_link_supports_carrier_detect (NMPlatform *self, int ifindex);
|
||||||
gboolean nm_platform_link_supports_vlans (NMPlatform *self, int ifindex);
|
gboolean nm_platform_link_supports_vlans (NMPlatform *self, int ifindex);
|
||||||
|
gboolean nm_platform_link_supports_sriov (NMPlatform *self, int ifindex);
|
||||||
|
|
||||||
gboolean nm_platform_link_enslave (NMPlatform *self, int master, int slave);
|
gboolean nm_platform_link_enslave (NMPlatform *self, int master, int slave);
|
||||||
gboolean nm_platform_link_release (NMPlatform *self, int master, int slave);
|
gboolean nm_platform_link_release (NMPlatform *self, int master, int slave);
|
||||||
|
Reference in New Issue
Block a user