From 0b20047244224d00de89d69faf8256284cad00c1 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 9 May 2019 07:21:06 +0200 Subject: [PATCH 01/10] network: move link_lldp_emit_enabled() to networkd-lldp-tx.c --- src/network/networkd-link.c | 15 --------------- src/network/networkd-lldp-tx.c | 17 +++++++++++++++++ src/network/networkd-lldp-tx.h | 6 +++++- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 2b6ff2b6c5..9c6dc4d6d6 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -216,21 +216,6 @@ static bool link_lldp_rx_enabled(Link *link) { return link->network->lldp_mode != LLDP_MODE_NO; } -static bool link_lldp_emit_enabled(Link *link) { - assert(link); - - if (link->flags & IFF_LOOPBACK) - return false; - - if (link->iftype != ARPHRD_ETHER) - return false; - - if (!link->network) - return false; - - return link->network->lldp_emit != LLDP_EMIT_NO; -} - static bool link_ipv4_forward_enabled(Link *link) { assert(link); diff --git a/src/network/networkd-lldp-tx.c b/src/network/networkd-lldp-tx.c index 8fd6365e68..00c4358a0a 100644 --- a/src/network/networkd-lldp-tx.c +++ b/src/network/networkd-lldp-tx.c @@ -2,6 +2,7 @@ #include #include +#include #include #include "alloc-util.h" @@ -9,6 +10,7 @@ #include "fd-util.h" #include "hostname-util.h" #include "missing_network.h" +#include "networkd-link.h" #include "networkd-lldp-tx.h" #include "networkd-manager.h" #include "parse-util.h" @@ -38,6 +40,21 @@ static const struct ether_addr lldp_multicast_addr[_LLDP_EMIT_MAX] = { [LLDP_EMIT_CUSTOMER_BRIDGE] = {{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }}, }; +bool link_lldp_emit_enabled(Link *link) { + assert(link); + + if (link->flags & IFF_LOOPBACK) + return false; + + if (link->iftype != ARPHRD_ETHER) + return false; + + if (!link->network) + return false; + + return link->network->lldp_emit != LLDP_EMIT_NO; +} + static int lldp_write_tlv_header(uint8_t **p, uint8_t id, size_t sz) { assert(p); diff --git a/src/network/networkd-lldp-tx.h b/src/network/networkd-lldp-tx.h index 6842804a7e..561becda41 100644 --- a/src/network/networkd-lldp-tx.h +++ b/src/network/networkd-lldp-tx.h @@ -1,8 +1,11 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +#include + #include "conf-parser.h" -#include "networkd-link.h" + +typedef struct Link Link; typedef enum LLDPEmit { LLDP_EMIT_NO, @@ -12,6 +15,7 @@ typedef enum LLDPEmit { _LLDP_EMIT_MAX, } LLDPEmit; +bool link_lldp_emit_enabled(Link *link); int link_lldp_emit_start(Link *link); void link_lldp_emit_stop(Link *link); From be7468f07ad2b0265033545bff9462ab0391e96d Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Fri, 10 May 2019 17:47:45 +0530 Subject: [PATCH 02/10] LLDP: Fix logs for LLDP ``` May 10 11:08:54 test systemd-networkd[447]: wwan0: Failed to stop LLDP: Success May 10 11:08:54 test systemd-networkd[447]: wwan0: Gained carrier May 10 11:08:54 test systemd-networkd[447]: wwan0: Failed to start LLDP: Success ``` --- src/network/networkd-link.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 9c6dc4d6d6..af83cb4935 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -3027,16 +3027,16 @@ static int link_update_lldp(Link *link) { 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 - log_link_warning_errno(link, r, "Failed to start LLDP: %m"); } 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."); - else - log_link_warning_errno(link, r, "Failed to stop LLDP: %m"); } return r; From 7f8539504cf4da1259845cee2b5136bf29c5cad2 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 9 May 2019 07:21:55 +0200 Subject: [PATCH 03/10] 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_; From 8e54db83e2837247bec2fc9f27a62877921c9f18 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 9 May 2019 15:53:01 +0900 Subject: [PATCH 04/10] network: make link_drop() can take custom handler It will be used in the later commit. --- src/network/netdev/netdev.c | 2 +- src/network/networkd-link.c | 9 +++++---- src/network/networkd-link.h | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index d8b8bca7e8..b6aa860ba5 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -254,7 +254,7 @@ static int netdev_enslave_ready(NetDev *netdev, Link* link, link_netlink_message if (link->flags & IFF_UP && netdev->kind == NETDEV_KIND_BOND) { log_netdev_debug(netdev, "Link '%s' was up when attempting to enslave it. Bringing link down.", link->ifname); - r = link_down(link); + r = link_down(link, NULL); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not bring link down: %m"); } diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 9f354b519f..c5857da8fc 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -2128,7 +2128,7 @@ static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link return 1; } -int link_down(Link *link) { +int link_down(Link *link, link_netlink_message_handler_t callback) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; int r; @@ -2147,7 +2147,8 @@ int link_down(Link *link) { if (r < 0) return log_link_error_errno(link, r, "Could not set link flags: %m"); - r = netlink_call_async(link->manager->rtnl, NULL, req, link_down_handler, + r = netlink_call_async(link->manager->rtnl, NULL, req, + callback ?: link_down_handler, link_netlink_destroy_callback, link); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -2179,7 +2180,7 @@ static int link_handle_bound_to_list(Link *link) { } if (!required_up && link_is_up) { - r = link_down(link); + r = link_down(link, NULL); if (r < 0) return r; } else if (required_up && !link_is_up) { @@ -2912,7 +2913,7 @@ static int link_configure_can(Link *link) { if (streq_ptr(link->kind, "can")) { /* The CAN interface must be down to configure bitrate, etc... */ if ((link->flags & IFF_UP)) { - r = link_down(link); + r = link_down(link, NULL); if (r < 0) { link_enter_failed(link); return r; diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 930dd25f92..e1f4b23a5a 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -139,7 +139,7 @@ int link_get(Manager *m, int ifindex, Link **ret); int link_add(Manager *manager, sd_netlink_message *message, Link **ret); void link_drop(Link *link); -int link_down(Link *link); +int link_down(Link *link, link_netlink_message_handler_t callback); void link_enter_failed(Link *link); int link_initialized(Link *link, sd_device *device); From 06d7cee5890840227d621cceb71c3d7a9af1e2fc Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 11 May 2019 06:21:40 +0900 Subject: [PATCH 05/10] network: make BindCarrier= work with CAN devices If CAN device is set `BindCarrier=` then the interface could not be down. This fixes the issue. --- src/network/networkd-link.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index c5857da8fc..84a0bf3c72 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -2122,9 +2122,6 @@ static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link if (r < 0) log_link_warning_errno(link, r, "Could not bring down interface: %m"); - if (streq_ptr(link->kind, "can")) - link_set_can(link); - return 1; } @@ -2907,13 +2904,35 @@ static int link_drop_config(Link *link) { return 0; } +static int can_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { + int r; + + assert(link); + + if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) + return 1; + + r = sd_netlink_message_get_errno(m); + if (r < 0) { + log_link_warning_errno(link, r, "Could not bring down interface: %m"); + link_enter_failed(link); + return 1; + } + + r = link_set_can(link); + if (r < 0) + link_enter_failed(link); + + return 1; +} + static int link_configure_can(Link *link) { int r; if (streq_ptr(link->kind, "can")) { /* The CAN interface must be down to configure bitrate, etc... */ if ((link->flags & IFF_UP)) { - r = link_down(link, NULL); + r = link_down(link, can_down_handler); if (r < 0) { link_enter_failed(link); return r; From 3ddcbeea4582449d6a9fa6c53fc52330977def7e Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 9 May 2019 15:39:19 +0900 Subject: [PATCH 06/10] network: move CAN link related functions to networkd-can.c --- src/network/meson.build | 2 + src/network/networkd-can.c | 229 ++++++++++++++++++++++++++++++++++++ src/network/networkd-can.h | 6 + src/network/networkd-link.c | 192 +----------------------------- 4 files changed, 238 insertions(+), 191 deletions(-) create mode 100644 src/network/networkd-can.c create mode 100644 src/network/networkd-can.h diff --git a/src/network/meson.build b/src/network/meson.build index a7192e2a2e..0bcf7f4a81 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -49,6 +49,8 @@ sources = files(''' networkd-address.h networkd-brvlan.c networkd-brvlan.h + networkd-can.c + networkd-can.h networkd-conf.c networkd-conf.h networkd-dhcp4.c diff --git a/src/network/networkd-can.c b/src/network/networkd-can.c new file mode 100644 index 0000000000..2df0e888f0 --- /dev/null +++ b/src/network/networkd-can.c @@ -0,0 +1,229 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include +#include + +#include "netlink-util.h" +#include "networkd-can.h" +#include "networkd-link.h" +#include "networkd-manager.h" +#include "string-util.h" + +static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { + int r; + + assert(link); + + if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) + return 1; + + r = sd_netlink_message_get_errno(m); + if (r < 0) + /* we warn but don't fail the link, as it may be brought up later */ + log_link_warning_errno(link, r, "Could not bring up interface: %m"); + + return 1; +} + +static int link_up_can(Link *link) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; + int r; + + assert(link); + + log_link_debug(link, "Bringing CAN link up"); + + r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex); + if (r < 0) + return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m"); + + r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP); + if (r < 0) + return log_link_error_errno(link, r, "Could not set link flags: %m"); + + r = netlink_call_async(link->manager->rtnl, NULL, req, link_up_handler, + link_netlink_destroy_callback, link); + if (r < 0) + return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); + + link_ref(link); + + return 0; +} + +static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { + int r; + + assert(link); + + log_link_debug(link, "Set link"); + + r = sd_netlink_message_get_errno(m); + if (r < 0 && r != -EEXIST) { + log_link_error_errno(link, r, "Failed to configure CAN link: %m"); + link_enter_failed(link); + } + + return 1; +} + +static int link_set_can(Link *link) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; + int r; + + assert(link); + assert(link->network); + assert(link->manager); + assert(link->manager->rtnl); + + log_link_debug(link, "Configuring CAN link."); + + r = sd_rtnl_message_new_link(link->manager->rtnl, &m, RTM_NEWLINK, link->ifindex); + if (r < 0) + return log_link_error_errno(link, r, "Failed to allocate netlink message: %m"); + + r = sd_netlink_message_set_flags(m, NLM_F_REQUEST | NLM_F_ACK); + if (r < 0) + return log_link_error_errno(link, r, "Could not set netlink flags: %m"); + + r = sd_netlink_message_open_container(m, IFLA_LINKINFO); + if (r < 0) + return log_link_error_errno(link, r, "Failed to open netlink container: %m"); + + r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, link->kind); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m"); + + if (link->network->can_bitrate > 0 || link->network->can_sample_point > 0) { + struct can_bittiming bt = { + .bitrate = link->network->can_bitrate, + .sample_point = link->network->can_sample_point, + }; + + if (link->network->can_bitrate > UINT32_MAX) { + log_link_error(link, "bitrate (%zu) too big.", link->network->can_bitrate); + return -ERANGE; + } + + log_link_debug(link, "Setting bitrate = %d bit/s", bt.bitrate); + if (link->network->can_sample_point > 0) + log_link_debug(link, "Setting sample point = %d.%d%%", bt.sample_point / 10, bt.sample_point % 10); + else + log_link_debug(link, "Using default sample point"); + + r = sd_netlink_message_append_data(m, IFLA_CAN_BITTIMING, &bt, sizeof(bt)); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_CAN_BITTIMING attribute: %m"); + } + + if (link->network->can_restart_us > 0) { + char time_string[FORMAT_TIMESPAN_MAX]; + uint64_t restart_ms; + + if (link->network->can_restart_us == USEC_INFINITY) + restart_ms = 0; + else + restart_ms = DIV_ROUND_UP(link->network->can_restart_us, USEC_PER_MSEC); + + format_timespan(time_string, FORMAT_TIMESPAN_MAX, restart_ms * 1000, MSEC_PER_SEC); + + if (restart_ms > UINT32_MAX) { + log_link_error(link, "restart timeout (%s) too big.", time_string); + return -ERANGE; + } + + log_link_debug(link, "Setting restart = %s", time_string); + + r = sd_netlink_message_append_u32(m, IFLA_CAN_RESTART_MS, restart_ms); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_CAN_RESTART_MS attribute: %m"); + } + + if (link->network->can_triple_sampling >= 0) { + struct can_ctrlmode cm = { + .mask = CAN_CTRLMODE_3_SAMPLES, + .flags = link->network->can_triple_sampling ? CAN_CTRLMODE_3_SAMPLES : 0, + }; + + log_link_debug(link, "%sabling triple-sampling", link->network->can_triple_sampling ? "En" : "Dis"); + + r = sd_netlink_message_append_data(m, IFLA_CAN_CTRLMODE, &cm, sizeof(cm)); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_CAN_CTRLMODE attribute: %m"); + } + + r = sd_netlink_message_close_container(m); + if (r < 0) + return log_link_error_errno(link, r, "Failed to close netlink container: %m"); + + r = sd_netlink_message_close_container(m); + if (r < 0) + return log_link_error_errno(link, r, "Failed to close netlink container: %m"); + + r = netlink_call_async(link->manager->rtnl, NULL, m, link_set_handler, + link_netlink_destroy_callback, link); + if (r < 0) + return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); + + link_ref(link); + + if (!(link->flags & IFF_UP)) + return link_up_can(link); + + return 0; +} + +static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { + int r; + + assert(link); + + if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) + return 1; + + r = sd_netlink_message_get_errno(m); + if (r < 0) { + log_link_warning_errno(link, r, "Could not bring down interface: %m"); + link_enter_failed(link); + return 1; + } + + r = link_set_can(link); + if (r < 0) + link_enter_failed(link); + + return 1; +} + +int link_configure_can(Link *link) { + int r; + + if (streq_ptr(link->kind, "can")) { + /* The CAN interface must be down to configure bitrate, etc... */ + if ((link->flags & IFF_UP)) { + r = link_down(link, link_down_handler); + if (r < 0) { + link_enter_failed(link); + return r; + } + } else { + r = link_set_can(link); + if (r < 0) { + link_enter_failed(link); + return r; + } + } + + return 0; + } + + if (!(link->flags & IFF_UP)) { + r = link_up_can(link); + if (r < 0) { + link_enter_failed(link); + return r; + } + } + + return 0; +} diff --git a/src/network/networkd-can.h b/src/network/networkd-can.h new file mode 100644 index 0000000000..c744bdfea7 --- /dev/null +++ b/src/network/networkd-can.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +typedef struct Link Link; + +int link_configure_can(Link *link); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 84a0bf3c72..a0ea793f05 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -2,7 +2,6 @@ #include #include -#include #include #include "alloc-util.h" @@ -16,6 +15,7 @@ #include "netdev/vrf.h" #include "netlink-util.h" #include "network-internal.h" +#include "networkd-can.h" #include "networkd-ipv6-proxy-ndp.h" #include "networkd-lldp-tx.h" #include "networkd-manager.h" @@ -1971,145 +1971,6 @@ static int link_up(Link *link) { return 0; } -static int link_up_can(Link *link) { - _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; - int r; - - assert(link); - - log_link_debug(link, "Bringing CAN link up"); - - r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex); - if (r < 0) - return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m"); - - r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP); - if (r < 0) - return log_link_error_errno(link, r, "Could not set link flags: %m"); - - r = netlink_call_async(link->manager->rtnl, NULL, req, link_up_handler, - link_netlink_destroy_callback, link); - if (r < 0) - return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); - - link_ref(link); - - return 0; -} - -static int link_set_can(Link *link) { - _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; - int r; - - assert(link); - assert(link->network); - assert(link->manager); - assert(link->manager->rtnl); - - log_link_debug(link, "link_set_can"); - - r = sd_rtnl_message_new_link(link->manager->rtnl, &m, RTM_NEWLINK, link->ifindex); - if (r < 0) - return log_link_error_errno(link, r, "Failed to allocate netlink message: %m"); - - r = sd_netlink_message_set_flags(m, NLM_F_REQUEST | NLM_F_ACK); - if (r < 0) - return log_link_error_errno(link, r, "Could not set netlink flags: %m"); - - r = sd_netlink_message_open_container(m, IFLA_LINKINFO); - if (r < 0) - return log_link_error_errno(link, r, "Failed to open netlink container: %m"); - - r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, link->kind); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m"); - - if (link->network->can_bitrate > 0 || link->network->can_sample_point > 0) { - struct can_bittiming bt = { - .bitrate = link->network->can_bitrate, - .sample_point = link->network->can_sample_point, - }; - - if (link->network->can_bitrate > UINT32_MAX) { - log_link_error(link, "bitrate (%zu) too big.", link->network->can_bitrate); - return -ERANGE; - } - - log_link_debug(link, "Setting bitrate = %d bit/s", bt.bitrate); - if (link->network->can_sample_point > 0) - log_link_debug(link, "Setting sample point = %d.%d%%", bt.sample_point / 10, bt.sample_point % 10); - else - log_link_debug(link, "Using default sample point"); - - r = sd_netlink_message_append_data(m, IFLA_CAN_BITTIMING, &bt, sizeof(bt)); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_CAN_BITTIMING attribute: %m"); - } - - if (link->network->can_restart_us > 0) { - char time_string[FORMAT_TIMESPAN_MAX]; - uint64_t restart_ms; - - if (link->network->can_restart_us == USEC_INFINITY) - restart_ms = 0; - else - restart_ms = DIV_ROUND_UP(link->network->can_restart_us, USEC_PER_MSEC); - - format_timespan(time_string, FORMAT_TIMESPAN_MAX, restart_ms * 1000, MSEC_PER_SEC); - - if (restart_ms > UINT32_MAX) { - log_link_error(link, "restart timeout (%s) too big.", time_string); - return -ERANGE; - } - - log_link_debug(link, "Setting restart = %s", time_string); - - r = sd_netlink_message_append_u32(m, IFLA_CAN_RESTART_MS, restart_ms); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_CAN_RESTART_MS attribute: %m"); - } - - if (link->network->can_triple_sampling >= 0) { - struct can_ctrlmode cm = { - .mask = CAN_CTRLMODE_3_SAMPLES, - .flags = link->network->can_triple_sampling ? CAN_CTRLMODE_3_SAMPLES : 0, - }; - - log_link_debug(link, "%sabling triple-sampling", link->network->can_triple_sampling ? "En" : "Dis"); - - r = sd_netlink_message_append_data(m, IFLA_CAN_CTRLMODE, &cm, sizeof(cm)); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_CAN_CTRLMODE attribute: %m"); - } - - r = sd_netlink_message_close_container(m); - if (r < 0) - return log_link_error_errno(link, r, "Failed to close netlink container: %m"); - - r = sd_netlink_message_close_container(m); - if (r < 0) - return log_link_error_errno(link, r, "Failed to close netlink container: %m"); - - r = netlink_call_async(link->manager->rtnl, NULL, m, link_set_handler, - link_netlink_destroy_callback, link); - if (r < 0) - return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); - - link_ref(link); - - if (!(link->flags & IFF_UP)) { - r = link_up_can(link); - if (r < 0) { - link_enter_failed(link); - return r; - } - } - - log_link_debug(link, "link_set_can done"); - - return r; -} - static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { int r; @@ -2904,57 +2765,6 @@ static int link_drop_config(Link *link) { return 0; } -static int can_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - int r; - - assert(link); - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 1; - - r = sd_netlink_message_get_errno(m); - if (r < 0) { - log_link_warning_errno(link, r, "Could not bring down interface: %m"); - link_enter_failed(link); - return 1; - } - - r = link_set_can(link); - if (r < 0) - link_enter_failed(link); - - return 1; -} - -static int link_configure_can(Link *link) { - int r; - - if (streq_ptr(link->kind, "can")) { - /* The CAN interface must be down to configure bitrate, etc... */ - if ((link->flags & IFF_UP)) { - r = link_down(link, can_down_handler); - if (r < 0) { - link_enter_failed(link); - return r; - } - - return 0; - } - - return link_set_can(link); - } - - if (!(link->flags & IFF_UP)) { - r = link_up_can(link); - if (r < 0) { - link_enter_failed(link); - return r; - } - } - - return 0; -} - static int link_configure(Link *link) { int r; From 9a81f119562879d93a8d518da39a5e61d457b36a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 10 May 2019 23:22:47 +0900 Subject: [PATCH 07/10] network: move link_set_bridge to netdev/bridge.c --- src/network/netdev/bridge.c | 137 ++++++++++++++++++++++++++++++++++++ src/network/netdev/bridge.h | 2 + src/network/networkd-link.c | 134 +---------------------------------- 3 files changed, 140 insertions(+), 133 deletions(-) diff --git a/src/network/netdev/bridge.c b/src/network/netdev/bridge.c index cbbf11220b..54390cad0e 100644 --- a/src/network/netdev/bridge.c +++ b/src/network/netdev/bridge.c @@ -5,6 +5,7 @@ #include "missing.h" #include "netlink-util.h" #include "netdev/bridge.h" +#include "network-internal.h" #include "networkd-manager.h" #include "vlan-util.h" @@ -138,6 +139,142 @@ static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_mess return r; } +static int link_set_bridge_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { + int r; + + assert(m); + assert(link); + assert(link->ifname); + + if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) + return 1; + + r = sd_netlink_message_get_errno(m); + if (r < 0) { + log_link_warning_errno(link, r, "Could not set bridge interface: %m"); + return 1; + } + + return 1; +} + +int link_set_bridge(Link *link) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; + int r; + + assert(link); + assert(link->network); + + r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex); + if (r < 0) + return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m"); + + r = sd_rtnl_message_link_set_family(req, PF_BRIDGE); + if (r < 0) + return log_link_error_errno(link, r, "Could not set message family: %m"); + + r = sd_netlink_message_open_container(req, IFLA_PROTINFO); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m"); + + if (link->network->use_bpdu >= 0) { + r = sd_netlink_message_append_u8(req, IFLA_BRPORT_GUARD, link->network->use_bpdu); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_GUARD attribute: %m"); + } + + if (link->network->hairpin >= 0) { + r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MODE, link->network->hairpin); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MODE attribute: %m"); + } + + if (link->network->fast_leave >= 0) { + r = sd_netlink_message_append_u8(req, IFLA_BRPORT_FAST_LEAVE, link->network->fast_leave); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_FAST_LEAVE attribute: %m"); + } + + if (link->network->allow_port_to_be_root >= 0) { + r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROTECT, link->network->allow_port_to_be_root); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROTECT attribute: %m"); + } + + if (link->network->unicast_flood >= 0) { + r = sd_netlink_message_append_u8(req, IFLA_BRPORT_UNICAST_FLOOD, link->network->unicast_flood); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_UNICAST_FLOOD attribute: %m"); + } + + if (link->network->multicast_flood >= 0) { + r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MCAST_FLOOD, link->network->multicast_flood); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MCAST_FLOOD attribute: %m"); + } + + if (link->network->multicast_to_unicast >= 0) { + r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MCAST_TO_UCAST, link->network->multicast_to_unicast); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MCAST_TO_UCAST attribute: %m"); + } + + if (link->network->neighbor_suppression >= 0) { + r = sd_netlink_message_append_u8(req, IFLA_BRPORT_NEIGH_SUPPRESS, link->network->neighbor_suppression); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_NEIGH_SUPPRESS attribute: %m"); + } + + if (link->network->learning >= 0) { + r = sd_netlink_message_append_u8(req, IFLA_BRPORT_LEARNING, link->network->learning); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_LEARNING attribute: %m"); + } + + if (link->network->bridge_proxy_arp >= 0) { + r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROXYARP, link->network->bridge_proxy_arp); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROXYARP attribute: %m"); + } + + if (link->network->bridge_proxy_arp_wifi >= 0) { + r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROXYARP_WIFI, link->network->bridge_proxy_arp_wifi); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROXYARP_WIFI attribute: %m"); + } + + if (link->network->cost != 0) { + r = sd_netlink_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_COST attribute: %m"); + } + + if (link->network->priority != LINK_BRIDGE_PORT_PRIORITY_INVALID) { + r = sd_netlink_message_append_u16(req, IFLA_BRPORT_PRIORITY, link->network->priority); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PRIORITY attribute: %m"); + } + + if (link->network->multicast_router != _MULTICAST_ROUTER_INVALID) { + r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MULTICAST_ROUTER, link->network->multicast_router); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MULTICAST_ROUTER attribute: %m"); + } + + r = sd_netlink_message_close_container(req); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m"); + + r = netlink_call_async(link->manager->rtnl, NULL, req, link_set_bridge_handler, + link_netlink_destroy_callback, link); + if (r < 0) + return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); + + link_ref(link); + + return r; +} + static void bridge_init(NetDev *n) { Bridge *b; diff --git a/src/network/netdev/bridge.h b/src/network/netdev/bridge.h index 3edc93a767..b03084790a 100644 --- a/src/network/netdev/bridge.h +++ b/src/network/netdev/bridge.h @@ -22,3 +22,5 @@ typedef struct Bridge { DEFINE_NETDEV_CAST(BRIDGE, Bridge); extern const NetDevVTable bridge_vtable; + +int link_set_bridge(Link *link); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index a0ea793f05..8ad590dae3 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -12,6 +12,7 @@ #include "fd-util.h" #include "fileio.h" #include "missing_network.h" +#include "netdev/bridge.h" #include "netdev/vrf.h" #include "netlink-util.h" #include "network-internal.h" @@ -1353,22 +1354,6 @@ static int link_set_proxy_arp(Link *link) { return 0; } -static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - int r; - - assert(link); - - log_link_debug(link, "Set link"); - - r = sd_netlink_message_get_errno(m); - if (r < 0 && r != -EEXIST) { - log_link_error_errno(link, r, "Could not join netdev: %m"); - link_enter_failed(link); - } - - return 1; -} - static int link_configure_after_setting_mtu(Link *link); static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { @@ -1515,123 +1500,6 @@ static int link_set_flags(Link *link) { return 0; } -static int link_set_bridge(Link *link) { - _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; - int r; - - assert(link); - assert(link->network); - - r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex); - if (r < 0) - return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m"); - - r = sd_rtnl_message_link_set_family(req, PF_BRIDGE); - if (r < 0) - return log_link_error_errno(link, r, "Could not set message family: %m"); - - r = sd_netlink_message_open_container(req, IFLA_PROTINFO); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m"); - - if (link->network->use_bpdu >= 0) { - r = sd_netlink_message_append_u8(req, IFLA_BRPORT_GUARD, link->network->use_bpdu); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_GUARD attribute: %m"); - } - - if (link->network->hairpin >= 0) { - r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MODE, link->network->hairpin); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MODE attribute: %m"); - } - - if (link->network->fast_leave >= 0) { - r = sd_netlink_message_append_u8(req, IFLA_BRPORT_FAST_LEAVE, link->network->fast_leave); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_FAST_LEAVE attribute: %m"); - } - - if (link->network->allow_port_to_be_root >= 0) { - r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROTECT, link->network->allow_port_to_be_root); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROTECT attribute: %m"); - } - - if (link->network->unicast_flood >= 0) { - r = sd_netlink_message_append_u8(req, IFLA_BRPORT_UNICAST_FLOOD, link->network->unicast_flood); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_UNICAST_FLOOD attribute: %m"); - } - - if (link->network->multicast_flood >= 0) { - r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MCAST_FLOOD, link->network->multicast_flood); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MCAST_FLOOD attribute: %m"); - } - - if (link->network->multicast_to_unicast >= 0) { - r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MCAST_TO_UCAST, link->network->multicast_to_unicast); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MCAST_TO_UCAST attribute: %m"); - } - - if (link->network->neighbor_suppression >= 0) { - r = sd_netlink_message_append_u8(req, IFLA_BRPORT_NEIGH_SUPPRESS, link->network->neighbor_suppression); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_NEIGH_SUPPRESS attribute: %m"); - } - - if (link->network->learning >= 0) { - r = sd_netlink_message_append_u8(req, IFLA_BRPORT_LEARNING, link->network->learning); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_LEARNING attribute: %m"); - } - - if (link->network->bridge_proxy_arp >= 0) { - r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROXYARP, link->network->bridge_proxy_arp); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROXYARP attribute: %m"); - } - - if (link->network->bridge_proxy_arp_wifi >= 0) { - r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROXYARP_WIFI, link->network->bridge_proxy_arp_wifi); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROXYARP_WIFI attribute: %m"); - } - - if (link->network->cost != 0) { - r = sd_netlink_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_COST attribute: %m"); - } - - if (link->network->priority != LINK_BRIDGE_PORT_PRIORITY_INVALID) { - r = sd_netlink_message_append_u16(req, IFLA_BRPORT_PRIORITY, link->network->priority); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PRIORITY attribute: %m"); - } - - if (link->network->multicast_router != _MULTICAST_ROUTER_INVALID) { - r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MULTICAST_ROUTER, link->network->multicast_router); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MULTICAST_ROUTER attribute: %m"); - } - - r = sd_netlink_message_close_container(req); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m"); - - r = netlink_call_async(link->manager->rtnl, NULL, req, link_set_handler, - link_netlink_destroy_callback, link); - if (r < 0) - return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); - - link_ref(link); - - return r; -} - static int link_set_bond_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { int r; From 4799f19e30623fcbc12fe0d39b7fbbd5b7ea1832 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 10 May 2019 23:29:07 +0900 Subject: [PATCH 08/10] network: move link_set_bond() to netdev/bond.c --- src/network/netdev/bond.c | 74 +++++++++++++++++++++++++++++++++++++ src/network/netdev/bond.h | 2 + src/network/networkd-link.c | 73 +----------------------------------- 3 files changed, 77 insertions(+), 72 deletions(-) diff --git a/src/network/netdev/bond.c b/src/network/netdev/bond.c index 166aa37139..240cfe34e2 100644 --- a/src/network/netdev/bond.c +++ b/src/network/netdev/bond.c @@ -7,6 +7,8 @@ #include "conf-parser.h" #include "ether-addr-util.h" #include "extract-word.h" +#include "netlink-util.h" +#include "networkd-manager.h" #include "string-table.h" #include "string-util.h" @@ -291,6 +293,78 @@ static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_netlin return 0; } +static int link_set_bond_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { + int r; + + assert(m); + assert(link); + assert(link->ifname); + + if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) + return 1; + + r = sd_netlink_message_get_errno(m); + if (r < 0) { + log_link_warning_errno(link, r, "Could not set bonding interface: %m"); + return 1; + } + + return 1; +} + +int link_set_bond(Link *link) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; + int r; + + assert(link); + assert(link->network); + + r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->network->bond->ifindex); + if (r < 0) + return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m"); + + r = sd_netlink_message_set_flags(req, NLM_F_REQUEST | NLM_F_ACK); + if (r < 0) + return log_link_error_errno(link, r, "Could not set netlink flags: %m"); + + r = sd_netlink_message_open_container(req, IFLA_LINKINFO); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m"); + + r = sd_netlink_message_open_container_union(req, IFLA_INFO_DATA, "bond"); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m"); + + if (link->network->active_slave) { + r = sd_netlink_message_append_u32(req, IFLA_BOND_ACTIVE_SLAVE, link->ifindex); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BOND_ACTIVE_SLAVE attribute: %m"); + } + + if (link->network->primary_slave) { + r = sd_netlink_message_append_u32(req, IFLA_BOND_PRIMARY, link->ifindex); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BOND_PRIMARY attribute: %m"); + } + + r = sd_netlink_message_close_container(req); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m"); + + r = sd_netlink_message_close_container(req); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m"); + + r = netlink_call_async(link->manager->rtnl, NULL, req, link_set_bond_handler, + link_netlink_destroy_callback, link); + if (r < 0) + return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); + + link_ref(link); + + return r; +} + int config_parse_arp_ip_target_address( const char *unit, const char *filename, diff --git a/src/network/netdev/bond.h b/src/network/netdev/bond.h index 038272f107..28796a3a8b 100644 --- a/src/network/netdev/bond.h +++ b/src/network/netdev/bond.h @@ -120,6 +120,8 @@ typedef struct Bond { DEFINE_NETDEV_CAST(BOND, Bond); extern const NetDevVTable bond_vtable; +int link_set_bond(Link *link); + const char *bond_mode_to_string(BondMode d) _const_; BondMode bond_mode_from_string(const char *d) _pure_; diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 8ad590dae3..aa28828354 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -12,6 +12,7 @@ #include "fd-util.h" #include "fileio.h" #include "missing_network.h" +#include "netdev/bond.h" #include "netdev/bridge.h" #include "netdev/vrf.h" #include "netlink-util.h" @@ -1500,78 +1501,6 @@ static int link_set_flags(Link *link) { return 0; } -static int link_set_bond_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - int r; - - assert(m); - assert(link); - assert(link->ifname); - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 1; - - r = sd_netlink_message_get_errno(m); - if (r < 0) { - log_link_warning_errno(link, r, "Could not set bonding interface: %m"); - return 1; - } - - return 1; -} - -static int link_set_bond(Link *link) { - _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; - int r; - - assert(link); - assert(link->network); - - r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->network->bond->ifindex); - if (r < 0) - return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m"); - - r = sd_netlink_message_set_flags(req, NLM_F_REQUEST | NLM_F_ACK); - if (r < 0) - return log_link_error_errno(link, r, "Could not set netlink flags: %m"); - - r = sd_netlink_message_open_container(req, IFLA_LINKINFO); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m"); - - r = sd_netlink_message_open_container_union(req, IFLA_INFO_DATA, "bond"); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m"); - - if (link->network->active_slave) { - r = sd_netlink_message_append_u32(req, IFLA_BOND_ACTIVE_SLAVE, link->ifindex); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_BOND_ACTIVE_SLAVE attribute: %m"); - } - - if (link->network->primary_slave) { - r = sd_netlink_message_append_u32(req, IFLA_BOND_PRIMARY, link->ifindex); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_BOND_PRIMARY attribute: %m"); - } - - r = sd_netlink_message_close_container(req); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m"); - - r = sd_netlink_message_close_container(req); - if (r < 0) - return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m"); - - r = netlink_call_async(link->manager->rtnl, NULL, req, link_set_bond_handler, - link_netlink_destroy_callback, link); - if (r < 0) - return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); - - link_ref(link); - - return r; -} - static int link_acquire_ipv6_conf(Link *link) { int r; From 86e2be7bc3e0707f70f85642191d94e87097cace Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 10 May 2019 23:31:20 +0900 Subject: [PATCH 09/10] network: drop unnecessary initializations --- src/network/netdev/wireguard.c | 2 +- src/network/networkd-dhcp4.c | 2 +- src/network/networkd-link.c | 2 +- src/network/networkd-ndisc.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/network/netdev/wireguard.c b/src/network/netdev/wireguard.c index 5ebc5dfed8..91fcee1401 100644 --- a/src/network/netdev/wireguard.c +++ b/src/network/netdev/wireguard.c @@ -401,7 +401,7 @@ static void resolve_endpoints(NetDev *netdev) { WireguardPeer *peer; Wireguard *w; Iterator i; - int r = 0; + int r; assert(netdev); w = WIREGUARD(netdev); diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 23831d25b6..85e088e204 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -542,7 +542,7 @@ static int dhcp_server_is_black_listed(Link *link, sd_dhcp_client *client) { static int dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) { Link *link = userdata; - int r = 0; + int r; assert(link); assert(link->network); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index aa28828354..bdf0a0a734 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1333,7 +1333,7 @@ static int link_request_set_addresses(Link *link) { } static int link_set_bridge_vlan(Link *link) { - int r = 0; + int r; r = br_vlan_configure(link, link->network->pvid, link->network->br_vid_bitmap, link->network->br_untagged_bitmap); if (r < 0) diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 325f7ae592..28d46f5fe3 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -559,7 +559,7 @@ static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) { static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) { uint64_t flags; - int r = 0; + int r; assert(link); assert(link->network); From 8e2cb51ce042d582e9ba59c47f7e825b0e8db6e3 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 11 May 2019 00:02:58 +0900 Subject: [PATCH 10/10] network: move MulticastRouter to netdev/bridge.[ch] --- src/network/netdev/bridge.c | 12 ++++++++++++ src/network/netdev/bridge.h | 20 +++++++++++++++++++- src/network/networkd-network.c | 11 ----------- src/network/networkd-network.h | 17 +---------------- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/network/netdev/bridge.c b/src/network/netdev/bridge.c index 54390cad0e..f20130d264 100644 --- a/src/network/netdev/bridge.c +++ b/src/network/netdev/bridge.c @@ -7,8 +7,20 @@ #include "netdev/bridge.h" #include "network-internal.h" #include "networkd-manager.h" +#include "string-table.h" #include "vlan-util.h" +static const char* const multicast_router_table[_MULTICAST_ROUTER_MAX] = { + [MULTICAST_ROUTER_NONE] = "no", + [MULTICAST_ROUTER_TEMPORARY_QUERY] = "query", + [MULTICAST_ROUTER_PERMANENT] = "permanent", + [MULTICAST_ROUTER_TEMPORARY] = "temporary", +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(multicast_router, MulticastRouter, _MULTICAST_ROUTER_INVALID); +DEFINE_CONFIG_PARSE_ENUM(config_parse_multicast_router, multicast_router, MulticastRouter, + "Failed to parse bridge multicast router setting"); + /* callback for bridge netdev's parameter set */ static int netdev_bridge_set_handler(sd_netlink *rtnl, sd_netlink_message *m, NetDev *netdev) { int r; diff --git a/src/network/netdev/bridge.h b/src/network/netdev/bridge.h index b03084790a..2954155c37 100644 --- a/src/network/netdev/bridge.h +++ b/src/network/netdev/bridge.h @@ -1,7 +1,11 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -#include "netdev/netdev.h" +#include +#include + +#include "conf-parser.h" +#include "netdev.h" typedef struct Bridge { NetDev meta; @@ -20,7 +24,21 @@ typedef struct Bridge { usec_t ageing_time; } Bridge; +typedef enum MulticastRouter { + MULTICAST_ROUTER_NONE = MDB_RTR_TYPE_DISABLED, + MULTICAST_ROUTER_TEMPORARY_QUERY = MDB_RTR_TYPE_TEMP_QUERY, + MULTICAST_ROUTER_PERMANENT = MDB_RTR_TYPE_PERM, + MULTICAST_ROUTER_TEMPORARY = MDB_RTR_TYPE_TEMP, + _MULTICAST_ROUTER_MAX, + _MULTICAST_ROUTER_INVALID = -1, +} MulticastRouter; + DEFINE_NETDEV_CAST(BRIDGE, Bridge); extern const NetDevVTable bridge_vtable; int link_set_bridge(Link *link); + +const char* multicast_router_to_string(MulticastRouter i) _const_; +MulticastRouter multicast_router_from_string(const char *s) _pure_; + +CONFIG_PARSER_PROTOTYPE(config_parse_multicast_router); diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 7bce68d7a9..56a45379c1 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -1779,14 +1779,3 @@ int config_parse_required_for_online( return 0; } - -static const char* const multicast_router_table[_MULTICAST_ROUTER_MAX] = { - [MULTICAST_ROUTER_NONE] = "no", - [MULTICAST_ROUTER_TEMPORARY_QUERY] = "query", - [MULTICAST_ROUTER_PERMANENT] = "permanent", - [MULTICAST_ROUTER_TEMPORARY] = "temporary", -}; - -DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(multicast_router, MulticastRouter, _MULTICAST_ROUTER_INVALID); -DEFINE_CONFIG_PARSE_ENUM(config_parse_multicast_router, multicast_router, MulticastRouter, - "Failed to parse bridge multicast router setting"); diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 8b6887a755..9217e838d2 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -1,9 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -#include -#include - #include "sd-bus.h" #include "sd-device.h" @@ -11,6 +8,7 @@ #include "conf-parser.h" #include "dhcp-identifier.h" #include "hashmap.h" +#include "netdev/bridge.h" #include "netdev/netdev.h" #include "networkd-address-label.h" #include "networkd-address.h" @@ -80,15 +78,6 @@ typedef enum RADVPrefixDelegation { _RADV_PREFIX_DELEGATION_INVALID = -1, } RADVPrefixDelegation; -typedef enum MulticastRouter { - MULTICAST_ROUTER_NONE = MDB_RTR_TYPE_DISABLED, - MULTICAST_ROUTER_TEMPORARY_QUERY = MDB_RTR_TYPE_TEMP_QUERY, - MULTICAST_ROUTER_PERMANENT = MDB_RTR_TYPE_PERM, - MULTICAST_ROUTER_TEMPORARY = MDB_RTR_TYPE_TEMP, - _MULTICAST_ROUTER_MAX, - _MULTICAST_ROUTER_INVALID = -1, -} MulticastRouter; - typedef struct Manager Manager; struct Network { @@ -326,7 +315,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ntp); CONFIG_PARSER_PROTOTYPE(config_parse_iaid); CONFIG_PARSER_PROTOTYPE(config_parse_required_for_online); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts); -CONFIG_PARSER_PROTOTYPE(config_parse_multicast_router); /* Legacy IPv4LL support */ CONFIG_PARSER_PROTOTYPE(config_parse_ipv4ll); @@ -345,6 +333,3 @@ DHCPUseDomains dhcp_use_domains_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_; - -const char* multicast_router_to_string(MulticastRouter i) _const_; -MulticastRouter multicast_router_from_string(const char *s) _pure_;