summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2018-05-22 10:48:11 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2018-07-11 16:16:22 +0200
commit53c2951f61fa9a11efeb36bbebff88e62297ea15 (patch)
tree25117fe1363b7e0c9eec43ede3a2ae560ac13c6b
parent8720dd3df1d9970684fca07bc62f3341988a77bd (diff)
downloadNetworkManager-53c2951f61fa9a11efeb36bbebff88e62297ea15.tar.gz
device: configure SR-IOV
-rw-r--r--clients/common/nm-client-utils.c1
-rw-r--r--libnm-core/nm-dbus-interface.h2
-rw-r--r--man/NetworkManager.conf.xml4
-rw-r--r--src/devices/nm-device.c138
4 files changed, 142 insertions, 3 deletions
diff --git a/clients/common/nm-client-utils.c b/clients/common/nm-client-utils.c
index 058ddae39a..2e3d45ca38 100644
--- a/clients/common/nm-client-utils.c
+++ b/clients/common/nm-client-utils.c
@@ -351,6 +351,7 @@ NM_UTILS_LOOKUP_STR_DEFINE (nmc_device_reason_to_string, NMDeviceStateReason,
NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_OVSDB_FAILED, N_("OpenVSwitch database connection failed")),
NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE, N_("A duplicate IP address was detected")),
NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED, N_("The selected IP method is not supported")),
+ NM_UTILS_LOOKUP_ITEM (NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED, N_("Failed to configure SR-IOV parameters")),
)
NM_UTILS_LOOKUP_STR_DEFINE (nm_active_connection_state_reason_to_string, NMActiveConnectionStateReason,
diff --git a/libnm-core/nm-dbus-interface.h b/libnm-core/nm-dbus-interface.h
index 0b451d8446..388898dd96 100644
--- a/libnm-core/nm-dbus-interface.h
+++ b/libnm-core/nm-dbus-interface.h
@@ -559,6 +559,7 @@ typedef enum {
* @NM_DEVICE_STATE_REASON_OVSDB_FAILED: problem communicating with Open vSwitch database
* @NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE: a duplicate IP address was detected
* @NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED: The selected IP method is not supported
+ * @NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED: configuration of SR-IOV parameters failed
*
* Device state change reason codes
*/
@@ -629,6 +630,7 @@ typedef enum {
NM_DEVICE_STATE_REASON_OVSDB_FAILED = 63,
NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE = 64,
NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED = 65,
+ NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED = 66,
} NMDeviceStateReason;
/**
diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml
index 17bc42f34b..34ab6999d3 100644
--- a/man/NetworkManager.conf.xml
+++ b/man/NetworkManager.conf.xml
@@ -728,6 +728,10 @@ ipv6.ip6-privacy=0
</para></listitem>
</varlistentry>
<varlistentry>
+ <term><varname>sriov.autoprobe-drivers</varname></term>
+ <listitem><para>If left unspecified, drivers are autoprobed when the SR-IOV VF gets created.</para></listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>vpn.timeout</varname></term>
<listitem><para>If left unspecified, default value of 60 seconds is used.</para></listitem>
</varlistentry>
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 8844672ab5..2117985e1b 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -724,6 +724,7 @@ NM_UTILS_LOOKUP_STR_DEFINE (nm_device_state_reason_to_str, NMDeviceStateReason,
NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_OVSDB_FAILED, "ovsdb-failed"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE, "ip-address-duplicate"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED, "ip-method-unsupported"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED, "sriov-configuration-failed"),
);
#define reason_to_string(reason) \
@@ -3937,7 +3938,7 @@ nm_device_update_from_platform_link (NMDevice *self, const NMPlatformLink *plink
}
static void
-device_init_sriov_num_vfs (NMDevice *self)
+device_init_static_sriov_num_vfs (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
gs_free char *value = NULL;
@@ -3971,7 +3972,7 @@ config_changed (NMConfig *config,
priv->ignore_carrier = nm_config_data_get_ignore_carrier (config_data, self);
if (NM_FLAGS_HAS (changes, NM_CONFIG_CHANGE_VALUES))
- device_init_sriov_num_vfs (self);
+ device_init_static_sriov_num_vfs (self);
}
static void
@@ -4115,7 +4116,7 @@ realize_start_setup (NMDevice *self,
nm_device_set_carrier_from_platform (self);
- device_init_sriov_num_vfs (self);
+ device_init_static_sriov_num_vfs (self);
nm_assert (!priv->stats.timeout_id);
real_rate = _stats_refresh_rate_real (priv->stats.refresh_rate_ms);
@@ -5859,9 +5860,140 @@ lldp_rx_enabled (NMDevice *self)
return lldp == NM_SETTING_CONNECTION_LLDP_ENABLE_RX;
}
+static NMPlatformVF *
+sriov_vf_config_to_platform (NMDevice *self,
+ NMSriovVF *vf,
+ GError **error)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ gs_free NMPlatformVF *plat_vf = NULL;
+ const guint *vlan_ids;
+ GVariant *variant;
+ guint i, num_vlans;
+ gsize length;
+
+ g_return_val_if_fail (!error || !*error, FALSE);
+
+ vlan_ids = nm_sriov_vf_get_vlan_ids (vf, &num_vlans);
+ plat_vf = g_malloc0 ( sizeof (NMPlatformVF)
+ + sizeof (NMPlatformVFVlan) * num_vlans);
+
+ plat_vf->index = nm_sriov_vf_get_index (vf);
+
+ variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_SPOOF_CHECK);
+ if (variant)
+ plat_vf->spoofchk = g_variant_get_boolean (variant);
+ else
+ plat_vf->spoofchk = -1;
+
+ variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_TRUST);
+ if (variant)
+ plat_vf->trust = g_variant_get_boolean (variant);
+ else
+ plat_vf->trust = -1;
+
+ variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_MAC);
+ if (variant) {
+ if (!_nm_utils_hwaddr_aton (g_variant_get_string (variant, NULL),
+ plat_vf->mac.data,
+ sizeof (plat_vf->mac.data),
+ &length)) {
+ g_set_error (error,
+ NM_DEVICE_ERROR,
+ NM_DEVICE_ERROR_FAILED,
+ "invalid MAC %s",
+ g_variant_get_string (variant, NULL));
+ return NULL;
+ }
+ if (length != priv->hw_addr_len) {
+ g_set_error (error,
+ NM_DEVICE_ERROR,
+ NM_DEVICE_ERROR_FAILED,
+ "wrong MAC length %" G_GSIZE_FORMAT ", should be %u",
+ length, priv->hw_addr_len);
+ return NULL;
+ }
+ plat_vf->mac.len = length;
+ }
+
+ variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_MIN_TX_RATE);
+ if (variant)
+ plat_vf->min_tx_rate = g_variant_get_uint32 (variant);
+
+ variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_MAX_TX_RATE);
+ if (variant)
+ plat_vf->max_tx_rate = g_variant_get_uint32 (variant);
+
+ plat_vf->num_vlans = num_vlans;
+ plat_vf->vlans = (NMPlatformVFVlan *) (&plat_vf[1]);
+ for (i = 0; i < num_vlans; i++) {
+ plat_vf->vlans[i].id = vlan_ids[i];
+ plat_vf->vlans[i].qos = nm_sriov_vf_get_vlan_qos (vf, vlan_ids[i]);
+ plat_vf->vlans[i].proto_ad = nm_sriov_vf_get_vlan_protocol (vf, vlan_ids[i]) == NM_SRIOV_VF_VLAN_PROTOCOL_802_1AD;
+ }
+
+ return g_steal_pointer (&plat_vf);
+}
+
static NMActStageReturn
act_stage1_prepare (NMDevice *self, NMDeviceStateReason *out_failure_reason)
{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ NMSettingSriov *s_sriov;
+ guint i, num;
+
+ if ( priv->ifindex > 0
+ && nm_device_has_capability (self, NM_DEVICE_CAP_SRIOV)
+ && (s_sriov = (NMSettingSriov *) nm_device_get_applied_setting (self, NM_TYPE_SETTING_SRIOV))) {
+ nm_auto_freev NMPlatformVF **plat_vfs = NULL;
+ gs_free_error GError *error = NULL;
+ gs_free const char *str = NULL;
+ NMSriovVF *vf;
+ int autoprobe;
+
+ autoprobe = nm_setting_sriov_get_autoprobe_drivers (s_sriov);
+ if (autoprobe == NM_TERNARY_DEFAULT) {
+ str = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
+ "sriov.autoprobe-drivers", self);
+ autoprobe = _nm_utils_ascii_str_to_int64 (str, 10,
+ NM_TERNARY_FALSE,
+ NM_TERNARY_TRUE,
+ NM_TERNARY_TRUE);
+ }
+
+ num = nm_setting_sriov_get_num_vfs (s_sriov);
+ plat_vfs = g_new0 (NMPlatformVF *, num + 1);
+ for (i = 0; i < num; i++) {
+ vf = nm_setting_sriov_get_vf (s_sriov, i);
+ plat_vfs[i] = sriov_vf_config_to_platform (self, vf, &error);
+ if (!plat_vfs[i]) {
+ _LOGE (LOGD_DEVICE,
+ "failed to apply SR-IOV VF '%s': %s",
+ nm_utils_sriov_vf_to_str (vf, FALSE, NULL),
+ error->message);
+ NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED);
+ return NM_ACT_STAGE_RETURN_FAILURE;
+ }
+ }
+
+ if (!nm_platform_link_set_sriov_params (nm_device_get_platform (self),
+ priv->ifindex,
+ nm_setting_sriov_get_total_vfs (s_sriov),
+ autoprobe)) {
+ _LOGE (LOGD_DEVICE, "failed to apply SR-IOV parameters");
+ NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED);
+ return NM_ACT_STAGE_RETURN_FAILURE;
+ }
+
+ if (!nm_platform_link_set_sriov_vfs (nm_device_get_platform (self),
+ priv->ifindex,
+ (const NMPlatformVF *const *) plat_vfs)) {
+ _LOGE (LOGD_DEVICE, "failed to apply SR-IOV VFs");
+ NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED);
+ return NM_ACT_STAGE_RETURN_FAILURE;
+ }
+ }
+
return NM_ACT_STAGE_RETURN_SUCCESS;
}