summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2017-04-14 23:03:33 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2017-04-18 23:28:59 +0200
commit2511e27e7673db2fa070395476aec93d54d7f148 (patch)
tree532b966778c73b51e2b674313b1ffe449817d016 /src
parent785b51ed0236b0edcd61c91f9bf3c00d180a9134 (diff)
downloadNetworkManager-2511e27e7673db2fa070395476aec93d54d7f148.tar.gz
platform: detect SR-IOV support and allow changing the number of VFs
(cherry picked from commit 0a7694cf81d27cd3e73295372065f46a4765f3a1)
Diffstat (limited to 'src')
-rw-r--r--src/platform/nm-fake-platform.c24
-rw-r--r--src/platform/nm-linux-platform.c91
-rw-r--r--src/platform/nm-platform.c24
-rw-r--r--src/platform/nm-platform.h4
4 files changed, 143 insertions, 0 deletions
diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c
index 42979ed209..38706f3796 100644
--- a/src/platform/nm-fake-platform.c
+++ b/src/platform/nm-fake-platform.c
@@ -573,6 +573,12 @@ link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu)
return !!device;
}
+static gboolean
+link_set_sriov_num_vfs (NMPlatform *platform, int ifindex, guint num_vfs)
+{
+ return TRUE;
+}
+
static const char *
link_get_udi (NMPlatform *platform, int ifindex)
{
@@ -633,6 +639,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
link_enslave (NMPlatform *platform, int master, int slave)
{
NMFakePlatformLink *device = link_get (platform, slave);
@@ -1470,11 +1492,13 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass)
platform_class->link_set_address = link_set_address;
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_supports_carrier_detect = link_supports_carrier_detect;
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_release = link_release;
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 251bc17f92..93264809be 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -4604,6 +4604,30 @@ link_supports_vlans (NMPlatform *platform, int 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
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);
}
+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 *
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_get_permanent_address = link_get_permanent_address;
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_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_vlans = link_supports_vlans;
+ platform_class->link_supports_sriov = link_supports_sriov;
platform_class->link_enslave = link_enslave;
platform_class->link_release = link_release;
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 334b94d411..7ef22ad5ab 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -1179,6 +1179,30 @@ nm_platform_link_supports_vlans (NMPlatform *self, int 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:
* @self: platform instance
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index 202cbe5c59..f1679fd113 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -575,6 +575,7 @@ typedef struct {
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_sriov_num_vfs) (NMPlatform *, int ifindex, guint num_vfs);
char * (*link_get_physical_port_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_vlans) (NMPlatform *, int ifindex);
+ gboolean (*link_supports_sriov) (NMPlatform *, int ifindex);
gboolean (*link_enslave) (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);
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_sriov_num_vfs (NMPlatform *self, int ifindex, guint num_vfs);
char *nm_platform_link_get_physical_port_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_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_release (NMPlatform *self, int master, int slave);