]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/netif-naming-scheme.c
Merge pull request #20609 from DaanDeMeyer/recursive-template
[thirdparty/systemd.git] / src / shared / netif-naming-scheme.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "alloc-util.h"
4 #include "netif-naming-scheme.h"
5 #include "proc-cmdline.h"
6 #include "string-util.h"
7
8 #ifdef _DEFAULT_NET_NAMING_SCHEME_TEST
9 /* The primary purpose of this check is to verify that _DEFAULT_NET_NAMING_SCHEME_TEST
10 * is a valid identifier. If an invalid name is given during configuration, this will
11 * fail with a name error. */
12 assert_cc(_DEFAULT_NET_NAMING_SCHEME_TEST >= 0);
13 #endif
14
15 static const NamingScheme naming_schemes[] = {
16 { "v238", NAMING_V238 },
17 { "v239", NAMING_V239 },
18 { "v240", NAMING_V240 },
19 { "v241", NAMING_V241 },
20 { "v243", NAMING_V243 },
21 { "v245", NAMING_V245 },
22 { "v247", NAMING_V247 },
23 { "v249", NAMING_V249 },
24 { "v250", NAMING_V250 },
25 /* … add more schemes here, as the logic to name devices is updated … */
26
27 EXTRA_NET_NAMING_MAP
28 };
29
30 const NamingScheme* naming_scheme_from_name(const char *name) {
31 /* "latest" may either be defined explicitly by the extra map, in which case we we will find it in
32 * the table like any other name. After iterating through the table, we check for "latest" again,
33 * which means that if not mapped explicitly, it maps to the last defined entry, whatever that is. */
34
35 for (size_t i = 0; i < ELEMENTSOF(naming_schemes); i++)
36 if (streq(naming_schemes[i].name, name))
37 return naming_schemes + i;
38
39 if (streq(name, "latest"))
40 return naming_schemes + ELEMENTSOF(naming_schemes) - 1;
41
42 return NULL;
43 }
44
45 const NamingScheme* naming_scheme(void) {
46 static const NamingScheme *cache = NULL;
47 _cleanup_free_ char *buffer = NULL;
48 const char *e, *k;
49
50 if (cache)
51 return cache;
52
53 /* Acquire setting from the kernel command line */
54 (void) proc_cmdline_get_key("net.naming-scheme", 0, &buffer);
55
56 /* Also acquire it from an env var */
57 e = getenv("NET_NAMING_SCHEME");
58 if (e) {
59 if (*e == ':') {
60 /* If prefixed with ':' the kernel cmdline takes precedence */
61 k = buffer ?: e + 1;
62 } else
63 k = e; /* Otherwise the env var takes precedence */
64 } else
65 k = buffer;
66
67 if (k) {
68 cache = naming_scheme_from_name(k);
69 if (cache) {
70 log_info("Using interface naming scheme '%s'.", cache->name);
71 return cache;
72 }
73
74 log_warning("Unknown interface naming scheme '%s' requested, ignoring.", k);
75 }
76
77 cache = naming_scheme_from_name(DEFAULT_NET_NAMING_SCHEME);
78 assert(cache);
79 log_info("Using default interface naming scheme '%s'.", cache->name);
80
81 return cache;
82 }