1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "alloc-util.h"
4 #include "device-private.h"
5 #include "device-util.h"
7 #include "errno-util.h"
8 #include "link-config.h"
10 #include "string-util.h"
12 #include "udev-builtin.h"
14 static LinkConfigContext
*ctx
= NULL
;
16 static int builtin_net_setup_link(UdevEvent
*event
, int argc
, char **argv
, bool test
) {
17 sd_device
*dev
= ASSERT_PTR(ASSERT_PTR(event
)->dev
);
18 _cleanup_(link_freep
) Link
*link
= NULL
;
19 _cleanup_free_
char *joined
= NULL
;
23 return log_device_error_errno(dev
, SYNTHETIC_ERRNO(EINVAL
), "This program takes no arguments.");
25 sd_device_action_t action
;
26 r
= sd_device_get_action(dev
, &action
);
28 return log_device_error_errno(dev
, r
, "Failed to get action: %m");
30 if (!IN_SET(action
, SD_DEVICE_ADD
, SD_DEVICE_BIND
, SD_DEVICE_MOVE
)) {
31 log_device_debug(dev
, "Skipping to apply .link settings on '%s' uevent.",
32 device_action_to_string(action
));
34 /* Import previously assigned .link file name. */
35 (void) udev_builtin_import_property(dev
, event
->dev_db_clone
, test
, "ID_NET_LINK_FILE");
36 (void) udev_builtin_import_property(dev
, event
->dev_db_clone
, test
, "ID_NET_LINK_FILE_DROPINS");
38 /* Set ID_NET_NAME= with the current interface name. */
40 if (sd_device_get_sysname(dev
, &value
) >= 0)
41 (void) udev_builtin_add_property(dev
, test
, "ID_NET_NAME", value
);
46 r
= link_new(ctx
, &event
->rtnl
, dev
, &link
);
48 log_device_debug_errno(dev
, r
, "Link vanished while getting information, ignoring.");
52 return log_device_warning_errno(dev
, r
, "Failed to get link information: %m");
54 r
= link_get_config(ctx
, link
);
57 log_device_debug_errno(dev
, r
, "No matching link configuration found, ignoring device.");
61 return log_device_error_errno(dev
, r
, "Failed to get link config: %m");
64 r
= link_apply_config(ctx
, &event
->rtnl
, link
);
66 log_device_debug_errno(dev
, r
, "Link vanished while applying configuration, ignoring.");
68 log_device_warning_errno(dev
, r
, "Could not apply link configuration, ignoring: %m");
70 udev_builtin_add_property(dev
, test
, "ID_NET_LINK_FILE", link
->config
->filename
);
72 udev_builtin_add_property(dev
, test
, "ID_NET_NAME", link
->new_name
);
74 event
->altnames
= TAKE_PTR(link
->altnames
);
76 STRV_FOREACH(d
, link
->config
->dropins
) {
77 _cleanup_free_
char *escaped
= NULL
;
79 escaped
= xescape(*d
, ":");
83 if (!strextend_with_separator(&joined
, ":", escaped
))
87 udev_builtin_add_property(dev
, test
, "ID_NET_LINK_FILE_DROPINS", joined
);
92 static int builtin_net_setup_link_init(void) {
98 r
= link_config_ctx_new(&ctx
);
102 r
= link_config_load(ctx
);
106 log_debug("Created link configuration context.");
110 static void builtin_net_setup_link_exit(void) {
111 ctx
= link_config_ctx_free(ctx
);
112 log_debug("Unloaded link configuration context.");
115 static bool builtin_net_setup_link_should_reload(void) {
119 if (link_config_should_reload(ctx
)) {
120 log_debug("Link configuration context needs reloading.");
127 const UdevBuiltin udev_builtin_net_setup_link
= {
128 .name
= "net_setup_link",
129 .cmd
= builtin_net_setup_link
,
130 .init
= builtin_net_setup_link_init
,
131 .exit
= builtin_net_setup_link_exit
,
132 .should_reload
= builtin_net_setup_link_should_reload
,
133 .help
= "Configure network link",