From: Yu Watanabe Date: Sun, 6 Jun 2021 07:59:41 +0000 (+0900) Subject: network: use request queue to handle bound_to list X-Git-Tag: v249-rc1~60^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=68f5206349b90f4c33537751d0fc341ab64bb3d9;p=thirdparty%2Fsystemd.git network: use request queue to handle bound_to list --- diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 2065cfd529f..d49ae056233 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -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; } diff --git a/src/network/networkd-queue.c b/src/network/networkd-queue.c index acda4994f08..dfb4a2bf127 100644 --- a/src/network/networkd-queue.c +++ b/src/network/networkd-queue.c @@ -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; } diff --git a/src/network/networkd-queue.h b/src/network/networkd-queue.h index 4fb49c48bc0..c3d7f050792 100644 --- a/src/network/networkd-queue.h +++ b/src/network/networkd-queue.h @@ -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; diff --git a/src/network/networkd-setlink.c b/src/network/networkd-setlink.c index 6207bcf23b3..a5aeb7636a7 100644 --- a/src/network/networkd-setlink.c +++ b/src/network/networkd-setlink.c @@ -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; +} diff --git a/src/network/networkd-setlink.h b/src/network/networkd-setlink.h index eb2633618bc..8caee1a1c05 100644 --- a/src/network/networkd-setlink.h +++ b/src/network/networkd-setlink.h @@ -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);