]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: re-design request queue 22631/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 28 Feb 2022 01:55:51 +0000 (10:55 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 11 Mar 2022 05:20:31 +0000 (14:20 +0900)
This makes Request object takes hash, compare, free, and process functions.

With this change, the logic in networkd-queue.c can be mostly
independent of the type of the request or the object (e.g. Address) assigned
to the request, and it becomes simpler.

38 files changed:
src/network/netdev/netdev.c
src/network/netdev/netdev.h
src/network/networkd-address-label.c
src/network/networkd-address-label.h
src/network/networkd-address.c
src/network/networkd-address.h
src/network/networkd-bridge-fdb.c
src/network/networkd-bridge-fdb.h
src/network/networkd-bridge-mdb.c
src/network/networkd-bridge-mdb.h
src/network/networkd-dhcp-server.c
src/network/networkd-dhcp-server.h
src/network/networkd-dhcp4.c
src/network/networkd-dhcp4.h
src/network/networkd-dhcp6.c
src/network/networkd-dhcp6.h
src/network/networkd-ipv6-proxy-ndp.c
src/network/networkd-ipv6-proxy-ndp.h
src/network/networkd-ndisc.c
src/network/networkd-ndisc.h
src/network/networkd-neighbor.c
src/network/networkd-neighbor.h
src/network/networkd-nexthop.c
src/network/networkd-nexthop.h
src/network/networkd-queue.c
src/network/networkd-queue.h
src/network/networkd-radv.c
src/network/networkd-radv.h
src/network/networkd-route.c
src/network/networkd-route.h
src/network/networkd-routing-policy-rule.c
src/network/networkd-routing-policy-rule.h
src/network/networkd-setlink.c
src/network/networkd-setlink.h
src/network/tc/qdisc.c
src/network/tc/qdisc.h
src/network/tc/tclass.c
src/network/tc/tclass.h

index ee3b883b5cafd4755deaa60f8e209f6d48e285df..187b24c5582044d234d208baee88b33836222615 100644 (file)
@@ -629,7 +629,7 @@ static int netdev_is_ready_to_create(NetDev *netdev, Link *link) {
         return true;
 }
 
-int stacked_netdev_process_request(Request *req, Link *link, void *userdata) {
+static int stacked_netdev_process_request(Request *req, Link *link, void *userdata) {
         NetDev *netdev = ASSERT_PTR(userdata);
         int r;
 
@@ -682,10 +682,12 @@ int link_request_stacked_netdev(Link *link, NetDev *netdev) {
                 return 0; /* Already created. */
 
         link->stacked_netdevs_created = false;
-        r = link_queue_request(link, REQUEST_TYPE_NETDEV_STACKED, netdev_ref(netdev), true,
-                               &link->create_stacked_netdev_messages,
-                               create_stacked_netdev_handler,
-                               NULL);
+        r = link_queue_request_full(link, REQUEST_TYPE_NETDEV_STACKED,
+                                    netdev_ref(netdev), (mfree_func_t) netdev_unref,
+                                    trivial_hash_func, trivial_compare_func,
+                                    stacked_netdev_process_request,
+                                    &link->create_stacked_netdev_messages,
+                                    create_stacked_netdev_handler, NULL);
         if (r < 0)
                 return log_link_error_errno(link, r, "Failed to request stacked netdev '%s': %m",
                                             netdev->ifname);
@@ -694,7 +696,7 @@ int link_request_stacked_netdev(Link *link, NetDev *netdev) {
         return 0;
 }
 
-int independent_netdev_process_request(Request *req, Link *link, void *userdata) {
+static int independent_netdev_process_request(Request *req, Link *link, void *userdata) {
         NetDev *netdev = ASSERT_PTR(userdata);
         int r;
 
@@ -730,9 +732,9 @@ static int netdev_request_to_create(NetDev *netdev) {
 
         } else {
                 /* Otherwise, wait for the dependencies being resolved. */
-                r = netdev_queue_request(netdev, NULL);
+                r = netdev_queue_request(netdev, independent_netdev_process_request, NULL);
                 if (r < 0)
-                        return log_netdev_warning_errno(netdev, r, "Failed to request to create: %m");
+                        return log_netdev_warning_errno(netdev, r, "Failed to request to create netdev: %m");
         }
 
         return 0;
index 4c2e949fb28f5f4fa4ef6e615c1478782d581eaf..6054e322d65d8ff27cac4834e516dfeba04e7507 100644 (file)
@@ -109,7 +109,6 @@ typedef enum NetDevCreateType {
 
 typedef struct Manager Manager;
 typedef struct Condition Condition;
-typedef struct Request Request;
 
 typedef struct NetDev {
         Manager *manager;
@@ -209,8 +208,6 @@ int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *newlink);
 int netdev_generate_hw_addr(NetDev *netdev, Link *link, const char *name,
                             const struct hw_addr_data *hw_addr, struct hw_addr_data *ret);
 
-int independent_netdev_process_request(Request *req, Link *link, void *userdata);
-int stacked_netdev_process_request(Request *req, Link *link, void *userdata);
 int link_request_stacked_netdev(Link *link, NetDev *netdev);
 
 const char *netdev_kind_to_string(NetDevKind d) _const_;
index 5c31a44ce4253e21e55ce2a4ac17aea6b9c289c1..745b959f7748cc592fffa694474f80b2d493dc04 100644 (file)
@@ -124,7 +124,7 @@ static int address_label_configure(AddressLabel *label, Link *link, Request *req
         return request_call_netlink_async(link->manager->rtnl, m, req);
 }
 
-int address_label_process_request(Request *req, Link *link, void *userdata) {
+static int address_label_process_request(Request *req, Link *link, void *userdata) {
         AddressLabel *label = ASSERT_PTR(userdata);
         int r;
 
@@ -151,8 +151,11 @@ int link_request_static_address_labels(Link *link) {
         link->static_address_labels_configured = false;
 
         HASHMAP_FOREACH(label, link->network->address_labels_by_section) {
-                r = link_queue_request(link, REQUEST_TYPE_ADDRESS_LABEL, label, false,
-                                       &link->static_address_label_messages, address_label_configure_handler, NULL);
+                r = link_queue_request_full(link, REQUEST_TYPE_ADDRESS_LABEL,
+                                            label, NULL, trivial_hash_func, trivial_compare_func,
+                                            address_label_process_request,
+                                            &link->static_address_label_messages,
+                                            address_label_configure_handler, NULL);
                 if (r < 0)
                         return log_link_warning_errno(link, r, "Failed to request address label: %m");
         }
index 19bb0383e6512355c3493b26f8aec45df43a8c5a..1e2ee70deeb23c377b32b5828b28e43b90da27b5 100644 (file)
@@ -9,7 +9,6 @@
 
 typedef struct Link Link;
 typedef struct Network Network;
-typedef struct Request Request;
 
 typedef struct AddressLabel {
         Network *network;
@@ -26,7 +25,6 @@ AddressLabel *address_label_free(AddressLabel *label);
 void network_drop_invalid_address_labels(Network *network);
 
 int link_request_static_address_labels(Link *link);
-int address_label_process_request(Request *req, Link *link, void *userdata);
 
 CONFIG_PARSER_PROTOTYPE(config_parse_address_label);
 CONFIG_PARSER_PROTOTYPE(config_parse_address_label_prefix);
index e9a79d352d1ef978cbc4210bb512559f3ed9d4dd..19a357130b5935a9b687d67024888536d3128eb1 100644 (file)
@@ -316,7 +316,7 @@ DEFINE_PRIVATE_HASH_OPS(
         address_kernel_hash_func,
         address_kernel_compare_func);
 
-void address_hash_func(const Address *a, struct siphash *state) {
+static void address_hash_func(const Address *a, struct siphash *state) {
         assert(a);
 
         siphash24_compress(&a->family, sizeof(a->family), state);
@@ -1104,7 +1104,7 @@ static bool address_is_ready_to_configure(Link *link, const Address *address) {
         return true;
 }
 
-int address_process_request(Request *req, Link *link, Address *address) {
+static int address_process_request(Request *req, Link *link, Address *address) {
         int r;
 
         assert(req);
@@ -1196,8 +1196,12 @@ int link_request_address(
                 return r;
 
         log_address_debug(existing, "Requesting", link);
-        r = link_queue_request(link, REQUEST_TYPE_ADDRESS, existing, false,
-                               message_counter, (request_netlink_handler_t) netlink_handler, ret);
+        r = link_queue_request_safe(link, REQUEST_TYPE_ADDRESS,
+                                    existing, NULL,
+                                    address_hash_func,
+                                    address_compare_func,
+                                    address_process_request,
+                                    message_counter, netlink_handler, ret);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to request address: %m");
         if (r == 0)
@@ -1281,7 +1285,9 @@ void address_cancel_request(Address *address) {
         req = (Request) {
                 .link = address->link,
                 .type = REQUEST_TYPE_ADDRESS,
-                .address = address,
+                .userdata = address,
+                .hash_func = (hash_func_t) address_hash_func,
+                .compare_func = (compare_func_t) address_compare_func,
         };
 
         request_detach(address->link->manager, &req);
index a41274a1fc3598395da442a6f18e3bf6f5b28744..563a3de4e27baae633dc0af2ff9360b1a58b91f9 100644 (file)
@@ -107,13 +107,11 @@ int link_request_address(
                 Request **ret);
 int link_request_static_address(Link *link, Address *address, bool consume);
 int link_request_static_addresses(Link *link);
-int address_process_request(Request *req, Link *link, Address *address);
 
 int manager_rtnl_process_address(sd_netlink *nl, sd_netlink_message *message, Manager *m);
 
 int network_drop_invalid_addresses(Network *network);
 
-void address_hash_func(const Address *a, struct siphash *state);
 int address_compare_func(const Address *a1, const Address *a2);
 
 DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(Address, address);
index cc02213c28a6ca6d70f2e9367af9f1717c29e622..803e27cdae1aea1534c60b51601bd9cb708873d5 100644 (file)
@@ -208,7 +208,7 @@ static bool bridge_fdb_is_ready_to_configure(BridgeFDB *fdb, Link *link) {
         return true;
 }
 
-int bridge_fdb_process_request(Request *req, Link *link, void *userdata) {
+static int bridge_fdb_process_request(Request *req, Link *link, void *userdata) {
         BridgeFDB *fdb = ASSERT_PTR(userdata);
         int r;
 
@@ -235,8 +235,14 @@ int link_request_static_bridge_fdb(Link *link) {
         link->static_bridge_fdb_configured = false;
 
         HASHMAP_FOREACH(fdb, link->network->bridge_fdb_entries_by_section) {
-                r = link_queue_request(link, REQUEST_TYPE_BRIDGE_FDB, fdb, false,
-                                       &link->static_bridge_fdb_messages, bridge_fdb_configure_handler, NULL);
+                r = link_queue_request_full(link, REQUEST_TYPE_BRIDGE_FDB,
+                                            fdb, NULL,
+                                            trivial_hash_func,
+                                            trivial_compare_func,
+                                            bridge_fdb_process_request,
+                                            &link->static_bridge_fdb_messages,
+                                            bridge_fdb_configure_handler,
+                                            NULL);
                 if (r < 0)
                         return log_link_error_errno(link, r, "Failed to request static bridge FDB entry: %m");
         }
index 6a6e80384ec2b8ab82166fc28aadd04b3363cefd..b59d673d048f09d3b9749b518773e8f4aca4aba8 100644 (file)
@@ -14,7 +14,6 @@
 
 typedef struct Link Link;
 typedef struct Network Network;
-typedef struct Request Request;
 
 typedef enum NeighborCacheEntryFlags {
         NEIGHBOR_CACHE_ENTRY_FLAGS_USE = NTF_USE,
@@ -47,8 +46,6 @@ void network_drop_invalid_bridge_fdb_entries(Network *network);
 
 int link_request_static_bridge_fdb(Link *link);
 
-int bridge_fdb_process_request(Request *req, Link *link, void *userdata);
-
 CONFIG_PARSER_PROTOTYPE(config_parse_fdb_hwaddr);
 CONFIG_PARSER_PROTOTYPE(config_parse_fdb_vlan_id);
 CONFIG_PARSER_PROTOTYPE(config_parse_fdb_destination);
index 88ae091c1a598a79b5678012360b58b7f144cb3e..3af4afe4a1d2826f3ce6d1cd0b4ede46157dd864 100644 (file)
@@ -194,7 +194,7 @@ static bool bridge_mdb_is_ready_to_configure(Link *link) {
         return true;
 }
 
-int bridge_mdb_process_request(Request *req, Link *link, void *userdata) {
+static int bridge_mdb_process_request(Request *req, Link *link, void *userdata) {
         BridgeMDB *mdb = ASSERT_PTR(userdata);
         int r;
 
@@ -227,8 +227,14 @@ int link_request_static_bridge_mdb(Link *link) {
                 goto finish;
 
         HASHMAP_FOREACH(mdb, link->network->bridge_mdb_entries_by_section) {
-                r = link_queue_request(link, REQUEST_TYPE_BRIDGE_MDB, mdb, false,
-                                       &link->static_bridge_mdb_messages, bridge_mdb_configure_handler, NULL);
+                r = link_queue_request_full(link, REQUEST_TYPE_BRIDGE_MDB,
+                                            mdb, NULL,
+                                            trivial_hash_func,
+                                            trivial_compare_func,
+                                            bridge_mdb_process_request,
+                                            &link->static_bridge_mdb_messages,
+                                            bridge_mdb_configure_handler,
+                                            NULL);
                 if (r < 0)
                         return log_link_error_errno(link, r, "Failed to request MDB entry to multicast group database: %m");
         }
index c9a34af88addd054d13a69da3ff2e01e9a5410cf..edea255769de8b7dbcf7d8cfefd5eb54d36d69e8 100644 (file)
@@ -9,7 +9,6 @@
 
 typedef struct Link Link;
 typedef struct Network Network;
-typedef struct Request Request;
 
 typedef struct BridgeMDB {
         Network *network;
@@ -25,7 +24,6 @@ BridgeMDB *bridge_mdb_free(BridgeMDB *mdb);
 void network_drop_invalid_bridge_mdb_entries(Network *network);
 
 int link_request_static_bridge_mdb(Link *link);
-int bridge_mdb_process_request(Request *req, Link *link, void *userdata);
 
 CONFIG_PARSER_PROTOTYPE(config_parse_mdb_group_address);
 CONFIG_PARSER_PROTOTYPE(config_parse_mdb_vlan_id);
index b11ff073bcfe9120eed7d7773f9aaa8fb0f056b7..3d24cbaf3ced846bffb3fac795582d2e149cc993 100644 (file)
@@ -567,7 +567,7 @@ static bool dhcp_server_is_ready_to_configure(Link *link) {
         return true;
 }
 
-int dhcp_server_process_request(Request *req, Link *link, void *userdata) {
+static int dhcp_server_process_request(Request *req, Link *link, void *userdata) {
         int r;
 
         assert(link);
@@ -594,7 +594,7 @@ int link_request_dhcp_server(Link *link) {
                 return 0;
 
         log_link_debug(link, "Requesting DHCP server.");
-        r = link_queue_request(link, REQUEST_TYPE_DHCP_SERVER, NULL, false, NULL, NULL, NULL);
+        r = link_queue_request(link, REQUEST_TYPE_DHCP_SERVER, dhcp_server_process_request, NULL);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to request configuration of DHCP server: %m");
 
index 7a204e7d0a0d59355618b1ee5bd8944e6b9fa9e6..cb2a8b6a34b537fc1918fff97036e53ba9e8f866 100644 (file)
@@ -5,13 +5,11 @@
 
 typedef struct Link Link;
 typedef struct Network Network;
-typedef struct Request Request;
 
 void network_adjust_dhcp_server(Network *network);
 
 int link_request_dhcp_server_address(Link *link);
 int link_request_dhcp_server(Link *link);
-int dhcp_server_process_request(Request *req, Link *link, void *userdata);
 
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_relay_agent_suboption);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_emit);
index dcde7f9bedb41d0959e2393ac3952104e815096f..2fcb9c853f33615b34f80722673bac5aad1d7b91 100644 (file)
@@ -1589,7 +1589,7 @@ static int dhcp4_configure_duid(Link *link) {
         return dhcp_configure_duid(link, link_get_dhcp4_duid(link));
 }
 
-int dhcp4_process_request(Request *req, Link *link, void *userdata) {
+static int dhcp4_process_request(Request *req, Link *link, void *userdata) {
         int r;
 
         assert(link);
@@ -1630,7 +1630,7 @@ int link_request_dhcp4_client(Link *link) {
         if (link->dhcp_client)
                 return 0;
 
-        r = link_queue_request(link, REQUEST_TYPE_DHCP4_CLIENT, NULL, false, NULL, NULL, NULL);
+        r = link_queue_request(link, REQUEST_TYPE_DHCP4_CLIENT, dhcp4_process_request, NULL);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to request configuring of the DHCPv4 client: %m");
 
index 4e466ca4f9618f66f8811edd4dabb9731d4a008a..1d30cd15dfba04ba9c65eb6f9c4d494c6eae55fe 100644 (file)
@@ -5,7 +5,6 @@
 
 typedef struct Link Link;
 typedef struct Network Network;
-typedef struct Request Request;
 
 typedef enum DHCPClientIdentifier {
         DHCP_CLIENT_ID_MAC,
@@ -25,7 +24,6 @@ int dhcp4_start(Link *link);
 int dhcp4_lease_lost(Link *link);
 int dhcp4_check_ready(Link *link);
 
-int dhcp4_process_request(Request *req, Link *link, void *userdata);
 int link_request_dhcp4_client(Link *link);
 
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier);
index bceae735b090ec25228907d48275738ec2f8ff41..c443098889c35bb75cca96c5d7220d762a5efadb 100644 (file)
@@ -712,7 +712,7 @@ int dhcp6_update_mac(Link *link) {
         return 0;
 }
 
-int dhcp6_process_request(Request *req, Link *link, void *userdata) {
+static int dhcp6_process_request(Request *req, Link *link, void *userdata) {
         int r;
 
         assert(link);
@@ -757,7 +757,7 @@ int link_request_dhcp6_client(Link *link) {
         if (link->dhcp6_client)
                 return 0;
 
-        r = link_queue_request(link, REQUEST_TYPE_DHCP6_CLIENT, NULL, false, NULL, NULL, NULL);
+        r = link_queue_request(link, REQUEST_TYPE_DHCP6_CLIENT, dhcp6_process_request, NULL);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to request configuring of the DHCPv6 client: %m");
 
index e3bc57cc30030b8ffef66cd4bc880035e448e003..81267c255f6ad3b482e992d8c00441b3f8a38d19 100644 (file)
@@ -13,7 +13,6 @@ typedef enum DHCP6ClientStartMode {
 } DHCP6ClientStartMode;
 
 typedef struct Link Link;
-typedef struct Request Request;
 
 bool link_dhcp6_with_address_enabled(Link *link);
 int dhcp6_check_ready(Link *link);
@@ -21,7 +20,6 @@ int dhcp6_update_mac(Link *link);
 int dhcp6_start(Link *link);
 int dhcp6_start_on_ra(Link *link, bool information_request);
 
-int dhcp6_process_request(Request *req, Link *link, void *userdata);
 int link_request_dhcp6_client(Link *link);
 
 int link_serialize_dhcp6_client(Link *link, FILE *f);
index b245a9eba2678aac617450df3929c4c895549b8a..8166851ed3c20f0d48a1f6540f883df6569cd6bb 100644 (file)
@@ -78,7 +78,7 @@ static int ipv6_proxy_ndp_address_configure(const struct in6_addr *address, Link
         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) {
+static int ipv6_proxy_ndp_address_process_request(Request *req, Link *link, struct in6_addr *address) {
         int r;
 
         assert(req);
@@ -105,10 +105,14 @@ int link_request_static_ipv6_proxy_ndp_addresses(Link *link) {
         link->static_ipv6_proxy_ndp_configured = false;
 
         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,
-                                       (request_netlink_handler_t) ipv6_proxy_ndp_address_configure_handler,
-                                       NULL);
+                r = link_queue_request_safe(link, REQUEST_TYPE_IPV6_PROXY_NDP,
+                                            address, NULL,
+                                            in6_addr_hash_func,
+                                            in6_addr_compare_func,
+                                            ipv6_proxy_ndp_address_process_request,
+                                            &link->static_ipv6_proxy_ndp_messages,
+                                            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");
         }
index 39a782059991de836006f3427775b50d71b021cd..e57d28f99ddf87cd182a6b6454baa5d9aa0c7b29 100644 (file)
@@ -5,11 +5,9 @@
 
 typedef struct Link Link;
 typedef struct Network Network;
-typedef struct Request Request;
 
 void network_adjust_ipv6_proxy_ndp(Network *network);
 
 int link_request_static_ipv6_proxy_ndp_addresses(Link *link);
-int ipv6_proxy_ndp_address_process_request(Request *req, Link *link, struct in6_addr *address);
 
 CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_proxy_ndp_address);
index 2a85fb3cfb1f57d69de4caaf647bd65e9cd71453..8cbc67f5429ba593716b3fc2a12ec19737eefa79 100644 (file)
@@ -1116,7 +1116,7 @@ int ndisc_start(Link *link) {
         return 1;
 }
 
-int ndisc_process_request(Request *req, Link *link, void *userdata) {
+static int ndisc_process_request(Request *req, Link *link, void *userdata) {
         int r;
 
         assert(link);
@@ -1152,7 +1152,7 @@ int link_request_ndisc(Link *link) {
         if (link->ndisc)
                 return 0;
 
-        r = link_queue_request(link, REQUEST_TYPE_NDISC, NULL, false, NULL, NULL, NULL);
+        r = link_queue_request(link, REQUEST_TYPE_NDISC, ndisc_process_request, NULL);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to request configuring of the IPv6 Router Discovery: %m");
 
index 5a7eb58a562c0c3d4af34378d50200e36c81ff98..f88a002c73e333bb48a95aa8be7498de81205a77 100644 (file)
@@ -6,7 +6,6 @@
 
 typedef struct Link Link;
 typedef struct Network Network;
-typedef struct Request Request;
 
 typedef enum IPv6AcceptRAStartDHCP6Client {
         IPV6_ACCEPT_RA_START_DHCP6_CLIENT_NO,
@@ -48,7 +47,6 @@ int ndisc_start(Link *link);
 void ndisc_vacuum(Link *link);
 void ndisc_flush(Link *link);
 
-int ndisc_process_request(Request *req, Link *link, void *userdata);
 int link_request_ndisc(Link *link);
 
 CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_accept_ra_start_dhcp6_client);
index 1cb5333b66187f46448dd9b735d3c0357a83a980..435fa7002e2c965974e89e62b07d5e46192fa74f 100644 (file)
@@ -87,7 +87,7 @@ static int neighbor_dup(const Neighbor *neighbor, Neighbor **ret) {
         return 0;
 }
 
-void neighbor_hash_func(const Neighbor *neighbor, struct siphash *state) {
+static void neighbor_hash_func(const Neighbor *neighbor, struct siphash *state) {
         assert(neighbor);
 
         siphash24_compress(&neighbor->family, sizeof(neighbor->family), state);
@@ -106,7 +106,7 @@ void neighbor_hash_func(const Neighbor *neighbor, struct siphash *state) {
         hw_addr_hash_func(&neighbor->ll_addr, state);
 }
 
-int neighbor_compare_func(const Neighbor *a, const Neighbor *b) {
+static int neighbor_compare_func(const Neighbor *a, const Neighbor *b) {
         int r;
 
         r = CMP(a->family, b->family);
@@ -218,7 +218,7 @@ static int neighbor_configure(Neighbor *neighbor, Link *link, Request *req) {
         return request_call_netlink_async(link->manager->rtnl, m, req);
 }
 
-int neighbor_process_request(Request *req, Link *link, Neighbor *neighbor) {
+static int neighbor_process_request(Request *req, Link *link, Neighbor *neighbor) {
         int r;
 
         assert(req);
@@ -282,10 +282,14 @@ static int link_request_neighbor(Link *link, const Neighbor *neighbor) {
                 existing->source = neighbor->source;
 
         log_neighbor_debug(existing, "Requesting", link);
-        r = link_queue_request(link, REQUEST_TYPE_NEIGHBOR, existing, false,
-                               &link->static_neighbor_messages,
-                               (request_netlink_handler_t) static_neighbor_configure_handler,
-                               NULL);
+        r = link_queue_request_safe(link, REQUEST_TYPE_NEIGHBOR,
+                                    existing, NULL,
+                                    neighbor_hash_func,
+                                    neighbor_compare_func,
+                                    neighbor_process_request,
+                                    &link->static_neighbor_messages,
+                                    static_neighbor_configure_handler,
+                                    NULL);
         if (r <= 0)
                 return r;
 
index 52a7733a893d61de08a62add49541fda34284fc7..758475a8ff6617fd4d2faf3fb4bf1e329197ef05 100644 (file)
@@ -13,7 +13,6 @@
 typedef struct Link Link;
 typedef struct Manager Manager;
 typedef struct Network Network;
-typedef struct Request Request;
 
 typedef struct Neighbor {
         Network *network;
@@ -29,9 +28,6 @@ typedef struct Neighbor {
 
 Neighbor *neighbor_free(Neighbor *neighbor);
 
-void neighbor_hash_func(const Neighbor *neighbor, struct siphash *state);
-int neighbor_compare_func(const Neighbor *a, const Neighbor *b);
-
 void network_drop_invalid_neighbors(Network *network);
 
 int link_drop_managed_neighbors(Link *link);
@@ -39,7 +35,6 @@ int link_drop_foreign_neighbors(Link *link);
 void link_foreignize_neighbors(Link *link);
 
 int link_request_static_neighbors(Link *link);
-int neighbor_process_request(Request *req, Link *link, Neighbor *neighbor);
 
 int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
 
index 219a08e1597eee10d3dc64c516d82ec61b947b15..3eb9d62f7c778ea83835d7d604624f0dfc84822b 100644 (file)
@@ -104,7 +104,7 @@ static int nexthop_new_static(Network *network, const char *filename, unsigned s
         return 0;
 }
 
-void nexthop_hash_func(const NextHop *nexthop, struct siphash *state) {
+static void nexthop_hash_func(const NextHop *nexthop, struct siphash *state) {
         assert(nexthop);
 
         siphash24_compress(&nexthop->protocol, sizeof(nexthop->protocol), state);
@@ -124,7 +124,7 @@ void nexthop_hash_func(const NextHop *nexthop, struct siphash *state) {
         }
 }
 
-int nexthop_compare_func(const NextHop *a, const NextHop *b) {
+static int nexthop_compare_func(const NextHop *a, const NextHop *b) {
         int r;
 
         r = CMP(a->protocol, b->protocol);
@@ -546,7 +546,7 @@ static bool nexthop_is_ready_to_configure(Link *link, const NextHop *nexthop) {
                 ORDERED_SET_FOREACH(req, link->manager->request_queue) {
                         if (req->type != REQUEST_TYPE_NEXTHOP)
                                 continue;
-                        if (req->nexthop->id != 0)
+                        if (((NextHop*) req->userdata)->id != 0)
                                 return false; /* first configure nexthop with id. */
                 }
         }
@@ -554,7 +554,7 @@ static bool nexthop_is_ready_to_configure(Link *link, const NextHop *nexthop) {
         return gateway_is_ready(link, FLAGS_SET(nexthop->flags, RTNH_F_ONLINK), nexthop->family, &nexthop->gw);
 }
 
-int nexthop_process_request(Request *req, Link *link, NextHop *nexthop) {
+static int nexthop_process_request(Request *req, Link *link, NextHop *nexthop) {
         int r;
 
         assert(req);
@@ -600,10 +600,14 @@ static int link_request_nexthop(Link *link, NextHop *nexthop) {
                 existing->source = nexthop->source;
 
         log_nexthop_debug(existing, "Requesting", link);
-        r = link_queue_request(link, REQUEST_TYPE_NEXTHOP, existing, false,
-                               &link->static_nexthop_messages,
-                               (request_netlink_handler_t) static_nexthop_handler,
-                               NULL);
+        r = link_queue_request_safe(link, REQUEST_TYPE_NEXTHOP,
+                                    existing, NULL,
+                                    nexthop_hash_func,
+                                    nexthop_compare_func,
+                                    nexthop_process_request,
+                                    &link->static_nexthop_messages,
+                                    static_nexthop_handler,
+                                    NULL);
         if (r <= 0)
                 return r;
 
index c5b58e5d38a9122275ae11688ad75a662e907a03..6f2aa6f6dc3f44a8e7b44f478d623649ebbba601 100644 (file)
@@ -16,7 +16,6 @@
 typedef struct Link Link;
 typedef struct Manager Manager;
 typedef struct Network Network;
-typedef struct Request Request;
 
 typedef struct NextHop {
         Network *network;
@@ -39,9 +38,6 @@ typedef struct NextHop {
 
 NextHop *nexthop_free(NextHop *nexthop);
 
-void nexthop_hash_func(const NextHop *nexthop, struct siphash *state);
-int nexthop_compare_func(const NextHop *a, const NextHop *b);
-
 void network_drop_invalid_nexthops(Network *network);
 
 int link_drop_managed_nexthops(Link *link);
@@ -49,7 +45,6 @@ int link_drop_foreign_nexthops(Link *link);
 void link_foreignize_nexthops(Link *link);
 
 int link_request_static_nexthops(Link *link, bool only_ipv4);
-int nexthop_process_request(Request *req, Link *link, NextHop *nexthop);
 
 int manager_get_nexthop_by_id(Manager *manager, uint32_t id, NextHop **ret);
 int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
index ecfb7acdd2da4f26f05f5692eeee9f699fc25e7f..1463f610b256cf4fd56f1fcf0abcac030febb05f 100644 (file)
@@ -1,93 +1,11 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#include "netdev.h"
 #include "netlink-util.h"
-#include "networkd-address.h"
-#include "networkd-address-label.h"
-#include "networkd-bridge-fdb.h"
-#include "networkd-bridge-mdb.h"
-#include "networkd-dhcp-server.h"
-#include "networkd-dhcp4.h"
-#include "networkd-dhcp6.h"
-#include "networkd-ipv6-proxy-ndp.h"
+#include "networkd-link.h"
 #include "networkd-manager.h"
-#include "networkd-ndisc.h"
-#include "networkd-neighbor.h"
-#include "networkd-nexthop.h"
-#include "networkd-route.h"
-#include "networkd-routing-policy-rule.h"
 #include "networkd-queue.h"
-#include "networkd-setlink.h"
-#include "qdisc.h"
 #include "string-table.h"
-#include "tclass.h"
-
-static void request_free_object(RequestType type, void *object) {
-        switch (type) {
-        case REQUEST_TYPE_ACTIVATE_LINK:
-                break;
-        case REQUEST_TYPE_ADDRESS:
-                address_free(object);
-                break;
-        case REQUEST_TYPE_ADDRESS_LABEL:
-                address_label_free(object);
-                break;
-        case REQUEST_TYPE_BRIDGE_FDB:
-                bridge_fdb_free(object);
-                break;
-        case REQUEST_TYPE_BRIDGE_MDB:
-                bridge_mdb_free(object);
-                break;
-        case REQUEST_TYPE_DHCP_SERVER:
-        case REQUEST_TYPE_DHCP4_CLIENT:
-        case REQUEST_TYPE_DHCP6_CLIENT:
-                break;
-        case REQUEST_TYPE_IPV6_PROXY_NDP:
-                free(object);
-                break;
-        case REQUEST_TYPE_NDISC:
-                break;
-        case REQUEST_TYPE_NEIGHBOR:
-                neighbor_free(object);
-                break;
-        case REQUEST_TYPE_NETDEV_INDEPENDENT:
-        case REQUEST_TYPE_NETDEV_STACKED:
-                netdev_unref(object);
-                break;
-        case REQUEST_TYPE_NEXTHOP:
-                nexthop_free(object);
-                break;
-        case REQUEST_TYPE_RADV:
-                break;
-        case REQUEST_TYPE_ROUTE:
-                route_free(object);
-                break;
-        case REQUEST_TYPE_ROUTING_POLICY_RULE:
-                routing_policy_rule_free(object);
-                break;
-        case REQUEST_TYPE_SET_LINK_ADDRESS_GENERATION_MODE:
-        case REQUEST_TYPE_SET_LINK_BOND:
-        case REQUEST_TYPE_SET_LINK_BRIDGE:
-        case REQUEST_TYPE_SET_LINK_BRIDGE_VLAN:
-        case REQUEST_TYPE_SET_LINK_CAN:
-        case REQUEST_TYPE_SET_LINK_FLAGS:
-        case REQUEST_TYPE_SET_LINK_GROUP:
-        case REQUEST_TYPE_SET_LINK_IPOIB:
-        case REQUEST_TYPE_SET_LINK_MAC:
-        case REQUEST_TYPE_SET_LINK_MASTER:
-        case REQUEST_TYPE_SET_LINK_MTU:
-                break;
-        case REQUEST_TYPE_TC_QDISC:
-                qdisc_free(object);
-                break;
-        case REQUEST_TYPE_TC_CLASS:
-                tclass_free(object);
-                break;
-        case REQUEST_TYPE_UP_DOWN:
-                break;
-        default:
-                assert_not_reached();
-        }
-}
 
 static Request *request_free(Request *req) {
         if (!req)
@@ -98,8 +16,8 @@ static Request *request_free(Request *req) {
         if (req->manager)
                 ordered_set_remove(req->manager->request_queue, req);
 
-        if (req->consume_object)
-                request_free_object(req->type, req->object);
+        if (req->free_func)
+                req->free_func(req->userdata);
 
         if (req->counter)
                 (*req->counter)--;
@@ -136,70 +54,11 @@ static void request_hash_func(const Request *req, struct siphash *state) {
 
         siphash24_compress(&req->type, sizeof(req->type), state);
 
-        switch (req->type) {
-        case REQUEST_TYPE_ACTIVATE_LINK:
-                break;
-        case REQUEST_TYPE_ADDRESS:
-                address_hash_func(req->address, state);
-                break;
-        case REQUEST_TYPE_ADDRESS_LABEL:
-        case REQUEST_TYPE_BRIDGE_FDB:
-        case REQUEST_TYPE_BRIDGE_MDB:
-        case REQUEST_TYPE_NETDEV_INDEPENDENT:
-        case REQUEST_TYPE_NETDEV_STACKED:
-                /* TODO: Currently, these types do not have any specific hash and compare functions.
-                 * Fortunately, all these objects are 'static', thus we can use the trivial functions. */
-                trivial_hash_func(req->object, state);
-                break;
-        case REQUEST_TYPE_DHCP_SERVER:
-        case REQUEST_TYPE_DHCP4_CLIENT:
-        case REQUEST_TYPE_DHCP6_CLIENT:
-                /* These types do not have an object. */
-                break;
-        case REQUEST_TYPE_IPV6_PROXY_NDP:
-                in6_addr_hash_func(req->ipv6_proxy_ndp, state);
-                break;
-        case REQUEST_TYPE_NDISC:
-                /* This type does not have an object. */
-                break;
-        case REQUEST_TYPE_NEIGHBOR:
-                neighbor_hash_func(req->neighbor, state);
-                break;
-        case REQUEST_TYPE_NEXTHOP:
-                nexthop_hash_func(req->nexthop, state);
-                break;
-        case REQUEST_TYPE_RADV:
-                /* This type does not have an object. */
-                break;
-        case REQUEST_TYPE_ROUTE:
-                route_hash_func(req->route, state);
-                break;
-        case REQUEST_TYPE_ROUTING_POLICY_RULE:
-                routing_policy_rule_hash_func(req->rule, state);
-                break;
-        case REQUEST_TYPE_SET_LINK_ADDRESS_GENERATION_MODE:
-        case REQUEST_TYPE_SET_LINK_BOND:
-        case REQUEST_TYPE_SET_LINK_BRIDGE:
-        case REQUEST_TYPE_SET_LINK_BRIDGE_VLAN:
-        case REQUEST_TYPE_SET_LINK_CAN:
-        case REQUEST_TYPE_SET_LINK_FLAGS:
-        case REQUEST_TYPE_SET_LINK_GROUP:
-        case REQUEST_TYPE_SET_LINK_IPOIB:
-        case REQUEST_TYPE_SET_LINK_MAC:
-        case REQUEST_TYPE_SET_LINK_MASTER:
-        case REQUEST_TYPE_SET_LINK_MTU:
-                break;
-        case REQUEST_TYPE_TC_QDISC:
-                qdisc_hash_func(req->qdisc, state);
-                break;
-        case REQUEST_TYPE_TC_CLASS:
-                tclass_hash_func(req->tclass, state);
-                break;
-        case REQUEST_TYPE_UP_DOWN:
-                break;
-        default:
-                assert_not_reached();
-        }
+        siphash24_compress(&req->hash_func, sizeof(req->hash_func), state);
+        siphash24_compress(&req->compare_func, sizeof(req->compare_func), state);
+
+        if (req->hash_func)
+                req->hash_func(req->userdata, state);
 }
 
 static int request_compare_func(const struct Request *a, const struct Request *b) {
@@ -222,56 +81,18 @@ static int request_compare_func(const struct Request *a, const struct Request *b
         if (r != 0)
                 return r;
 
-        switch (a->type) {
-        case REQUEST_TYPE_ACTIVATE_LINK:
-                return 0;
-        case REQUEST_TYPE_ADDRESS:
-                return address_compare_func(a->address, b->address);
-        case REQUEST_TYPE_ADDRESS_LABEL:
-        case REQUEST_TYPE_BRIDGE_FDB:
-        case REQUEST_TYPE_BRIDGE_MDB:
-        case REQUEST_TYPE_NETDEV_INDEPENDENT:
-        case REQUEST_TYPE_NETDEV_STACKED:
-                return trivial_compare_func(a->object, b->object);
-        case REQUEST_TYPE_DHCP_SERVER:
-        case REQUEST_TYPE_DHCP4_CLIENT:
-        case REQUEST_TYPE_DHCP6_CLIENT:
-                return 0;
-        case REQUEST_TYPE_IPV6_PROXY_NDP:
-                return in6_addr_compare_func(a->ipv6_proxy_ndp, b->ipv6_proxy_ndp);
-        case REQUEST_TYPE_NDISC:
-                return 0;
-        case REQUEST_TYPE_NEIGHBOR:
-                return neighbor_compare_func(a->neighbor, b->neighbor);
-        case REQUEST_TYPE_NEXTHOP:
-                return nexthop_compare_func(a->nexthop, b->nexthop);
-        case REQUEST_TYPE_ROUTE:
-                return route_compare_func(a->route, b->route);
-        case REQUEST_TYPE_RADV:
-                return 0;
-        case REQUEST_TYPE_ROUTING_POLICY_RULE:
-                return routing_policy_rule_compare_func(a->rule, b->rule);
-        case REQUEST_TYPE_SET_LINK_ADDRESS_GENERATION_MODE:
-        case REQUEST_TYPE_SET_LINK_BOND:
-        case REQUEST_TYPE_SET_LINK_BRIDGE:
-        case REQUEST_TYPE_SET_LINK_BRIDGE_VLAN:
-        case REQUEST_TYPE_SET_LINK_CAN:
-        case REQUEST_TYPE_SET_LINK_FLAGS:
-        case REQUEST_TYPE_SET_LINK_GROUP:
-        case REQUEST_TYPE_SET_LINK_IPOIB:
-        case REQUEST_TYPE_SET_LINK_MAC:
-        case REQUEST_TYPE_SET_LINK_MASTER:
-        case REQUEST_TYPE_SET_LINK_MTU:
-                return 0;
-        case REQUEST_TYPE_TC_QDISC:
-                return qdisc_compare_func(a->qdisc, b->qdisc);
-        case REQUEST_TYPE_TC_CLASS:
-                return tclass_compare_func(a->tclass, b->tclass);
-        case REQUEST_TYPE_UP_DOWN:
-                return 0;
-        default:
-                assert_not_reached();
-        }
+        r = CMP(PTR_TO_UINT64(a->hash_func), PTR_TO_UINT64(b->hash_func));
+        if (r != 0)
+                return r;
+
+        r = CMP(PTR_TO_UINT64(a->compare_func), PTR_TO_UINT64(b->compare_func));
+        if (r != 0)
+                return r;
+
+        if (a->compare_func)
+                return a->compare_func(a->userdata, b->userdata);
+
+        return 0;
 }
 
 DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
@@ -281,54 +102,15 @@ DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
                 request_compare_func,
                 request_unref);
 
-int netdev_queue_request(
-                NetDev *netdev,
-                Request **ret) {
-
-        _cleanup_(request_unrefp) Request *req = NULL;
-        Request *existing;
-        int r;
-
-        assert(netdev);
-        assert(netdev->manager);
-
-        req = new(Request, 1);
-        if (!req)
-                return -ENOMEM;
-
-        *req = (Request) {
-                .n_ref = 1,
-                .manager = netdev->manager,
-                .netdev = netdev_ref(netdev),
-                .type = REQUEST_TYPE_NETDEV_INDEPENDENT,
-                .consume_object = true,
-        };
-
-        existing = ordered_set_get(netdev->manager->request_queue, req);
-        if (existing) {
-                if (ret)
-                        *ret = existing;
-                return 0;
-        }
-
-        r = ordered_set_ensure_put(&netdev->manager->request_queue, &request_hash_ops, req);
-        if (r < 0)
-                return r;
-
-        req->manager = netdev->manager;
-
-        if (ret)
-                *ret = req;
-
-        TAKE_PTR(req);
-        return 1;
-}
-
-int link_queue_request(
+static int request_new(
+                Manager *manager,
                 Link *link,
                 RequestType type,
-                void *object,
-                bool consume_object,
+                void *userdata,
+                mfree_func_t free_func,
+                hash_func_t hash_func,
+                compare_func_t compare_func,
+                request_process_func_t process,
                 unsigned *counter,
                 request_netlink_handler_t netlink_handler,
                 Request **ret) {
@@ -337,65 +119,40 @@ int link_queue_request(
         Request *existing;
         int r;
 
-        assert(link);
-        assert(link->manager);
-        assert(type >= 0 && type < _REQUEST_TYPE_MAX);
-        assert(IN_SET(type,
-                      REQUEST_TYPE_ACTIVATE_LINK,
-                      REQUEST_TYPE_DHCP_SERVER,
-                      REQUEST_TYPE_DHCP4_CLIENT,
-                      REQUEST_TYPE_DHCP6_CLIENT,
-                      REQUEST_TYPE_NDISC,
-                      REQUEST_TYPE_RADV,
-                      REQUEST_TYPE_SET_LINK_ADDRESS_GENERATION_MODE,
-                      REQUEST_TYPE_SET_LINK_BOND,
-                      REQUEST_TYPE_SET_LINK_BRIDGE,
-                      REQUEST_TYPE_SET_LINK_BRIDGE_VLAN,
-                      REQUEST_TYPE_SET_LINK_CAN,
-                      REQUEST_TYPE_SET_LINK_FLAGS,
-                      REQUEST_TYPE_SET_LINK_GROUP,
-                      REQUEST_TYPE_SET_LINK_IPOIB,
-                      REQUEST_TYPE_SET_LINK_MAC,
-                      REQUEST_TYPE_SET_LINK_MASTER,
-                      REQUEST_TYPE_SET_LINK_MTU,
-                      REQUEST_TYPE_UP_DOWN) ||
-               object);
-        assert(IN_SET(type,
-                      REQUEST_TYPE_DHCP_SERVER,
-                      REQUEST_TYPE_DHCP4_CLIENT,
-                      REQUEST_TYPE_DHCP6_CLIENT,
-                      REQUEST_TYPE_NDISC,
-                      REQUEST_TYPE_RADV) ||
-               netlink_handler);
+        assert(manager);
+        assert(process);
 
         req = new(Request, 1);
         if (!req) {
-                if (consume_object)
-                        request_free_object(type, object);
+                if (free_func)
+                        free_func(userdata);
                 return -ENOMEM;
         }
 
         *req = (Request) {
                 .n_ref = 1,
-                .link = link_ref(link),
+                .link = link_ref(link), /* link may be NULL, but link_ref() handles it gracefully. */
                 .type = type,
-                .object = object,
-                .consume_object = consume_object,
+                .userdata = userdata,
+                .free_func = free_func,
+                .hash_func = hash_func,
+                .compare_func = compare_func,
+                .process = process,
                 .netlink_handler = netlink_handler,
         };
 
-        existing = ordered_set_get(link->manager->request_queue, req);
+        existing = ordered_set_get(manager->request_queue, req);
         if (existing) {
                 if (ret)
                         *ret = existing;
                 return 0;
         }
 
-        r = ordered_set_ensure_put(&link->manager->request_queue, &request_hash_ops, req);
+        r = ordered_set_ensure_put(&manager->request_queue, &request_hash_ops, req);
         if (r < 0)
                 return r;
 
-        req->manager = link->manager;
+        req->manager = manager;
         req->counter = counter;
         if (req->counter)
                 (*req->counter)++;
@@ -407,12 +164,42 @@ int link_queue_request(
         return 1;
 }
 
+int netdev_queue_request(
+                NetDev *netdev,
+                request_process_func_t process,
+                Request **ret) {
+
+        assert(netdev);
+
+        return request_new(netdev->manager, NULL, REQUEST_TYPE_NETDEV_INDEPENDENT,
+                           netdev_ref(netdev), (mfree_func_t) netdev_unref,
+                           trivial_hash_func, trivial_compare_func,
+                           process, NULL, NULL, ret);
+}
+
+int link_queue_request_full(
+                Link *link,
+                RequestType type,
+                void *userdata,
+                mfree_func_t free_func,
+                hash_func_t hash_func,
+                compare_func_t compare_func,
+                request_process_func_t process,
+                unsigned *counter,
+                request_netlink_handler_t netlink_handler,
+                Request **ret) {
+
+        assert(link);
+
+        return request_new(link->manager, link, type,
+                           userdata, free_func, hash_func, compare_func,
+                           process, counter, netlink_handler, ret);
+}
+
 int manager_process_requests(sd_event_source *s, void *userdata) {
-        Manager *manager = userdata;
+        Manager *manager = ASSERT_PTR(userdata);
         int r;
 
-        assert(manager);
-
         for (;;) {
                 bool processed = false;
                 Request *req;
@@ -421,83 +208,9 @@ int manager_process_requests(sd_event_source *s, void *userdata) {
                         _unused_ _cleanup_(request_unrefp) Request *ref = request_ref(req);
                         _cleanup_(link_unrefp) Link *link = link_ref(req->link);
 
-                        switch (req->type) {
-                        case REQUEST_TYPE_ACTIVATE_LINK:
-                                r = link_process_activation(req, req->link, req->userdata);
-                                break;
-                        case REQUEST_TYPE_ADDRESS:
-                                r = address_process_request(req, req->link, req->address);
-                                break;
-                        case REQUEST_TYPE_ADDRESS_LABEL:
-                                r = address_label_process_request(req, req->link, req->label);
-                                break;
-                        case REQUEST_TYPE_BRIDGE_FDB:
-                                r = bridge_fdb_process_request(req, req->link, req->fdb);
-                                break;
-                        case REQUEST_TYPE_BRIDGE_MDB:
-                                r = bridge_mdb_process_request(req, req->link, req->mdb);
-                                break;
-                        case REQUEST_TYPE_DHCP_SERVER:
-                                r = dhcp_server_process_request(req, req->link, NULL);
-                                break;
-                        case REQUEST_TYPE_DHCP4_CLIENT:
-                                r = dhcp4_process_request(req, req->link, NULL);
-                                break;
-                        case REQUEST_TYPE_DHCP6_CLIENT:
-                                r = dhcp6_process_request(req, req->link, NULL);
-                                break;
-                        case REQUEST_TYPE_IPV6_PROXY_NDP:
-                                r = ipv6_proxy_ndp_address_process_request(req, req->link, req->ipv6_proxy_ndp);
-                                break;
-                        case REQUEST_TYPE_NDISC:
-                                r = ndisc_process_request(req, req->link, NULL);
-                                break;
-                        case REQUEST_TYPE_NEIGHBOR:
-                                r = neighbor_process_request(req, req->link, req->neighbor);
-                                break;
-                        case REQUEST_TYPE_NETDEV_INDEPENDENT:
-                                r = independent_netdev_process_request(req, req->link, req->netdev);
-                                break;
-                        case REQUEST_TYPE_NETDEV_STACKED:
-                                r = stacked_netdev_process_request(req, req->link, req->netdev);
-                                break;
-                        case REQUEST_TYPE_NEXTHOP:
-                                r = nexthop_process_request(req, req->link, req->nexthop);
-                                break;
-                        case REQUEST_TYPE_RADV:
-                                r = radv_process_request(req, req->link, NULL);
-                                break;
-                        case REQUEST_TYPE_ROUTE:
-                                r = route_process_request(req, req->link, req->route);
-                                break;
-                        case REQUEST_TYPE_ROUTING_POLICY_RULE:
-                                r = routing_policy_rule_process_request(req, req->link, req->rule);
-                                break;
-                        case REQUEST_TYPE_SET_LINK_ADDRESS_GENERATION_MODE:
-                        case REQUEST_TYPE_SET_LINK_BOND:
-                        case REQUEST_TYPE_SET_LINK_BRIDGE:
-                        case REQUEST_TYPE_SET_LINK_BRIDGE_VLAN:
-                        case REQUEST_TYPE_SET_LINK_CAN:
-                        case REQUEST_TYPE_SET_LINK_FLAGS:
-                        case REQUEST_TYPE_SET_LINK_GROUP:
-                        case REQUEST_TYPE_SET_LINK_IPOIB:
-                        case REQUEST_TYPE_SET_LINK_MAC:
-                        case REQUEST_TYPE_SET_LINK_MASTER:
-                        case REQUEST_TYPE_SET_LINK_MTU:
-                                r = link_process_set_link(req, req->link, NULL);
-                                break;
-                        case REQUEST_TYPE_TC_QDISC:
-                                r = qdisc_process_request(req, req->link, NULL);
-                                break;
-                        case REQUEST_TYPE_TC_CLASS:
-                                r = tclass_process_request(req, req->link, NULL);
-                                break;
-                        case REQUEST_TYPE_UP_DOWN:
-                                r = link_process_up_or_down(req, req->link, req->userdata);
-                                break;
-                        default:
-                                return -EINVAL;
-                        }
+                        assert(req->process);
+
+                        r = req->process(req, link, req->userdata);
                         if (r == 0)
                                 continue;
 
@@ -533,7 +246,7 @@ static int request_netlink_handler(sd_netlink *nl, sd_netlink_message *m, Reques
                 return 0;
 
         if (req->netlink_handler)
-                return req->netlink_handler(nl, m, req, req->link, req->object);
+                return req->netlink_handler(nl, m, req, req->link, req->userdata);
 
         return 0;
 }
index 0c822094e86d46cea036aded3cd7f2f38e4a7caf..d1110119ccc46306a9490450c113557a529c114b 100644 (file)
@@ -4,21 +4,15 @@
 #include "sd-event.h"
 #include "sd-netlink.h"
 
-#include "networkd-link.h"
+#include "alloc-util.h"
+#include "hash-funcs.h"
 
-typedef struct Address Address;
-typedef struct AddressLabel AddressLabel;
-typedef struct BridgeFDB BridgeFDB;
-typedef struct BridgeMDB BridgeMDB;
-typedef struct Neighbor Neighbor;
+typedef struct Link Link;
 typedef struct NetDev NetDev;
-typedef struct NextHop NextHop;
-typedef struct Route Route;
-typedef struct RoutingPolicyRule RoutingPolicyRule;
-typedef struct QDisc QDisc;
-typedef struct TClass TClass;
+typedef struct Manager Manager;
 typedef struct Request Request;
 
+typedef int (*request_process_func_t)(Request *req, Link *link, void *userdata);
 typedef int (*request_netlink_handler_t)(sd_netlink *nl, sd_netlink_message *m, Request *req, Link *link, void *userdata);
 
 typedef enum RequestType {
@@ -64,24 +58,19 @@ struct Request {
         Link *link; /* can be NULL */
 
         RequestType type;
-        bool consume_object;
-        union {
-                Address *address;
-                AddressLabel *label;
-                BridgeFDB *fdb;
-                BridgeMDB *mdb;
-                struct in6_addr *ipv6_proxy_ndp;
-                Neighbor *neighbor;
-                NextHop *nexthop;
-                Route *route;
-                RoutingPolicyRule *rule;
-                void *set_link_operation_ptr;
-                NetDev *netdev;
-                QDisc *qdisc;
-                TClass *tclass;
-                void *object;
-        };
+
+        /* Target object, e.g. Address, Route, NetDev, and so on. */
         void *userdata;
+        /* freeing userdata when the request is completed or failed. */
+        mfree_func_t free_func;
+
+        /* hash and compare functions for userdata, used for dedup requests. */
+        hash_func_t hash_func;
+        compare_func_t compare_func;
+
+        /* Checks the request dependencies, and then processes this request, e.g. call address_configure().
+         * Return 1 when processed, 0 when its dependencies not resolved, and negative errno on failure. */
+        request_process_func_t process;
 
         /* incremented when requested, decremented when request is completed or failed. */
         unsigned *counter;
@@ -100,17 +89,49 @@ void request_detach(Manager *manager, Request *req);
 
 int netdev_queue_request(
                 NetDev *netdev,
+                request_process_func_t process,
                 Request **ret);
 
-int link_queue_request(
+int link_queue_request_full(
                 Link *link,
                 RequestType type,
-                void *object,
-                bool consume_object,
+                void *userdata,
+                mfree_func_t free_func,
+                hash_func_t hash_func,
+                compare_func_t compare_func,
+                request_process_func_t process,
                 unsigned *counter,
                 request_netlink_handler_t netlink_handler,
                 Request **ret);
 
+static inline int link_queue_request(
+                Link *link,
+                RequestType type,
+                request_process_func_t process,
+                Request **ret) {
+
+        return link_queue_request_full(link, type, NULL, NULL, NULL, NULL,
+                                       process, NULL, NULL, ret);
+}
+
+#define link_queue_request_safe(link, type, userdata, free_func, hash_func, compare_func, process, counter, netlink_handler, ret) \
+        ({                                                              \
+                typeof(userdata) (*_f)(typeof(userdata)) = (free_func); \
+                void (*_h)(const typeof(*userdata)*, struct siphash*) = (hash_func); \
+                int (*_c)(const typeof(*userdata)*, const typeof(*userdata)*) = (compare_func); \
+                int (*_p)(Request*, Link*, typeof(userdata)) = (process); \
+                int (*_n)(sd_netlink*, sd_netlink_message*, Request*, Link*, typeof(userdata)) = (netlink_handler); \
+                                                                        \
+                link_queue_request_full(link, type, userdata,           \
+                                        (mfree_func_t) _f,              \
+                                        (hash_func_t) _h,               \
+                                        (compare_func_t) _c,            \
+                                        (request_process_func_t) _p,    \
+                                        counter,                        \
+                                        (request_netlink_handler_t) _n, \
+                                        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);
 
index f6e1841c058a15bf5ef6d0e4a58ecb49d48fcc1b..b9f5c55f4c5eb890d528495961c8f2a7b6cdb5c7 100644 (file)
@@ -582,7 +582,7 @@ static int radv_is_ready_to_configure(Link *link) {
         return true;
 }
 
-int radv_process_request(Request *req, Link *link, void *userdata) {
+static int radv_process_request(Request *req, Link *link, void *userdata) {
         int r;
 
         assert(link);
@@ -617,7 +617,7 @@ int link_request_radv(Link *link) {
         if (link->radv)
                 return 0;
 
-        r = link_queue_request(link, REQUEST_TYPE_RADV, NULL, false, NULL, NULL, NULL);
+        r = link_queue_request(link, REQUEST_TYPE_RADV, radv_process_request, NULL);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to request configuring of the IPv6 Router Advertisement engine: %m");
 
index 0d340c955ed47a678c2e7f981760e9b3f5ba839b..ebebb3942b81d9ec9c83f64008ba69b7c6e612b1 100644 (file)
@@ -16,7 +16,6 @@
 
 typedef struct Link Link;
 typedef struct Network Network;
-typedef struct Request Request;
 
 typedef enum RADVPrefixDelegation {
         RADV_PREFIX_DELEGATION_NONE   = 0,
@@ -68,7 +67,6 @@ int radv_update_mac(Link *link);
 int radv_add_prefix(Link *link, const struct in6_addr *prefix, uint8_t prefix_len,
                     usec_t lifetime_preferred_usec, usec_t lifetime_valid_usec);
 
-int radv_process_request(Request *req, Link *link, void *userdata);
 int link_request_radv(Link *link);
 
 const char* radv_prefix_delegation_to_string(RADVPrefixDelegation i) _const_;
index cfc69679632bb5f1a3a68b2fec4e89a12da690c9..c9fb872ae57e2fd0f3fbcd6d52e6dce90e199dd7 100644 (file)
@@ -110,7 +110,7 @@ Route *route_free(Route *route) {
         return mfree(route);
 }
 
-void route_hash_func(const Route *route, struct siphash *state) {
+static void route_hash_func(const Route *route, struct siphash *state) {
         assert(route);
 
         siphash24_compress(&route->family, sizeof(route->family), state);
@@ -152,7 +152,7 @@ void route_hash_func(const Route *route, struct siphash *state) {
         }
 }
 
-int route_compare_func(const Route *a, const Route *b) {
+static int route_compare_func(const Route *a, const Route *b) {
         int r;
 
         r = CMP(a->family, b->family);
@@ -1310,7 +1310,7 @@ static int route_is_ready_to_configure(const Route *route, Link *link) {
         return true;
 }
 
-int route_process_request(Request *req, Link *link, Route *route) {
+static int route_process_request(Request *req, Link *link, Route *route) {
         _cleanup_(converted_routes_freep) ConvertedRoutes *converted = NULL;
         int r;
 
@@ -1423,8 +1423,12 @@ int link_request_route(
         }
 
         log_route_debug(existing, "Requesting", link, link->manager);
-        r = link_queue_request(link, REQUEST_TYPE_ROUTE, existing, false,
-                               message_counter, (request_netlink_handler_t) netlink_handler, ret);
+        r = link_queue_request_safe(link, REQUEST_TYPE_ROUTE,
+                                    existing, NULL,
+                                    route_hash_func,
+                                    route_compare_func,
+                                    route_process_request,
+                                    message_counter, netlink_handler, ret);
         if (r <= 0)
                 return r;
 
@@ -1460,10 +1464,10 @@ static int link_request_static_route(Link *link, Route *route) {
                                           static_route_handler, NULL);
 
         log_route_debug(route, "Requesting", link, link->manager);
-        return link_queue_request(link, REQUEST_TYPE_ROUTE, route, false,
-                                  &link->static_route_messages,
-                                  (request_netlink_handler_t) static_route_handler,
-                                  NULL);
+        return link_queue_request_safe(link, REQUEST_TYPE_ROUTE,
+                                       route, NULL, route_hash_func, route_compare_func,
+                                       route_process_request,
+                                       &link->static_route_messages, static_route_handler, NULL);
 }
 
 static int link_request_wireguard_routes(Link *link, bool only_ipv4) {
@@ -1547,7 +1551,9 @@ void route_cancel_request(Route *route, Link *link) {
         req = (Request) {
                 .link = link,
                 .type = REQUEST_TYPE_ROUTE,
-                .route = route,
+                .userdata = route,
+                .hash_func = (hash_func_t) route_hash_func,
+                .compare_func = (compare_func_t) route_compare_func,
         };
 
         request_detach(link->manager, &req);
index 8c1c5cf6809d37a157a244b58368353e9f46da55..b431e1a30f4c60f1eb33e5154c1e0cd399683b68 100644 (file)
@@ -75,8 +75,6 @@ struct Route {
         sd_event_source *expire;
 };
 
-void route_hash_func(const Route *route, struct siphash *state);
-int route_compare_func(const Route *a, const Route *b);
 extern const struct hash_ops route_hash_ops;
 
 int route_new(Route **ret);
@@ -102,7 +100,6 @@ int link_request_route(
                 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);
 
 int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
 
index 535af175a32a0da3a358f6798a6dfcc6e3d331e9..8f4297a86add8e23961c27c511dc3ecd628f2c9e 100644 (file)
@@ -153,7 +153,7 @@ static int routing_policy_rule_dup(const RoutingPolicyRule *src, RoutingPolicyRu
         return 0;
 }
 
-void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct siphash *state) {
+static void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct siphash *state) {
         assert(rule);
 
         siphash24_compress(&rule->family, sizeof(rule->family), state);
@@ -194,7 +194,7 @@ void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct siphash
         }
 }
 
-int routing_policy_rule_compare_func(const RoutingPolicyRule *a, const RoutingPolicyRule *b) {
+static int routing_policy_rule_compare_func(const RoutingPolicyRule *a, const RoutingPolicyRule *b) {
         int r;
 
         r = CMP(a->family, b->family);
@@ -718,7 +718,7 @@ void link_foreignize_routing_policy_rules(Link *link) {
         }
 }
 
-int routing_policy_rule_process_request(Request *req, Link *link, RoutingPolicyRule *rule) {
+static int routing_policy_rule_process_request(Request *req, Link *link, RoutingPolicyRule *rule) {
         int r;
 
         assert(req);
@@ -793,10 +793,14 @@ static int link_request_routing_policy_rule(Link *link, RoutingPolicyRule *rule)
                 existing->source = rule->source;
 
         log_routing_policy_rule_debug(existing, "Requesting", link, link->manager);
-        r = link_queue_request(link, REQUEST_TYPE_ROUTING_POLICY_RULE, existing, false,
-                               &link->static_routing_policy_rule_messages,
-                               (request_netlink_handler_t) static_routing_policy_rule_configure_handler,
-                               NULL);
+        r = link_queue_request_safe(link, REQUEST_TYPE_ROUTING_POLICY_RULE,
+                                    existing, NULL,
+                                    routing_policy_rule_hash_func,
+                                    routing_policy_rule_compare_func,
+                                    routing_policy_rule_process_request,
+                                    &link->static_routing_policy_rule_messages,
+                                    static_routing_policy_rule_configure_handler,
+                                    NULL);
         if (r <= 0)
                 return r;
 
index 2d60e595655e4a3eceab0c1e80326c6f83385acc..b6ce2fa19c42ecffce97de0f74cf1ff51a873d9b 100644 (file)
@@ -12,7 +12,6 @@
 typedef struct Link Link;
 typedef struct Manager Manager;
 typedef struct Network Network;
-typedef struct Request Request;
 
 typedef struct RoutingPolicyRule {
         Manager *manager;
@@ -58,13 +57,9 @@ const char *fr_act_type_full_to_string(int t) _const_;
 
 RoutingPolicyRule *routing_policy_rule_free(RoutingPolicyRule *rule);
 
-void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct siphash *state);
-int routing_policy_rule_compare_func(const RoutingPolicyRule *a, const RoutingPolicyRule *b);
-
 void network_drop_invalid_routing_policy_rules(Network *network);
 
 int link_request_static_routing_policy_rules(Link *link);
-int routing_policy_rule_process_request(Request *req, Link *link, RoutingPolicyRule *rule);
 
 int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
 int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const Link *except);
index 5128c33719b8b38911083b13f4af03e6cdd1518c..148277685e0355e693e4e0477ef244fe58b1c2de 100644 (file)
@@ -420,7 +420,6 @@ static int link_configure(Link *link, Request *req) {
 
         assert(link);
         assert(link->manager);
-        assert(link->manager->rtnl);
         assert(req);
 
         log_link_debug(link, "Setting %s", request_type_to_string(req->type));
@@ -560,7 +559,7 @@ static int link_is_ready_to_set_link(Link *link, Request *req) {
         return true;
 }
 
-int link_process_set_link(Request *req, Link *link, void *userdata) {
+static int link_process_set_link(Request *req, Link *link, void *userdata) {
         int r;
 
         assert(req);
@@ -587,10 +586,12 @@ static int link_request_set_link(
         int r;
 
         assert(link);
-        assert(netlink_handler);
 
-        r = link_queue_request(link, type, NULL, false,
-                               &link->set_link_messages, netlink_handler, &req);
+        r = link_queue_request_full(link, type, NULL, NULL, NULL, NULL,
+                                    link_process_set_link,
+                                    &link->set_link_messages,
+                                    netlink_handler,
+                                    &req);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to request to set %s: %m",
                                               request_type_to_string(type));
@@ -1016,7 +1017,7 @@ static bool link_is_ready_to_activate(Link *link) {
         return true;
 }
 
-int link_process_activation(Request *req, Link *link, void *userdata) {
+static int link_process_activation(Request *req, Link *link, void *userdata) {
         bool up = PTR_TO_INT(userdata);
         int r;
 
@@ -1034,7 +1035,6 @@ int link_process_activation(Request *req, Link *link, void *userdata) {
 }
 
 int link_request_to_activate(Link *link) {
-        Request *req;
         bool up;
         int r;
 
@@ -1065,13 +1065,14 @@ 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,
-                               link_up_or_down_handler, &req);
+        r = link_queue_request_full(link, REQUEST_TYPE_ACTIVATE_LINK,
+                                    INT_TO_PTR(up), NULL, NULL, NULL,
+                                    link_process_activation,
+                                    &link->set_flags_messages,
+                                    link_up_or_down_handler, NULL);
         if (r < 0)
                 return log_link_error_errno(link, r, "Failed to request to activate link: %m");
 
-        req->userdata = INT_TO_PTR(up);
-
         log_link_debug(link, "Requested to activate link");
         return 0;
 }
@@ -1106,7 +1107,7 @@ static bool link_is_ready_to_bring_up_or_down(Link *link, bool up) {
         return true;
 }
 
-int link_process_up_or_down(Request *req, Link *link, void *userdata) {
+static int link_process_up_or_down(Request *req, Link *link, void *userdata) {
         bool up = PTR_TO_INT(userdata);
         int r;
 
@@ -1124,19 +1125,19 @@ int link_process_up_or_down(Request *req, Link *link, void *userdata) {
 }
 
 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, &link->set_flags_messages,
-                               link_up_or_down_handler, &req);
+        r = link_queue_request_full(link, REQUEST_TYPE_UP_DOWN,
+                                    INT_TO_PTR(up), NULL, NULL, NULL,
+                                    link_process_up_or_down,
+                                    &link->set_flags_messages,
+                                    link_up_or_down_handler, NULL);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to request to bring link %s: %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 5dce0c7b5f47d5e13885b81d806db1a6597b7f53..7e5ba32ef1c4846a60594cd566071d14fa2de884 100644 (file)
@@ -5,7 +5,6 @@
 #include <stdbool.h>
 
 typedef struct Link Link;
-typedef struct Request Request;
 
 int link_request_to_set_addrgen_mode(Link *link);
 int link_request_to_set_bond(Link *link);
@@ -21,12 +20,8 @@ int link_request_to_set_mtu(Link *link, uint32_t mtu);
 
 int link_configure_mtu(Link *link);
 
-int link_process_set_link(Request *req, Link *link, void *userdata);
-
-int link_process_activation(Request *req, Link *link, void *userdata);
 int link_request_to_activate(Link *link);
 
-int link_process_up_or_down(Request *req, Link *link, void *userdata);
 int link_request_to_bring_up_or_down(Link *link, bool up);
 
 int link_down_now(Link *link);
index 6ec6ed0aff74ab794c40b29bcb44bbd72ab9914d..6aef268d1f98dd7390ed92311b88a2c124fa5880 100644 (file)
@@ -151,7 +151,7 @@ static const char *qdisc_get_tca_kind(const QDisc *qdisc) {
                 QDISC_VTABLE(qdisc)->tca_kind : qdisc->tca_kind;
 }
 
-void qdisc_hash_func(const QDisc *qdisc, struct siphash *state) {
+static void qdisc_hash_func(const QDisc *qdisc, struct siphash *state) {
         assert(qdisc);
         assert(state);
 
@@ -160,7 +160,7 @@ void qdisc_hash_func(const QDisc *qdisc, struct siphash *state) {
         siphash24_compress_string(qdisc_get_tca_kind(qdisc), state);
 }
 
-int qdisc_compare_func(const QDisc *a, const QDisc *b) {
+static int qdisc_compare_func(const QDisc *a, const QDisc *b) {
         int r;
 
         assert(a);
@@ -359,7 +359,7 @@ static bool qdisc_is_ready_to_configure(QDisc *qdisc, Link *link) {
         return link_find_tclass(link, qdisc->parent, NULL) >= 0;
 }
 
-int qdisc_process_request(Request *req, Link *link, QDisc *qdisc) {
+static int qdisc_process_request(Request *req, Link *link, QDisc *qdisc) {
         int r;
 
         assert(req);
@@ -400,10 +400,14 @@ int link_request_qdisc(Link *link, QDisc *qdisc) {
                 existing->source = qdisc->source;
 
         log_qdisc_debug(existing, link, "Requesting");
-        r = link_queue_request(link, REQUEST_TYPE_TC_QDISC, existing, false,
-                               &link->tc_messages,
-                               (request_netlink_handler_t) qdisc_handler,
-                               NULL);
+        r = link_queue_request_safe(link, REQUEST_TYPE_TC_QDISC,
+                                    existing, NULL,
+                                    qdisc_hash_func,
+                                    qdisc_compare_func,
+                                    qdisc_process_request,
+                                    &link->tc_messages,
+                                    qdisc_handler,
+                                    NULL);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to request QDisc: %m");
         if (r == 0)
index 37ec61cbc7083eb3cd93b851af0a28c868da46e6..adaaf260c471a3161a60a91d22b47d35b6523421 100644 (file)
@@ -8,7 +8,6 @@
 typedef struct Link Link;
 typedef struct Manager Manager;
 typedef struct Network Network;
-typedef struct Request Request;
 
 typedef enum QDiscKind {
         QDISC_KIND_BFIFO,
@@ -77,12 +76,8 @@ DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(QDisc, qdisc);
 QDisc* qdisc_free(QDisc *qdisc);
 int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, unsigned section_line, QDisc **ret);
 
-void qdisc_hash_func(const QDisc *qdisc, struct siphash *state);
-int qdisc_compare_func(const QDisc *a, const QDisc *b);
-
 int link_find_qdisc(Link *link, uint32_t handle, uint32_t parent, const char *kind, QDisc **qdisc);
 
-int qdisc_process_request(Request *req, Link *link, QDisc *qdisc);
 int link_request_qdisc(Link *link, QDisc *qdisc);
 
 void network_drop_invalid_qdisc(Network *network);
index 42011a93e8fcfa28c8421be4b255a919b1f83601..d3b3c19bdf2b5c3b4567ef1f498da927f917c940 100644 (file)
@@ -121,7 +121,7 @@ static const char *tclass_get_tca_kind(const TClass *tclass) {
                 TCLASS_VTABLE(tclass)->tca_kind : tclass->tca_kind;
 }
 
-void tclass_hash_func(const TClass *tclass, struct siphash *state) {
+static void tclass_hash_func(const TClass *tclass, struct siphash *state) {
         assert(tclass);
         assert(state);
 
@@ -130,7 +130,7 @@ void tclass_hash_func(const TClass *tclass, struct siphash *state) {
         siphash24_compress_string(tclass_get_tca_kind(tclass), state);
 }
 
-int tclass_compare_func(const TClass *a, const TClass *b) {
+static int tclass_compare_func(const TClass *a, const TClass *b) {
         int r;
 
         assert(a);
@@ -318,7 +318,7 @@ static bool tclass_is_ready_to_configure(TClass *tclass, Link *link) {
         return link_find_qdisc(link, tclass->classid, tclass->parent, tclass_get_tca_kind(tclass), NULL) >= 0;
 }
 
-int tclass_process_request(Request *req, Link *link, TClass *tclass) {
+static int tclass_process_request(Request *req, Link *link, TClass *tclass) {
         int r;
 
         assert(req);
@@ -359,10 +359,14 @@ int link_request_tclass(Link *link, TClass *tclass) {
                 existing->source = tclass->source;
 
         log_tclass_debug(existing, link, "Requesting");
-        r = link_queue_request(link, REQUEST_TYPE_TC_CLASS, existing, false,
-                               &link->tc_messages,
-                               (request_netlink_handler_t) tclass_handler,
-                               NULL);
+        r = link_queue_request_safe(link, REQUEST_TYPE_TC_CLASS,
+                                    existing, NULL,
+                                    tclass_hash_func,
+                                    tclass_compare_func,
+                                    tclass_process_request,
+                                    &link->tc_messages,
+                                    tclass_handler,
+                                    NULL);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to request TClass: %m");
         if (r == 0)
index f7b724b002039cac578f03486919c8e90e042ac6..606bb3fef3345a0456a8717b200120d470c635df 100644 (file)
@@ -8,7 +8,6 @@
 typedef struct Link Link;
 typedef struct Manager Manager;
 typedef struct Network Network;
-typedef struct Request Request;
 
 typedef enum TClassKind {
         TCLASS_KIND_DRR,
@@ -59,12 +58,8 @@ DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(TClass, tclass);
 TClass* tclass_free(TClass *tclass);
 int tclass_new_static(TClassKind kind, Network *network, const char *filename, unsigned section_line, TClass **ret);
 
-void tclass_hash_func(const TClass *qdisc, struct siphash *state);
-int tclass_compare_func(const TClass *a, const TClass *b);
-
 int link_find_tclass(Link *link, uint32_t classid, TClass **ret);
 
-int tclass_process_request(Request *req, Link *link, TClass *tclass);
 int link_request_tclass(Link *link, TClass *tclass);
 
 void network_drop_invalid_tclass(Network *network);