]>
Commit | Line | Data |
---|---|---|
1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ | |
2 | ||
3 | #include <stdlib.h> | |
4 | ||
5 | #include "sd-device.h" | |
6 | ||
7 | #include "alloc-util.h" | |
8 | #include "device-private.h" | |
9 | #include "log.h" | |
10 | #include "netif-naming-scheme.h" | |
11 | #include "proc-cmdline.h" | |
12 | #include "string-table.h" | |
13 | #include "string-util.h" | |
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 | { "v251", NAMING_V251 }, | |
26 | { "v252", NAMING_V252 }, | |
27 | { "v253", NAMING_V253 }, | |
28 | { "v254", NAMING_V254 }, | |
29 | { "v255", NAMING_V255 }, | |
30 | { "v257", NAMING_V257 }, | |
31 | { "v258", NAMING_V258 }, | |
32 | /* … add more schemes here, as the logic to name devices is updated … */ | |
33 | ||
34 | EXTRA_NET_NAMING_MAP | |
35 | }; | |
36 | ||
37 | const NamingScheme* naming_scheme_from_name(const char *name) { | |
38 | /* "latest" may either be defined explicitly by the extra map, in which case we will find it in | |
39 | * the table like any other name. After iterating through the table, we check for "latest" again, | |
40 | * which means that if not mapped explicitly, it maps to the last defined entry, whatever that is. */ | |
41 | ||
42 | FOREACH_ELEMENT(scheme, naming_schemes) | |
43 | if (streq(scheme->name, name)) | |
44 | return scheme; | |
45 | ||
46 | if (streq(name, "latest")) | |
47 | return naming_schemes + ELEMENTSOF(naming_schemes) - 1; | |
48 | ||
49 | return NULL; | |
50 | } | |
51 | ||
52 | const NamingScheme* naming_scheme(void) { | |
53 | static const NamingScheme *cache = NULL; | |
54 | _cleanup_free_ char *buffer = NULL; | |
55 | const char *e, *k; | |
56 | ||
57 | if (cache) | |
58 | return cache; | |
59 | ||
60 | /* Acquire setting from the kernel command line */ | |
61 | (void) proc_cmdline_get_key("net.naming_scheme", 0, &buffer); | |
62 | ||
63 | /* Also acquire it from an env var */ | |
64 | e = getenv("NET_NAMING_SCHEME"); | |
65 | if (e) { | |
66 | if (*e == ':') { | |
67 | /* If prefixed with ':' the kernel cmdline takes precedence */ | |
68 | k = buffer ?: e + 1; | |
69 | } else | |
70 | k = e; /* Otherwise the env var takes precedence */ | |
71 | } else | |
72 | k = buffer; | |
73 | ||
74 | if (k) { | |
75 | cache = naming_scheme_from_name(k); | |
76 | if (cache) { | |
77 | log_info("Using interface naming scheme '%s'.", cache->name); | |
78 | return cache; | |
79 | } | |
80 | ||
81 | log_warning("Unknown interface naming scheme '%s' requested, ignoring.", k); | |
82 | } | |
83 | ||
84 | cache = naming_scheme_from_name(DEFAULT_NET_NAMING_SCHEME); | |
85 | assert(cache); | |
86 | log_info("Using default interface naming scheme '%s'.", cache->name); | |
87 | ||
88 | return cache; | |
89 | } | |
90 | ||
91 | static const char* const name_policy_table[_NAMEPOLICY_MAX] = { | |
92 | [NAMEPOLICY_KERNEL] = "kernel", | |
93 | [NAMEPOLICY_KEEP] = "keep", | |
94 | [NAMEPOLICY_DATABASE] = "database", | |
95 | [NAMEPOLICY_ONBOARD] = "onboard", | |
96 | [NAMEPOLICY_SLOT] = "slot", | |
97 | [NAMEPOLICY_PATH] = "path", | |
98 | [NAMEPOLICY_MAC] = "mac", | |
99 | }; | |
100 | ||
101 | DEFINE_STRING_TABLE_LOOKUP(name_policy, NamePolicy); | |
102 | ||
103 | static const char* const alternative_names_policy_table[_NAMEPOLICY_MAX] = { | |
104 | [NAMEPOLICY_DATABASE] = "database", | |
105 | [NAMEPOLICY_ONBOARD] = "onboard", | |
106 | [NAMEPOLICY_SLOT] = "slot", | |
107 | [NAMEPOLICY_PATH] = "path", | |
108 | [NAMEPOLICY_MAC] = "mac", | |
109 | }; | |
110 | ||
111 | DEFINE_STRING_TABLE_LOOKUP(alternative_names_policy, NamePolicy); | |
112 | ||
113 | static int naming_sysattr_allowed_by_default(sd_device *dev) { | |
114 | int r; | |
115 | ||
116 | assert(dev); | |
117 | ||
118 | r = device_get_property_bool(dev, "ID_NET_NAME_ALLOW"); | |
119 | if (r == -ENOENT) | |
120 | return true; | |
121 | ||
122 | return r; | |
123 | } | |
124 | ||
125 | static int naming_sysattr_allowed(sd_device *dev, const char *sysattr) { | |
126 | char *sysattr_property; | |
127 | int r; | |
128 | ||
129 | assert(dev); | |
130 | assert(sysattr); | |
131 | ||
132 | sysattr_property = strjoina("ID_NET_NAME_ALLOW_", sysattr); | |
133 | ascii_strupper(sysattr_property); | |
134 | ||
135 | r = device_get_property_bool(dev, sysattr_property); | |
136 | if (r == -ENOENT) | |
137 | /* If ID_NET_NAME_ALLOW is not set or set to 1 default is to allow */ | |
138 | return naming_sysattr_allowed_by_default(dev); | |
139 | ||
140 | return r; | |
141 | } | |
142 | ||
143 | int device_get_sysattr_int_filtered(sd_device *device, const char *sysattr, int *ret_value) { | |
144 | int r; | |
145 | ||
146 | r = naming_sysattr_allowed(device, sysattr); | |
147 | if (r < 0) | |
148 | return r; | |
149 | if (r == 0) | |
150 | return -ENOENT; | |
151 | ||
152 | return device_get_sysattr_int(device, sysattr, ret_value); | |
153 | } | |
154 | ||
155 | int device_get_sysattr_unsigned_filtered(sd_device *device, const char *sysattr, unsigned *ret_value) { | |
156 | int r; | |
157 | ||
158 | r = naming_sysattr_allowed(device, sysattr); | |
159 | if (r < 0) | |
160 | return r; | |
161 | if (r == 0) | |
162 | return -ENOENT; | |
163 | ||
164 | return device_get_sysattr_unsigned(device, sysattr, ret_value); | |
165 | } | |
166 | ||
167 | int device_get_sysattr_bool_filtered(sd_device *device, const char *sysattr) { | |
168 | int r; | |
169 | ||
170 | r = naming_sysattr_allowed(device, sysattr); | |
171 | if (r < 0) | |
172 | return r; | |
173 | if (r == 0) | |
174 | return -ENOENT; | |
175 | ||
176 | return device_get_sysattr_bool(device, sysattr); | |
177 | } | |
178 | ||
179 | int device_get_sysattr_value_filtered(sd_device *device, const char *sysattr, const char **ret_value) { | |
180 | int r; | |
181 | ||
182 | r = naming_sysattr_allowed(device, sysattr); | |
183 | if (r < 0) | |
184 | return r; | |
185 | if (r == 0) | |
186 | return -ENOENT; | |
187 | ||
188 | return sd_device_get_sysattr_value(device, sysattr, ret_value); | |
189 | } |