summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2018-05-24 17:32:37 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2018-07-11 16:16:22 +0200
commitc02d1c488f69ed6183cb86c80a771c902ea5e397 (patch)
treed668a75734135d812babb447c59a10818344406f
parent53c2951f61fa9a11efeb36bbebff88e62297ea15 (diff)
downloadNetworkManager-c02d1c488f69ed6183cb86c80a771c902ea5e397.tar.gz
ifcfg-rh: SR-IOV support
-rw-r--r--Makefile.am2
-rw-r--r--libnm-core/nm-setting-sriov.c22
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c67
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c41
-rw-r--r--src/settings/plugins/ifcfg-rh/shvar.c4
-rw-r--r--src/settings/plugins/ifcfg-rh/shvar.h1
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sriov19
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sriov-write.cexpected18
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c150
9 files changed, 324 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index ab9f649a85..45074fa1e7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2303,6 +2303,8 @@ EXTRA_DIST += \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-permissions \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-read-proxy-basic \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sit-ignore \
+ src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sriov \
+ src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sriov-write.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-static-routes-legacy \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-static-routes-legacy.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-tc \
diff --git a/libnm-core/nm-setting-sriov.c b/libnm-core/nm-setting-sriov.c
index 45608f9dc8..29161c8cd9 100644
--- a/libnm-core/nm-setting-sriov.c
+++ b/libnm-core/nm-setting-sriov.c
@@ -1250,6 +1250,13 @@ nm_setting_sriov_class_init (NMSettingSriovClass *setting_class)
*
* Since: 1.14
**/
+ /* ---ifcfg-rh---
+ * property: total-vfs
+ * variable: SRIOV_TOTAL_VFS(+)
+ * description: The total number of virtual functions to create
+ * example: SRIOV_TOTAL_VFS=16
+ * ---end---
+ */
g_object_class_install_property
(object_class, PROP_TOTAL_VFS,
g_param_spec_uint (NM_SETTING_SRIOV_TOTAL_VFS, "", "",
@@ -1286,6 +1293,13 @@ nm_setting_sriov_class_init (NMSettingSriovClass *setting_class)
*
* Since: 1.14
**/
+ /* ---ifcfg-rh---
+ * property: vfs
+ * variable: SRIOV_VF1(+), SRIOV_VF2(+), ...
+ * description: SR-IOV virtual function descriptors
+ * example: SRIOV_VF10="mac=00:11:22:33:44:55", ...
+ * ---end---
+ */
g_object_class_install_property
(object_class, PROP_VFS,
g_param_spec_boxed (NM_SETTING_SRIOV_VFS, "", "",
@@ -1319,6 +1333,14 @@ nm_setting_sriov_class_init (NMSettingSriovClass *setting_class)
*
* Since: 1.14
**/
+ /* ---ifcfg-rh---
+ * property: autoprobe-drivers
+ * variable: SRIOV_AUTOPROBE_DRIVERS(+)
+ * default: missing variable means global default
+ * description: Whether to autoprobe virtual functions by a compatible driver
+ * example: SRIOV_AUTOPROBE_DRIVERS=0,1
+ * ---end---
+ */
g_object_class_install_property
(object_class, PROP_AUTOPROBE_DRIVERS,
g_param_spec_enum (NM_SETTING_SRIOV_AUTOPROBE_DRIVERS, "", "",
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
index 882932b11a..5cea628013 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
@@ -1979,6 +1979,68 @@ error:
}
static NMSetting *
+make_sriov_setting (shvarFile *ifcfg)
+{
+ gs_unref_hashtable GHashTable *keys = NULL;
+ gs_unref_ptrarray GPtrArray *vfs = NULL;
+ NMTernary autoprobe_drivers;
+ NMSettingSriov *s_sriov;
+ int total_vfs;
+
+ total_vfs = svGetValueInt64 (ifcfg, "SRIOV_TOTAL_VFS", 10, 0, G_MAXINT32, 0);
+ if (!total_vfs)
+ return NULL;
+
+ autoprobe_drivers = svGetValueInt64 (ifcfg,
+ "SRIOV_AUTOPROBE_DRIVERS",
+ 10,
+ NM_TERNARY_FALSE,
+ NM_TERNARY_TRUE,
+ NM_TERNARY_DEFAULT);
+
+ keys = svGetKeys (ifcfg, SV_KEY_TYPE_SRIOV_VF);
+ if (keys) {
+ GHashTableIter iter;
+ const char *key;
+
+ g_hash_table_iter_init (&iter, keys);
+ while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL)) {
+ gs_free_error GError *error = NULL;
+ gs_free char *value_to_free = NULL;
+ const char *value;
+ NMSriovVF *vf;
+
+ nm_assert (g_str_has_prefix (key, "SRIOV_VF"));
+
+ value = svGetValue (ifcfg, key, &value_to_free);
+ if (!value)
+ continue;
+
+ key += NM_STRLEN ("SRIOV_VF");
+
+ vf = _nm_utils_sriov_vf_from_strparts (key, value, &error);
+ if (!vf) {
+ PARSE_WARNING ("ignoring invalid SR-IOV VF '%s %s': %s",
+ key, value, error->message);
+ continue;
+ }
+ if (!vfs)
+ vfs = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_sriov_vf_unref);
+ g_ptr_array_add (vfs, vf);
+ }
+ }
+
+ s_sriov = (NMSettingSriov *) nm_setting_sriov_new ();
+ g_object_set (s_sriov,
+ NM_SETTING_SRIOV_TOTAL_VFS, total_vfs,
+ NM_SETTING_SRIOV_VFS, vfs,
+ NM_SETTING_SRIOV_AUTOPROBE_DRIVERS, (int) autoprobe_drivers,
+ NULL);
+
+ return (NMSetting *) s_sriov;
+}
+
+static NMSetting *
make_tc_setting (shvarFile *ifcfg)
{
NMSettingTCConfig *s_tc = NULL;
@@ -5324,6 +5386,7 @@ connection_from_file_full (const char *filename,
gs_free char *type = NULL;
char *devtype, *bootproto;
NMSetting *s_ip4, *s_ip6, *s_tc, *s_proxy, *s_port, *s_dcb = NULL, *s_user;
+ NMSetting *s_sriov;
const char *ifcfg_name = NULL;
gboolean has_ip4_defroute = FALSE;
gboolean has_complex_routes_v4;
@@ -5579,6 +5642,10 @@ connection_from_file_full (const char *filename,
nm_connection_add_setting (connection, s_ip4);
}
+ s_sriov = make_sriov_setting (parsed);
+ if (s_sriov)
+ nm_connection_add_setting (connection, s_sriov);
+
s_tc = make_tc_setting (parsed);
if (s_tc)
nm_connection_add_setting (connection, s_tc);
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
index 8921646597..ab1938f180 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
@@ -2135,6 +2135,45 @@ write_user_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
return TRUE;
}
+static void
+write_sriov_setting (NMConnection *connection, shvarFile *ifcfg)
+{
+ NMSettingSriov *s_sriov;
+ guint i, num = 0;
+ NMTernary b;
+ NMSriovVF *vf;
+ char key[32];
+ char *str;
+
+ svUnsetAll (ifcfg, SV_KEY_TYPE_SRIOV_VF);
+
+ s_sriov = nm_connection_get_setting_sriov (connection);
+ if (s_sriov)
+ num = nm_setting_sriov_get_total_vfs (s_sriov);
+ if (num == 0) {
+ svUnsetValue (ifcfg, "SRIOV_TOTAL_VFS");
+ svUnsetValue (ifcfg, "SRIOV_AUTOPROBE_DRIVERS");
+ return;
+ }
+
+ svSetValueInt64 (ifcfg, "SRIOV_TOTAL_VFS", num);
+
+ b = nm_setting_sriov_get_autoprobe_drivers (s_sriov);
+ if (b != NM_TERNARY_DEFAULT)
+ svSetValueInt64 (ifcfg, "SRIOV_AUTOPROBE_DRIVERS", b);
+ else
+ svUnsetValue (ifcfg, "SRIOV_AUTOPROBE_DRIVERS");
+
+ num = nm_setting_sriov_get_num_vfs (s_sriov);
+ for (i = 0; i < num; i++) {
+ vf = nm_setting_sriov_get_vf (s_sriov, i);
+ nm_sprintf_buf (key, "SRIOV_VF%u", nm_sriov_vf_get_index (vf));
+ str = nm_utils_sriov_vf_to_str (vf, TRUE, NULL);
+ svSetValueStr (ifcfg, key, str);
+ g_free (str);
+ }
+}
+
static gboolean
write_tc_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
{
@@ -2921,6 +2960,8 @@ do_write_construct (NMConnection *connection,
if (!write_user_setting (connection, ifcfg, error))
return FALSE;
+ write_sriov_setting (connection, ifcfg);
+
if (!write_tc_setting (connection, ifcfg, error))
return FALSE;
diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c
index e8d028094b..f09bc2472f 100644
--- a/src/settings/plugins/ifcfg-rh/shvar.c
+++ b/src/settings/plugins/ifcfg-rh/shvar.c
@@ -915,6 +915,10 @@ _svKeyMatchesType (const char *key, SvKeyType match_key_type)
|| IS_NUMBERED_TAG (key, "FILTER"))
return TRUE;
}
+ if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_SRIOV_VF)) {
+ if (IS_NUMBERED_TAG (key, "SRIOV_VF"))
+ return TRUE;
+ }
return FALSE;
}
diff --git a/src/settings/plugins/ifcfg-rh/shvar.h b/src/settings/plugins/ifcfg-rh/shvar.h
index bef5f47743..622bb474b1 100644
--- a/src/settings/plugins/ifcfg-rh/shvar.h
+++ b/src/settings/plugins/ifcfg-rh/shvar.h
@@ -39,6 +39,7 @@ typedef enum {
SV_KEY_TYPE_IP4_ADDRESS = (1LL << 2),
SV_KEY_TYPE_TC = (1LL << 3),
SV_KEY_TYPE_USER = (1LL << 4),
+ SV_KEY_TYPE_SRIOV_VF = (1LL << 5),
} SvKeyType;
const char *svFileGetName (const shvarFile *s);
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sriov b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sriov
new file mode 100644
index 0000000000..142f56e434
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sriov
@@ -0,0 +1,19 @@
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:55
+BOOTPROTO=none
+ONBOOT=yes
+DNS1=4.2.2.1
+DNS2=4.2.2.2
+IPADDR=192.168.1.5
+PREFIX=24
+NETMASK=255.255.255.0
+GATEWAY=192.168.1.1
+IPV6INIT=no
+NAME=ethernet-sriov
+UUID=acc703b8-e751-44ce-b456-1550bdf2057e
+SRIOV_TOTAL_VFS=16
+SRIOV_AUTOPROBE_DRIVERS=0
+SRIOV_VF15="max-tx-rate=200 mac=01:23:45:67:89:ab vlans=2"
+SRIOV_VF12="trust=false min-tx-rate=100 vlans=1.200.ad"
+SRIOV_VF3="mac=55:44:33:22:11:00 spoof-check=true"
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sriov-write.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sriov-write.cexpected
new file mode 100644
index 0000000000..c882c4796e
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sriov-write.cexpected
@@ -0,0 +1,18 @@
+TYPE=Ethernet
+PROXY_METHOD=none
+BROWSER_ONLY=no
+SRIOV_TOTAL_VFS=64
+SRIOV_AUTOPROBE_DRIVERS=1
+SRIOV_VF2="mac=55:55:55:55:55:55 vlans=3.10.ad;10"
+SRIOV_VF19=spoof-check=true
+BOOTPROTO=none
+IPADDR=1.1.1.3
+PREFIX=24
+GATEWAY=1.1.1.1
+DEFROUTE=yes
+IPV4_FAILURE_FATAL=no
+IPV6INIT=no
+NAME="Test Write SR-IOV config"
+UUID=${UUID}
+DEVICE=eth0
+ONBOOT=yes
diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
index 1331391dc2..8d4efbbfd1 100644
--- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
+++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
@@ -9632,6 +9632,153 @@ test_utils_ignore (void)
do_test_utils_ignored ("ignored-augtmp", "ifcfg-FooBar" AUGTMP_TAG, TRUE);
}
+/*****************************************************************************/
+
+static void
+test_sriov_read (void)
+{
+ gs_unref_object NMConnection *connection = NULL;
+ NMSettingSriov *s_sriov;
+ NMSriovVF *vf;
+ GVariant *variant;
+ GError *error = NULL;
+ char *str;
+
+ connection = _connection_from_file (TEST_IFCFG_DIR "/ifcfg-test-sriov",
+ NULL, TYPE_ETHERNET,NULL);
+
+ g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "eth0");
+
+ s_sriov = nm_connection_get_setting_sriov (connection);
+ g_assert (s_sriov);
+
+ g_assert_cmpint (nm_setting_sriov_get_total_vfs (s_sriov), ==, 16);
+ g_assert_cmpint (nm_setting_sriov_get_num_vfs (s_sriov), ==, 3);
+ g_assert_cmpint (nm_setting_sriov_get_autoprobe_drivers (s_sriov), ==, NM_TERNARY_FALSE);
+
+ /* VF 3 */
+ vf = nm_setting_sriov_get_vf (s_sriov, 0);
+ g_assert (vf);
+ g_assert_cmpint (nm_sriov_vf_get_index (vf), ==, 3);
+
+ variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_MAC);
+ g_assert (variant);
+ g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING));
+ g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "55:44:33:22:11:00");
+
+ variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_SPOOF_CHECK);
+ g_assert (variant);
+ g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN));
+ g_assert_cmpint (g_variant_get_boolean (variant), ==, TRUE);
+
+ /* VF 12 */
+ vf = nm_setting_sriov_get_vf (s_sriov, 1);
+ str = nm_utils_sriov_vf_to_str (vf, FALSE, &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (str, ==, "12 min-tx-rate=100 trust=false vlans=1.200.ad");
+ g_free (str);
+
+ /* VF 15 */
+ vf = nm_setting_sriov_get_vf (s_sriov, 2);
+ str = nm_utils_sriov_vf_to_str (vf, FALSE, &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (str, ==, "15 mac=01:23:45:67:89:ab max-tx-rate=200 vlans=2");
+ g_free (str);
+}
+
+static void
+test_sriov_write (void)
+{
+ nmtst_auto_unlinkfile char *testfile = NULL;
+ gs_unref_object NMConnection *connection = NULL;
+ gs_unref_object NMConnection *reread = NULL;
+ NMSettingConnection *s_con;
+ NMSettingIPConfig *s_ip4;
+ NMSettingIPConfig *s_ip6;
+ NMSettingWired *s_wired;
+ NMSettingSriov *s_sriov;
+ NMSriovVF *vf;
+ gs_unref_ptrarray GPtrArray *vfs = NULL;
+ NMIPAddress *addr;
+ GError *error = NULL;
+
+ connection = nm_simple_connection_new ();
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write SR-IOV config",
+ NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (),
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_INTERFACE_NAME, "eth0",
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+ NULL);
+
+ /* Wired setting */
+ s_wired = (NMSettingWired *) nm_setting_wired_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
+ NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1",
+ NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
+ NULL);
+
+ addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error);
+ g_assert_no_error (error);
+ nm_setting_ip_config_add_address (s_ip4, addr);
+ nm_ip_address_unref (addr);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6,
+ NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
+ NULL);
+
+ /* SRIOV setting */
+ s_sriov = (NMSettingSriov *) nm_setting_sriov_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_sriov));
+
+ vfs = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_sriov_vf_unref);
+
+ vf = nm_utils_sriov_vf_from_str ("2 mac=55:55:55:55:55:55 vlans=3.10.ad;10", &error);
+ nmtst_assert_success (vf, error);
+ g_ptr_array_add (vfs, vf);
+
+ vf = nm_utils_sriov_vf_from_str ("19 spoof-check=true", &error);
+ nmtst_assert_success (vf, error);
+ g_ptr_array_add (vfs, vf);
+
+ g_object_set (s_sriov,
+ NM_SETTING_SRIOV_TOTAL_VFS, 64,
+ NM_SETTING_SRIOV_VFS, vfs,
+ NM_SETTING_SRIOV_AUTOPROBE_DRIVERS, NM_TERNARY_TRUE,
+ NULL);
+
+ nm_connection_add_setting (connection, nm_setting_proxy_new ());
+
+ nmtst_assert_connection_verifies_without_normalization (connection);
+
+ _writer_new_connec_exp (connection,
+ TEST_SCRATCH_DIR,
+ TEST_IFCFG_DIR "/ifcfg-test-sriov-write.cexpected",
+ &testfile);
+
+ reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL);
+
+ nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);
+}
+
+/*****************************************************************************/
+
static void
test_tc_read (void)
{
@@ -10033,6 +10180,9 @@ int main (int argc, char **argv)
g_test_add_func (TPATH "utils/path", test_utils_path);
g_test_add_func (TPATH "utils/ignore", test_utils_ignore);
+ g_test_add_func (TPATH "sriov/read", test_sriov_read);
+ g_test_add_func (TPATH "sriov/write", test_sriov_write);
+
g_test_add_func (TPATH "tc/read", test_tc_read);
g_test_add_func (TPATH "tc/write", test_tc_write);