]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: use request queue to configure DHCP server
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 17 May 2021 16:55:42 +0000 (01:55 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 7 Jun 2021 21:33:27 +0000 (06:33 +0900)
src/network/networkd-address.c
src/network/networkd-dhcp-server.c
src/network/networkd-dhcp-server.h
src/network/networkd-link.c
src/network/networkd-network.h
src/network/networkd-queue.c
src/network/networkd-queue.h

index 550e5c7f5acbc7d90d5987a357b2320d7c2e39e8..5192bbcc006d18aac0bf316cd6ff70080f0e1a4f 100644 (file)
@@ -1091,10 +1091,6 @@ static int static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
                 log_link_debug(link, "Addresses set");
                 link->static_addresses_configured = true;
                 link_check_ready(link);
-
-                r = dhcp4_server_configure(link);
-                if (r < 0)
-                        link_enter_failed(link);
         }
 
         return 1;
index 045c40e9c577762e38293034b631ea1666946cf7..8d88464271faf602f0b1b3291b4c8f7da0ac5e84 100644 (file)
@@ -15,6 +15,7 @@
 #include "networkd-link.h"
 #include "networkd-manager.h"
 #include "networkd-network.h"
+#include "networkd-queue.h"
 #include "parse-util.h"
 #include "socket-netlink.h"
 #include "string-table.h"
@@ -289,7 +290,7 @@ static int dhcp4_server_set_dns_from_resolve_conf(Link *link) {
         return sd_dhcp_server_set_dns(link->dhcp_server, addresses, n_addresses);
 }
 
