diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index d296d799c3..ee3b883b5c 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -595,13 +595,10 @@ static int stacked_netdev_create(NetDev *netdev, Link *link, Request *req) { if (r < 0) return r; - r = netlink_call_async(netdev->manager->rtnl, NULL, m, req->netlink_handler, - link_netlink_destroy_callback, link); + r = request_call_netlink_async(netdev->manager->rtnl, m, req); if (r < 0) return r; - link_ref(link); - netdev->state = NETDEV_STATE_CREATING; log_netdev_debug(netdev, "Creating"); return 0; @@ -650,17 +647,11 @@ int stacked_netdev_process_request(Request *req, Link *link, void *userdata) { return 1; } -static int link_create_stacked_netdev_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int create_stacked_netdev_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) { int r; assert(m); assert(link); - assert(link->create_stacked_netdev_messages > 0); - - link->create_stacked_netdev_messages--; - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 0; r = sd_netlink_message_get_errno(m); if (r < 0 && r != -EEXIST) { @@ -693,7 +684,7 @@ int link_request_stacked_netdev(Link *link, NetDev *netdev) { link->stacked_netdevs_created = false; r = link_queue_request(link, REQUEST_TYPE_NETDEV_STACKED, netdev_ref(netdev), true, &link->create_stacked_netdev_messages, - link_create_stacked_netdev_handler, + create_stacked_netdev_handler, NULL); if (r < 0) return log_link_error_errno(link, r, "Failed to request stacked netdev '%s': %m", diff --git a/src/network/networkd-address-label.c b/src/network/networkd-address-label.c index c165cde092..5c31a44ce4 100644 --- a/src/network/networkd-address-label.c +++ b/src/network/networkd-address-label.c @@ -65,19 +65,17 @@ static int address_label_new_static(Network *network, const char *filename, unsi return 0; } -static int address_label_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int address_label_configure_handler( + sd_netlink *rtnl, + sd_netlink_message *m, + Request *req, + Link *link, + void *userdata) { + int r; - assert(rtnl); assert(m); assert(link); - assert(link->ifname); - assert(link->static_address_label_messages > 0); - - link->static_address_label_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) { @@ -123,13 +121,7 @@ static int address_label_configure(AddressLabel *label, Link *link, Request *req if (r < 0) return r; - r = netlink_call_async(link->manager->rtnl, NULL, m, req->netlink_handler, - link_netlink_destroy_callback, link); - if (r < 0) - return r; - - link_ref(link); - return 0; + return request_call_netlink_async(link->manager->rtnl, m, req); } int address_label_process_request(Request *req, Link *link, void *userdata) { diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 63b40da432..e9a79d352d 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -1023,9 +1023,6 @@ int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, assert(link); assert(error_msg); - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 0; - r = sd_netlink_message_get_errno(m); if (r < 0 && r != -EEXIST) { log_link_message_warning_errno(link, m, r, error_msg); @@ -1087,12 +1084,7 @@ static int address_configure(const Address *address, Link *link, Request *req) { if (r < 0) return r; - r = netlink_call_async(link->manager->rtnl, NULL, m, req->netlink_handler, link_netlink_destroy_callback, link); - if (r < 0) - return r; - - link_ref(link); - return 0; + return request_call_netlink_async(link->manager->rtnl, m, req); } static bool address_is_ready_to_configure(Link *link, const Address *address) { @@ -1135,7 +1127,7 @@ int link_request_address( Address *address, bool consume_object, unsigned *message_counter, - link_netlink_message_handler_t netlink_handler, + address_netlink_handler_t netlink_handler, Request **ret) { Address *acquired, *existing; @@ -1205,7 +1197,7 @@ int link_request_address( log_address_debug(existing, "Requesting", link); r = link_queue_request(link, REQUEST_TYPE_ADDRESS, existing, false, - message_counter, netlink_handler, ret); + message_counter, (request_netlink_handler_t) netlink_handler, ret); if (r < 0) return log_link_warning_errno(link, r, "Failed to request address: %m"); if (r == 0) @@ -1216,13 +1208,10 @@ int link_request_address( return 1; } -static int static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) { int r; assert(link); - assert(link->static_address_messages > 0); - - link->static_address_messages--; r = address_configure_handler_internal(rtnl, m, link, "Failed to set static address"); if (r <= 0) diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h index a90dbceb64..a41274a1fc 100644 --- a/src/network/networkd-address.h +++ b/src/network/networkd-address.h @@ -18,6 +18,12 @@ typedef struct Manager Manager; typedef struct Network Network; typedef struct Request Request; typedef int (*address_ready_callback_t)(Address *address); +typedef int (*address_netlink_handler_t)( + sd_netlink *rtnl, + sd_netlink_message *m, + Request *req, + Link *link, + Address *address); struct Address { Link *link; @@ -97,7 +103,7 @@ int link_request_address( Address *address, bool consume_object, unsigned *message_counter, - link_netlink_message_handler_t netlink_handler, + address_netlink_handler_t netlink_handler, Request **ret); int link_request_static_address(Link *link, Address *address, bool consume); int link_request_static_addresses(Link *link); diff --git a/src/network/networkd-bridge-fdb.c b/src/network/networkd-bridge-fdb.c index e8a05e5e13..cc02213c28 100644 --- a/src/network/networkd-bridge-fdb.c +++ b/src/network/networkd-bridge-fdb.c @@ -93,16 +93,11 @@ static int bridge_fdb_new_static( return 0; } -static int bridge_fdb_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int bridge_fdb_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) { int r; + assert(m); assert(link); - assert(link->static_bridge_fdb_messages > 0); - - link->static_bridge_fdb_messages--; - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 0; r = sd_netlink_message_get_errno(m); if (r < 0 && r != -EEXIST) { @@ -185,13 +180,7 @@ static int bridge_fdb_configure(BridgeFDB *fdb, Link *link, Request *req) { if (r < 0) return r; - r = netlink_call_async(link->manager->rtnl, NULL, m, req->netlink_handler, - link_netlink_destroy_callback, link); - if (r < 0) - return r; - - link_ref(link); - return 0; + return request_call_netlink_async(link->manager->rtnl, m, req); } static bool bridge_fdb_is_ready_to_configure(BridgeFDB *fdb, Link *link) { diff --git a/src/network/networkd-bridge-mdb.c b/src/network/networkd-bridge-mdb.c index b9320f7ea2..88ae091c1a 100644 --- a/src/network/networkd-bridge-mdb.c +++ b/src/network/networkd-bridge-mdb.c @@ -81,16 +81,11 @@ static int bridge_mdb_new_static( return 0; } -static int bridge_mdb_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int bridge_mdb_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) { int r; + assert(m); assert(link); - assert(link->static_bridge_mdb_messages > 0); - - link->static_bridge_mdb_messages--; - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 1; r = sd_netlink_message_get_errno(m); if (r == -EINVAL && streq_ptr(link->kind, "bridge") && link->master_ifindex <= 0) { @@ -164,13 +159,7 @@ static int bridge_mdb_configure(BridgeMDB *mdb, Link *link, Request *req) { if (r < 0) return r; - r = netlink_call_async(link->manager->rtnl, NULL, m, req->netlink_handler, - link_netlink_destroy_callback, link); - if (r < 0) - return r; - - link_ref(link); - return 0; + return request_call_netlink_async(link->manager->rtnl, m, req); } static bool bridge_mdb_is_ready_to_configure(Link *link) { diff --git a/src/network/networkd-dhcp-prefix-delegation.c b/src/network/networkd-dhcp-prefix-delegation.c index bba66f71ed..edc893e9f6 100644 --- a/src/network/networkd-dhcp-prefix-delegation.c +++ b/src/network/networkd-dhcp-prefix-delegation.c @@ -288,13 +288,10 @@ static int dhcp_pd_check_ready(Link *link) { return 1; } -static int dhcp_pd_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int dhcp_pd_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) { int r; assert(link); - assert(link->dhcp_pd_messages > 0); - - link->dhcp_pd_messages--; r = route_configure_handler_internal(rtnl, m, link, "Failed to add prefix route for DHCP delegated subnet prefix"); if (r <= 0) @@ -344,13 +341,10 @@ static int dhcp_pd_request_route(Link *link, const struct in6_addr *prefix, usec return 0; } -static int dhcp_pd_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int dhcp_pd_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) { int r; assert(link); - assert(link->dhcp_pd_messages > 0); - - link->dhcp_pd_messages--; r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCP-PD address"); if (r <= 0) @@ -658,13 +652,10 @@ void dhcp4_pd_prefix_lost(Link *uplink) { (void) link_remove(tunnel); } -static int dhcp4_unreachable_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int dhcp4_unreachable_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) { int r; assert(link); - assert(link->dhcp4_messages > 0); - - link->dhcp4_messages--; r = route_configure_handler_internal(rtnl, m, link, "Failed to set unreachable route for DHCPv4 delegated prefix"); if (r <= 0) @@ -677,13 +668,10 @@ static int dhcp4_unreachable_route_handler(sd_netlink *rtnl, sd_netlink_message return 1; } -static int dhcp6_unreachable_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int dhcp6_unreachable_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) { int r; assert(link); - assert(link->dhcp6_messages > 0); - - link->dhcp6_messages--; r = route_configure_handler_internal(rtnl, m, link, "Failed to set unreachable route for DHCPv6 delegated prefix"); if (r <= 0) @@ -704,7 +692,7 @@ static int dhcp_request_unreachable_route( NetworkConfigSource source, const union in_addr_union *server_address, unsigned *counter, - link_netlink_message_handler_t callback) { + route_netlink_handler_t callback) { _cleanup_(route_freep) Route *route = NULL; Route *existing; diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 1aa389bb53..dcde7f9bed 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -177,16 +177,11 @@ static int dhcp4_retry(Link *link) { return dhcp4_request_address_and_routes(link, false); } -static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) { int r; + assert(m); assert(link); - assert(link->dhcp4_messages > 0); - - link->dhcp4_messages--; - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 1; r = sd_netlink_message_get_errno(m); if (r == -ENETUNREACH && !link->dhcp4_route_retrying) { @@ -829,13 +824,10 @@ int dhcp4_lease_lost(Link *link) { return link_request_static_routes(link, true); } -static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) { int r; assert(link); - assert(link->dhcp4_messages > 0); - - link->dhcp4_messages--; r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCPv4 address"); if (r <= 0) diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 3bb013ebaf..bceae735b0 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -136,13 +136,10 @@ int dhcp6_check_ready(Link *link) { return 0; } -static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) { int r; assert(link); - assert(link->dhcp6_messages > 0); - - link->dhcp6_messages--; r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCPv6 address"); if (r <= 0) diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c index 5e3854281c..67eb9d2aa1 100644 --- a/src/network/networkd-ipv4ll.c +++ b/src/network/networkd-ipv4ll.c @@ -70,7 +70,7 @@ static int ipv4ll_address_lost(Link *link) { return address_remove(existing); } -static int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) { int r; assert(link); diff --git a/src/network/networkd-ipv6-proxy-ndp.c b/src/network/networkd-ipv6-proxy-ndp.c index def456c9aa..b245a9eba2 100644 --- a/src/network/networkd-ipv6-proxy-ndp.c +++ b/src/network/networkd-ipv6-proxy-ndp.c @@ -26,13 +26,17 @@ void network_adjust_ipv6_proxy_ndp(Network *network) { } } -static int ipv6_proxy_ndp_address_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int ipv6_proxy_ndp_address_configure_handler( + sd_netlink *rtnl, + sd_netlink_message *m, + Request *req, + Link *link, + struct in6_addr *address) { + int r; + assert(m); assert(link); - assert(link->static_ipv6_proxy_ndp_messages > 0); - - link->static_ipv6_proxy_ndp_messages--; r = sd_netlink_message_get_errno(m); if (r < 0) @@ -71,13 +75,7 @@ static int ipv6_proxy_ndp_address_configure(const struct in6_addr *address, Link if (r < 0) return r; - r = netlink_call_async(link->manager->rtnl, NULL, m, req->netlink_handler, - link_netlink_destroy_callback, link); - if (r < 0) - return r; - - link_ref(link); - return 0; + return request_call_netlink_async(link->manager->rtnl, m, req); } int ipv6_proxy_ndp_address_process_request(Request *req, Link *link, struct in6_addr *address) { @@ -109,7 +107,8 @@ int link_request_static_ipv6_proxy_ndp_addresses(Link *link) { SET_FOREACH(address, link->network->ipv6_proxy_ndp_addresses) { r = link_queue_request(link, REQUEST_TYPE_IPV6_PROXY_NDP, address, false, &link->static_ipv6_proxy_ndp_messages, - ipv6_proxy_ndp_address_configure_handler, NULL); + (request_netlink_handler_t) ipv6_proxy_ndp_address_configure_handler, + NULL); if (r < 0) return log_link_warning_errno(link, r, "Failed to request IPv6 proxy NDP address: %m"); } diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 2f86ade325..2a85fb3cfb 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -203,13 +203,10 @@ static int ndisc_check_ready(Link *link) { return 0; } -static int ndisc_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int ndisc_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) { int r; assert(link); - assert(link->ndisc_messages > 0); - - link->ndisc_messages--; r = route_configure_handler_internal(rtnl, m, link, "Could not set NDisc route"); if (r <= 0) @@ -254,13 +251,10 @@ static int ndisc_request_route(Route *in, Link *link, sd_ndisc_router *rt) { ndisc_route_handler, NULL); } -static int ndisc_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int ndisc_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) { int r; assert(link); - assert(link->ndisc_messages > 0); - - link->ndisc_messages--; r = address_configure_handler_internal(rtnl, m, link, "Could not set NDisc address"); if (r <= 0) diff --git a/src/network/networkd-neighbor.c b/src/network/networkd-neighbor.c index 33fa5e21ec..1cb5333b66 100644 --- a/src/network/networkd-neighbor.c +++ b/src/network/networkd-neighbor.c @@ -215,14 +215,7 @@ static int neighbor_configure(Neighbor *neighbor, Link *link, Request *req) { if (r < 0) return r; - r = netlink_call_async(link->manager->rtnl, NULL, m, req->netlink_handler, - link_netlink_destroy_callback, link); - if (r < 0) - return r; - - link_ref(link); - - return 0; + return request_call_netlink_async(link->manager->rtnl, m, req); } int neighbor_process_request(Request *req, Link *link, Neighbor *neighbor) { @@ -243,17 +236,11 @@ int neighbor_process_request(Request *req, Link *link, Neighbor *neighbor) { return 1; } -static int static_neighbor_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int static_neighbor_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Neighbor *neighbor) { int r; assert(m); assert(link); - assert(link->static_neighbor_messages > 0); - - 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) { @@ -271,13 +258,7 @@ static int static_neighbor_configure_handler(sd_netlink *rtnl, sd_netlink_messag return 1; } -static int link_request_neighbor( - Link *link, - const Neighbor *neighbor, - unsigned *message_counter, - link_netlink_message_handler_t netlink_handler, - Request **ret) { - +static int link_request_neighbor(Link *link, const Neighbor *neighbor) { Neighbor *existing; int r; @@ -302,7 +283,9 @@ static int link_request_neighbor( log_neighbor_debug(existing, "Requesting", link); r = link_queue_request(link, REQUEST_TYPE_NEIGHBOR, existing, false, - message_counter, netlink_handler, ret); + &link->static_neighbor_messages, + (request_netlink_handler_t) static_neighbor_configure_handler, + NULL); if (r <= 0) return r; @@ -321,8 +304,7 @@ int link_request_static_neighbors(Link *link) { link->static_neighbors_configured = false; HASHMAP_FOREACH(neighbor, link->network->neighbors_by_section) { - r = link_request_neighbor(link, neighbor, &link->static_neighbor_messages, - static_neighbor_configure_handler, NULL); + r = link_request_neighbor(link, neighbor); if (r < 0) return log_link_warning_errno(link, r, "Could not request neighbor: %m"); } diff --git a/src/network/networkd-nexthop.c b/src/network/networkd-nexthop.c index 143ecce6c4..219a08e159 100644 --- a/src/network/networkd-nexthop.c +++ b/src/network/networkd-nexthop.c @@ -485,25 +485,14 @@ static int nexthop_configure(NextHop *nexthop, Link *link, Request *req) { } } - r = netlink_call_async(link->manager->rtnl, NULL, m, req->netlink_handler, - link_netlink_destroy_callback, link); - if (r < 0) - return r; - - link_ref(link); - return 0; + return request_call_netlink_async(link->manager->rtnl, m, req); } -static int static_nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int static_nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, NextHop *nexthop) { int r; + assert(m); assert(link); - assert(link->static_nexthop_messages > 0); - - link->static_nexthop_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) { @@ -583,13 +572,7 @@ int nexthop_process_request(Request *req, Link *link, NextHop *nexthop) { return 1; } -static int link_request_nexthop( - Link *link, - NextHop *nexthop, - unsigned *message_counter, - link_netlink_message_handler_t netlink_handler, - Request **ret) { - +static int link_request_nexthop(Link *link, NextHop *nexthop) { NextHop *existing; int r; @@ -618,7 +601,9 @@ static int link_request_nexthop( log_nexthop_debug(existing, "Requesting", link); r = link_queue_request(link, REQUEST_TYPE_NEXTHOP, existing, false, - message_counter, netlink_handler, ret); + &link->static_nexthop_messages, + (request_netlink_handler_t) static_nexthop_handler, + NULL); if (r <= 0) return r; @@ -639,8 +624,7 @@ int link_request_static_nexthops(Link *link, bool only_ipv4) { if (only_ipv4 && nh->family != AF_INET) continue; - r = link_request_nexthop(link, nh, &link->static_nexthop_messages, - static_nexthop_handler, NULL); + r = link_request_nexthop(link, nh); if (r < 0) return log_link_warning_errno(link, r, "Could not request nexthop: %m"); } diff --git a/src/network/networkd-queue.c b/src/network/networkd-queue.c index 70edc27fcd..a509cd4d4b 100644 --- a/src/network/networkd-queue.c +++ b/src/network/networkd-queue.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include "netlink-util.h" #include "networkd-address.h" #include "networkd-address-label.h" #include "networkd-bridge-fdb.h" @@ -89,12 +90,16 @@ static Request *request_free(Request *req) { if (req->consume_object) request_free_object(req->type, req->object); + if (req->counter) + (*req->counter)--; + link_unref(req->link); /* link may be NULL, but link_unref() can handle it gracefully. */ return mfree(req); } DEFINE_TRIVIAL_REF_UNREF_FUNC(Request, request, request_free); +DEFINE_TRIVIAL_DESTRUCTOR(request_destroy_callback, Request, request_unref); void request_detach(Manager *manager, Request *req) { assert(manager); @@ -107,13 +112,6 @@ void request_detach(Manager *manager, Request *req) { return; req->manager = NULL; - - if (req->message_counter) { - assert(*req->message_counter > 0); - (*req->message_counter)--; - req->message_counter = NULL; /* To prevent double decrement. */ - } - request_unref(req); } @@ -301,8 +299,8 @@ int link_queue_request( RequestType type, void *object, bool consume_object, - unsigned *message_counter, - link_netlink_message_handler_t netlink_handler, + unsigned *counter, + request_netlink_handler_t netlink_handler, Request **ret) { _cleanup_(request_unrefp) Request *req = NULL; @@ -343,7 +341,6 @@ int link_queue_request( .type = type, .object = object, .consume_object = consume_object, - .message_counter = message_counter, .netlink_handler = netlink_handler, }; @@ -359,8 +356,9 @@ int link_queue_request( return r; req->manager = link->manager; - if (req->message_counter) - (*req->message_counter)++; + req->counter = counter; + if (req->counter) + (*req->counter)++; if (ret) *ret = req; @@ -447,14 +445,14 @@ int manager_process_requests(sd_event_source *s, void *userdata) { default: return -EINVAL; } - if (r < 0) { - if (req->link) - link_enter_failed(req->link); - } else if (r > 0) { - req->message_counter = NULL; - request_detach(manager, req); - processed = true; - } + if (r == 0) + continue; + + processed = true; + request_detach(manager, req); + + if (r < 0 && req->link) + link_enter_failed(req->link); } if (!processed) @@ -463,3 +461,36 @@ int manager_process_requests(sd_event_source *s, void *userdata) { return 0; } + +static int request_netlink_handler(sd_netlink *nl, sd_netlink_message *m, Request *req) { + assert(req); + + if (req->counter) { + assert(*req->counter > 0); + (*req->counter)--; + req->counter = NULL; /* To prevent double decrement on free. */ + } + + if (req->link && IN_SET(req->link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) + return 0; + + if (req->netlink_handler) + return req->netlink_handler(nl, m, req, req->link, req->object); + + return 0; +} + +int request_call_netlink_async(sd_netlink *nl, sd_netlink_message *m, Request *req) { + int r; + + assert(nl); + assert(m); + assert(req); + + r = netlink_call_async(nl, NULL, m, request_netlink_handler, request_destroy_callback, req); + if (r < 0) + return r; + + request_ref(req); + return 0; +} diff --git a/src/network/networkd-queue.h b/src/network/networkd-queue.h index 14403efdd0..ac4c5c13af 100644 --- a/src/network/networkd-queue.h +++ b/src/network/networkd-queue.h @@ -2,6 +2,7 @@ #pragma once #include "sd-event.h" +#include "sd-netlink.h" #include "networkd-link.h" @@ -16,6 +17,9 @@ typedef struct Route Route; typedef struct RoutingPolicyRule RoutingPolicyRule; typedef struct QDisc QDisc; typedef struct TClass TClass; +typedef struct Request Request; + +typedef int (*request_netlink_handler_t)(sd_netlink *nl, sd_netlink_message *m, Request *req, Link *link, void *userdata); typedef enum RequestType { REQUEST_TYPE_ACTIVATE_LINK, @@ -43,7 +47,7 @@ typedef enum RequestType { _REQUEST_TYPE_INVALID = -EINVAL, } RequestType; -typedef struct Request { +struct Request { unsigned n_ref; Manager *manager; /* must be non-NULL */ @@ -68,9 +72,15 @@ typedef struct Request { void *object; }; void *userdata; - unsigned *message_counter; - link_netlink_message_handler_t netlink_handler; -} Request; + + /* incremented when requested, decremented when request is completed or failed. */ + unsigned *counter; + /* called in netlink handler, the 'counter' is decremented before this is called. + * If this is specified, then the 'process' function must increment the reference of this + * request, and pass this request to the netlink_call_async(), and set the destroy function + * to the slot. */ + request_netlink_handler_t netlink_handler; +}; Request *request_ref(Request *req); Request *request_unref(Request *req); @@ -87,8 +97,9 @@ int link_queue_request( RequestType type, void *object, bool consume_object, - unsigned *message_counter, - link_netlink_message_handler_t netlink_handler, + unsigned *counter, + request_netlink_handler_t netlink_handler, Request **ret); int manager_process_requests(sd_event_source *s, void *userdata); +int request_call_netlink_async(sd_netlink *nl, sd_netlink_message *m, Request *req); diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 9be1190655..cfc6967963 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -1141,9 +1141,6 @@ int route_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Li assert(link); assert(error_msg); - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 0; - r = sd_netlink_message_get_errno(m); if (r < 0 && r != -EEXIST) { log_link_message_warning_errno(link, m, r, "Could not set route"); @@ -1246,13 +1243,7 @@ static int route_configure(const Route *route, Link *link, Request *req) { return r; } - r = netlink_call_async(link->manager->rtnl, NULL, m, req->netlink_handler, - link_netlink_destroy_callback, link); - if (r < 0) - return r; - - link_ref(link); - return 0; + return request_call_netlink_async(link->manager->rtnl, m, req); } static int route_is_ready_to_configure(const Route *route, Link *link) { @@ -1385,7 +1376,7 @@ int link_request_route( Route *route, bool consume_object, unsigned *message_counter, - link_netlink_message_handler_t netlink_handler, + route_netlink_handler_t netlink_handler, Request **ret) { Route *existing; @@ -1433,7 +1424,7 @@ int link_request_route( log_route_debug(existing, "Requesting", link, link->manager); r = link_queue_request(link, REQUEST_TYPE_ROUTE, existing, false, - message_counter, netlink_handler, ret); + message_counter, (request_netlink_handler_t) netlink_handler, ret); if (r <= 0) return r; @@ -1441,13 +1432,10 @@ int link_request_route( return 1; } -static int static_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int static_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) { int r; assert(link); - assert(link->static_route_messages > 0); - - link->static_route_messages--; r = route_configure_handler_internal(rtnl, m, link, "Could not set route"); if (r <= 0) @@ -1473,7 +1461,9 @@ static int link_request_static_route(Link *link, Route *route) { log_route_debug(route, "Requesting", link, link->manager); return link_queue_request(link, REQUEST_TYPE_ROUTE, route, false, - &link->static_route_messages, static_route_handler, NULL); + &link->static_route_messages, + (request_netlink_handler_t) static_route_handler, + NULL); } static int link_request_wireguard_routes(Link *link, bool only_ipv4) { diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index 634ed16176..8c1c5cf680 100644 --- a/src/network/networkd-route.h +++ b/src/network/networkd-route.h @@ -14,8 +14,15 @@ typedef struct Manager Manager; typedef struct Network Network; typedef struct Request Request; +typedef struct Route Route; +typedef int (*route_netlink_handler_t)( + sd_netlink *rtnl, + sd_netlink_message *m, + Request *req, + Link *link, + Route *route); -typedef struct Route { +struct Route { Link *link; Manager *manager; Network *network; @@ -66,7 +73,7 @@ typedef struct Route { usec_t lifetime_usec; /* Used when kernel does not support RTA_EXPIRES attribute. */ sd_event_source *expire; -} Route; +}; void route_hash_func(const Route *route, struct siphash *state); int route_compare_func(const Route *a, const Route *b); @@ -92,7 +99,7 @@ int link_request_route( Route *route, bool consume_object, unsigned *message_counter, - link_netlink_message_handler_t netlink_handler, + route_netlink_handler_t netlink_handler, Request **ret); int link_request_static_routes(Link *link, bool only_ipv4); int route_process_request(Request *req, Link *link, Route *route); diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index a90c176f76..535af175a3 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -626,13 +626,7 @@ static int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, Re if (r < 0) return r; - r = netlink_call_async(link->manager->rtnl, NULL, m, req->netlink_handler, - link_netlink_destroy_callback, link); - if (r < 0) - return r; - - link_ref(link); - return 0; + return request_call_netlink_async(link->manager->rtnl, m, req); } static void manager_mark_routing_policy_rules(Manager *m, bool foreign, const Link *except) { @@ -742,19 +736,17 @@ int routing_policy_rule_process_request(Request *req, Link *link, RoutingPolicyR return 1; } -static int static_routing_policy_rule_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int static_routing_policy_rule_configure_handler( + sd_netlink *rtnl, + sd_netlink_message *m, + Request *req, + Link *link, + RoutingPolicyRule *rule) { + int r; - assert(rtnl); assert(m); assert(link); - assert(link->ifname); - assert(link->static_routing_policy_rule_messages > 0); - - link->static_routing_policy_rule_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) { @@ -772,13 +764,7 @@ static int static_routing_policy_rule_configure_handler(sd_netlink *rtnl, sd_net return 1; } -static int link_request_routing_policy_rule( - Link *link, - RoutingPolicyRule *rule, - unsigned *message_counter, - link_netlink_message_handler_t netlink_handler, - Request **ret) { - +static int link_request_routing_policy_rule(Link *link, RoutingPolicyRule *rule) { RoutingPolicyRule *existing; int r; @@ -808,7 +794,9 @@ static int link_request_routing_policy_rule( log_routing_policy_rule_debug(existing, "Requesting", link, link->manager); r = link_queue_request(link, REQUEST_TYPE_ROUTING_POLICY_RULE, existing, false, - message_counter, netlink_handler, ret); + &link->static_routing_policy_rule_messages, + (request_netlink_handler_t) static_routing_policy_rule_configure_handler, + NULL); if (r <= 0) return r; @@ -820,26 +808,17 @@ static int link_request_static_routing_policy_rule(Link *link, RoutingPolicyRule int r; if (IN_SET(rule->family, AF_INET, AF_INET6)) - return link_request_routing_policy_rule(link, rule, - &link->static_routing_policy_rule_messages, - static_routing_policy_rule_configure_handler, - NULL); + return link_request_routing_policy_rule(link, rule); rule->family = AF_INET; - r = link_request_routing_policy_rule(link, rule, - &link->static_routing_policy_rule_messages, - static_routing_policy_rule_configure_handler, - NULL); + r = link_request_routing_policy_rule(link, rule); if (r < 0) { rule->family = AF_UNSPEC; return r; } rule->family = AF_INET6; - r = link_request_routing_policy_rule(link, rule, - &link->static_routing_policy_rule_messages, - static_routing_policy_rule_configure_handler, - NULL); + r = link_request_routing_policy_rule(link, rule); rule->family = AF_UNSPEC; return r; } diff --git a/src/network/networkd-setlink.c b/src/network/networkd-setlink.c index f5d879af78..b012967462 100644 --- a/src/network/networkd-setlink.c +++ b/src/network/networkd-setlink.c @@ -54,22 +54,19 @@ static int get_link_update_flag_handler(sd_netlink *rtnl, sd_netlink_message *m, static int set_link_handler_internal( sd_netlink *rtnl, sd_netlink_message *m, + Request *req, Link *link, - SetLinkOperation op, bool ignore, link_netlink_message_handler_t get_link_handler) { + SetLinkOperation op; int r; assert(m); + assert(req); assert(link); - assert(link->set_link_messages > 0); - assert(op >= 0 && op < _SET_LINK_OPERATION_MAX); - link->set_link_messages--; - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - goto on_error; + op = PTR_TO_INT(req->set_link_operation_ptr); r = sd_netlink_message_get_errno(m); if (r < 0) { @@ -80,7 +77,7 @@ static int set_link_handler_internal( if (!ignore) link_enter_failed(link); - goto on_error; + return 0; } log_link_debug(link, "%s set.", set_link_operation_to_string(op)); @@ -89,7 +86,7 @@ static int set_link_handler_internal( r = link_call_getlink(link, get_link_handler); if (r < 0) { link_enter_failed(link); - goto on_error; + return 0; } } @@ -97,27 +94,12 @@ static int set_link_handler_internal( link_check_ready(link); return 1; - -on_error: - switch (op) { - case SET_LINK_FLAGS: - assert(link->set_flags_messages > 0); - link->set_flags_messages--; - break; - case SET_LINK_MASTER: - link->master_set = true; - break; - default: - break; - } - - return 0; } -static int link_set_addrgen_mode_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int link_set_addrgen_mode_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) { int r; - r = set_link_handler_internal(rtnl, m, link, SET_LINK_ADDRESS_GENERATION_MODE, /* ignore = */ true, NULL); + r = set_link_handler_internal(rtnl, m, req, link, /* ignore = */ true, NULL); if (r <= 0) return r; @@ -130,49 +112,43 @@ static int link_set_addrgen_mode_handler(sd_netlink *rtnl, sd_netlink_message *m return 0; } -static int link_set_bond_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - return set_link_handler_internal(rtnl, m, link, SET_LINK_BOND, /* ignore = */ false, NULL); +static int link_set_bond_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) { + return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ false, NULL); } -static int link_set_bridge_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - return set_link_handler_internal(rtnl, m, link, SET_LINK_BRIDGE, /* ignore = */ true, NULL); +static int link_set_bridge_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) { + return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ true, NULL); } -static int link_set_bridge_vlan_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - return set_link_handler_internal(rtnl, m, link, SET_LINK_BRIDGE_VLAN, /* ignore = */ false, NULL); +static int link_set_bridge_vlan_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) { + return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ false, NULL); } -static int link_set_can_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - return set_link_handler_internal(rtnl, m, link, SET_LINK_CAN, /* ignore = */ false, NULL); +static int link_set_can_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) { + return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ false, NULL); } -static int link_set_flags_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - return set_link_handler_internal(rtnl, m, link, SET_LINK_FLAGS, /* ignore = */ false, get_link_update_flag_handler); +static int link_set_flags_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) { + return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ false, get_link_default_handler); } -static int link_set_group_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - return set_link_handler_internal(rtnl, m, link, SET_LINK_GROUP, /* ignore = */ false, NULL); +static int link_set_group_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) { + return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ false, NULL); } -static int link_set_ipoib_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - return set_link_handler_internal(rtnl, m, link, SET_LINK_IPOIB, /* ignore = */ true, NULL); +static int link_set_ipoib_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) { + return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ true, NULL); } -static int link_set_mac_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - return set_link_handler_internal(rtnl, m, link, SET_LINK_MAC, /* ignore = */ true, get_link_default_handler); +static int link_set_mac_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) { + return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ true, get_link_default_handler); } -static int link_set_mac_allow_retry_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int link_set_mac_allow_retry_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) { int r; assert(m); assert(link); - assert(link->set_link_messages > 0); - - link->set_link_messages--; - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 0; r = sd_netlink_message_get_errno(m); if (r == -EBUSY) { @@ -189,24 +165,22 @@ static int link_set_mac_allow_retry_handler(sd_netlink *rtnl, sd_netlink_message return 0; } - /* set_link_mac_handler() also decrements set_link_messages, so increment the value once. */ - link->set_link_messages++; - return link_set_mac_handler(rtnl, m, link); + return link_set_mac_handler(rtnl, m, req, link, userdata); } -static int link_set_master_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - return set_link_handler_internal(rtnl, m, link, SET_LINK_MASTER, /* ignore = */ false, get_link_master_handler); +static int link_set_master_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) { + return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ false, get_link_master_handler); } -static int link_unset_master_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int link_unset_master_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) { /* Some devices do not support setting master ifindex. Let's ignore error on unsetting master ifindex. */ - return set_link_handler_internal(rtnl, m, link, SET_LINK_MASTER, /* ignore = */ true, get_link_master_handler); + return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ true, get_link_master_handler); } -static int link_set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int link_set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) { int r; - r = set_link_handler_internal(rtnl, m, link, SET_LINK_MTU, /* ignore = */ true, get_link_default_handler); + r = set_link_handler_internal(rtnl, m, req, link, /* ignore = */ true, get_link_default_handler); if (r <= 0) return r; @@ -460,44 +434,34 @@ static int link_configure_fill_message( return 0; } -static int link_configure( - Link *link, - SetLinkOperation op, - void *userdata, - link_netlink_message_handler_t callback) { - - _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; +static int link_configure(Link *link, Request *req) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; + SetLinkOperation op; int r; assert(link); assert(link->manager); assert(link->manager->rtnl); - assert(link->network); - assert(op >= 0 && op < _SET_LINK_OPERATION_MAX); - assert(callback); + assert(req); + + op = PTR_TO_INT(req->set_link_operation_ptr); log_link_debug(link, "Setting %s", set_link_operation_to_string(op)); if (op == SET_LINK_BOND) - r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->master_ifindex); + r = sd_rtnl_message_new_link(link->manager->rtnl, &m, RTM_NEWLINK, link->master_ifindex); else if (IN_SET(op, SET_LINK_CAN, SET_LINK_IPOIB)) - r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->ifindex); + r = sd_rtnl_message_new_link(link->manager->rtnl, &m, RTM_NEWLINK, link->ifindex); else - r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex); + r = sd_rtnl_message_new_link(link->manager->rtnl, &m, RTM_SETLINK, link->ifindex); if (r < 0) - return log_link_debug_errno(link, r, "Could not allocate netlink message: %m"); + return r; - r = link_configure_fill_message(link, req, op, userdata); + r = link_configure_fill_message(link, m, op, req->userdata); if (r < 0) - return log_link_debug_errno(link, r, "Could not create netlink message: %m"); + return r; - r = netlink_call_async(link->manager->rtnl, NULL, req, callback, - link_netlink_destroy_callback, link); - if (r < 0) - return log_link_debug_errno(link, r, "Could not send netlink message: %m"); - - link_ref(link); - return 0; + return request_call_netlink_async(link->manager->rtnl, m, req); } static bool netdev_is_ready(NetDev *netdev) { @@ -641,21 +605,18 @@ int request_process_set_link(Request *req) { if (!link_is_ready_to_call_set_link(req)) return 0; - r = link_configure(req->link, op, req->userdata, req->netlink_handler); + r = link_configure(req->link, req); if (r < 0) return log_link_error_errno(req->link, r, "Failed to set %s: %m", set_link_operation_to_string(op)); - if (op == SET_LINK_FLAGS) - req->link->set_flags_messages++; - return 1; } static int link_request_set_link( Link *link, SetLinkOperation op, - link_netlink_message_handler_t netlink_handler, + request_netlink_handler_t netlink_handler, Request **ret) { Request *req; @@ -991,14 +952,16 @@ static int link_up_dsa_slave(Link *link) { return 1; } -static int link_up_or_down_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, bool up, bool on_activate) { +static int link_up_or_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) { + bool on_activate, up; int r; assert(m); + assert(req); assert(link); - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - goto on_error; + on_activate = req->type == REQUEST_TYPE_ACTIVATE_LINK; + up = PTR_TO_INT(req->userdata); r = sd_netlink_message_get_errno(m); if (r == -ENETDOWN && up && link_up_dsa_slave(link) > 0) @@ -1012,45 +975,25 @@ static int link_up_or_down_handler_internal(sd_netlink *rtnl, sd_netlink_message log_link_message_warning_errno(link, m, r, error_msg); if (on_activate) - goto on_error; + return 0; } r = link_call_getlink(link, get_link_update_flag_handler); if (r < 0) { link_enter_failed(link); - goto on_error; + return 0; } + link->set_flags_messages++; + if (on_activate) { link->activated = true; link_check_ready(link); } - return 1; - -on_error: - assert(link->set_flags_messages > 0); - link->set_flags_messages--; - return 0; } -static int link_activate_up_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - return link_up_or_down_handler_internal(rtnl, m, link, /* up = */ true, /* on_activate = */ true); -} - -static int link_activate_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - return link_up_or_down_handler_internal(rtnl, m, link, /* up = */ false, /* on_activate = */ true); -} - -static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - return link_up_or_down_handler_internal(rtnl, m, link, /* up = */ true, /* on_activate = */ false); -} - -static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - return link_up_or_down_handler_internal(rtnl, m, link, /* up = */ false, /* on_activate = */ false); -} - static const char *up_or_down(bool up) { return up ? "up" : "down"; } @@ -1074,14 +1017,7 @@ static int link_up_or_down(Link *link, bool up, Request *req) { if (r < 0) return r; - r = netlink_call_async(link->manager->rtnl, NULL, m, req->netlink_handler, - link_netlink_destroy_callback, link); - if (r < 0) - return r; - - link_ref(link); - - return 0; + return request_call_netlink_async(link->manager->rtnl, m, req); } static bool link_is_ready_to_activate(Link *link) { @@ -1146,7 +1082,7 @@ int link_request_to_activate(Link *link) { link->activated = false; r = link_queue_request(link, REQUEST_TYPE_ACTIVATE_LINK, NULL, false, &link->set_flags_messages, - up ? link_activate_up_handler : link_activate_down_handler, &req); + link_up_or_down_handler, &req); if (r < 0) return log_link_error_errno(link, r, "Failed to request to activate link: %m"); @@ -1210,7 +1146,7 @@ int link_request_to_bring_up_or_down(Link *link, bool up) { assert(link); r = link_queue_request(link, REQUEST_TYPE_UP_DOWN, NULL, false, &link->set_flags_messages, - up ? link_up_handler : link_down_handler, &req); + link_up_or_down_handler, &req); if (r < 0) return log_link_warning_errno(link, r, "Failed to request to bring link %s: %m", up_or_down(up)); diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c index fa3b0925b9..6ec6ed0aff 100644 --- a/src/network/tc/qdisc.c +++ b/src/network/tc/qdisc.c @@ -293,15 +293,11 @@ int link_find_qdisc(Link *link, uint32_t handle, uint32_t parent, const char *ki return -ENOENT; } -static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, QDisc *qdisc) { int r; + assert(m); assert(link); - assert(link->tc_messages > 0); - link->tc_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) { @@ -347,12 +343,7 @@ static int qdisc_configure(QDisc *qdisc, Link *link, Request *req) { return r; } - r = netlink_call_async(link->manager->rtnl, NULL, m, req->netlink_handler, link_netlink_destroy_callback, link); - if (r < 0) - return r; - - link_ref(link); - return 0; + return request_call_netlink_async(link->manager->rtnl, m, req); } static bool qdisc_is_ready_to_configure(QDisc *qdisc, Link *link) { @@ -410,7 +401,9 @@ int link_request_qdisc(Link *link, QDisc *qdisc) { log_qdisc_debug(existing, link, "Requesting"); r = link_queue_request(link, REQUEST_TYPE_TC_QDISC, existing, false, - &link->tc_messages, qdisc_handler, NULL); + &link->tc_messages, + (request_netlink_handler_t) qdisc_handler, + NULL); if (r < 0) return log_link_warning_errno(link, r, "Failed to request QDisc: %m"); if (r == 0) diff --git a/src/network/tc/tclass.c b/src/network/tc/tclass.c index b5b3615d98..42011a93e8 100644 --- a/src/network/tc/tclass.c +++ b/src/network/tc/tclass.c @@ -255,15 +255,11 @@ static void log_tclass_debug(TClass *tclass, Link *link, const char *str) { strna(tclass_get_tca_kind(tclass))); } -static int tclass_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { +static int tclass_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, TClass *tclass) { int r; + assert(m); assert(link); - assert(link->tc_messages > 0); - link->tc_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) { @@ -309,12 +305,7 @@ static int tclass_configure(TClass *tclass, Link *link, Request *req) { return r; } - r = netlink_call_async(link->manager->rtnl, NULL, m, req->netlink_handler, link_netlink_destroy_callback, link); - if (r < 0) - return r; - - link_ref(link); - return 0; + return request_call_netlink_async(link->manager->rtnl, m, req); } static bool tclass_is_ready_to_configure(TClass *tclass, Link *link) { @@ -369,7 +360,9 @@ int link_request_tclass(Link *link, TClass *tclass) { log_tclass_debug(existing, link, "Requesting"); r = link_queue_request(link, REQUEST_TYPE_TC_CLASS, existing, false, - &link->tc_messages, tclass_handler, NULL); + &link->tc_messages, + (request_netlink_handler_t) tclass_handler, + NULL); if (r < 0) return log_link_warning_errno(link, r, "Failed to request TClass: %m"); if (r == 0)