]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: use request queue to configure neighbors
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 7 May 2021 07:05:31 +0000 (16:05 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 12 May 2021 02:26:06 +0000 (11:26 +0900)
src/network/networkd-link.c
src/network/networkd-link.h
src/network/networkd-neighbor.c
src/network/networkd-neighbor.h
src/network/networkd-queue.c
src/network/networkd-queue.h

index c41baec21546844c5e418e1a5e767ee97c1648da..abf090bc059165d48538d53d1cf418c533e70bb4 100644 (file)
@@ -796,9 +796,6 @@ void link_check_ready(Link *link) {
         if (!link->addresses_configured)
                 return (void) log_link_debug(link, "%s(): static addresses are not configured.", __func__);
 
-        if (!link->neighbors_configured)
-                return (void) log_link_debug(link, "%s(): static neighbors are not configured.", __func__);
-
         SET_FOREACH(a, link->addresses)
                 if (!address_is_ready(a)) {
                         _cleanup_free_ char *str = NULL;
@@ -807,6 +804,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_neighbors_configured)
+                return (void) log_link_debug(link, "%s(): static neighbors are not configured.", __func__);
+
         if (!link->static_routes_configured)
                 return (void) log_link_debug(link, "%s(): static routes are not configured.", __func__);
 
@@ -881,7 +881,6 @@ static int link_set_static_configs(Link *link) {
         link->request_static_addresses = false;
         link->addresses_configured = false;
         link->addresses_ready = false;
-        link->neighbors_configured = false;
         link->static_routes_configured = false;
         link->static_nexthops_configured = false;
 
@@ -897,11 +896,11 @@ static int link_set_static_configs(Link *link) {
         if (r < 0)
                 return r;
 
-        r = link_set_neighbors(link);
+        r = link_set_addresses(link);
         if (r < 0)
                 return r;
 
-        r = link_set_addresses(link);
+        r = link_request_static_neighbors(link);
         if (r < 0)
                 return r;
 
index 9fd95abc3f072f0911f8a46e6a8a50c9fe163027..f8aff1cc8fa54c23743306261edb1e050161c446 100644 (file)
@@ -81,10 +81,11 @@ typedef struct Link {
         unsigned address_messages;
         unsigned address_remove_messages;
         unsigned address_label_messages;
-        unsigned neighbor_messages;
+        unsigned static_neighbor_messages;
         unsigned route_messages;
         unsigned nexthop_messages;
         unsigned static_routing_policy_rule_messages;
+        unsigned neighbor_remove_messages;
         unsigned tc_messages;
         unsigned sr_iov_messages;
         unsigned enslaving;
@@ -121,7 +122,7 @@ typedef struct Link {
         bool request_static_addresses:1;
         bool addresses_configured:1;
         bool addresses_ready:1;
-        bool neighbors_configured:1;
+        bool static_neighbors_configured:1;
         bool static_routes_configured:1;
         bool static_nexthops_configured:1;
         bool static_routing_policy_rules_configured:1;
index 41ce52a3eedb7331f5ea505d483a03d7f8fc34ea..2afe71c5f8a175b553955d4be90dc6639a45e41e 100644 (file)
@@ -7,6 +7,7 @@
 #include "networkd-manager.h"
 #include "networkd-neighbor.h"
 #include "networkd-network.h"
+#include "networkd-queue.h"
 #include "set.h"
 
 Neighbor *neighbor_free(Neighbor *neighbor) {
@@ -270,18 +271,17 @@ static int neighbor_configure(
         if (r < 0)
                 return log_link_error_errno(link, r, "Could not append NDA_DST attribute: %m");
 
+        r = neighbor_add(link, neighbor, ret);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Could not add neighbor: %m");
+
         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->neighbor_messages++;
         link_ref(link);
 
-        r = neighbor_add(link, neighbor, ret);
-        if (r < 0)
-                return log_link_error_errno(link, r, "Could not add neighbor: %m");
-
         return r;
 }
 
@@ -290,28 +290,46 @@ static int static_neighbor_configure_handler(sd_netlink *rtnl, sd_netlink_messag
 
         assert(m);
         assert(link);
-        assert(link->neighbor_messages > 0);
+        assert(link->static_neighbor_messages > 0);
 
-        link->neighbor_messages--;
+        link->static_neighbor_messages--;
 
         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return 1;
 
         r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -EEXIST)
-                /* Neighbor may not exist yet. So, do not enter failed state here. */
-                log_link_message_warning_errno(link, m, r, "Could not set neighbor, ignoring");
+        if (r < 0 && r != -EEXIST) {
+                log_link_message_warning_errno(link, m, r, "Could not set neighbor");
+                link_enter_failed(link);
+                return 1;
+        }
 
-        if (link->neighbor_messages == 0) {
+        if (link->static_neighbor_messages == 0) {
                 log_link_debug(link, "Neighbors set");
-                link->neighbors_configured = true;
+                link->static_neighbors_configured = true;
                 link_check_ready(link);
         }
 
         return 1;
 }
 
-int link_set_neighbors(Link *link) {
+static int link_request_neighbor(
+                Link *link,
+                Neighbor *neighbor,
+                bool consume_object,
+                unsigned *message_counter,
+                link_netlink_message_handler_t netlink_handler,
+                Request **ret) {
+
+        assert(link);
+        assert(neighbor);
+
+        log_neighbor_debug(neighbor, "Requesting", link);
+        return link_queue_request(link, REQUEST_TYPE_NEIGHBOR, neighbor, consume_object,
+                                  message_counter, netlink_handler, ret);
+}
+
+int link_request_static_neighbors(Link *link) {
         Neighbor *neighbor;
         int r;
 
@@ -319,24 +337,20 @@ int link_set_neighbors(Link *link) {
         assert(link->network);
         assert(link->state != _LINK_STATE_INVALID);
 
-        if (link->neighbor_messages != 0) {
-                log_link_debug(link, "Neighbors are configuring.");
-                return 0;
-        }
-
-        link->neighbors_configured = false;
+        link->static_neighbors_configured = false;
 
         HASHMAP_FOREACH(neighbor, link->network->neighbors_by_section) {
-                r = neighbor_configure(neighbor, link, static_neighbor_configure_handler, NULL);
+                r = link_request_neighbor(link, neighbor, false, &link->static_neighbor_messages,
+                                          static_neighbor_configure_handler, NULL);
                 if (r < 0)
-                        return log_link_warning_errno(link, r, "Could not set neighbor: %m");
+                        return log_link_warning_errno(link, r, "Could not request neighbor: %m");
         }
 
-        if (link->neighbor_messages == 0) {
-                link->neighbors_configured = true;
+        if (link->static_neighbor_messages == 0) {
+                link->static_neighbors_configured = true;
                 link_check_ready(link);
         } else {
-                log_link_debug(link, "Setting neighbors");
+                log_link_debug(link, "Requesting neighbors");
                 link_set_state(link, LINK_STATE_CONFIGURING);
         }
 
@@ -348,6 +362,9 @@ static int neighbor_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
 
         assert(m);
         assert(link);
+        assert(link->neighbor_remove_messages > 0);
+
+        link->neighbor_remove_messages--;
 
         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return 1;
@@ -387,6 +404,7 @@ static int neighbor_remove(Neighbor *neighbor, Link *link) {
                 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
 
         link_ref(link);
+        link->neighbor_remove_messages++;
 
         return 0;
 }
@@ -442,6 +460,34 @@ int link_drop_neighbors(Link *link) {
         return r;
 }
 
+int request_process_neighbor(Request *req) {
+        Neighbor *ret;
+        int r;
+
+        assert(req);
+        assert(req->link);
+        assert(req->neighbor);
+        assert(req->type == REQUEST_TYPE_NEIGHBOR);
+
+        if (!link_is_ready_to_configure(req->link, false))
+                return 0;
+
+        if (req->link->neighbor_remove_messages > 0)
+                return 0;
+
+        r = neighbor_configure(req->neighbor, req->link, req->netlink_handler, &ret);
+        if (r < 0)
+                return r;
+
+        if (req->after_configure) {
+                r = req->after_configure(req, ret);
+                if (r < 0)
+                        return r;
+        }
+
+        return 1;
+}
+
 int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
         _cleanup_(neighbor_freep) Neighbor *tmp = NULL;
         _cleanup_free_ void *lladdr = NULL;
index 8ad790be2db5a9cb946a582b6ff2305d5d5057c5..7ac2f90eb388e33e0b5bbad4f8e00c6a507c001d 100644 (file)
 #include "in-addr-util.h"
 #include "networkd-util.h"
 
-typedef Manager Manager;
-typedef Network Network;
-typedef Link Link;
+typedef struct Link Link;
+typedef struct Manager Manager;
+typedef struct Network Network;
+typedef struct Request Request;
 
 union lladdr_union {
         struct ether_addr mac;
@@ -34,10 +35,12 @@ Neighbor *neighbor_free(Neighbor *neighbor);
 
 void network_drop_invalid_neighbors(Network *network);
 
-int link_set_neighbors(Link *link);
 int link_drop_neighbors(Link *link);
 int link_drop_foreign_neighbors(Link *link);
 
+int link_request_static_neighbors(Link *link);
+int request_process_neighbor(Request *req);
+
 int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
 
 CONFIG_PARSER_PROTOTYPE(config_parse_neighbor_address);
index e06a16bbb48037f556ea9df7705243beee99a33f..c515e79716b99365aefab4ab3d8bcfd44675aede 100644 (file)
@@ -10,6 +10,9 @@
 
 static void request_free_object(RequestType type, void *object) {
         switch(type) {
+        case REQUEST_TYPE_NEIGHBOR:
+                neighbor_free(object);
+                break;
         case REQUEST_TYPE_ROUTING_POLICY_RULE:
                 routing_policy_rule_free(object);
                 break;
@@ -104,6 +107,9 @@ int manager_process_requests(sd_event_source *s, void *userdata) {
 
                 ORDERED_SET_FOREACH(req, manager->request_queue) {
                         switch(req->type) {
+                        case REQUEST_TYPE_NEIGHBOR:
+                                r = request_process_neighbor(req);
+                                break;
                         case REQUEST_TYPE_ROUTING_POLICY_RULE:
                                 r = request_process_routing_policy_rule(req);
                                 break;
index e666d446786d68d298a1a2fdcfc34974546302ab..369e7db3a26cd0005b7244af5bc8523227df46e1 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "networkd-link.h"
 
+typedef struct Neighbor Neighbor;
 typedef struct RoutingPolicyRule RoutingPolicyRule;
 
 typedef struct Request Request;
@@ -13,6 +14,7 @@ typedef int (*request_after_configure_handler_t)(Request*, void*);
 typedef void (*request_on_free_handler_t)(Request*);
 
 typedef enum RequestType {
+        REQUEST_TYPE_NEIGHBOR,
         REQUEST_TYPE_ROUTING_POLICY_RULE,
         _REQUEST_TYPE_MAX,
         _REQUEST_TYPE_INVALID = -EINVAL,
@@ -23,6 +25,7 @@ typedef struct Request {
         RequestType type;
         bool consume_object;
         union {
+                Neighbor *neighbor;
                 RoutingPolicyRule *rule;
                 void *object;
         };