diff options
-rw-r--r-- | src/network/networkd-address-label.c | 70 | ||||
-rw-r--r-- | src/network/networkd-address-label.h | 6 | ||||
-rw-r--r-- | src/network/networkd-link.c | 7 | ||||
-rw-r--r-- | src/network/networkd-link.h | 3 | ||||
-rw-r--r-- | src/network/networkd-queue.c | 7 | ||||
-rw-r--r-- | src/network/networkd-queue.h | 3 |
6 files changed, 69 insertions, 27 deletions
diff --git a/src/network/networkd-address-label.c b/src/network/networkd-address-label.c index cf99473cf8..139610631f 100644 --- a/src/network/networkd-address-label.c +++ b/src/network/networkd-address-label.c @@ -9,6 +9,7 @@ #include "networkd-link.h" #include "networkd-manager.h" #include "networkd-network.h" +#include "networkd-queue.h" #include "parse-util.h" AddressLabel *address_label_free(AddressLabel *label) { @@ -63,16 +64,16 @@ static int address_label_new_static(Network *network, const char *filename, unsi return 0; } -static int address_label_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int address_label_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { int r; assert(rtnl); assert(m); assert(link); assert(link->ifname); - assert(link->address_label_messages > 0); + assert(link->static_address_label_messages > 0); - link->address_label_messages--; + link->static_address_label_messages--; if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) return 1; @@ -84,13 +85,16 @@ static int address_label_handler(sd_netlink *rtnl, sd_netlink_message *m, Link * return 1; } - if (link->address_label_messages == 0) + if (link->static_address_label_messages == 0) { log_link_debug(link, "Addresses label set"); + link->static_address_labels_configured = true; + link_check_ready(link); + } return 1; } -static int address_label_configure(AddressLabel *label, Link *link) { +static int address_label_configure(AddressLabel *label, Link *link, link_netlink_message_handler_t callback) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; int r; @@ -99,6 +103,7 @@ static int address_label_configure(AddressLabel *label, Link *link) { assert(link->ifindex > 0); assert(link->manager); assert(link->manager->rtnl); + assert(callback); r = sd_rtnl_message_new_addrlabel(link->manager->rtnl, &req, RTM_NEWADDRLABEL, link->ifindex, AF_INET6); @@ -117,35 +122,55 @@ static int address_label_configure(AddressLabel *label, Link *link) { if (r < 0) return log_link_error_errno(link, r, "Could not append IFA_ADDRESS attribute: %m"); - r = netlink_call_async(link->manager->rtnl, NULL, req, - address_label_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"); link_ref(link); - return 0; + return 1; } -int link_set_address_labels(Link *link) { +int link_request_static_address_labels(Link *link) { AddressLabel *label; int r; assert(link); assert(link->network); + link->static_address_labels_configured = false; + HASHMAP_FOREACH(label, link->network->address_labels_by_section) { - r = address_label_configure(label, link); + r = link_queue_request(link, REQUEST_TYPE_ADDRESS_LABEL, label, false, + &link->static_address_label_messages, address_label_configure_handler, NULL); if (r < 0) - return log_link_warning_errno(link, r, "Could not set address label: %m"); + return log_link_warning_errno(link, r, "Failed to request address label: %m"); + } - link->address_label_messages++; + if (link->static_address_label_messages == 0) { + link->static_address_labels_configured = true; + link_check_ready(link); + } else { + log_link_debug(link, "Setting address labels."); + link_set_state(link, LINK_STATE_CONFIGURING); } return 0; } +int request_process_address_label(Request *req) { + assert(req); + assert(req->link); + assert(req->label); + assert(req->type == REQUEST_TYPE_ADDRESS_LABEL); + + if (!link_is_ready_to_configure(req->link, false)) + return 0; + + return address_label_configure(req->label, req->link, req->netlink_handler); +} + void network_drop_invalid_address_labels(Network *network) { AddressLabel *label; @@ -156,16 +181,17 @@ void network_drop_invalid_address_labels(Network *network) { address_label_free(label); } -int config_parse_address_label_prefix(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { +int config_parse_address_label_prefix( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { _cleanup_(address_label_free_or_set_invalidp) AddressLabel *n = NULL; Network *network = userdata; diff --git a/src/network/networkd-address-label.h b/src/network/networkd-address-label.h index 5a93de4dfc..26d2d94911 100644 --- a/src/network/networkd-address-label.h +++ b/src/network/networkd-address-label.h @@ -7,8 +7,9 @@ #include "in-addr-util.h" #include "networkd-util.h" -typedef struct Network Network; typedef struct Link Link; +typedef struct Network Network; +typedef struct Request Request; typedef struct AddressLabel { Network *network; @@ -23,7 +24,8 @@ AddressLabel *address_label_free(AddressLabel *label); void network_drop_invalid_address_labels(Network *network); -int link_set_address_labels(Link *link); +int link_request_static_address_labels(Link *link); +int request_process_address_label(Request *req); CONFIG_PARSER_PROTOTYPE(config_parse_address_label); CONFIG_PARSER_PROTOTYPE(config_parse_address_label_prefix); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 23c751a39f..d7e939c8ea 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -750,6 +750,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_address_labels_configured) + return (void) log_link_debug(link, "%s(): static address labels are not configured.", __func__); + if (!link->static_bridge_fdb_configured) return (void) log_link_debug(link, "%s(): static bridge MDB entries are not configured.", __func__); @@ -830,11 +833,11 @@ static int link_set_static_configs(Link *link) { if (r < 0) return r; - r = link_set_address_labels(link); + r = link_request_static_addresses(link); if (r < 0) return r; - r = link_request_static_addresses(link); + r = link_request_static_address_labels(link); if (r < 0) return r; diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 2cf79a1f64..ab102b1f12 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -79,8 +79,8 @@ typedef struct Link { LinkAddressState ipv6_address_state; LinkOnlineState online_state; - unsigned address_label_messages; unsigned static_address_messages; + unsigned static_address_label_messages; unsigned static_bridge_fdb_messages; unsigned static_bridge_mdb_messages; unsigned static_neighbor_messages; @@ -123,6 +123,7 @@ typedef struct Link { bool ipv4ll_address_configured:1; bool static_addresses_configured:1; + bool static_address_labels_configured:1; bool static_bridge_fdb_configured:1; bool static_bridge_mdb_configured:1; bool static_neighbors_configured:1; diff --git a/src/network/networkd-queue.c b/src/network/networkd-queue.c index 563cdc4f95..77628cf47c 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-address-label.h" #include "networkd-bridge-fdb.h" #include "networkd-bridge-mdb.h" #include "networkd-dhcp-server.h" @@ -16,6 +17,9 @@ static void request_free_object(RequestType type, void *object) { case REQUEST_TYPE_ADDRESS: address_free(object); break; + case REQUEST_TYPE_ADDRESS_LABEL: + address_label_free(object); + break; case REQUEST_TYPE_BRIDGE_FDB: bridge_fdb_free(object); break; @@ -132,6 +136,9 @@ int manager_process_requests(sd_event_source *s, void *userdata) { case REQUEST_TYPE_ADDRESS: r = request_process_address(req); break; + case REQUEST_TYPE_ADDRESS_LABEL: + r = request_process_address_label(req); + break; case REQUEST_TYPE_BRIDGE_FDB: r = request_process_bridge_fdb(req); break; diff --git a/src/network/networkd-queue.h b/src/network/networkd-queue.h index f963d18d74..20d153f140 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 AddressLabel AddressLabel; typedef struct BridgeFDB BridgeFDB; typedef struct BridgeMDB BridgeMDB; typedef struct Neighbor Neighbor; @@ -20,6 +21,7 @@ typedef void (*request_on_free_handler_t)(Request*); typedef enum RequestType { REQUEST_TYPE_ADDRESS, + REQUEST_TYPE_ADDRESS_LABEL, REQUEST_TYPE_BRIDGE_FDB, REQUEST_TYPE_BRIDGE_MDB, REQUEST_TYPE_DHCP_SERVER, @@ -37,6 +39,7 @@ typedef struct Request { bool consume_object; union { Address *address; + AddressLabel *label; BridgeFDB *fdb; BridgeMDB *mdb; Neighbor *neighbor; |