]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: use request queue to handle bound_to list
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 6 Jun 2021 07:59:41 +0000 (16:59 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 8 Jun 2021 19:59:23 +0000 (04:59 +0900)
src/network/networkd-link.c
src/network/networkd-queue.c
src/network/networkd-queue.h
src/network/networkd-setlink.c
src/network/networkd-setlink.h

index 2065cfd529fc031a7bad3eb656d3b96f89800cbe..d49ae056233ca337ec6a8f0f8b39d410dd9eba28 100644 (file)
@@ -708,9 +708,9 @@ int link_handle_bound_to_list(Link *link) {
                 }
 
         if (!required_up && link_is_up)
-                return link_down(link);
+                return link_request_to_bring_up_or_down(link, /* up = */ false);
         if (required_up && !link_is_up)
-                return link_up(link);
+                return link_request_to_bring_up_or_down(link, /* up = */ true);
 
         return 0;
 }
index acda4994f081a5b3b9f3e1647d4dfb2cb4df389d..dfb4a2bf127dbcb4528dd68da4f9d35cdc20b13e 100644 (file)
@@ -49,6 +49,7 @@ static void request_free_object(RequestType type, void *object) {
                 routing_policy_rule_free(object);
                 break;
         case REQUEST_TYPE_SET_LINK:
+        case REQUEST_TYPE_UP_DOWN:
                 break;
         default:
                 assert_not_reached("invalid request type.");
@@ -125,6 +126,8 @@ static void request_hash_func(const Request *req, struct siphash *state) {
         case REQUEST_TYPE_SET_LINK:
                 siphash24_compress(&req->set_link_operation, sizeof(req->set_link_operation), state);
                 break;
+        case REQUEST_TYPE_UP_DOWN:
+                break;
         default:
                 assert_not_reached("invalid request type.");
         }
@@ -170,6 +173,8 @@ static int request_compare_func(const struct Request *a, const struct Request *b
                 return routing_policy_rule_compare_func(a->rule, b->rule);
         case REQUEST_TYPE_SET_LINK:
                 return CMP(a->set_link_operation, b->set_link_operation);
+        case REQUEST_TYPE_UP_DOWN:
+                return 0;
         default:
                 assert_not_reached("invalid request type.");
         }
@@ -201,7 +206,8 @@ int link_queue_request(
         assert(IN_SET(type,
                       REQUEST_TYPE_ACTIVATE_LINK,
                       REQUEST_TYPE_DHCP_SERVER,
-                      REQUEST_TYPE_SET_LINK) ||
+                      REQUEST_TYPE_SET_LINK,
+                      REQUEST_TYPE_UP_DOWN) ||
                object);
         assert(type == REQUEST_TYPE_DHCP_SERVER || netlink_handler);
 
@@ -296,6 +302,9 @@ int manager_process_requests(sd_event_source *s, void *userdata) {
                         case REQUEST_TYPE_SET_LINK:
                                 r = request_process_set_link(req);
                                 break;
+                        case REQUEST_TYPE_UP_DOWN:
+                                r = request_process_link_up_or_down(req);
+                                break;
                         default:
                                 return -EINVAL;
                         }
index 4fb49c48bc02f2304bb1ea72d78e5b482f19cbe1..c3d7f050792a15f422ba73de833da02af35743b9 100644 (file)
@@ -35,6 +35,7 @@ typedef enum RequestType {
         REQUEST_TYPE_ROUTE,
         REQUEST_TYPE_ROUTING_POLICY_RULE,
         REQUEST_TYPE_SET_LINK,
+        REQUEST_TYPE_UP_DOWN,
         _REQUEST_TYPE_MAX,
         _REQUEST_TYPE_INVALID = -EINVAL,
 } RequestType;
index 6207bcf23b344378faf8abb6ccedcbb30d8e7dbf..a5aeb7636a7330e77d0ca3ce65c62e17852a71d9 100644 (file)
@@ -802,6 +802,10 @@ static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link
         return link_up_or_down_handler_internal(rtnl, m, link, false, false);
 }
 
+static const char *up_or_down(bool up) {
+        return up ? "up" : "down";
+}
+
 static int link_up_or_down(Link *link, bool up, link_netlink_message_handler_t callback) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
         int r;
@@ -811,7 +815,7 @@ static int link_up_or_down(Link *link, bool up, link_netlink_message_handler_t c
         assert(link->manager->rtnl);
         assert(callback);
 
-        log_link_debug(link, "Bringing link %s", up ? "up" : "down");
+        log_link_debug(link, "Bringing link %s", up_or_down(up));
 
         r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
         if (r < 0)
@@ -869,7 +873,7 @@ int request_process_activation(Request *req) {
 
         r = link_up_or_down(link, up, req->netlink_handler);
         if (r < 0)
-                return log_link_error_errno(link, r, "Failed to bring %s: %m", up ? "up" : "down");
+                return log_link_error_errno(link, r, "Failed to bring %s: %m", up_or_down(up));
 
         return 1;
 }
@@ -884,7 +888,6 @@ int link_request_to_activate(Link *link) {
 
         switch (link->network->activation_policy) {
         case ACTIVATION_POLICY_BOUND:
-                /* FIXME: also use request queue to handle the list. */
                 r = link_handle_bound_to_list(link);
                 if (r < 0)
                         return r;
@@ -917,3 +920,61 @@ int link_request_to_activate(Link *link) {
         log_link_debug(link, "Requested to activate link");
         return 0;
 }
+
+static bool link_is_ready_to_bring_up_or_down(Link *link) {
+        assert(link);
+
+        if (link->state == LINK_STATE_UNMANAGED)
+                return true;
+
+        if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
+                return false;
+
+        if (link->set_link_messages > 0)
+                return false;
+
+        if (!link->activated)
+                return false;
+
+        return true;
+}
+
+int request_process_link_up_or_down(Request *req) {
+        Link *link;
+        bool up;
+        int r;
+
+        assert(req);
+        assert(req->link);
+        assert(req->type == REQUEST_TYPE_UP_DOWN);
+
+        link = req->link;
+        up = PTR_TO_INT(req->userdata);
+
+        if (!link_is_ready_to_bring_up_or_down(link))
+                return 0;
+
+        r = link_up_or_down(link, up, req->netlink_handler);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Failed to bring %s: %m", up_or_down(up));
+
+        return 1;
+}
+
+int link_request_to_bring_up_or_down(Link *link, bool up) {
+        Request *req;
+        int r;
+
+        assert(link);
+
+        r = link_queue_request(link, REQUEST_TYPE_UP_DOWN, NULL, false, NULL,
+                               up ? link_up_handler : link_down_handler, &req);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Failed to request to bring %s link: %m",
+                                            up_or_down(up));
+
+        req->userdata = INT_TO_PTR(up);
+
+        log_link_debug(link, "Requested to bring link %s", up_or_down(up));
+        return 0;
+}
index eb2633618bc12508dd7f6bfe4e5ba39894b3b2a1..8caee1a1c0539845d2a4c8890dd3612d7c03cba1 100644 (file)
@@ -41,3 +41,6 @@ int link_down(Link *link);
 
 int request_process_activation(Request *req);
 int link_request_to_activate(Link *link);
+
+int request_process_link_up_or_down(Request *req);
+int link_request_to_bring_up_or_down(Link *link, bool up);