diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-05-14 07:05:00 +0200 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-05-20 11:23:15 +0200 |
commit | e5b35bf6c28a0c63dff452ebe12917b716255b62 (patch) | |
tree | d032d49e9b1502958bd0909b08295a390cd6951c /src | |
parent | network: bridgeFDB: rename FdbEntry -> BridgeFDB (diff) | |
download | systemd-e5b35bf6c28a0c63dff452ebe12917b716255b62.tar.xz systemd-e5b35bf6c28a0c63dff452ebe12917b716255b62.zip |
network: use queue to configure bridge FDB
Diffstat (limited to 'src')
-rw-r--r-- | src/network/networkd-bridge-fdb.c | 59 | ||||
-rw-r--r-- | src/network/networkd-bridge-fdb.h | 6 | ||||
-rw-r--r-- | src/network/networkd-link.c | 11 | ||||
-rw-r--r-- | src/network/networkd-link.h | 2 | ||||
-rw-r--r-- | src/network/networkd-queue.c | 7 | ||||
-rw-r--r-- | src/network/networkd-queue.h | 3 |
6 files changed, 70 insertions, 18 deletions
diff --git a/src/network/networkd-bridge-fdb.c b/src/network/networkd-bridge-fdb.c index 3c754aa126..8000d0ffe4 100644 --- a/src/network/networkd-bridge-fdb.c +++ b/src/network/networkd-bridge-fdb.c @@ -13,6 +13,8 @@ #include "networkd-link.h" #include "networkd-manager.h" #include "networkd-network.h" +#include "networkd-queue.h" +#include "networkd-util.h" #include "parse-util.h" #include "string-table.h" #include "vlan-util.h" @@ -89,33 +91,43 @@ static int bridge_fdb_new_static( return 0; } -static int set_fdb_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int bridge_fdb_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { int r; assert(link); + assert(link->static_bridge_fdb_messages > 0); + + link->static_bridge_fdb_messages--; if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 1; + return 0; r = sd_netlink_message_get_errno(m); if (r < 0 && r != -EEXIST) { - log_link_message_warning_errno(link, m, r, "Could not add FDB entry"); + log_link_message_warning_errno(link, m, r, "Could not add bridge FDB entry"); link_enter_failed(link); - return 1; + return 0; } - return 1; + if (link->static_bridge_fdb_messages == 0) { + log_link_debug(link, "Bridge FDB entries set"); + link->static_bridge_fdb_configured = true; + link_check_ready(link); + } + + return 0; } /* send a request to the kernel to add a FDB entry in its static MAC table. */ -static int bridge_fdb_configure(Link *link, BridgeFDB *fdb) { +static int bridge_fdb_configure(const BridgeFDB *fdb, Link *link, link_netlink_message_handler_t callback) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; int r; + assert(fdb); assert(link); - assert(link->network); assert(link->manager); - assert(fdb); + assert(link->manager->rtnl); + assert(callback); /* create new RTM message */ r = sd_rtnl_message_new_neigh(link->manager->rtnl, &req, RTM_NEWNEIGH, link->ifindex, AF_BRIDGE); @@ -155,7 +167,7 @@ static int bridge_fdb_configure(Link *link, BridgeFDB *fdb) { } /* send message to the kernel to update its internal static MAC table. */ - r = netlink_call_async(link->manager->rtnl, NULL, req, set_fdb_handler, + r = netlink_call_async(link->manager->rtnl, NULL, req, callback, link_netlink_destroy_callback, link); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -165,22 +177,45 @@ static int bridge_fdb_configure(Link *link, BridgeFDB *fdb) { return 1; } -int link_set_bridge_fdb(Link *link) { +int link_request_static_bridge_fdb(Link *link) { BridgeFDB *fdb; int r; assert(link); assert(link->network); + link->static_bridge_fdb_configured = false; + HASHMAP_FOREACH(fdb, link->network->bridge_fdb_entries_by_section) { - r = bridge_fdb_configure(link, fdb); + r = link_queue_request(link, REQUEST_TYPE_BRIDGE_FDB, fdb, false, + &link->static_bridge_fdb_messages, bridge_fdb_configure_handler, NULL); if (r < 0) - return log_link_error_errno(link, r, "Failed to add MAC entry to static MAC table: %m"); + return log_link_error_errno(link, r, "Failed to request static bridge FDB entry: %m"); + } + + if (link->static_bridge_fdb_messages == 0) { + link->static_bridge_fdb_configured = true; + link_check_ready(link); + } else { + log_link_debug(link, "Setting bridge FDB entries"); + link_set_state(link, LINK_STATE_CONFIGURING); } return 0; } +int request_process_bridge_fdb(Request *req) { + assert(req); + assert(req->link); + assert(req->fdb); + assert(req->type == REQUEST_TYPE_BRIDGE_FDB); + + if (!link_is_ready_to_configure(req->link, false)) + return 0; + + return bridge_fdb_configure(req->fdb, req->link, req->netlink_handler); +} + void network_drop_invalid_bridge_fdb_entries(Network *network) { BridgeFDB *fdb; diff --git a/src/network/networkd-bridge-fdb.h b/src/network/networkd-bridge-fdb.h index dcee035c2c..c091dd7c49 100644 --- a/src/network/networkd-bridge-fdb.h +++ b/src/network/networkd-bridge-fdb.h @@ -11,10 +11,10 @@ #include "conf-parser.h" #include "ether-addr-util.h" #include "in-addr-util.h" -#include "networkd-util.h" typedef struct Link Link; typedef struct Network Network; +typedef struct Request Request; typedef enum NeighborCacheEntryFlags { NEIGHBOR_CACHE_ENTRY_FLAGS_USE = NTF_USE, @@ -43,7 +43,9 @@ BridgeFDB *bridge_fdb_free(BridgeFDB *fdb); void network_drop_invalid_bridge_fdb_entries(Network *network); -int link_set_bridge_fdb(Link *link); +int link_request_static_bridge_fdb(Link *link); + +int request_process_bridge_fdb(Request *req); CONFIG_PARSER_PROTOTYPE(config_parse_fdb_hwaddr); CONFIG_PARSER_PROTOTYPE(config_parse_fdb_vlan_id); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index c732e43645..1e3ab3827b 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -744,6 +744,9 @@ void link_check_ready(Link *link) { return (void) log_link_debug(link, "%s(): an address %s is not ready.", __func__, strna(str)); } + if (!link->static_bridge_fdb_configured) + return (void) log_link_debug(link, "%s(): static bridge MDB entries are not configured.", __func__); + if (!link->static_neighbors_configured) return (void) log_link_debug(link, "%s(): static neighbors are not configured.", __func__); @@ -817,10 +820,6 @@ static int link_set_static_configs(Link *link) { assert(link->network); assert(link->state != _LINK_STATE_INVALID); - r = link_set_bridge_fdb(link); - if (r < 0) - return r; - r = link_set_bridge_mdb(link); if (r < 0) return r; @@ -837,6 +836,10 @@ static int link_set_static_configs(Link *link) { if (r < 0) return r; + r = link_request_static_bridge_fdb(link); + if (r < 0) + return r; + r = link_request_static_neighbors(link); if (r < 0) return r; diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index ddfc32b294..22cde53d3d 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -81,6 +81,7 @@ typedef struct Link { unsigned address_label_messages; unsigned static_address_messages; + unsigned static_bridge_fdb_messages; unsigned static_neighbor_messages; unsigned static_nexthop_messages; unsigned static_route_messages; @@ -122,6 +123,7 @@ typedef struct Link { bool ipv4ll_address_configured:1; bool static_addresses_configured:1; + bool static_bridge_fdb_configured:1; bool static_neighbors_configured:1; bool static_nexthops_configured:1; bool static_routes_configured:1; diff --git a/src/network/networkd-queue.c b/src/network/networkd-queue.c index 3b9d17651e..8f4fda5da9 100644 --- a/src/network/networkd-queue.c +++ b/src/network/networkd-queue.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include "networkd-address.h" +#include "networkd-bridge-fdb.h" #include "networkd-manager.h" #include "networkd-neighbor.h" #include "networkd-nexthop.h" @@ -13,6 +14,9 @@ static void request_free_object(RequestType type, void *object) { case REQUEST_TYPE_ADDRESS: address_free(object); break; + case REQUEST_TYPE_BRIDGE_FDB: + bridge_fdb_free(object); + break; case REQUEST_TYPE_NEIGHBOR: neighbor_free(object); break; @@ -119,6 +123,9 @@ int manager_process_requests(sd_event_source *s, void *userdata) { case REQUEST_TYPE_ADDRESS: r = request_process_address(req); break; + case REQUEST_TYPE_BRIDGE_FDB: + r = request_process_bridge_fdb(req); + break; case REQUEST_TYPE_NEIGHBOR: r = request_process_neighbor(req); break; diff --git a/src/network/networkd-queue.h b/src/network/networkd-queue.h index f8664d087c..343fe067ae 100644 --- a/src/network/networkd-queue.h +++ b/src/network/networkd-queue.h @@ -6,6 +6,7 @@ #include "networkd-link.h" typedef struct Address Address; +typedef struct BridgeFDB BridgeFDB; typedef struct Neighbor Neighbor; typedef struct NextHop NextHop; typedef struct Route Route; @@ -18,6 +19,7 @@ typedef void (*request_on_free_handler_t)(Request*); typedef enum RequestType { REQUEST_TYPE_ADDRESS, + REQUEST_TYPE_BRIDGE_FDB, REQUEST_TYPE_NEIGHBOR, REQUEST_TYPE_NEXTHOP, REQUEST_TYPE_ROUTE, @@ -32,6 +34,7 @@ typedef struct Request { bool consume_object; union { Address *address; + BridgeFDB *fdb; Neighbor *neighbor; NextHop *nexthop; Route *route; |