diff options
Diffstat (limited to 'src/platform')
-rw-r--r-- | src/platform/nm-fake-platform.c | 24 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.c | 91 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 24 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 4 |
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); |