summaryrefslogtreecommitdiffstats
path: root/src/network/networkd-queue.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/networkd-queue.h')
-rw-r--r--src/network/networkd-queue.h141
1 files changed, 141 insertions, 0 deletions
diff --git a/src/network/networkd-queue.h b/src/network/networkd-queue.h
new file mode 100644
index 0000000..e58d1be
--- /dev/null
+++ b/src/network/networkd-queue.h
@@ -0,0 +1,141 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "sd-event.h"
+#include "sd-netlink.h"
+
+#include "alloc-util.h"
+#include "hash-funcs.h"
+
+typedef struct Link Link;
+typedef struct NetDev NetDev;
+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 {
+ REQUEST_TYPE_ACTIVATE_LINK,
+ REQUEST_TYPE_ADDRESS,
+ REQUEST_TYPE_ADDRESS_LABEL,
+ REQUEST_TYPE_BRIDGE_FDB,
+ REQUEST_TYPE_BRIDGE_MDB,
+ REQUEST_TYPE_DHCP_SERVER,
+ REQUEST_TYPE_DHCP4_CLIENT,
+ REQUEST_TYPE_DHCP6_CLIENT,
+ REQUEST_TYPE_IPV6_PROXY_NDP,
+ REQUEST_TYPE_NDISC,
+ REQUEST_TYPE_NEIGHBOR,
+ REQUEST_TYPE_NETDEV_INDEPENDENT,
+ REQUEST_TYPE_NETDEV_STACKED,
+ REQUEST_TYPE_NEXTHOP,
+ REQUEST_TYPE_RADV,
+ REQUEST_TYPE_ROUTE,
+ REQUEST_TYPE_ROUTING_POLICY_RULE,
+ REQUEST_TYPE_SET_LINK_ADDRESS_GENERATION_MODE, /* Setting IPv6LL address generation mode. */
+ REQUEST_TYPE_SET_LINK_BOND, /* Setting bond configs. */
+ REQUEST_TYPE_SET_LINK_BRIDGE, /* Setting bridge configs. */
+ REQUEST_TYPE_SET_LINK_BRIDGE_VLAN, /* Setting bridge VLAN configs. */
+ REQUEST_TYPE_SET_LINK_CAN, /* Setting CAN interface configs. */
+ REQUEST_TYPE_SET_LINK_FLAGS, /* Setting IFF_NOARP or friends. */
+ REQUEST_TYPE_SET_LINK_GROUP, /* Setting interface group. */
+ REQUEST_TYPE_SET_LINK_IPOIB, /* Setting IPoIB configs. */
+ REQUEST_TYPE_SET_LINK_MAC, /* Setting MAC address. */
+ REQUEST_TYPE_SET_LINK_MASTER, /* Setting IFLA_MASTER. */
+ REQUEST_TYPE_SET_LINK_MTU, /* Setting MTU. */
+ REQUEST_TYPE_SRIOV,
+ REQUEST_TYPE_TC_CLASS,
+ REQUEST_TYPE_TC_QDISC,
+ REQUEST_TYPE_UP_DOWN,
+ _REQUEST_TYPE_MAX,
+ _REQUEST_TYPE_INVALID = -EINVAL,
+} RequestType;
+
+struct Request {
+ unsigned n_ref;
+
+ Manager *manager; /* must be non-NULL */
+ Link *link; /* can be NULL */
+
+ RequestType type;
+
+ /* 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;
+ /* 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;
+
+ bool waiting_reply;
+};
+
+Request *request_ref(Request *req);
+Request *request_unref(Request *req);
+DEFINE_TRIVIAL_CLEANUP_FUNC(Request*, request_unref);
+
+void request_detach(Manager *manager, Request *req);
+
+int netdev_queue_request(
+ NetDev *netdev,
+ request_process_func_t process,
+ Request **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);
+
+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);
+
+const char* request_type_to_string(RequestType t) _const_;