| From d8798eb733d5680047128ec1f74c82f347c321ed Mon Sep 17 00:00:00 2001 |
| From: Ryan Wilson <ryantimwilson@meta4.com> |
| Date: Wed, 4 Dec 2024 16:53:40 -0800 |
| Subject: [PATCH] Revert "network/lldp: do not save LLDP neighbors under |
| /run/systemd" |
| |
| This reverts commit 5a0f6adbb2e39914897f404ac97fecebcc2c385a. |
| |
| src/libsystemd-network/lldp-neighbor.c | 11 ++++ |
| src/network/networkd-link.c | 7 ++- |
| src/network/networkd-link.h | 1 + |
| src/network/networkd-lldp-rx.c | 69 ++++++++++++++++++++++++++ |
| src/network/networkd-lldp-rx.h | 1 + |
| src/network/networkd-state-file.c | 2 + |
| src/network/networkd.c | 3 +- |
| src/systemd/sd-lldp-rx.h | 1 + |
| tmpfiles.d/systemd-network.conf | 1 + |
| 9 files changed, 94 insertions(+), 2 deletions(-) |
| |
| diff --git a/src/libsystemd-network/lldp-neighbor.c b/src/libsystemd-network/lldp-neighbor.c |
| index 02af2954ae..3d381294e6 100644 |
| |
| |
| @@ -376,6 +376,17 @@ int sd_lldp_neighbor_get_destination_address(sd_lldp_neighbor *n, struct ether_a |
| return 0; |
| } |
| |
| +int sd_lldp_neighbor_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size) { |
| + assert_return(n, -EINVAL); |
| + assert_return(ret, -EINVAL); |
| + assert_return(size, -EINVAL); |
| + |
| + *ret = LLDP_NEIGHBOR_RAW(n); |
| + *size = n->raw_size; |
| + |
| + return 0; |
| +} |
| + |
| int sd_lldp_neighbor_get_chassis_id(sd_lldp_neighbor *n, uint8_t *type, const void **ret, size_t *size) { |
| assert_return(n, -EINVAL); |
| assert_return(type, -EINVAL); |
| diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c |
| index 9ce75361fd..0436233ac9 100644 |
| |
| |
| @@ -273,6 +273,7 @@ static Link *link_free(Link *link) { |
| free(link->driver); |
| |
| unlink_and_free(link->lease_file); |
| + unlink_and_free(link->lldp_file); |
| unlink_and_free(link->state_file); |
| |
| sd_device_unref(link->dev); |
| @@ -2645,7 +2646,7 @@ static Link *link_drop_or_unref(Link *link) { |
| DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_drop_or_unref); |
| |
| static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { |
| - _cleanup_free_ char *ifname = NULL, *kind = NULL, *state_file = NULL, *lease_file = NULL; |
| + _cleanup_free_ char *ifname = NULL, *kind = NULL, *state_file = NULL, *lease_file = NULL, *lldp_file = NULL; |
| _cleanup_(link_drop_or_unrefp) Link *link = NULL; |
| unsigned short iftype; |
| int r, ifindex; |
| @@ -2686,6 +2687,9 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { |
| |
| if (asprintf(&lease_file, "/run/systemd/netif/leases/%d", ifindex) < 0) |
| return log_oom_debug(); |
| + |
| + if (asprintf(&lldp_file, "/run/systemd/netif/lldp/%d", ifindex) < 0) |
| + return log_oom_debug(); |
| } |
| |
| link = new(Link, 1); |
| @@ -2708,6 +2712,7 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { |
| |
| .state_file = TAKE_PTR(state_file), |
| .lease_file = TAKE_PTR(lease_file), |
| + .lldp_file = TAKE_PTR(lldp_file), |
| |
| .n_dns = UINT_MAX, |
| .dns_default_route = -1, |
| diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h |
| index b1b2fe42db..d590d071bd 100644 |
| |
| |
| @@ -184,6 +184,7 @@ typedef struct Link { |
| |
| /* This is about LLDP reception */ |
| sd_lldp_rx *lldp_rx; |
| + char *lldp_file; |
| |
| /* This is about LLDP transmission */ |
| sd_lldp_tx *lldp_tx; |
| diff --git a/src/network/networkd-lldp-rx.c b/src/network/networkd-lldp-rx.c |
| index f74485488e..c45d3e32d7 100644 |
| |
| |
| @@ -52,6 +52,8 @@ static void lldp_rx_handler(sd_lldp_rx *lldp_rx, sd_lldp_rx_event_t event, sd_ll |
| Link *link = ASSERT_PTR(userdata); |
| int r; |
| |
| + (void) link_lldp_save(link); |
| + |
| if (link->lldp_tx && event == SD_LLDP_RX_EVENT_ADDED) { |
| /* If we received information about a new neighbor, restart the LLDP "fast" logic */ |
| |
| @@ -102,3 +104,70 @@ int link_lldp_rx_configure(Link *link) { |
| |
| return 0; |
| } |
| + |
| +int link_lldp_save(Link *link) { |
| + _cleanup_(unlink_and_freep) char *temp_path = NULL; |
| + _cleanup_fclose_ FILE *f = NULL; |
| + sd_lldp_neighbor **l = NULL; |
| + int n = 0, r, i; |
| + |
| + assert(link); |
| + |
| + if (isempty(link->lldp_file)) |
| + return 0; /* Do not update state file when running in test mode. */ |
| + |
| + if (!link->lldp_rx) { |
| + (void) unlink(link->lldp_file); |
| + return 0; |
| + } |
| + |
| + r = sd_lldp_rx_get_neighbors(link->lldp_rx, &l); |
| + if (r < 0) |
| + return r; |
| + if (r == 0) { |
| + (void) unlink(link->lldp_file); |
| + return 0; |
| + } |
| + |
| + n = r; |
| + |
| + r = fopen_temporary(link->lldp_file, &f, &temp_path); |
| + if (r < 0) |
| + goto finish; |
| + |
| + (void) fchmod(fileno(f), 0644); |
| + |
| + for (i = 0; i < n; i++) { |
| + const void *p; |
| + le64_t u; |
| + size_t sz; |
| + |
| + r = sd_lldp_neighbor_get_raw(l[i], &p, &sz); |
| + if (r < 0) |
| + goto finish; |
| + |
| + u = htole64(sz); |
| + fwrite(&u, 1, sizeof(u), f); |
| + fwrite(p, 1, sz, f); |
| + } |
| + |
| + r = fflush_and_check(f); |
| + if (r < 0) |
| + goto finish; |
| + |
| + r = conservative_rename(temp_path, link->lldp_file); |
| + if (r < 0) |
| + goto finish; |
| + |
| +finish: |
| + if (r < 0) |
| + log_link_error_errno(link, r, "Failed to save LLDP data to %s: %m", link->lldp_file); |
| + |
| + if (l) { |
| + for (i = 0; i < n; i++) |
| + sd_lldp_neighbor_unref(l[i]); |
| + free(l); |
| + } |
| + |
| + return r; |
| +} |
| diff --git a/src/network/networkd-lldp-rx.h b/src/network/networkd-lldp-rx.h |
| index 75c9f8ca86..22f6602bd0 100644 |
| |
| |
| @@ -14,6 +14,7 @@ typedef enum LLDPMode { |
| } LLDPMode; |
| |
| int link_lldp_rx_configure(Link *link); |
| +int link_lldp_save(Link *link); |
| |
| const char* lldp_mode_to_string(LLDPMode m) _const_; |
| LLDPMode lldp_mode_from_string(const char *s) _pure_; |
| diff --git a/src/network/networkd-state-file.c b/src/network/networkd-state-file.c |
| index fbe4fee17d..bc08a84c74 100644 |
| |
| |
| @@ -584,6 +584,8 @@ static int link_save(Link *link) { |
| if (link->state == LINK_STATE_LINGER) |
| return 0; |
| |
| + link_lldp_save(link); |
| + |
| admin_state = link_state_to_string(link->state); |
| assert(admin_state); |
| |
| diff --git a/src/network/networkd.c b/src/network/networkd.c |
| index 69a28647c8..3384c7c3ea 100644 |
| |
| |
| @@ -72,7 +72,8 @@ static int run(int argc, char *argv[]) { |
| * to support old kernels not supporting AmbientCapabilities=. */ |
| FOREACH_STRING(p, |
| "/run/systemd/netif/links/", |
| - "/run/systemd/netif/leases/") { |
| + "/run/systemd/netif/leases/", |
| + "/run/systemd/netif/lldp/") { |
| r = mkdir_safe_label(p, 0755, UID_INVALID, GID_INVALID, MKDIR_WARN_MODE); |
| if (r < 0) |
| log_warning_errno(r, "Could not create directory '%s': %m", p); |
| diff --git a/src/systemd/sd-lldp-rx.h b/src/systemd/sd-lldp-rx.h |
| index 154e37e2d8..a876e41b25 100644 |
| |
| |
| @@ -75,6 +75,7 @@ sd_lldp_neighbor *sd_lldp_neighbor_unref(sd_lldp_neighbor *n); |
| int sd_lldp_neighbor_get_source_address(sd_lldp_neighbor *n, struct ether_addr* address); |
| int sd_lldp_neighbor_get_destination_address(sd_lldp_neighbor *n, struct ether_addr* address); |
| int sd_lldp_neighbor_get_timestamp(sd_lldp_neighbor *n, clockid_t clock, uint64_t *ret); |
| +int sd_lldp_neighbor_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size); |
| |
| /* High-level, direct, parsed out field access. These fields exist at most once, hence may be queried directly. */ |
| int sd_lldp_neighbor_get_chassis_id(sd_lldp_neighbor *n, uint8_t *type, const void **ret, size_t *size); |
| diff --git a/tmpfiles.d/systemd-network.conf b/tmpfiles.d/systemd-network.conf |
| index 323beca59c..107317a03c 100644 |
| |
| |
| @@ -10,4 +10,5 @@ |
| d /run/systemd/netif 0755 systemd-network systemd-network - |
| d /run/systemd/netif/links 0755 systemd-network systemd-network - |
| d /run/systemd/netif/leases 0755 systemd-network systemd-network - |
| +d /run/systemd/netif/lldp 0755 systemd-network systemd-network - |
| d /var/lib/systemd/network 0755 systemd-network systemd-network - |
| -- |
| 2.43.5 |
| |