diff options
author | Thomas Haller <thaller@redhat.com> | 2023-05-24 17:32:19 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2023-05-25 22:25:10 +0200 |
commit | 30f0429d129f7fff736ed600c47e4ad1288e7146 (patch) | |
tree | b0f8973826de523bdfe96117eaa7791286a8ec9a | |
parent | 2945254e29c58839410127e695e0216763a3dd01 (diff) |
libnm: normalize interface-name for infiniband profiles
NetworkManager does not support changing the interface name for
infiniband interfaces. Consequently, we verify that
"connection.interface-name" is either unset or set to the expected
"$parent.$p_key". Anything else wouldn't work anyway and is rejected as
invalid configuration. That brings problems however.
Rejecting invalid configuration seems fine at first:
$ nmcli --offline connection add type infiniband infiniband.parent ib0 infiniband.p-key 0x8010 connection.interface-name xxx
Error: Error writing connection: connection.interface-name: interface name of software infiniband device must be 'ib0.8010' or unset (instead it is 'xxx')
However, when we modify the p-key, we also get an error message:
$ nmcli --offline connection add type infiniband infiniband.parent ib0 infiniband.p-key 0x8010 connection.interface-name ib0.8010 |
nmcli --offline connection modify infiniband.p-key 5
Error: Error writing connection: connection.interface-name: interface name of software infiniband device must be 'ib0.0005' or unset (instead it is 'ib0.8010')
It's worse, because ifcfg-rh reader will mangle the PKEY_ID with |=0x8000 to set
the full membership flag. That means, if you add a profile like
$ nmcli --offline connection add type infiniband infiniband.parent ib0 infiniband.p-key 0x0010 connection.interface-name ib0.0010
it gets written to ifcfg-rh file. Then upon reload it's invalid (as the
interface name mismatches).
There are multiple solutions for this. For example, ifcfg-rh reader could also
mangle the connection.interface-name, so that the overall result is valid. Or
we could just not validate at all, and accept any bogus interface-name.
With this patch instead we will just normalize the invalid configuration to
make it right.
$ nmcli --offline connection add type infiniband infiniband.parent ib0 infiniband.p-key 0x8010 connection.interface-name ib0.8010 |
nmcli --offline connection modify infiniband.p-key 5
...
The downside is that this happens silently, so a user doesn't
notice that configuration is ignored:
$ nmcli --offline connection add type infiniband infiniband.parent ib0 infiniband.p-key 0x8010 connection.interface-name foo
...
interface-name=ib0.8010
This approach still seems preferable, because setting
"connection.interface-name" for infiniband profiles makes little sense,
so what we care here is to avoid problems.
(cherry picked from commit 4610fd67e6e795131a358b292ec3fc1ba2a2250f)
-rw-r--r-- | src/libnm-core-impl/nm-connection.c | 39 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting-infiniband.c | 14 | ||||
-rw-r--r-- | src/libnm-core-impl/tests/test-general.c | 30 |
3 files changed, 63 insertions, 20 deletions
diff --git a/src/libnm-core-impl/nm-connection.c b/src/libnm-core-impl/nm-connection.c index 3a9eda0e18..b017a6e51c 100644 --- a/src/libnm-core-impl/nm-connection.c +++ b/src/libnm-core-impl/nm-connection.c @@ -1332,18 +1332,41 @@ _normalize_ip_config(NMConnection *self, GHashTable *parameters) } static gboolean -_normalize_infiniband_mtu(NMConnection *self) +_normalize_infiniband(NMConnection *self) { NMSettingInfiniband *s_infini = nm_connection_get_setting_infiniband(self); + gboolean changed = FALSE; + const char *interface_name; + int p_key; - if (!s_infini || nm_setting_infiniband_get_mtu(s_infini) <= NM_INFINIBAND_MAX_MTU - || !NM_IN_STRSET(nm_setting_infiniband_get_transport_mode(s_infini), - "datagram", - "connected")) + if (!s_infini) return FALSE; - g_object_set(s_infini, NM_SETTING_INFINIBAND_MTU, (guint) NM_INFINIBAND_MAX_MTU, NULL); - return TRUE; + if (nm_setting_infiniband_get_mtu(s_infini) > NM_INFINIBAND_MAX_MTU) { + if (NM_IN_STRSET(nm_setting_infiniband_get_transport_mode(s_infini), + "datagram", + "connected")) { + g_object_set(s_infini, NM_SETTING_INFINIBAND_MTU, (guint) NM_INFINIBAND_MAX_MTU, NULL); + changed = TRUE; + } + } + + if ((p_key = nm_setting_infiniband_get_p_key(s_infini)) != -1 + && (interface_name = nm_connection_get_interface_name(self))) { + const char *virtual_iface_name; + + virtual_iface_name = nm_setting_infiniband_get_virtual_interface_name(s_infini); + + if (!nm_streq0(interface_name, virtual_iface_name)) { + g_object_set(nm_connection_get_setting_connection(self), + NM_SETTING_CONNECTION_INTERFACE_NAME, + virtual_iface_name, + NULL); + changed = TRUE; + } + } + + return changed; } static gboolean @@ -1986,7 +2009,7 @@ _connection_normalize(NMConnection *connection, was_modified |= _normalize_invalid_slave_port_settings(connection); was_modified |= _normalize_ip_config(connection, parameters); was_modified |= _normalize_ethernet_link_neg(connection); - was_modified |= _normalize_infiniband_mtu(connection); + was_modified |= _normalize_infiniband(connection); was_modified |= _normalize_bond_mode(connection); was_modified |= _normalize_bond_options(connection); was_modified |= _normalize_wireless_mac_address_randomization(connection); diff --git a/src/libnm-core-impl/nm-setting-infiniband.c b/src/libnm-core-impl/nm-setting-infiniband.c index 7ba5720619..f5b5bb3d1f 100644 --- a/src/libnm-core-impl/nm-setting-infiniband.c +++ b/src/libnm-core-impl/nm-setting-infiniband.c @@ -181,8 +181,8 @@ nm_setting_infiniband_get_virtual_interface_name(NMSettingInfiniband *setting) static gboolean verify(NMSetting *setting, NMConnection *connection, GError **error) { - NMSettingConnection *s_con = NULL; - NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE(setting); + NMSettingConnection *s_con; + NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE(setting); if (priv->mac_address && !nm_utils_hwaddr_valid(priv->mac_address, INFINIBAND_ALEN)) { g_set_error_literal(error, @@ -251,8 +251,10 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } } - if (connection) - s_con = nm_connection_get_setting_connection(connection); + /* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */ + + s_con = connection ? nm_connection_get_setting_connection(connection) : NULL; + if (s_con) { const char *interface_name = nm_setting_connection_get_interface_name(s_con); @@ -287,13 +289,11 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME); - return FALSE; + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; } } } - /* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */ - if (priv->mtu > NM_INFINIBAND_MAX_MTU) { /* Traditionally, MTU for "datagram" mode was limited to 2044 * and for "connected" mode it was 65520. diff --git a/src/libnm-core-impl/tests/test-general.c b/src/libnm-core-impl/tests/test-general.c index 8a98265abb..78ef9dcdac 100644 --- a/src/libnm-core-impl/tests/test-general.c +++ b/src/libnm-core-impl/tests/test-general.c @@ -6156,16 +6156,17 @@ test_connection_normalize_slave_type_2(void) } static void -test_connection_normalize_infiniband_mtu(void) +test_connection_normalize_infiniband(void) { gs_unref_object NMConnection *con = NULL; NMSettingInfiniband *s_infini; + NMSettingConnection *s_con; guint mtu_regular = nmtst_rand_select(2044, 2045, 65520); - con = nmtst_create_minimal_connection("test_connection_normalize_infiniband_mtu", + con = nmtst_create_minimal_connection("test_connection_normalize_infiniband", NULL, NM_SETTING_INFINIBAND_SETTING_NAME, - NULL); + &s_con); s_infini = nm_connection_get_setting_infiniband(con); g_object_set(s_infini, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", NULL); @@ -6213,6 +6214,25 @@ test_connection_normalize_infiniband_mtu(void) NM_CONNECTION_ERROR_INVALID_PROPERTY); nmtst_connection_normalize(con); g_assert_cmpint(65520, ==, nm_setting_infiniband_get_mtu(s_infini)); + + g_object_set(s_infini, + NM_SETTING_INFINIBAND_PARENT, + "foo", + NM_SETTING_INFINIBAND_P_KEY, + 0x005c, + NULL); + nmtst_assert_connection_verifies_without_normalization(con); + + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "foo.005c", NULL); + nmtst_assert_connection_verifies_without_normalization(con); + + g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "foo", NULL); + nmtst_assert_connection_verifies_after_normalization(con, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); + + nmtst_connection_normalize(con); + g_assert_cmpstr(nm_connection_get_interface_name(con), ==, "foo.005c"); } static void @@ -11511,8 +11531,8 @@ main(int argc, char **argv) test_connection_normalize_slave_type_1); g_test_add_func("/core/general/test_connection_normalize_slave_type_2", test_connection_normalize_slave_type_2); - g_test_add_func("/core/general/test_connection_normalize_infiniband_mtu", - test_connection_normalize_infiniband_mtu); + g_test_add_func("/core/general/test_connection_normalize_infiniband", + test_connection_normalize_infiniband); g_test_add_func("/core/general/test_connection_normalize_gateway_never_default", test_connection_normalize_gateway_never_default); g_test_add_func("/core/general/test_connection_normalize_may_fail", |