initrd: support infiniband pkeys

Introduce a new "ib.pkey=<parent>.<pkey>" command line argument to
create a Infiniband partition.

The new connection has IPv4 and IPv6 enabled by default. Unlike for
VLANs, the generator doesn't create a connection for the parent
Infiniband interface.

See also: https://github.com/dracutdevs/dracut/pull/1538

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/884
This commit is contained in:
Beniamino Galvani 2021-06-08 18:03:29 +02:00
parent 109d561bed
commit 9060c14ccf
3 changed files with 98 additions and 0 deletions

View file

@ -142,6 +142,7 @@
<member><option>bond</option></member>
<member><option>team</option></member>
<member><option>vlan</option></member>
<member><option>ib.pkey</option></member>
<member><option>bootdev</option></member>
<member><option>nameserver</option></member>
<member><option>rd.peerdns</option></member>
@ -184,6 +185,16 @@
the command line wins.</para>
</listitem>
<listitem>
<para>NetworkManager supports the
<option>ib.pkey</option>=<replaceable>PARENT</replaceable>.<replaceable>PKEY</replaceable>
argument to set up an Infiniband partition on IPoIB parent
device <replaceable>PARENT</replaceable> using the specified
partition key <replaceable>PKEY</replaceable>. The partition
key must be in hexadecimal notation without leading "0x", for
example "ib.pkey=ib0.8004".
</para>
</listitem>
</itemizedlist>
</refsect1>

View file

@ -916,6 +916,56 @@ reader_parse_vlan(Reader *reader, char *argument)
g_ptr_array_add(reader->vlan_parents, g_strdup(phy));
}
static void
reader_parse_ib_pkey(Reader *reader, char *argument)
{
NMConnection * connection;
NMSettingInfiniband *s_ib;
char * ifname;
gs_free char * parent = NULL;
char * pkey;
gint64 pkey_int;
/* At the moment we only support ib.pkey=<parent>.<pkey>;
* in the future we want to possibly support other options:
* ib.pkey=<parent>.<pkey>:<option>:...
*/
ifname = get_word(&argument, ':');
if (!ifname) {
_LOGW(LOGD_CORE, "ib.pkey= without argument");
return;
}
parent = g_strdup(ifname);
pkey = strchr(parent, '.');
if (!pkey) {
_LOGW(LOGD_CORE, "No pkey found for '%s'", ifname);
return;
}
*pkey = '\0';
pkey++;
pkey_int = _nm_utils_ascii_str_to_int64(pkey, 16, 0, 0xFFFF, -1);
if (pkey_int == -1) {
_LOGW(LOGD_CORE, "Invalid pkey '%s'", pkey);
return;
}
connection = reader_get_connection(reader, ifname, NM_SETTING_INFINIBAND_SETTING_NAME, TRUE);
s_ib = nm_connection_get_setting_infiniband(connection);
g_object_set(s_ib,
NM_SETTING_INFINIBAND_PARENT,
parent,
NM_SETTING_INFINIBAND_P_KEY,
(int) pkey_int,
NULL);
if (argument && *argument)
_LOGW(LOGD_CORE, "Ignoring extra: '%s' for ib.pkey=", argument);
}
static void
reader_parse_rd_znet(Reader *reader, char *argument, gboolean net_ifnames)
{
@ -1160,6 +1210,8 @@ nmi_cmdline_reader_parse(const char * sysfs_dir,
reader_parse_master(reader, argument, NM_SETTING_TEAM_SETTING_NAME, NULL);
else if (nm_streq(tag, "vlan"))
reader_parse_vlan(reader, argument);
else if (nm_streq(tag, "ib.pkey"))
reader_parse_ib_pkey(reader, argument);
else if (nm_streq(tag, "bootdev")) {
g_free(bootdev);
bootdev = g_strdup(argument);

View file

@ -2214,6 +2214,40 @@ test_infiniband_mac(void)
"00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33");
}
static void
test_infiniband_pkey(void)
{
const char *const *const ARGV = NM_MAKE_STRV("ib.pkey=ib0.8004", "ip=ib0.8004:dhcp");
gs_unref_hashtable GHashTable *connections = NULL;
NMConnection * connection;
NMSettingInfiniband * s_ib;
NMSettingIPConfig * s_ip4;
NMSettingIPConfig * s_ip6;
connections = _parse_cons(ARGV);
g_assert_cmpint(g_hash_table_size(connections), ==, 1);
connection = g_hash_table_lookup(connections, "ib0.8004");
g_assert_cmpstr(nm_connection_get_connection_type(connection),
==,
NM_SETTING_INFINIBAND_SETTING_NAME);
g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "ib0.8004");
s_ib = nm_connection_get_setting_infiniband(connection);
g_assert(s_ib);
g_assert_cmpint(nm_setting_infiniband_get_p_key(s_ib), ==, 0x8004);
s_ip4 = nm_connection_get_setting_ip4_config(connection);
g_assert(s_ip4);
g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO);
g_assert(!nm_setting_ip_config_get_may_fail(s_ip4));
s_ip6 = nm_connection_get_setting_ip6_config(connection);
g_assert(s_ip6);
g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO);
g_assert(nm_setting_ip_config_get_may_fail(s_ip6));
}
static void
test_carrier_timeout(void)
{
@ -2280,6 +2314,7 @@ main(int argc, char **argv)
g_test_add_func("/initrd/cmdline/dhcp/vendor_class_id", test_dhcp_vendor_class_id);
g_test_add_func("/initrd/cmdline/infiniband/iface", test_infiniband_iface);
g_test_add_func("/initrd/cmdline/infiniband/mac", test_infiniband_mac);
g_test_add_func("/initrd/cmdline/infiniband/pkey", test_infiniband_pkey);
g_test_add_func("/initrd/cmdline/carrier_timeout", test_carrier_timeout);
return g_test_run();