-int dhcp4_server_configure(Link *link) {
+static int dhcp4_server_configure(Link *link) {
         bool acquired_uplink = false;
         sd_dhcp_option *p;
         DHCPStaticLease *static_lease;
@@ -300,21 +301,18 @@ int dhcp4_server_configure(Link *link) {
 
         assert(link);
 
-        if (!link_dhcp4_server_enabled(link))
-                return 0;
+        log_link_debug(link, "Configuring DHCP Server.");
 
-        if (!(link->flags & IFF_UP))
-                return 0;
+        if (link->dhcp_server)
+                return -EBUSY;
 
-        if (!link->dhcp_server) {
-                r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
-                if (r < 0)
-                        return r;
+        r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
+        if (r < 0)
+                return r;
 
-                r = sd_dhcp_server_attach_event(link->dhcp_server, link->manager->event, 0);
-                if (r < 0)
-                        return r;
-        }
+        r = sd_dhcp_server_attach_event(link->dhcp_server, link->manager->event, 0);
+        if (r < 0)
+                return r;
 
         r = sd_dhcp_server_set_callback(link->dhcp_server, dhcp_server_callback, link);
         if (r < 0)
@@ -455,7 +453,60 @@ int dhcp4_server_configure(Link *link) {
                 log_link_debug(link, "Offering DHCPv4 leases");
         }
 
-        return 0;
+        return 1;
+}
+
+int link_request_dhcp_server(Link *link) {
+        assert(link);
+
+        if (!link_dhcp4_server_enabled(link))
+                return 0;
+
+        if (link->dhcp_server)
+                return 0;
+
+        log_link_debug(link, "Requesting DHCP server.");
+        return link_queue_request(link, REQUEST_TYPE_DHCP_SERVER, NULL, false, NULL, NULL, NULL);
+}
+
+static bool dhcp_server_is_ready_to_configure(Link *link) {
+        Address *a;
+
+        assert(link);
+
+        if (!link->network)
+                return false;
+
+        if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
+                return false;
+
+        if (!link_has_carrier(link))
+                return false;
+
+        if (link->address_remove_messages > 0)
+                return false;
+
+        if (!link->static_addresses_configured)
+                return false;
+
+        if (link_find_dhcp_server_address(link, &a) < 0)
+                return false;
+
+        if (!address_is_ready(a))
+                return false;
+
+        return true;
+}
+
+int request_process_dhcp_server(Request *req) {
+        assert(req);
+        assert(req->link);
+        assert(req->type == REQUEST_TYPE_DHCP_SERVER);
+
+        if (!dhcp_server_is_ready_to_configure(req->link))
+                return 0;
+
+        return dhcp4_server_configure(req->link);
 }
 
 int config_parse_dhcp_server_relay_agent_suboption(
index d58978cc051f6629ea2432ca75f264c5b51fca80..a02cd995ec049c3247a9417add3d072a7709cdc6 100644 (file)
@@ -5,10 +5,12 @@
 
 typedef struct Link Link;
 typedef struct Network Network;
+typedef struct Request Request;
 
 void network_adjust_dhcp_server(Network *network);
 
-int dhcp4_server_configure(Link *link);
+int link_request_dhcp_server(Link *link);
+int request_process_dhcp_server(Request *req);
 
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_relay_agent_suboption);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_emit);
index 97529f6be00b80649cd948d1ac0985d9a11144b7..9aa69bdc732e608304db6d205491571e9b9b7ed2 100644 (file)
@@ -2122,6 +2122,10 @@ static int link_configure(Link *link) {
         if (r < 0)
                 return r;
 
+        r = link_request_dhcp_server(link);
+        if (r < 0)
+                return r;
+
         r = radv_configure(link);
         if (r < 0)
                 return r;
index cb782c72bc519ed0ab40f3aeb40c3b69a63779f5..ca472a6174482b2866f2b4371ac333ca12c70363 100644 (file)
@@ -16,7 +16,6 @@
 #include "networkd-dhcp-common.h"
 #include "networkd-dhcp4.h"
 #include "networkd-dhcp6.h"
-#include "networkd-dhcp-server.h"
 #include "networkd-lldp-rx.h"
 #include "networkd-lldp-tx.h"
 #include "networkd-ndisc.h"
index 8f4fda5da97ad17ede2d84e7787f6f96a0f24fc5..758cd4de2a44b2603780c46870b92cbd95454a18 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "networkd-address.h"
 #include "networkd-bridge-fdb.h"
+#include "networkd-dhcp-server.h"
 #include "networkd-manager.h"
 #include "networkd-neighbor.h"
 #include "networkd-nexthop.h"
@@ -17,6 +18,8 @@ static void request_free_object(RequestType type, void *object) {
         case REQUEST_TYPE_BRIDGE_FDB:
                 bridge_fdb_free(object);
                 break;
+        case REQUEST_TYPE_DHCP_SERVER:
+                break;
         case REQUEST_TYPE_NEIGHBOR:
                 neighbor_free(object);
                 break;
@@ -73,8 +76,10 @@ int link_queue_request(
         assert(link);
         assert(link->manager);
         assert(type >= 0 && type < _REQUEST_TYPE_MAX);
-        assert(object);
-        assert(netlink_handler);
+        if (type != REQUEST_TYPE_DHCP_SERVER) {
+                assert(object);
+                assert(netlink_handler);
+        }
 
         req = new(Request, 1);
         if (!req) {
@@ -126,6 +131,9 @@ int manager_process_requests(sd_event_source *s, void *userdata) {
                         case REQUEST_TYPE_BRIDGE_FDB:
                                 r = request_process_bridge_fdb(req);
                                 break;
+                        case REQUEST_TYPE_DHCP_SERVER:
+                                r = request_process_dhcp_server(req);
+                                break;
                         case REQUEST_TYPE_NEIGHBOR:
                                 r = request_process_neighbor(req);
                                 break;
index 343fe067ae7d7dba18cc7d9508f3c879454c0881..9eab751da42529f1e450bdd9593fb932d799b89c 100644 (file)
@@ -20,6 +20,7 @@ typedef void (*request_on_free_handler_t)(Request*);
 typedef enum RequestType {
         REQUEST_TYPE_ADDRESS,
         REQUEST_TYPE_BRIDGE_FDB,
+        REQUEST_TYPE_DHCP_SERVER,
         REQUEST_TYPE_NEIGHBOR,
         REQUEST_TYPE_NEXTHOP,
         REQUEST_TYPE_ROUTE,