diff --git a/meson.build b/meson.build index 9db035c3b7..0d716d5485 100644 --- a/meson.build +++ b/meson.build @@ -707,8 +707,30 @@ else conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_ALL') endif +extra_net_naming_schemes = [] +extra_net_naming_map = [] +foreach scheme: get_option('extra-net-naming-schemes').split(',') + if scheme != '' + name = scheme.split('=')[0] + value = scheme.split('=')[1] + NAME = name.underscorify().to_upper() + VALUE = [] + foreach field: value.split('+') + VALUE += 'NAMING_' + field.underscorify().to_upper() + endforeach + extra_net_naming_schemes += 'NAMING_@0@ = @1@,'.format(NAME, '|'.join(VALUE)) + extra_net_naming_map += '{ "@0@", NAMING_@1@ },'.format(name, NAME) + endif +endforeach +conf.set('EXTRA_NET_NAMING_SCHEMES', ' '.join(extra_net_naming_schemes)) +conf.set('EXTRA_NET_NAMING_MAP', ' '.join(extra_net_naming_map)) + default_net_naming_scheme = get_option('default-net-naming-scheme') conf.set_quoted('DEFAULT_NET_NAMING_SCHEME', default_net_naming_scheme) +if default_net_naming_scheme != 'latest' + conf.set('_DEFAULT_NET_NAMING_SCHEME_TEST', + 'NAMING_' + default_net_naming_scheme.underscorify().to_upper()) +endif time_epoch = get_option('time-epoch') if time_epoch == -1 diff --git a/meson_options.txt b/meson_options.txt index dcd3c01ae4..c09a23dc03 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -200,8 +200,9 @@ option('fallback-hostname', type : 'string', value : 'localhost', option('default-hierarchy', type : 'combo', choices : ['legacy', 'hybrid', 'unified'], value : 'unified', description : 'default cgroup hierarchy') -option('default-net-naming-scheme', type : 'combo', - choices : ['latest', 'v238', 'v239', 'v240', 'v241', 'v243', 'v245', 'v247', 'v249'], +option('extra-net-naming-schemes', type : 'string', + description : 'comma-separated list of extra net.naming-scheme= definitions') +option('default-net-naming-scheme', type : 'string', value : 'latest', description : 'default net.naming-scheme= value') option('status-unit-format-default', type : 'combo', choices : ['description', 'name', 'combined'], diff --git a/src/shared/netif-naming-scheme.c b/src/shared/netif-naming-scheme.c index 4dcf2889ce..d949f7381a 100644 --- a/src/shared/netif-naming-scheme.c +++ b/src/shared/netif-naming-scheme.c @@ -5,6 +5,13 @@ #include "proc-cmdline.h" #include "string-util.h" +#ifdef _DEFAULT_NET_NAMING_SCHEME_TEST +/* The primary purpose of this check is to verify that _DEFAULT_NET_NAMING_SCHEME_TEST + * is a valid identifier. If an invalid name is given during configuration, this will + * fail with a name error. */ +assert_cc(_DEFAULT_NET_NAMING_SCHEME_TEST >= 0); +#endif + static const NamingScheme naming_schemes[] = { { "v238", NAMING_V238 }, { "v239", NAMING_V239 }, @@ -15,19 +22,22 @@ static const NamingScheme naming_schemes[] = { { "v247", NAMING_V247 }, { "v249", NAMING_V249 }, /* … add more schemes here, as the logic to name devices is updated … */ - /* also remember to update the list of options in meson_options.txt */ + + EXTRA_NET_NAMING_MAP }; -static const NamingScheme* naming_scheme_from_name(const char *name) { - size_t i; +const NamingScheme* naming_scheme_from_name(const char *name) { + /* "latest" may either be defined explicitly by the extra map, in which case we we will find it in + * the table like any other name. After iterating through the table, we check for "latest" again, + * which means that if not mapped explicitly, it maps to the last defined entry, whatever that is. */ + + for (size_t i = 0; i < ELEMENTSOF(naming_schemes); i++) + if (streq(naming_schemes[i].name, name)) + return naming_schemes + i; if (streq(name, "latest")) return naming_schemes + ELEMENTSOF(naming_schemes) - 1; - for (i = 0; i < ELEMENTSOF(naming_schemes); i++) - if (streq(naming_schemes[i].name, name)) - return naming_schemes + i; - return NULL; } diff --git a/src/shared/netif-naming-scheme.h b/src/shared/netif-naming-scheme.h index 119b80178f..0141a4fb90 100644 --- a/src/shared/netif-naming-scheme.h +++ b/src/shared/netif-naming-scheme.h @@ -46,6 +46,8 @@ typedef enum NamingSchemeFlags { NAMING_V247 = NAMING_V245 | NAMING_BRIDGE_NO_SLOT, NAMING_V249 = NAMING_V247 | NAMING_SLOT_FUNCTION_ID | NAMING_16BIT_INDEX | NAMING_REPLACE_STRICTLY, + EXTRA_NET_NAMING_SCHEMES + _NAMING_SCHEME_FLAGS_INVALID = -EINVAL, } NamingSchemeFlags; @@ -54,6 +56,7 @@ typedef struct NamingScheme { NamingSchemeFlags flags; } NamingScheme; +const NamingScheme* naming_scheme_from_name(const char *name); const NamingScheme* naming_scheme(void); static inline bool naming_scheme_has(NamingSchemeFlags flags) { diff --git a/src/test/meson.build b/src/test/meson.build index 04c5b6ba42..ee7c1a1c83 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -429,6 +429,8 @@ tests += [ [['src/test/test-firewall-util.c']], + [['src/test/test-net-naming-scheme.c']], + [['src/test/test-netlink-manual.c'], [], [libkmod], diff --git a/src/test/test-net-naming-scheme.c b/src/test/test-net-naming-scheme.c new file mode 100644 index 0000000000..693b2f6604 --- /dev/null +++ b/src/test/test-net-naming-scheme.c @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "netif-naming-scheme.h" +#include "string-util.h" +#include "tests.h" + +static void test_default_net_naming_scheme(void) { + log_info("/* %s */", __func__); + + const NamingScheme *n; + assert_se(n = naming_scheme_from_name(DEFAULT_NET_NAMING_SCHEME)); + log_info("default → %s", n->name); +} + +static void test_naming_scheme_conversions(void) { + log_info("/* %s */", __func__); + + const NamingScheme *n; + assert_se(n = naming_scheme_from_name("latest")); + log_info("latest → %s", n->name); + + assert_se(n = naming_scheme_from_name("v238")); + assert_se(streq(n->name, "v238")); +} + +int main(int argc, char **argv) { + test_setup_logging(LOG_INFO); + + test_default_net_naming_scheme(); + test_naming_scheme_conversions(); +}