1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include <linux/netdevice.h>
4 #include <netinet/ether.h>
5 #include <unistd.h>
6 
7 #include "sd-device.h"
8 #include "sd-netlink.h"
9 
10 #include "alloc-util.h"
11 #include "arphrd-util.h"
12 #include "conf-files.h"
13 #include "conf-parser.h"
14 #include "creds-util.h"
15 #include "def.h"
16 #include "device-private.h"
17 #include "device-util.h"
18 #include "ethtool-util.h"
19 #include "fd-util.h"
20 #include "fileio.h"
21 #include "link-config.h"
22 #include "log-link.h"
23 #include "memory-util.h"
24 #include "net-condition.h"
25 #include "netif-sriov.h"
26 #include "netif-util.h"
27 #include "netlink-util.h"
28 #include "parse-util.h"
29 #include "path-lookup.h"
30 #include "path-util.h"
31 #include "proc-cmdline.h"
32 #include "random-util.h"
33 #include "stat-util.h"
34 #include "string-table.h"
35 #include "string-util.h"
36 #include "strv.h"
37 #include "utf8.h"
38 
39 struct LinkConfigContext {
40         LIST_HEAD(LinkConfig, configs);
41         int ethtool_fd;
42         usec_t network_dirs_ts_usec;
43         Hashmap *stats_by_path;
44 };
45 
link_config_free(LinkConfig * config)46 static LinkConfig* link_config_free(LinkConfig *config) {
47         if (!config)
48                 return NULL;
49 
50         free(config->filename);
51 
52         net_match_clear(&config->match);
53         condition_free_list(config->conditions);
54 
55         free(config->description);
56         free(config->name_policy);
57         free(config->name);
58         strv_free(config->alternative_names);
59         free(config->alternative_names_policy);
60         free(config->alias);
61         free(config->wol_password_file);
62         erase_and_free(config->wol_password);
63 
64         ordered_hashmap_free_with_destructor(config->sr_iov_by_section, sr_iov_free);
65 
66         return mfree(config);
67 }
68 
69 DEFINE_TRIVIAL_CLEANUP_FUNC(LinkConfig*, link_config_free);
70 
link_configs_free(LinkConfigContext * ctx)71 static void link_configs_free(LinkConfigContext *ctx) {
72         if (!ctx)
73                 return;
74 
75         ctx->stats_by_path = hashmap_free(ctx->stats_by_path);
76 
77         LIST_FOREACH(configs, config, ctx->configs)
78                 link_config_free(config);
79 }
80 
link_config_ctx_free(LinkConfigContext * ctx)81 LinkConfigContext *link_config_ctx_free(LinkConfigContext *ctx) {
82         if (!ctx)
83                 return NULL;
84 
85         safe_close(ctx->ethtool_fd);
86         link_configs_free(ctx);
87         return mfree(ctx);
88 }
89 
link_config_ctx_new(LinkConfigContext ** ret)90 int link_config_ctx_new(LinkConfigContext **ret) {
91         _cleanup_(link_config_ctx_freep) LinkConfigContext *ctx = NULL;
92 
93         if (!ret)
94                 return -EINVAL;
95 
96         ctx = new(LinkConfigContext, 1);
97         if (!ctx)
98                 return -ENOMEM;
99 
100         *ctx = (LinkConfigContext) {
101                 .ethtool_fd = -1,
102         };
103 
104         *ret = TAKE_PTR(ctx);
105 
106         return 0;
107 }
108 
link_parse_wol_password(LinkConfig * config,const char * str)109 static int link_parse_wol_password(LinkConfig *config, const char *str) {
110         _cleanup_(erase_and_freep) uint8_t *p = NULL;
111         int r;
112 
113         assert(config);
114         assert(str);
115 
116         assert_cc(sizeof(struct ether_addr) == SOPASS_MAX);
117 
118         p = new(uint8_t, SOPASS_MAX);
119         if (!p)
120                 return -ENOMEM;
121 
122         /* Reuse parse_ether_addr(), as their formats are equivalent. */
123         r = parse_ether_addr(str, (struct ether_addr*) p);
124         if (r < 0)
125                 return r;
126 
127         erase_and_free(config->wol_password);
128         config->wol_password = TAKE_PTR(p);
129         return 0;
130 }
131 
link_read_wol_password_from_file(LinkConfig * config)132 static int link_read_wol_password_from_file(LinkConfig *config) {
133         _cleanup_(erase_and_freep) char *password = NULL;
134         int r;
135 
136         assert(config);
137 
138         if (!config->wol_password_file)
139                 return 0;
140 
141         r = read_full_file_full(
142                         AT_FDCWD, config->wol_password_file, UINT64_MAX, SIZE_MAX,
143                         READ_FULL_FILE_SECURE | READ_FULL_FILE_WARN_WORLD_READABLE | READ_FULL_FILE_CONNECT_SOCKET,
144                         NULL, &password, NULL);
145         if (r < 0)
146                 return r;
147 
148         return link_parse_wol_password(config, password);
149 }
150 
link_read_wol_password_from_cred(LinkConfig * config)151 static int link_read_wol_password_from_cred(LinkConfig *config) {
152         _cleanup_free_ char *base = NULL, *cred_name = NULL;
153         _cleanup_(erase_and_freep) char *password = NULL;
154         int r;
155 
156         assert(config);
157         assert(config->filename);
158 
159         if (config->wol == UINT32_MAX)
160                 return 0; /* WakeOnLan= is not specified. */
161         if (!FLAGS_SET(config->wol, WAKE_MAGICSECURE))
162                 return 0; /* secureon is not specified in WakeOnLan=. */
163         if (config->wol_password)
164                 return 0; /* WakeOnLanPassword= is specified. */
165         if (config->wol_password_file)
166                 return 0; /* a file name is specified in WakeOnLanPassword=, but failed to read it. */
167 
168         r = path_extract_filename(config->filename, &base);
169         if (r < 0)
170                 return r;
171 
172         cred_name = strjoin(base, ".wol.password");
173         if (!cred_name)
174                 return -ENOMEM;
175 
176         r = read_credential(cred_name, (void**) &password, NULL);
177         if (r == -ENOENT)
178                 r = read_credential("wol.password", (void**) &password, NULL);
179         if (r < 0)
180                 return r;
181 
182         return link_parse_wol_password(config, password);
183 }
184 
link_adjust_wol_options(LinkConfig * config)185 static int link_adjust_wol_options(LinkConfig *config) {
186         int r;
187 
188         assert(config);
189 
190         r = link_read_wol_password_from_file(config);
191         if (r == -ENOMEM)
192                 return log_oom();
193         if (r < 0)
194                 log_warning_errno(r, "Failed to read WakeOnLan password from %s, ignoring: %m", config->wol_password_file);
195 
196         r = link_read_wol_password_from_cred(config);
197         if (r == -ENOMEM)
198                 return log_oom();
199         if (r < 0)
200                 log_warning_errno(r, "Failed to read WakeOnLan password from credential, ignoring: %m");
201 
202         if (config->wol != UINT32_MAX && config->wol_password)
203                 /* Enable WAKE_MAGICSECURE flag when WakeOnLanPassword=. Note that when
204                  * WakeOnLanPassword= is set without WakeOnLan=, then ethtool_set_wol() enables
205                  * WAKE_MAGICSECURE flag and other flags are not changed. */
206                 config->wol |= WAKE_MAGICSECURE;
207 
208         return 0;
209 }
210 
link_load_one(LinkConfigContext * ctx,const char * filename)211 int link_load_one(LinkConfigContext *ctx, const char *filename) {
212         _cleanup_(link_config_freep) LinkConfig *config = NULL;
213         _cleanup_hashmap_free_ Hashmap *stats_by_path = NULL;
214         _cleanup_free_ char *name = NULL;
215         const char *dropin_dirname;
216         size_t i;
217         int r;
218 
219         assert(ctx);
220         assert(filename);
221 
222         r = null_or_empty_path(filename);
223         if (r < 0)
224                 return log_warning_errno(r, "Failed to check if \"%s\" is empty: %m", filename);
225         if (r > 0) {
226                 log_debug("Skipping empty file: %s", filename);
227                 return 0;
228         }
229 
230         name = strdup(filename);
231         if (!name)
232                 return log_oom();
233 
234         config = new(LinkConfig, 1);
235         if (!config)
236                 return log_oom();
237 
238         *config = (LinkConfig) {
239                 .filename = TAKE_PTR(name),
240                 .mac_address_policy = MAC_ADDRESS_POLICY_NONE,
241                 .wol = UINT32_MAX, /* UINT32_MAX means do not change WOL setting. */
242                 .duplex = _DUP_INVALID,
243                 .port = _NET_DEV_PORT_INVALID,
244                 .autonegotiation = -1,
245                 .rx_flow_control = -1,
246                 .tx_flow_control = -1,
247                 .autoneg_flow_control = -1,
248                 .txqueuelen = UINT32_MAX,
249                 .coalesce.use_adaptive_rx_coalesce = -1,
250                 .coalesce.use_adaptive_tx_coalesce = -1,
251                 .mdi = ETH_TP_MDI_INVALID,
252                 .sr_iov_num_vfs = UINT32_MAX,
253         };
254 
255         for (i = 0; i < ELEMENTSOF(config->features); i++)
256                 config->features[i] = -1;
257 
258         dropin_dirname = strjoina(basename(filename), ".d");
259         r = config_parse_many(
260                         STRV_MAKE_CONST(filename),
261                         NETWORK_DIRS,
262                         dropin_dirname,
263                         "Match\0"
264                         "Link\0"
265                         "SR-IOV\0",
266                         config_item_perf_lookup, link_config_gperf_lookup,
267                         CONFIG_PARSE_WARN, config, &stats_by_path);
268         if (r < 0)
269                 return r; /* config_parse_many() logs internally. */
270 
271         if (ctx->stats_by_path) {
272                 r = hashmap_move(ctx->stats_by_path, stats_by_path);
273                 if (r < 0)
274                         log_warning_errno(r, "Failed to save stats of '%s' and its drop-in configs, ignoring: %m", filename);
275         } else
276                 ctx->stats_by_path = TAKE_PTR(stats_by_path);
277 
278         if (net_match_is_empty(&config->match) && !config->conditions) {
279                 log_warning("%s: No valid settings found in the [Match] section, ignoring file. "
280                             "To match all interfaces, add OriginalName=* in the [Match] section.",
281                             filename);
282                 return 0;
283         }
284 
285         if (!condition_test_list(config->conditions, environ, NULL, NULL, NULL)) {
286                 log_debug("%s: Conditions do not match the system environment, skipping.", filename);
287                 return 0;
288         }
289 
290         if (IN_SET(config->mac_address_policy, MAC_ADDRESS_POLICY_PERSISTENT, MAC_ADDRESS_POLICY_RANDOM) &&
291             config->hw_addr.length > 0)
292                 log_warning("%s: MACAddress= in [Link] section will be ignored when MACAddressPolicy= "
293                             "is set to \"persistent\" or \"random\".",
294                             filename);
295 
296         r = link_adjust_wol_options(config);
297         if (r < 0)
298                 return r; /* link_adjust_wol_options() logs internally. */
299 
300         r = sr_iov_drop_invalid_sections(config->sr_iov_num_vfs, config->sr_iov_by_section);
301         if (r < 0)
302                 return r; /* sr_iov_drop_invalid_sections() logs internally. */
303 
304         log_debug("Parsed configuration file \"%s\"", filename);
305 
306         LIST_PREPEND(configs, ctx->configs, TAKE_PTR(config));
307         return 0;
308 }
309 
device_unsigned_attribute(sd_device * device,const char * attr,unsigned * type)310 static int device_unsigned_attribute(sd_device *device, const char *attr, unsigned *type) {
311         const char *s;
312         int r;
313 
314         r = sd_device_get_sysattr_value(device, attr, &s);
315         if (r < 0)
316                 return log_device_debug_errno(device, r, "Failed to query %s: %m", attr);
317 
318         r = safe_atou(s, type);
319         if (r < 0)
320                 return log_device_warning_errno(device, r, "Failed to parse %s \"%s\": %m", attr, s);
321 
322         log_device_debug(device, "Device has %s=%u", attr, *type);
323         return 0;
324 }
325 
link_config_load(LinkConfigContext * ctx)326 int link_config_load(LinkConfigContext *ctx) {
327         _cleanup_strv_free_ char **files = NULL;
328         int r;
329 
330         assert(ctx);
331 
332         link_configs_free(ctx);
333 
334         r = conf_files_list_strv(&files, ".link", NULL, 0, NETWORK_DIRS);
335         if (r < 0)
336                 return log_error_errno(r, "failed to enumerate link files: %m");
337 
338         STRV_FOREACH_BACKWARDS(f, files)
339                 (void) link_load_one(ctx, *f);
340 
341         return 0;
342 }
343 
link_config_should_reload(LinkConfigContext * ctx)344 bool link_config_should_reload(LinkConfigContext *ctx) {
345         _cleanup_hashmap_free_ Hashmap *stats_by_path = NULL;
346         int r;
347 
348         assert(ctx);
349 
350         r = config_get_stats_by_path(".link", NULL, 0, NETWORK_DIRS, &stats_by_path);
351         if (r < 0) {
352                 log_warning_errno(r, "Failed to get stats of .link files: %m");
353                 return true;
354         }
355 
356         return !stats_by_path_equal(ctx->stats_by_path, stats_by_path);
357 }
358 
link_free(Link * link)359 Link *link_free(Link *link) {
360         if (!link)
361                 return NULL;
362 
363         sd_device_unref(link->device);
364         free(link->kind);
365         free(link->driver);
366         return mfree(link);
367 }
368 
link_new(LinkConfigContext * ctx,sd_netlink ** rtnl,sd_device * device,Link ** ret)369 int link_new(LinkConfigContext *ctx, sd_netlink **rtnl, sd_device *device, Link **ret) {
370         _cleanup_(link_freep) Link *link = NULL;
371         int r;
372 
373         assert(ctx);
374         assert(rtnl);
375         assert(device);
376         assert(ret);
377 
378         link = new(Link, 1);
379         if (!link)
380                 return -ENOMEM;
381 
382         *link = (Link) {
383                 .device = sd_device_ref(device),
384         };
385 
386         r = sd_device_get_sysname(device, &link->ifname);
387         if (r < 0)
388                 return r;
389 
390         r = sd_device_get_ifindex(device, &link->ifindex);
391         if (r < 0)
392                 return r;
393 
394         r = sd_device_get_action(device, &link->action);
395         if (r < 0)
396                 return r;
397 
398         r = device_unsigned_attribute(device, "name_assign_type", &link->name_assign_type);
399         if (r < 0)
400                 log_link_debug_errno(link, r, "Failed to get \"name_assign_type\" attribute, ignoring: %m");
401 
402         r = device_unsigned_attribute(device, "addr_assign_type", &link->addr_assign_type);
403         if (r < 0)
404                 log_link_debug_errno(link, r, "Failed to get \"addr_assign_type\" attribute, ignoring: %m");
405 
406         r = rtnl_get_link_info(rtnl, link->ifindex, &link->iftype, &link->flags,
407                                &link->kind, &link->hw_addr, &link->permanent_hw_addr);
408         if (r < 0)
409                 return r;
410 
411         if (link->hw_addr.length > 0 && link->permanent_hw_addr.length == 0) {
412                 r = ethtool_get_permanent_hw_addr(&ctx->ethtool_fd, link->ifname, &link->permanent_hw_addr);
413                 if (r < 0)
414                         log_link_debug_errno(link, r, "Failed to get permanent hardware address, ignoring: %m");
415         }
416 
417         r = ethtool_get_driver(&ctx->ethtool_fd, link->ifname, &link->driver);
418         if (r < 0)
419                 log_link_debug_errno(link, r, "Failed to get driver, ignoring: %m");
420 
421         *ret = TAKE_PTR(link);
422         return 0;
423 }
424 
link_get_config(LinkConfigContext * ctx,Link * link)425 int link_get_config(LinkConfigContext *ctx, Link *link) {
426         int r;
427 
428         assert(ctx);
429         assert(link);
430 
431         /* Do not configure loopback interfaces by .link files. */
432         if (link->flags & IFF_LOOPBACK)
433                 return -ENOENT;
434 
435         LIST_FOREACH(configs, config, ctx->configs) {
436                 r = net_match_config(
437                                 &config->match,
438                                 link->device,
439                                 &link->hw_addr,
440                                 &link->permanent_hw_addr,
441                                 link->driver,
442                                 link->iftype,
443                                 link->kind,
444                                 link->ifname,
445                                 /* alternative_names = */ NULL,
446                                 /* wlan_iftype = */ 0,
447                                 /* ssid = */ NULL,
448                                 /* bssid = */ NULL);
449                 if (r < 0)
450                         return r;
451                 if (r == 0)
452                         continue;
453 
454                 if (config->match.ifname && !strv_contains(config->match.ifname, "*") && link->name_assign_type == NET_NAME_ENUM)
455                         log_link_warning(link, "Config file %s is applied to device based on potentially unpredictable interface name.",
456                                          config->filename);
457                 else
458                         log_link_debug(link, "Config file %s is applied", config->filename);
459 
460                 link->config = config;
461                 return 0;
462         }
463 
464         return -ENOENT;
465 }
466 
link_apply_ethtool_settings(Link * link,int * ethtool_fd)467 static int link_apply_ethtool_settings(Link *link, int *ethtool_fd) {
468         LinkConfig *config;
469         const char *name;
470         int r;
471 
472         assert(link);
473         assert(link->config);
474         assert(ethtool_fd);
475 
476         config = link->config;
477         name = link->ifname;
478 
479         r = ethtool_set_glinksettings(ethtool_fd, name,
480                                       config->autonegotiation, config->advertise,
481                                       config->speed, config->duplex, config->port, config->mdi);
482         if (r < 0) {
483                 if (config->autonegotiation >= 0)
484                         log_link_warning_errno(link, r, "Could not %s auto negotiation, ignoring: %m",
485                                                enable_disable(config->autonegotiation));
486 
487                 if (!eqzero(config->advertise))
488                         log_link_warning_errno(link, r, "Could not set advertise mode, ignoring: %m");
489 
490                 if (config->speed > 0)
491                         log_link_warning_errno(link, r, "Could not set speed to %"PRIu64"Mbps, ignoring: %m",
492                                                DIV_ROUND_UP(config->speed, 1000000));
493 
494                 if (config->duplex >= 0)
495                         log_link_warning_errno(link, r, "Could not set duplex to %s, ignoring: %m",
496                                                duplex_to_string(config->duplex));
497 
498                 if (config->port >= 0)
499                         log_link_warning_errno(link, r, "Could not set port to '%s', ignoring: %m",
500                                                port_to_string(config->port));
501 
502                 if (config->mdi != ETH_TP_MDI_INVALID)
503                         log_link_warning_errno(link, r, "Could not set MDI-X to '%s', ignoring: %m",
504                                                mdi_to_string(config->mdi));
505         }
506 
507         r = ethtool_set_wol(ethtool_fd, name, config->wol, config->wol_password);
508         if (r < 0) {
509                 _cleanup_free_ char *str = NULL;
510 
511                 (void) wol_options_to_string_alloc(config->wol, &str);
512                 log_link_warning_errno(link, r, "Could not set WakeOnLan%s%s, ignoring: %m",
513                                        isempty(str) ? "" : " to ", strempty(str));
514         }
515 
516         r = ethtool_set_features(ethtool_fd, name, config->features);
517         if (r < 0)
518                 log_link_warning_errno(link, r, "Could not set offload features, ignoring: %m");
519 
520         r = ethtool_set_channels(ethtool_fd, name, &config->channels);
521         if (r < 0)
522                 log_link_warning_errno(link, r, "Could not set channels, ignoring: %m");
523 
524         r = ethtool_set_nic_buffer_size(ethtool_fd, name, &config->ring);
525         if (r < 0)
526                 log_link_warning_errno(link, r, "Could not set ring buffer, ignoring: %m");
527 
528         r = ethtool_set_flow_control(ethtool_fd, name, config->rx_flow_control, config->tx_flow_control, config->autoneg_flow_control);
529         if (r < 0)
530                 log_link_warning_errno(link, r, "Could not set flow control, ignoring: %m");
531 
532         r = ethtool_set_nic_coalesce_settings(ethtool_fd, name, &config->coalesce);
533         if (r < 0)
534                 log_link_warning_errno(link, r, "Could not set coalesce settings, ignoring: %m");
535 
536         return 0;
537 }
538 
hw_addr_is_valid(Link * link,const struct hw_addr_data * hw_addr)539 static bool hw_addr_is_valid(Link *link, const struct hw_addr_data *hw_addr) {
540         assert(link);
541         assert(hw_addr);
542 
543         switch (link->iftype) {
544         case ARPHRD_ETHER:
545                 /* Refuse all zero and all 0xFF. */
546                 assert(hw_addr->length == ETH_ALEN);
547                 return !ether_addr_is_null(&hw_addr->ether) && !ether_addr_is_broadcast(&hw_addr->ether);
548 
549         case ARPHRD_INFINIBAND:
550                 /* The last 8 bytes cannot be zero*/
551                 assert(hw_addr->length == INFINIBAND_ALEN);
552                 return !memeqzero(hw_addr->bytes + INFINIBAND_ALEN - 8, 8);
553 
554         default:
555                 assert_not_reached();
556         }
557 }
558 
link_generate_new_hw_addr(Link * link,struct hw_addr_data * ret)559 static int link_generate_new_hw_addr(Link *link, struct hw_addr_data *ret) {
560         struct hw_addr_data hw_addr = HW_ADDR_NULL;
561         bool is_static = false;
562         uint8_t *p;
563         size_t len;
564         int r;
565 
566         assert(link);
567         assert(link->config);
568         assert(link->device);
569         assert(ret);
570 
571         if (link->hw_addr.length == 0)
572                 goto finalize;
573 
574         if (link->config->mac_address_policy == MAC_ADDRESS_POLICY_NONE) {
575                 log_link_debug(link, "Using static MAC address.");
576                 hw_addr = link->config->hw_addr;
577                 is_static = true;
578                 goto finalize;
579         }
580 
581         if (!IN_SET(link->iftype, ARPHRD_ETHER, ARPHRD_INFINIBAND))
582                 goto finalize;
583 
584         switch (link->addr_assign_type) {
585         case NET_ADDR_SET:
586                 log_link_debug(link, "MAC address on the device already set by userspace.");
587                 goto finalize;
588         case NET_ADDR_STOLEN:
589                 log_link_debug(link, "MAC address on the device already set based on another device.");
590                 goto finalize;
591         case NET_ADDR_RANDOM:
592         case NET_ADDR_PERM:
593                 break;
594         default:
595                 log_link_warning(link, "Unknown addr_assign_type %u, ignoring", link->addr_assign_type);
596                 goto finalize;
597         }
598 
599         if ((link->config->mac_address_policy == MAC_ADDRESS_POLICY_RANDOM) == (link->addr_assign_type == NET_ADDR_RANDOM)) {
600                 log_link_debug(link, "MAC address on the device already matches policy \"%s\".",
601                                mac_address_policy_to_string(link->config->mac_address_policy));
602                 goto finalize;
603         }
604 
605         hw_addr = (struct hw_addr_data) {
606                 .length = arphrd_to_hw_addr_len(link->iftype),
607         };
608 
609         switch (link->iftype) {
610         case ARPHRD_ETHER:
611                 p = hw_addr.bytes;
612                 len = hw_addr.length;
613                 break;
614         case ARPHRD_INFINIBAND:
615                 p = hw_addr.bytes + INFINIBAND_ALEN - 8;
616                 len = 8;
617                 break;
618         default:
619                 assert_not_reached();
620         }
621 
622         if (link->config->mac_address_policy == MAC_ADDRESS_POLICY_RANDOM)
623                 /* We require genuine randomness here, since we want to make sure we won't collide with other
624                  * systems booting up at the very same time. */
625                 for (;;) {
626                         r = genuine_random_bytes(p, len, 0);
627                         if (r < 0)
628                                 return log_link_warning_errno(link, r, "Failed to acquire random data to generate MAC address: %m");
629 
630                         if (hw_addr_is_valid(link, &hw_addr))
631                                 break;
632                 }
633 
634         else {
635                 uint64_t result;
636 
637                 r = net_get_unique_predictable_data(link->device,
638                                                     naming_scheme_has(NAMING_STABLE_VIRTUAL_MACS),
639                                                     &result);
640                 if (r < 0)
641                         return log_link_warning_errno(link, r, "Could not generate persistent MAC address: %m");
642 
643                 assert(len <= sizeof(result));
644                 memcpy(p, &result, len);
645                 if (!hw_addr_is_valid(link, &hw_addr))
646                         return log_link_warning_errno(link, SYNTHETIC_ERRNO(EINVAL),
647                                                       "Could not generate valid persistent MAC address: %m");
648         }
649 
650 finalize:
651 
652         r = net_verify_hardware_address(link->ifname, is_static, link->iftype, &link->hw_addr, &hw_addr);
653         if (r < 0)
654                 return r;
655 
656         if (hw_addr_equal(&link->hw_addr, &hw_addr)) {
657                 *ret = HW_ADDR_NULL;
658                 return 0;
659         }
660 
661         if (hw_addr.length > 0)
662                 log_link_debug(link, "Applying %s MAC address: %s",
663                                link->config->mac_address_policy == MAC_ADDRESS_POLICY_NONE ? "static" :
664                                mac_address_policy_to_string(link->config->mac_address_policy),
665                                HW_ADDR_TO_STR(&hw_addr));
666 
667         *ret = hw_addr;
668         return 0;
669 }
670 
link_apply_rtnl_settings(Link * link,sd_netlink ** rtnl)671 static int link_apply_rtnl_settings(Link *link, sd_netlink **rtnl) {
672         struct hw_addr_data hw_addr = {};
673         LinkConfig *config;
674         int r;
675 
676         assert(link);
677         assert(link->config);
678         assert(rtnl);
679 
680         config = link->config;
681 
682         (void) link_generate_new_hw_addr(link, &hw_addr);
683 
684         r = rtnl_set_link_properties(rtnl, link->ifindex, config->alias, &hw_addr,
685                                      config->txqueues, config->rxqueues, config->txqueuelen,
686                                      config->mtu, config->gso_max_size, config->gso_max_segments);
687         if (r < 0)
688                 log_link_warning_errno(link, r,
689                                        "Could not set Alias=, MACAddress=/MACAddressPolicy=, "
690                                        "TransmitQueues=, ReceiveQueues=, TransmitQueueLength=, MTUBytes=, "
691                                        "GenericSegmentOffloadMaxBytes= or GenericSegmentOffloadMaxSegments=, "
692                                        "ignoring: %m");
693 
694         return 0;
695 }
696 
enable_name_policy(void)697 static bool enable_name_policy(void) {
698         static int cached = -1;
699         bool b;
700         int r;
701 
702         if (cached >= 0)
703                 return cached;
704 
705         r = proc_cmdline_get_bool("net.ifnames", &b);
706         if (r < 0)
707                 log_warning_errno(r, "Failed to parse net.ifnames= kernel command line option, ignoring: %m");
708         if (r <= 0)
709                 return (cached = true);
710 
711         if (!b)
712                 log_info("Network interface NamePolicy= disabled on kernel command line.");
713 
714         return (cached = b);
715 }
716 
link_generate_new_name(Link * link)717 static int link_generate_new_name(Link *link) {
718         LinkConfig *config;
719         sd_device *device;
720 
721         assert(link);
722         assert(link->config);
723         assert(link->device);
724 
725         config = link->config;
726         device = link->device;
727 
728         if (link->action == SD_DEVICE_MOVE) {
729                 log_link_debug(link, "Skipping to apply Name= and NamePolicy= on '%s' uevent.",
730                                device_action_to_string(link->action));
731                 goto no_rename;
732         }
733 
734         if (IN_SET(link->name_assign_type, NET_NAME_USER, NET_NAME_RENAMED) &&
735             !naming_scheme_has(NAMING_ALLOW_RERENAMES)) {
736                 log_link_debug(link, "Device already has a name given by userspace, not renaming.");
737                 goto no_rename;
738         }
739 
740         if (enable_name_policy() && config->name_policy)
741                 for (NamePolicy *policy = config->name_policy; *policy != _NAMEPOLICY_INVALID; policy++) {
742                         const char *new_name = NULL;
743 
744                         switch (*policy) {
745                         case NAMEPOLICY_KERNEL:
746                                 if (link->name_assign_type != NET_NAME_PREDICTABLE)
747                                         continue;
748 
749                                 /* The kernel claims to have given a predictable name, keep it. */
750                                 log_link_debug(link, "Policy *%s*: keeping predictable kernel name",
751                                                name_policy_to_string(*policy));
752                                 goto no_rename;
753                         case NAMEPOLICY_KEEP:
754                                 if (!IN_SET(link->name_assign_type, NET_NAME_USER, NET_NAME_RENAMED))
755                                         continue;
756 
757                                 log_link_debug(link, "Policy *%s*: keeping existing userspace name",
758                                                name_policy_to_string(*policy));
759                                 goto no_rename;
760                         case NAMEPOLICY_DATABASE:
761                                 (void) sd_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE", &new_name);
762                                 break;
763                         case NAMEPOLICY_ONBOARD:
764                                 (void) sd_device_get_property_value(device, "ID_NET_NAME_ONBOARD", &new_name);
765                                 break;
766                         case NAMEPOLICY_SLOT:
767                                 (void) sd_device_get_property_value(device, "ID_NET_NAME_SLOT", &new_name);
768                                 break;
769                         case NAMEPOLICY_PATH:
770                                 (void) sd_device_get_property_value(device, "ID_NET_NAME_PATH", &new_name);
771                                 break;
772                         case NAMEPOLICY_MAC:
773                                 (void) sd_device_get_property_value(device, "ID_NET_NAME_MAC", &new_name);
774                                 break;
775                         default:
776                                 assert_not_reached();
777                         }
778                         if (ifname_valid(new_name)) {
779                                 log_link_debug(link, "Policy *%s* yields \"%s\".", name_policy_to_string(*policy), new_name);
780                                 link->new_name = new_name;
781                                 return 0;
782                         }
783                 }
784 
785         if (link->config->name) {
786                 log_link_debug(link, "Policies didn't yield a name, using specified Name=%s.", link->config->name);
787                 link->new_name = link->config->name;
788                 return 0;
789         }
790 
791         log_link_debug(link, "Policies didn't yield a name and Name= is not given, not renaming.");
792 no_rename:
793         link->new_name = link->ifname;
794         return 0;
795 }
796 
link_apply_alternative_names(Link * link,sd_netlink ** rtnl)797 static int link_apply_alternative_names(Link *link, sd_netlink **rtnl) {
798         _cleanup_strv_free_ char **altnames = NULL, **current_altnames = NULL;
799         LinkConfig *config;
800         sd_device *device;
801         int r;
802 
803         assert(link);
804         assert(link->config);
805         assert(link->device);
806         assert(rtnl);
807 
808         config = link->config;
809         device = link->device;
810 
811         if (config->alternative_names) {
812                 altnames = strv_copy(config->alternative_names);
813                 if (!altnames)
814                         return log_oom();
815         }
816 
817         if (config->alternative_names_policy)
818                 for (NamePolicy *p = config->alternative_names_policy; *p != _NAMEPOLICY_INVALID; p++) {
819                         const char *n = NULL;
820 
821                         switch (*p) {
822                         case NAMEPOLICY_DATABASE:
823                                 (void) sd_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE", &n);
824                                 break;
825                         case NAMEPOLICY_ONBOARD:
826                                 (void) sd_device_get_property_value(device, "ID_NET_NAME_ONBOARD", &n);
827                                 break;
828                         case NAMEPOLICY_SLOT:
829                                 (void) sd_device_get_property_value(device, "ID_NET_NAME_SLOT", &n);
830                                 break;
831                         case NAMEPOLICY_PATH:
832                                 (void) sd_device_get_property_value(device, "ID_NET_NAME_PATH", &n);
833                                 break;
834                         case NAMEPOLICY_MAC:
835                                 (void) sd_device_get_property_value(device, "ID_NET_NAME_MAC", &n);
836                                 break;
837                         default:
838                                 assert_not_reached();
839                         }
840                         if (!isempty(n)) {
841                                 r = strv_extend(&altnames, n);
842                                 if (r < 0)
843                                         return log_oom();
844                         }
845                 }
846 
847         if (link->new_name)
848                 strv_remove(altnames, link->new_name);
849         strv_remove(altnames, link->ifname);
850 
851         r = rtnl_get_link_alternative_names(rtnl, link->ifindex, &current_altnames);
852         if (r < 0)
853                 log_link_debug_errno(link, r, "Failed to get alternative names, ignoring: %m");
854 
855         STRV_FOREACH(p, current_altnames)
856                 strv_remove(altnames, *p);
857 
858         strv_uniq(altnames);
859         strv_sort(altnames);
860         r = rtnl_set_link_alternative_names(rtnl, link->ifindex, altnames);
861         if (r < 0)
862                 log_link_full_errno(link, r == -EOPNOTSUPP ? LOG_DEBUG : LOG_WARNING, r,
863                                     "Could not set AlternativeName= or apply AlternativeNamesPolicy=, ignoring: %m");
864 
865         return 0;
866 }
867 
sr_iov_configure(Link * link,sd_netlink ** rtnl,SRIOV * sr_iov)868 static int sr_iov_configure(Link *link, sd_netlink **rtnl, SRIOV *sr_iov) {
869         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
870         int r;
871 
872         assert(link);
873         assert(rtnl);
874         assert(link->ifindex > 0);
875 
876         if (!*rtnl) {
877                 r = sd_netlink_open(rtnl);
878                 if (r < 0)
879                         return r;
880         }
881 
882         r = sd_rtnl_message_new_link(*rtnl, &req, RTM_SETLINK, link->ifindex);
883         if (r < 0)
884                 return r;
885 
886         r = sr_iov_set_netlink_message(sr_iov, req);
887         if (r < 0)
888                 return r;
889 
890         r = sd_netlink_call(*rtnl, req, 0, NULL);
891         if (r < 0)
892                 return r;
893 
894         return 0;
895 }
896 
link_apply_sr_iov_config(Link * link,sd_netlink ** rtnl)897 static int link_apply_sr_iov_config(Link *link, sd_netlink **rtnl) {
898         SRIOV *sr_iov;
899         uint32_t n;
900         int r;
901 
902         assert(link);
903         assert(link->config);
904         assert(link->device);
905 
906         r = sr_iov_set_num_vfs(link->device, link->config->sr_iov_num_vfs, link->config->sr_iov_by_section);
907         if (r < 0)
908                 log_link_warning_errno(link, r, "Failed to set the number of SR-IOV virtual functions, ignoring: %m");
909 
910         if (ordered_hashmap_isempty(link->config->sr_iov_by_section))
911                 return 0;
912 
913         r = sr_iov_get_num_vfs(link->device, &n);
914         if (r < 0) {
915                 log_link_warning_errno(link, r, "Failed to get the number of SR-IOV virtual functions, ignoring [SR-IOV] sections: %m");
916                 return 0;
917         }
918         if (n == 0) {
919                 log_link_warning(link, "No SR-IOV virtual function exists, ignoring [SR-IOV] sections: %m");
920                 return 0;
921         }
922 
923         ORDERED_HASHMAP_FOREACH(sr_iov, link->config->sr_iov_by_section) {
924                 if (sr_iov->vf >= n) {
925                         log_link_warning(link, "SR-IOV virtual function %"PRIu32" does not exist, ignoring.", sr_iov->vf);
926                         continue;
927                 }
928 
929                 r = sr_iov_configure(link, rtnl, sr_iov);
930                 if (r < 0)
931                         log_link_warning_errno(link, r,
932                                                "Failed to configure SR-IOV virtual function %"PRIu32", ignoring: %m",
933                                                sr_iov->vf);
934         }
935 
936         return 0;
937 }
938 
link_apply_config(LinkConfigContext * ctx,sd_netlink ** rtnl,Link * link)939 int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link) {
940         int r;
941 
942         assert(ctx);
943         assert(rtnl);
944         assert(link);
945 
946         if (!IN_SET(link->action, SD_DEVICE_ADD, SD_DEVICE_BIND, SD_DEVICE_MOVE)) {
947                 log_link_debug(link, "Skipping to apply .link settings on '%s' uevent.",
948                                device_action_to_string(link->action));
949 
950                 link->new_name = link->ifname;
951                 return 0;
952         }
953 
954         r = link_apply_ethtool_settings(link, &ctx->ethtool_fd);
955         if (r < 0)
956                 return r;
957 
958         r = link_apply_rtnl_settings(link, rtnl);
959         if (r < 0)
960                 return r;
961 
962         r = link_generate_new_name(link);
963         if (r < 0)
964                 return r;
965 
966         r = link_apply_alternative_names(link, rtnl);
967         if (r < 0)
968                 return r;
969 
970         r = link_apply_sr_iov_config(link, rtnl);
971         if (r < 0)
972                 return r;
973 
974         return 0;
975 }
976 
config_parse_ifalias(const char * unit,const char * filename,unsigned line,const char * section,unsigned section_line,const char * lvalue,int ltype,const char * rvalue,void * data,void * userdata)977 int config_parse_ifalias(
978                 const char *unit,
979                 const char *filename,
980                 unsigned line,
981                 const char *section,
982                 unsigned section_line,
983                 const char *lvalue,
984                 int ltype,
985                 const char *rvalue,
986                 void *data,
987                 void *userdata) {
988 
989         char **s = data;
990 
991         assert(filename);
992         assert(lvalue);
993         assert(rvalue);
994         assert(data);
995 
996         if (isempty(rvalue)) {
997                 *s = mfree(*s);
998                 return 0;
999         }
1000 
1001         if (!ascii_is_valid(rvalue)) {
1002                 log_syntax(unit, LOG_WARNING, filename, line, 0,
1003                            "Interface alias is not ASCII clean, ignoring assignment: %s", rvalue);
1004                 return 0;
1005         }
1006 
1007         if (strlen(rvalue) >= IFALIASZ) {
1008                 log_syntax(unit, LOG_WARNING, filename, line, 0,
1009                            "Interface alias is too long, ignoring assignment: %s", rvalue);
1010                 return 0;
1011         }
1012 
1013         return free_and_strdup_warn(s, rvalue);
1014 }
1015 
config_parse_rx_tx_queues(const char * unit,const char * filename,unsigned line,const char * section,unsigned section_line,const char * lvalue,int ltype,const char * rvalue,void * data,void * userdata)1016 int config_parse_rx_tx_queues(
1017                 const char *unit,
1018                 const char *filename,
1019                 unsigned line,
1020                 const char *section,
1021                 unsigned section_line,
1022                 const char *lvalue,
1023                 int ltype,
1024                 const char *rvalue,
1025                 void *data,
1026                 void *userdata) {
1027 
1028         uint32_t k, *v = data;
1029         int r;
1030 
1031         if (isempty(rvalue)) {
1032                 *v = 0;
1033                 return 0;
1034         }
1035 
1036         r = safe_atou32(rvalue, &k);
1037         if (r < 0) {
1038                 log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse %s=, ignoring assignment: %s.", lvalue, rvalue);
1039                 return 0;
1040         }
1041         if (k == 0 || k > 4096) {
1042                 log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid %s=, ignoring assignment: %s.", lvalue, rvalue);
1043                 return 0;
1044         }
1045 
1046         *v = k;
1047         return 0;
1048 }
1049 
config_parse_txqueuelen(const char * unit,const char * filename,unsigned line,const char * section,unsigned section_line,const char * lvalue,int ltype,const char * rvalue,void * data,void * userdata)1050 int config_parse_txqueuelen(
1051                 const char *unit,
1052                 const char *filename,
1053                 unsigned line,
1054                 const char *section,
1055                 unsigned section_line,
1056                 const char *lvalue,
1057                 int ltype,
1058                 const char *rvalue,
1059                 void *data,
1060                 void *userdata) {
1061 
1062         uint32_t k, *v = data;
1063         int r;
1064 
1065         if (isempty(rvalue)) {
1066                 *v = UINT32_MAX;
1067                 return 0;
1068         }
1069 
1070         r = safe_atou32(rvalue, &k);
1071         if (r < 0) {
1072                 log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse %s=, ignoring assignment: %s.", lvalue, rvalue);
1073                 return 0;
1074         }
1075         if (k == UINT32_MAX) {
1076                 log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid %s=, ignoring assignment: %s.", lvalue, rvalue);
1077                 return 0;
1078         }
1079 
1080         *v = k;
1081         return 0;
1082 }
1083 
config_parse_wol_password(const char * unit,const char * filename,unsigned line,const char * section,unsigned section_line,const char * lvalue,int ltype,const char * rvalue,void * data,void * userdata)1084 int config_parse_wol_password(
1085                 const char *unit,
1086                 const char *filename,
1087                 unsigned line,
1088                 const char *section,
1089                 unsigned section_line,
1090                 const char *lvalue,
1091                 int ltype,
1092                 const char *rvalue,
1093                 void *data,
1094                 void *userdata) {
1095 
1096         LinkConfig *config = userdata;
1097         int r;
1098 
1099         assert(filename);
1100         assert(lvalue);
1101         assert(rvalue);
1102         assert(userdata);
1103 
1104         if (isempty(rvalue)) {
1105                 config->wol_password = erase_and_free(config->wol_password);
1106                 config->wol_password_file = mfree(config->wol_password_file);
1107                 return 0;
1108         }
1109 
1110         if (path_is_absolute(rvalue) && path_is_safe(rvalue)) {
1111                 config->wol_password = erase_and_free(config->wol_password);
1112                 return free_and_strdup_warn(&config->wol_password_file, rvalue);
1113         }
1114 
1115         warn_file_is_world_accessible(filename, NULL, unit, line);
1116 
1117         r = link_parse_wol_password(config, rvalue);
1118         if (r == -ENOMEM)
1119                 return log_oom();
1120         if (r < 0) {
1121                 log_syntax(unit, LOG_WARNING, filename, line, r,
1122                            "Failed to parse %s=, ignoring assignment: %s.", lvalue, rvalue);
1123                 return 0;
1124         }
1125 
1126         config->wol_password_file = mfree(config->wol_password_file);
1127         return 0;
1128 }
1129 
1130 static const char* const mac_address_policy_table[_MAC_ADDRESS_POLICY_MAX] = {
1131         [MAC_ADDRESS_POLICY_PERSISTENT] = "persistent",
1132         [MAC_ADDRESS_POLICY_RANDOM] = "random",
1133         [MAC_ADDRESS_POLICY_NONE] = "none",
1134 };
1135 
1136 DEFINE_STRING_TABLE_LOOKUP(mac_address_policy, MACAddressPolicy);
1137 DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(
1138         config_parse_mac_address_policy,
1139         mac_address_policy,
1140         MACAddressPolicy,
1141         MAC_ADDRESS_POLICY_NONE,
1142         "Failed to parse MAC address policy");
1143 
1144 DEFINE_CONFIG_PARSE_ENUMV(config_parse_name_policy, name_policy, NamePolicy,
1145                           _NAMEPOLICY_INVALID,
1146                           "Failed to parse interface name policy");
1147 
1148 DEFINE_CONFIG_PARSE_ENUMV(config_parse_alternative_names_policy, alternative_names_policy, NamePolicy,
1149                           _NAMEPOLICY_INVALID,
1150                           "Failed to parse alternative names policy");
1151