From d920b48a5fa6fcb71b2df307fe7255328add19fc Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 21 Dec 2023 13:40:38 +0100 Subject: [PATCH] initrd: add support for rd.net.dhcp.dscp property Add a new kernel command line option, so that the DSCP value can by changed even in early boot. --- man/nm-initrd-generator.xml | 10 +++++++ src/nm-initrd-generator/nmi-cmdline-reader.c | 16 ++++++++++- .../tests/test-cmdline-reader.c | 28 +++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/man/nm-initrd-generator.xml b/man/nm-initrd-generator.xml index 336d7f0365..27219fda4c 100644 --- a/man/nm-initrd-generator.xml +++ b/man/nm-initrd-generator.xml @@ -160,6 +160,7 @@ + @@ -223,6 +224,15 @@ SPEED accepts positive integer values. + + + NetworkManager supports the + ={CS0|CS4|CS6} + kernel command line option to set a specific DSCP (TOS) value + in the IP header of DHCP messages. + + + diff --git a/src/nm-initrd-generator/nmi-cmdline-reader.c b/src/nm-initrd-generator/nmi-cmdline-reader.c index 7bb7e43e1c..1c35a9059c 100644 --- a/src/nm-initrd-generator/nmi-cmdline-reader.c +++ b/src/nm-initrd-generator/nmi-cmdline-reader.c @@ -39,6 +39,7 @@ typedef struct { gboolean ignore_auto_dns; int dhcp_timeout; char *dhcp4_vci; + char *dhcp_dscp; gint64 carrier_timeout_sec; } Reader; @@ -73,6 +74,7 @@ reader_destroy(Reader *reader, gboolean free_hash) nm_clear_g_free(&reader->hostname); g_hash_table_unref(reader->znet_ifnames); nm_clear_g_free(&reader->dhcp4_vci); + nm_clear_g_free(&reader->dhcp_dscp); nm_g_slice_free(reader); if (!free_hash) return g_steal_pointer(&hash); @@ -122,6 +124,8 @@ reader_create_connection(Reader *reader, reader->dhcp_timeout, NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER, reader->dhcp4_vci, + NM_SETTING_IP_CONFIG_DHCP_DSCP, + reader->dhcp_dscp, NM_SETTING_IP_CONFIG_REQUIRED_TIMEOUT, NMI_IP_REQUIRED_TIMEOUT_MSEC, NULL); @@ -1289,6 +1293,8 @@ _normalize_conn(gpointer key, gpointer value, gpointer user_data) NULL, NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER, NULL, + NM_SETTING_IP_CONFIG_DHCP_DSCP, + NULL, NULL); } } @@ -1429,6 +1435,13 @@ nmi_cmdline_reader_parse(const char *etc_connections_dir, } else if (nm_streq(tag, "rd.net.dhcp.vendor-class")) { if (nm_utils_validate_dhcp4_vendor_class_id(argument, NULL)) nm_strdup_reset(&reader->dhcp4_vci, argument); + } else if (nm_streq(tag, "rd.net.dhcp.dscp")) { + gs_free_error GError *error = NULL; + + if (nm_utils_validate_dhcp_dscp(argument, &error)) + nm_strdup_reset(&reader->dhcp_dscp, argument); + else + _LOGW(LOGD_CORE, "Ignoring 'rd.net.dhcp.dscp=%s': %s", argument, error->message); } else if (nm_streq(tag, "rd.net.timeout.carrier")) { reader->carrier_timeout_sec = _nm_utils_ascii_str_to_int64(argument, 10, 0, G_MAXINT32, 0); @@ -1491,8 +1504,9 @@ nmi_cmdline_reader_parse(const char *etc_connections_dir, } else if (g_ascii_strcasecmp(tag, "BOOTIF") == 0) { nm_clear_g_free(&bootif_val); bootif_val = g_strdup(argument); - } else if (nm_streq(tag, "rd.ethtool")) + } else if (nm_streq(tag, "rd.ethtool")) { reader_parse_ethtool(reader, argument); + } } for (i = 0; i < reader->vlan_parents->len; i++) { diff --git a/src/nm-initrd-generator/tests/test-cmdline-reader.c b/src/nm-initrd-generator/tests/test-cmdline-reader.c index 3dbbd4d5fe..fd663b6d99 100644 --- a/src/nm-initrd-generator/tests/test-cmdline-reader.c +++ b/src/nm-initrd-generator/tests/test-cmdline-reader.c @@ -2354,6 +2354,33 @@ test_dhcp_vendor_class_id(void) g_assert(nm_setting_ip4_config_get_dhcp_vendor_class_identifier(s_ip4) == NULL); } +static void +test_dhcp_dscp(void) +{ + const char *const *ARGV; + gs_unref_object NMConnection *connection = NULL; + NMSettingIPConfig *s_ip4; + + ARGV = NM_MAKE_STRV("rd.net.dhcp.dscp=CS4", "ip=eno1:dhcp"); + connection = _parse_con(ARGV, "eno1"); + s_ip4 = NM_SETTING_IP_CONFIG(nm_connection_get_setting_ip4_config(connection)); + g_assert_cmpstr(nm_setting_ip_config_get_dhcp_dscp(s_ip4), ==, "CS4"); + + g_clear_object(&connection); + + ARGV = NM_MAKE_STRV("rd.net.dhcp.dscp=CS0", "ip=eno1:dhcp"); + connection = _parse_con(ARGV, "eno1"); + s_ip4 = NM_SETTING_IP_CONFIG(nm_connection_get_setting_ip4_config(connection)); + g_assert_cmpstr(nm_setting_ip_config_get_dhcp_dscp(s_ip4), ==, "CS0"); + + g_clear_object(&connection); + + ARGV = NM_MAKE_STRV("ip=eno1:dhcp"); + connection = _parse_con(ARGV, "eno1"); + s_ip4 = NM_SETTING_IP_CONFIG(nm_connection_get_setting_ip4_config(connection)); + g_assert_cmpstr(nm_setting_ip_config_get_dhcp_dscp(s_ip4), ==, NULL); +} + static void test_infiniband_iface(void) { @@ -2652,6 +2679,7 @@ main(int argc, char **argv) g_test_add_func("/initrd/cmdline/neednet/no_args", test_neednet_no_args); g_test_add_func("/initrd/cmdline/neednet/args", test_neednet_args); g_test_add_func("/initrd/cmdline/dhcp/vendor_class_id", test_dhcp_vendor_class_id); + g_test_add_func("/initrd/cmdline/dhcp/dscp", test_dhcp_dscp); 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);