From 7f8539504cf4da1259845cee2b5136bf29c5cad2 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 9 May 2019 07:21:55 +0200 Subject: [PATCH] network: move sd_lldp related functions to networkd-lldp-rx.c --- src/network/meson.build | 2 + src/network/networkd-link.c | 165 +-------------------------- src/network/networkd-lldp-rx.c | 197 +++++++++++++++++++++++++++++++++ src/network/networkd-lldp-rx.h | 26 +++++ src/network/networkd-network.c | 10 -- src/network/networkd-network.h | 13 +-- 6 files changed, 227 insertions(+), 186 deletions(-) create mode 100644 src/network/networkd-lldp-rx.c create mode 100644 src/network/networkd-lldp-rx.h diff --git a/src/network/meson.build b/src/network/meson.build index 2acbe858bb..a7192e2a2e 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -61,6 +61,8 @@ sources = files(''' networkd-link-bus.c networkd-link.c networkd-link.h + networkd-lldp-rx.c + networkd-lldp-rx.h networkd-lldp-tx.c networkd-lldp-tx.h networkd-manager-bus.c diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index af83cb4935..9f354b519f 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -195,27 +195,6 @@ static bool link_radv_enabled(Link *link) { return link->network->router_prefix_delegation != RADV_PREFIX_DELEGATION_NONE; } -static bool link_lldp_rx_enabled(Link *link) { - assert(link); - - if (link->flags & IFF_LOOPBACK) - return false; - - if (link->iftype != ARPHRD_ETHER) - return false; - - if (!link->network) - return false; - - /* LLDP should be handled on bridge slaves as those have a direct - * connection to their peers not on the bridge master. Linux doesn't - * even (by default) forward lldp packets to the bridge master.*/ - if (streq_ptr("bridge", link->kind)) - return false; - - return link->network->lldp_mode != LLDP_MODE_NO; -} - static bool link_ipv4_forward_enabled(Link *link) { assert(link); @@ -1725,96 +1704,6 @@ static int link_set_bond(Link *link) { return r; } -static int link_lldp_save(Link *link) { - _cleanup_free_ char *temp_path = NULL; - _cleanup_fclose_ FILE *f = NULL; - sd_lldp_neighbor **l = NULL; - int n = 0, r, i; - - assert(link); - assert(link->lldp_file); - - if (!link->lldp) { - (void) unlink(link->lldp_file); - return 0; - } - - r = sd_lldp_get_neighbors(link->lldp, &l); - if (r < 0) - goto finish; - if (r == 0) { - (void) unlink(link->lldp_file); - goto finish; - } - - n = r; - - r = fopen_temporary(link->lldp_file, &f, &temp_path); - if (r < 0) - goto finish; - - 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); - (void) fwrite(&u, 1, sizeof(u), f); - (void) fwrite(p, 1, sz, f); - } - - r = fflush_and_check(f); - if (r < 0) - goto finish; - - if (rename(temp_path, link->lldp_file) < 0) { - r = -errno; - goto finish; - } - -finish: - if (r < 0) { - (void) unlink(link->lldp_file); - if (temp_path) - (void) unlink(temp_path); - - 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; -} - -static void lldp_handler(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n, void *userdata) { - Link *link = userdata; - int r; - - assert(link); - - (void) link_lldp_save(link); - - if (link_lldp_emit_enabled(link) && event == SD_LLDP_EVENT_ADDED) { - /* If we received information about a new neighbor, restart the LLDP "fast" logic */ - - log_link_debug(link, "Received LLDP datagram from previously unknown neighbor, restarting 'fast' LLDP transmission."); - - r = link_lldp_emit_start(link); - if (r < 0) - log_link_warning_errno(link, r, "Failed to restart LLDP transmission: %m"); - } -} - static int link_acquire_ipv6_conf(Link *link) { int r; @@ -3017,31 +2906,6 @@ static int link_drop_config(Link *link) { return 0; } -static int link_update_lldp(Link *link) { - int r; - - assert(link); - - if (!link->lldp) - return 0; - - if (link->flags & IFF_UP) { - r = sd_lldp_start(link->lldp); - if (r < 0) - return log_link_warning_errno(link, r, "Failed to start LLDP: %m"); - if (r > 0) - log_link_debug(link, "Started LLDP."); - } else { - r = sd_lldp_stop(link->lldp); - if (r < 0) - return log_link_warning_errno(link, r, "Failed to stop LLDP: %m"); - if (r > 0) - log_link_debug(link, "Stopped LLDP."); - } - - return r; -} - static int link_configure_can(Link *link) { int r; @@ -3175,34 +3039,7 @@ static int link_configure(Link *link) { } if (link_lldp_rx_enabled(link)) { - r = sd_lldp_new(&link->lldp); - if (r < 0) - return r; - - r = sd_lldp_set_ifindex(link->lldp, link->ifindex); - if (r < 0) - return r; - - r = sd_lldp_match_capabilities(link->lldp, - link->network->lldp_mode == LLDP_MODE_ROUTERS_ONLY ? - SD_LLDP_SYSTEM_CAPABILITIES_ALL_ROUTERS : - SD_LLDP_SYSTEM_CAPABILITIES_ALL); - if (r < 0) - return r; - - r = sd_lldp_set_filter_address(link->lldp, &link->mac); - if (r < 0) - return r; - - r = sd_lldp_attach_event(link->lldp, NULL, 0); - if (r < 0) - return r; - - r = sd_lldp_set_callback(link->lldp, lldp_handler, link); - if (r < 0) - return r; - - r = link_update_lldp(link); + r = link_lldp_rx_configure(link); if (r < 0) return r; } diff --git a/src/network/networkd-lldp-rx.c b/src/network/networkd-lldp-rx.c new file mode 100644 index 0000000000..95018d37a3 --- /dev/null +++ b/src/network/networkd-lldp-rx.c @@ -0,0 +1,197 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include +#include + +#include "fd-util.h" +#include "fileio.h" +#include "networkd-link.h" +#include "networkd-lldp-rx.h" +#include "networkd-lldp-tx.h" +#include "networkd-network.h" +#include "string-table.h" +#include "string-util.h" +#include "tmpfile-util.h" + +DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode, lldp_mode, LLDPMode, "Failed to parse LLDP= setting."); + +static const char* const lldp_mode_table[_LLDP_MODE_MAX] = { + [LLDP_MODE_NO] = "no", + [LLDP_MODE_YES] = "yes", + [LLDP_MODE_ROUTERS_ONLY] = "routers-only", +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode, LLDPMode, LLDP_MODE_YES); + +bool link_lldp_rx_enabled(Link *link) { + assert(link); + + if (link->flags & IFF_LOOPBACK) + return false; + + if (link->iftype != ARPHRD_ETHER) + return false; + + if (!link->network) + return false; + + /* LLDP should be handled on bridge slaves as those have a direct + * connection to their peers not on the bridge master. Linux doesn't + * even (by default) forward lldp packets to the bridge master.*/ + if (streq_ptr("bridge", link->kind)) + return false; + + return link->network->lldp_mode != LLDP_MODE_NO; +} + +static void lldp_handler(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n, void *userdata) { + Link *link = userdata; + int r; + + assert(link); + + (void) link_lldp_save(link); + + if (link_lldp_emit_enabled(link) && event == SD_LLDP_EVENT_ADDED) { + /* If we received information about a new neighbor, restart the LLDP "fast" logic */ + + log_link_debug(link, "Received LLDP datagram from previously unknown neighbor, restarting 'fast' LLDP transmission."); + + r = link_lldp_emit_start(link); + if (r < 0) + log_link_warning_errno(link, r, "Failed to restart LLDP transmission: %m"); + } +} + +int link_lldp_rx_configure(Link *link) { + int r; + + r = sd_lldp_new(&link->lldp); + if (r < 0) + return r; + + r = sd_lldp_set_ifindex(link->lldp, link->ifindex); + if (r < 0) + return r; + + r = sd_lldp_match_capabilities(link->lldp, + link->network->lldp_mode == LLDP_MODE_ROUTERS_ONLY ? + SD_LLDP_SYSTEM_CAPABILITIES_ALL_ROUTERS : + SD_LLDP_SYSTEM_CAPABILITIES_ALL); + if (r < 0) + return r; + + r = sd_lldp_set_filter_address(link->lldp, &link->mac); + if (r < 0) + return r; + + r = sd_lldp_attach_event(link->lldp, NULL, 0); + if (r < 0) + return r; + + r = sd_lldp_set_callback(link->lldp, lldp_handler, link); + if (r < 0) + return r; + + r = link_update_lldp(link); + if (r < 0) + return r; + + return 0; +} + +int link_update_lldp(Link *link) { + int r; + + assert(link); + + if (!link->lldp) + return 0; + + if (link->flags & IFF_UP) { + r = sd_lldp_start(link->lldp); + if (r < 0) + return log_link_warning_errno(link, r, "Failed to start LLDP: %m"); + if (r > 0) + log_link_debug(link, "Started LLDP."); + } else { + r = sd_lldp_stop(link->lldp); + if (r < 0) + return log_link_warning_errno(link, r, "Failed to stop LLDP: %m"); + if (r > 0) + log_link_debug(link, "Stopped LLDP."); + } + + return r; +} + +int link_lldp_save(Link *link) { + _cleanup_free_ char *temp_path = NULL; + _cleanup_fclose_ FILE *f = NULL; + sd_lldp_neighbor **l = NULL; + int n = 0, r, i; + + assert(link); + assert(link->lldp_file); + + if (!link->lldp) { + (void) unlink(link->lldp_file); + return 0; + } + + r = sd_lldp_get_neighbors(link->lldp, &l); + if (r < 0) + goto finish; + if (r == 0) { + (void) unlink(link->lldp_file); + goto finish; + } + + n = r; + + r = fopen_temporary(link->lldp_file, &f, &temp_path); + if (r < 0) + goto finish; + + 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); + (void) fwrite(&u, 1, sizeof(u), f); + (void) fwrite(p, 1, sz, f); + } + + r = fflush_and_check(f); + if (r < 0) + goto finish; + + if (rename(temp_path, link->lldp_file) < 0) { + r = -errno; + goto finish; + } + +finish: + if (r < 0) { + (void) unlink(link->lldp_file); + if (temp_path) + (void) unlink(temp_path); + + 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 new file mode 100644 index 0000000000..12f512f628 --- /dev/null +++ b/src/network/networkd-lldp-rx.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +#include + +#include "conf-parser.h" + +typedef struct Link Link; + +typedef enum LLDPMode { + LLDP_MODE_NO = 0, + LLDP_MODE_YES = 1, + LLDP_MODE_ROUTERS_ONLY = 2, + _LLDP_MODE_MAX, + _LLDP_MODE_INVALID = -1, +} LLDPMode; + +bool link_lldp_rx_enabled(Link *link); +int link_lldp_rx_configure(Link *link); +int link_update_lldp(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_; + +CONFIG_PARSER_PROTOTYPE(config_parse_lldp_mode); diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index d39aaa207b..7bce68d7a9 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -1705,16 +1705,6 @@ static const char* const dhcp_use_domains_table[_DHCP_USE_DOMAINS_MAX] = { DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains, DHCPUseDomains, DHCP_USE_DOMAINS_YES); -DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode, lldp_mode, LLDPMode, "Failed to parse LLDP= setting."); - -static const char* const lldp_mode_table[_LLDP_MODE_MAX] = { - [LLDP_MODE_NO] = "no", - [LLDP_MODE_YES] = "yes", - [LLDP_MODE_ROUTERS_ONLY] = "routers-only", -}; - -DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode, LLDPMode, LLDP_MODE_YES); - int config_parse_iaid(const char *unit, const char *filename, unsigned line, diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 366f9d3f39..8b6887a755 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -17,6 +17,7 @@ #include "networkd-brvlan.h" #include "networkd-fdb.h" #include "networkd-ipv6-proxy-ndp.h" +#include "networkd-lldp-rx.h" #include "networkd-lldp-tx.h" #include "networkd-neighbor.h" #include "networkd-radv.h" @@ -61,14 +62,6 @@ typedef enum DHCPUseDomains { _DHCP_USE_DOMAINS_INVALID = -1, } DHCPUseDomains; -typedef enum LLDPMode { - LLDP_MODE_NO = 0, - LLDP_MODE_YES = 1, - LLDP_MODE_ROUTERS_ONLY = 2, - _LLDP_MODE_MAX, - _LLDP_MODE_INVALID = -1, -} LLDPMode; - typedef struct DUID { /* Value of Type in [DHCP] section */ DUIDType type; @@ -327,7 +320,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_radv_search_domains); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ntp); CONFIG_PARSER_PROTOTYPE(config_parse_dnssec_negative_trust_anchors); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_domains); -CONFIG_PARSER_PROTOTYPE(config_parse_lldp_mode); CONFIG_PARSER_PROTOTYPE(config_parse_section_route_table); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_class); CONFIG_PARSER_PROTOTYPE(config_parse_ntp); @@ -351,9 +343,6 @@ IPv6PrivacyExtensions ipv6_privacy_extensions_from_string(const char *s) _pure_; const char* dhcp_use_domains_to_string(DHCPUseDomains p) _const_; DHCPUseDomains dhcp_use_domains_from_string(const char *s) _pure_; -const char* lldp_mode_to_string(LLDPMode m) _const_; -LLDPMode lldp_mode_from_string(const char *s) _pure_; - const char* radv_prefix_delegation_to_string(RADVPrefixDelegation i) _const_; RADVPrefixDelegation radv_prefix_delegation_from_string(const char *s) _pure_;