1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include "alloc-util.h"
4 #include "device-util.h"
5 #include "errno-util.h"
6 #include "link-config.h"
7 #include "log.h"
8 #include "string-util.h"
9 #include "udev-builtin.h"
10 
11 static LinkConfigContext *ctx = NULL;
12 
builtin_net_setup_link(sd_device * dev,sd_netlink ** rtnl,int argc,char ** argv,bool test)13 static int builtin_net_setup_link(sd_device *dev, sd_netlink **rtnl, int argc, char **argv, bool test) {
14         _cleanup_(link_freep) Link *link = NULL;
15         int r;
16 
17         if (argc > 1)
18                 return log_device_error_errno(dev, SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments.");
19 
20         r = link_new(ctx, rtnl, dev, &link);
21         if (r == -ENODEV) {
22                 log_device_debug_errno(dev, r, "Link vanished while getting information, ignoring.");
23                 return 0;
24         }
25         if (r < 0)
26                 return log_device_warning_errno(dev, r, "Failed to get link information: %m");
27 
28         if (link->driver)
29                 udev_builtin_add_property(dev, test, "ID_NET_DRIVER", link->driver);
30 
31         r = link_get_config(ctx, link);
32         if (r < 0) {
33                 if (r == -ENOENT) {
34                         log_device_debug_errno(dev, r, "No matching link configuration found, ignoring device.");
35                         return 0;
36                 }
37 
38                 return log_device_error_errno(dev, r, "Failed to get link config: %m");
39         }
40 
41         r = link_apply_config(ctx, rtnl, link);
42         if (r == -ENODEV)
43                 log_device_debug_errno(dev, r, "Link vanished while applying configuration, ignoring.");
44         else if (r < 0)
45                 log_device_warning_errno(dev, r, "Could not apply link configuration, ignoring: %m");
46 
47         udev_builtin_add_property(dev, test, "ID_NET_LINK_FILE", link->config->filename);
48         if (link->new_name)
49                 udev_builtin_add_property(dev, test, "ID_NET_NAME", link->new_name);
50 
51         return 0;
52 }
53 
builtin_net_setup_link_init(void)54 static int builtin_net_setup_link_init(void) {
55         int r;
56 
57         if (ctx)
58                 return 0;
59 
60         r = link_config_ctx_new(&ctx);
61         if (r < 0)
62                 return r;
63 
64         r = link_config_load(ctx);
65         if (r < 0)
66                 return r;
67 
68         log_debug("Created link configuration context.");
69         return 0;
70 }
71 
builtin_net_setup_link_exit(void)72 static void builtin_net_setup_link_exit(void) {
73         ctx = link_config_ctx_free(ctx);
74         log_debug("Unloaded link configuration context.");
75 }
76 
builtin_net_setup_link_validate(void)77 static bool builtin_net_setup_link_validate(void) {
78         log_debug("Check if link configuration needs reloading.");
79         if (!ctx)
80                 return false;
81 
82         return link_config_should_reload(ctx);
83 }
84 
85 const UdevBuiltin udev_builtin_net_setup_link = {
86         .name = "net_setup_link",
87         .cmd = builtin_net_setup_link,
88         .init = builtin_net_setup_link_init,
89         .exit = builtin_net_setup_link_exit,
90         .validate = builtin_net_setup_link_validate,
91         .help = "Configure network link",
92         .run_once = false,
93 };
94