summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaan De Meyer <daan.j.demeyer@gmail.com>2022-11-30 16:13:23 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2023-01-12 05:44:52 +0100
commita2640646f1bf30193a39a820268d86a33e08eeef (patch)
tree83f83143bd2a89dd670fc7efe36934c920e84e56 /src
parentnetwork: fix race between RTM_NEWLINK and NL82011_CMD_NEW_INTERFACE (diff)
downloadsystemd-a2640646f1bf30193a39a820268d86a33e08eeef.tar.xz
systemd-a2640646f1bf30193a39a820268d86a33e08eeef.zip
network: Show network and link file dropins in networkctl status
Fixes #24428
Diffstat (limited to 'src')
-rw-r--r--src/libsystemd/sd-network/sd-network.c19
-rw-r--r--src/network/networkctl.c46
-rw-r--r--src/network/networkd-json.c13
-rw-r--r--src/network/networkd-network.c3
-rw-r--r--src/network/networkd-network.h1
-rw-r--r--src/network/networkd-state-file.c15
-rw-r--r--src/systemd/sd-network.h3
-rw-r--r--src/udev/net/link-config.c3
-rw-r--r--src/udev/net/link-config.h1
-rw-r--r--src/udev/udev-builtin-net_setup_link.c16
10 files changed, 113 insertions, 7 deletions
diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c
index 56de3f965c..dd440a5d17 100644
--- a/src/libsystemd/sd-network/sd-network.c
+++ b/src/libsystemd/sd-network/sd-network.c
@@ -159,6 +159,25 @@ int sd_network_link_get_network_file(int ifindex, char **ret) {
return network_link_get_string(ifindex, "NETWORK_FILE", ret);
}
+int sd_network_link_get_network_file_dropins(int ifindex, char ***ret) {
+ _cleanup_free_ char **sv = NULL, *joined = NULL;
+ int r;
+
+ assert_return(ifindex > 0, -EINVAL);
+ assert_return(ret, -EINVAL);
+
+ r = network_link_get_string(ifindex, "NETWORK_FILE_DROPINS", &joined);
+ if (r < 0)
+ return r;
+
+ r = strv_split_full(&sv, joined, ":", EXTRACT_CUNESCAPE);
+ if (r < 0)
+ return r;
+
+ *ret = TAKE_PTR(sv);
+ return 0;
+}
+
int sd_network_link_get_operational_state(int ifindex, char **ret) {
return network_link_get_string(ifindex, "OPER_STATE", ret);
}
diff --git a/src/network/networkctl.c b/src/network/networkctl.c
index 357d38f5ea..65015b132f 100644
--- a/src/network/networkctl.c
+++ b/src/network/networkctl.c
@@ -1536,13 +1536,29 @@ static int table_add_string_line(Table *table, const char *key, const char *valu
return 0;
}
+static int format_dropins(char **dropins) {
+ STRV_FOREACH(d, dropins) {
+ _cleanup_free_ char *s = NULL;
+ int glyph = *(d + 1) == NULL ? SPECIAL_GLYPH_TREE_RIGHT : SPECIAL_GLYPH_TREE_BRANCH;
+
+ s = strjoin(special_glyph(glyph), *d);
+ if (!s)
+ return log_oom();
+
+ free_and_replace(*d, s);
+ }
+
+ return 0;
+}
+
static int link_status_one(
sd_bus *bus,
sd_netlink *rtnl,
sd_hwdb *hwdb,
const LinkInfo *info) {
- _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **sip = NULL, **search_domains = NULL, **route_domains = NULL;
+ _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **sip = NULL, **search_domains = NULL,
+ **route_domains = NULL, **link_dropins = NULL, **network_dropins = NULL;
_cleanup_free_ char *t = NULL, *network = NULL, *iaid = NULL, *duid = NULL,
*setup_state = NULL, *operational_state = NULL, *online_state = NULL, *activation_policy = NULL;
const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL,
@@ -1571,12 +1587,22 @@ static int link_status_one(
(void) sd_network_link_get_ntp(info->ifindex, &ntp);
(void) sd_network_link_get_sip(info->ifindex, &sip);
(void) sd_network_link_get_network_file(info->ifindex, &network);
+ (void) sd_network_link_get_network_file_dropins(info->ifindex, &network_dropins);
(void) sd_network_link_get_carrier_bound_to(info->ifindex, &carrier_bound_to);
(void) sd_network_link_get_carrier_bound_by(info->ifindex, &carrier_bound_by);
(void) sd_network_link_get_activation_policy(info->ifindex, &activation_policy);
if (info->sd_device) {
+ const char *joined;
+
(void) sd_device_get_property_value(info->sd_device, "ID_NET_LINK_FILE", &link);
+
+ if (sd_device_get_property_value(info->sd_device, "ID_NET_LINK_FILE_DROPINS", &joined) >= 0) {
+ r = strv_split_full(&link_dropins, joined, ":", EXTRACT_CUNESCAPE);
+ if (r < 0)
+ return r;
+ }
+
(void) sd_device_get_property_value(info->sd_device, "ID_NET_DRIVER", &driver);
(void) sd_device_get_property_value(info->sd_device, "ID_PATH", &path);
@@ -1596,6 +1622,20 @@ static int link_status_one(
(void) dhcp_lease_load(&lease, lease_file);
+ r = format_dropins(network_dropins);
+ if (r < 0)
+ return r;
+
+ if (strv_prepend(&network_dropins, network) < 0)
+ return log_oom();
+
+ r = format_dropins(link_dropins);
+ if (r < 0)
+ return r;
+
+ if (strv_prepend(&link_dropins, link) < 0)
+ return log_oom();
+
table = table_new("dot", "key", "value");
if (!table)
return log_oom();
@@ -1631,10 +1671,10 @@ static int link_status_one(
TABLE_EMPTY,
TABLE_STRING, "Link File:",
TABLE_SET_ALIGN_PERCENT, 100,
- TABLE_STRING, strna(link),
+ TABLE_STRV, link_dropins ?: STRV_MAKE("n/a"),
TABLE_EMPTY,
TABLE_STRING, "Network File:",
- TABLE_STRING, strna(network),
+ TABLE_STRV, network_dropins ?: STRV_MAKE("n/a"),
TABLE_EMPTY,
TABLE_STRING, "State:");
if (r < 0)
diff --git a/src/network/networkd-json.c b/src/network/networkd-json.c
index 9e2ff33d97..c37f734d61 100644
--- a/src/network/networkd-json.c
+++ b/src/network/networkd-json.c
@@ -464,6 +464,7 @@ static int network_build_json(Network *network, JsonVariant **ret) {
return json_build(ret, JSON_BUILD_OBJECT(
JSON_BUILD_PAIR_STRING("NetworkFile", network->filename),
+ JSON_BUILD_PAIR_STRV("NetworkFileDropins", network->dropins),
JSON_BUILD_PAIR_BOOLEAN("RequiredForOnline", network->required_for_online),
JSON_BUILD_PAIR("RequiredOperationalStateForOnline",
JSON_BUILD_ARRAY(JSON_BUILD_STRING(link_operstate_to_string(network->required_operstate_for_online.min)),
@@ -475,7 +476,9 @@ static int network_build_json(Network *network, JsonVariant **ret) {
}
static int device_build_json(sd_device *device, JsonVariant **ret) {
- const char *link = NULL, *path = NULL, *vendor = NULL, *model = NULL;
+ _cleanup_strv_free_ char **link_dropins = NULL;
+ const char *link = NULL, *path = NULL, *vendor = NULL, *model = NULL, *joined;
+ int r;
assert(ret);
@@ -485,6 +488,13 @@ static int device_build_json(sd_device *device, JsonVariant **ret) {
}
(void) sd_device_get_property_value(device, "ID_NET_LINK_FILE", &link);
+
+ if (sd_device_get_property_value(device, "ID_NET_LINK_FILE_DROPINS", &joined) >= 0) {
+ r = strv_split_full(&link_dropins, joined, ":", EXTRACT_CUNESCAPE);
+ if (r < 0)
+ return r;
+ }
+
(void) sd_device_get_property_value(device, "ID_PATH", &path);
if (sd_device_get_property_value(device, "ID_VENDOR_FROM_DATABASE", &vendor) < 0)
@@ -495,6 +505,7 @@ static int device_build_json(sd_device *device, JsonVariant **ret) {
return json_build(ret, JSON_BUILD_OBJECT(
JSON_BUILD_PAIR_STRING_NON_EMPTY("LinkFile", link),
+ JSON_BUILD_PAIR_STRV_NON_EMPTY("LinkFileDropins", link_dropins),
JSON_BUILD_PAIR_STRING_NON_EMPTY("Path", path),
JSON_BUILD_PAIR_STRING_NON_EMPTY("Vendor", vendor),
JSON_BUILD_PAIR_STRING_NON_EMPTY("Model", model)));
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index d516918c78..d881889316 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -552,7 +552,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
CONFIG_PARSE_WARN,
network,
&network->stats_by_path,
- NULL);
+ &network->dropins);
if (r < 0)
return r; /* config_parse_many() logs internally. */
@@ -670,6 +670,7 @@ static Network *network_free(Network *network) {
free(network->name);
free(network->filename);
free(network->description);
+ strv_free(network->dropins);
hashmap_free(network->stats_by_path);
/* conditions */
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 09f0e9beea..fbeec6072e 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -65,6 +65,7 @@ struct Network {
char *name;
char *filename;
+ char **dropins;
Hashmap *stats_by_path;
char *description;
diff --git a/src/network/networkd-state-file.c b/src/network/networkd-state-file.c
index 0800e91202..6e962c03f6 100644
--- a/src/network/networkd-state-file.c
+++ b/src/network/networkd-state-file.c
@@ -5,6 +5,7 @@
#include "alloc-util.h"
#include "dns-domain.h"
+#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
@@ -515,7 +516,7 @@ int link_save(Link *link) {
if (link->network) {
const char *online_state;
- bool space;
+ bool space = false;
online_state = link_online_state_to_string(link->online_state);
if (online_state)
@@ -538,6 +539,18 @@ int link_save(Link *link) {
fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
+ fputs("NETWORK_FILE_DROPINS=\"", f);
+ STRV_FOREACH(d, link->network->dropins) {
+ _cleanup_free_ char *escaped = NULL;
+
+ escaped = xescape(*d, ":");
+ if (!escaped)
+ return -ENOMEM;
+
+ fputs_with_space(f, escaped, ":", &space);
+ }
+ fputs("\"\n", f);
+
/************************************************************/
fputs("DNS=", f);
diff --git a/src/systemd/sd-network.h b/src/systemd/sd-network.h
index b89e035fd6..9cc2cbaa6e 100644
--- a/src/systemd/sd-network.h
+++ b/src/systemd/sd-network.h
@@ -119,6 +119,9 @@ int sd_network_link_get_activation_policy(int ifindex, char **ret);
/* Get path to .network file applied to link */
int sd_network_link_get_network_file(int ifindex, char **ret);
+/* Get paths to .network file dropins applied to link */
+int sd_network_link_get_network_file_dropins(int ifindex, char ***ret);
+
/* Get DNS entries for a given link. These are string representations of
* IP addresses */
int sd_network_link_get_dns(int ifindex, char ***ret);
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 5f18ba35fc..9efdb6000a 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -47,6 +47,7 @@ static LinkConfig* link_config_free(LinkConfig *config) {
return NULL;
free(config->filename);
+ strv_free(config->dropins);
net_match_clear(&config->match);
condition_free_list(config->conditions);
@@ -264,7 +265,7 @@ int link_load_one(LinkConfigContext *ctx, const char *filename) {
"SR-IOV\0",
config_item_perf_lookup, link_config_gperf_lookup,
CONFIG_PARSE_WARN, config, &stats_by_path,
- NULL);
+ &config->dropins);
if (r < 0)
return r; /* config_parse_many() logs internally. */
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
index ea9f560f45..ed0896e9de 100644
--- a/src/udev/net/link-config.h
+++ b/src/udev/net/link-config.h
@@ -44,6 +44,7 @@ typedef struct Link {
struct LinkConfig {
char *filename;
+ char **dropins;
NetMatch match;
LIST_HEAD(Condition, conditions);
diff --git a/src/udev/udev-builtin-net_setup_link.c b/src/udev/udev-builtin-net_setup_link.c
index ea7b1c5f60..18450536b5 100644
--- a/src/udev/udev-builtin-net_setup_link.c
+++ b/src/udev/udev-builtin-net_setup_link.c
@@ -2,16 +2,19 @@
#include "alloc-util.h"
#include "device-util.h"
+#include "escape.h"
#include "errno-util.h"
#include "link-config.h"
#include "log.h"
#include "string-util.h"
+#include "strv.h"
#include "udev-builtin.h"
static LinkConfigContext *ctx = NULL;
static int builtin_net_setup_link(sd_device *dev, sd_netlink **rtnl, int argc, char **argv, bool test) {
_cleanup_(link_freep) Link *link = NULL;
+ _cleanup_free_ char *joined = NULL;
int r;
if (argc > 1)
@@ -48,6 +51,19 @@ static int builtin_net_setup_link(sd_device *dev, sd_netlink **rtnl, int argc, c
if (link->new_name)
udev_builtin_add_property(dev, test, "ID_NET_NAME", link->new_name);
+ STRV_FOREACH(d, link->config->dropins) {
+ _cleanup_free_ char *escaped = NULL;
+
+ escaped = xescape(*d, ":");
+ if (!escaped)
+ return log_oom();
+
+ if (!strextend_with_separator(&joined, ":", escaped))
+ return log_oom();
+ }
+
+ udev_builtin_add_property(dev, test, "ID_NET_LINK_FILE_DROPINS", joined);
+
return 0;
}