]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-netlink/netlink-internal.h
Revert "mkosi: Don't install wireguard-tools on Debian"
[thirdparty/systemd.git] / src / libsystemd / sd-netlink / netlink-internal.h
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
3
4 #include <linux/netlink.h>
5
6 #include "sd-netlink.h"
7
8 #include "list.h"
9 #include "netlink-types.h"
10 #include "ordered-set.h"
11 #include "prioq.h"
12 #include "time-util.h"
13
14 #define NETLINK_DEFAULT_TIMEOUT_USEC ((usec_t) (25 * USEC_PER_SEC))
15
16 #define NETLINK_RQUEUE_MAX 64*1024
17
18 #define NETLINK_CONTAINER_DEPTH 32
19
20 struct reply_callback {
21 sd_netlink_message_handler_t callback;
22 usec_t timeout;
23 uint32_t serial;
24 unsigned prioq_idx;
25 };
26
27 struct match_callback {
28 sd_netlink_message_handler_t callback;
29 uint32_t *groups;
30 size_t n_groups;
31 uint16_t type;
32 uint8_t cmd; /* used by genl */
33
34 LIST_FIELDS(struct match_callback, match_callbacks);
35 };
36
37 typedef enum NetlinkSlotType {
38 NETLINK_REPLY_CALLBACK,
39 NETLINK_MATCH_CALLBACK,
40 _NETLINK_SLOT_INVALID = -EINVAL,
41 } NetlinkSlotType;
42
43 struct sd_netlink_slot {
44 unsigned n_ref;
45 NetlinkSlotType type:8;
46 bool floating;
47 sd_netlink *netlink;
48 void *userdata;
49 sd_netlink_destroy_t destroy_callback;
50
51 char *description;
52
53 LIST_FIELDS(sd_netlink_slot, slots);
54
55 union {
56 struct reply_callback reply_callback;
57 struct match_callback match_callback;
58 };
59 };
60
61 struct sd_netlink {
62 unsigned n_ref;
63
64 int fd;
65
66 union {
67 struct sockaddr sa;
68 struct sockaddr_nl nl;
69 } sockaddr;
70
71 int protocol;
72
73 Hashmap *broadcast_group_refs;
74 bool broadcast_group_dont_leave:1; /* until we can rely on 4.2 */
75
76 OrderedSet *rqueue;
77 Hashmap *rqueue_by_serial;
78 Hashmap *rqueue_partial_by_serial;
79
80 struct nlmsghdr *rbuffer;
81
82 bool processing:1;
83
84 uint32_t serial;
85
86 struct Prioq *reply_callbacks_prioq;
87 Hashmap *reply_callbacks;
88
89 LIST_HEAD(struct match_callback, match_callbacks);
90
91 LIST_HEAD(sd_netlink_slot, slots);
92
93 pid_t original_pid;
94
95 sd_event_source *io_event_source;
96 sd_event_source *time_event_source;
97 sd_event_source *exit_event_source;
98 sd_event *event;
99
100 Hashmap *genl_family_by_name;
101 Hashmap *genl_family_by_id;
102 };
103
104 struct netlink_attribute {
105 size_t offset; /* offset from hdr to attribute */
106 bool nested:1;
107 bool net_byteorder:1;
108 };
109
110 struct netlink_container {
111 const struct NLAPolicySet *policy_set; /* the policy set of the container */
112 size_t offset; /* offset from hdr to the start of the container */
113 struct netlink_attribute *attributes;
114 uint16_t max_attribute; /* the maximum attribute in container */
115 };
116
117 struct sd_netlink_message {
118 unsigned n_ref;
119
120 int protocol;
121
122 struct nlmsghdr *hdr;
123 struct netlink_container containers[NETLINK_CONTAINER_DEPTH];
124 unsigned n_containers; /* number of containers */
125 uint32_t multicast_group;
126 bool sealed:1;
127
128 sd_netlink_message *next; /* next in a chain of multi-part messages */
129 };
130
131 int message_new_empty(sd_netlink *nl, sd_netlink_message **ret);
132 int message_new_full(
133 sd_netlink *nl,
134 uint16_t nlmsg_type,
135 const NLAPolicySet *policy_set,
136 size_t header_size,
137 sd_netlink_message **ret);
138 int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type);
139 int message_new_synthetic_error(sd_netlink *nl, int error, uint32_t serial, sd_netlink_message **ret);
140
141 static inline uint32_t message_get_serial(sd_netlink_message *m) {
142 assert(m);
143 return ASSERT_PTR(m->hdr)->nlmsg_seq;
144 }
145
146 void message_seal(sd_netlink_message *m);
147
148 int netlink_open_family(sd_netlink **ret, int family);
149 bool netlink_pid_changed(sd_netlink *nl);
150
151 int socket_bind(sd_netlink *nl);
152 int socket_broadcast_group_ref(sd_netlink *nl, unsigned group);
153 int socket_broadcast_group_unref(sd_netlink *nl, unsigned group);
154 int socket_write_message(sd_netlink *nl, sd_netlink_message *m);
155 int socket_read_message(sd_netlink *nl);
156
157 int netlink_add_match_internal(
158 sd_netlink *nl,
159 sd_netlink_slot **ret_slot,
160 const uint32_t *groups,
161 size_t n_groups,
162 uint16_t type,
163 uint8_t cmd,
164 sd_netlink_message_handler_t callback,
165 sd_netlink_destroy_t destroy_callback,
166 void *userdata,
167 const char *description);
168
169 /* Make sure callbacks don't destroy the netlink connection */
170 #define NETLINK_DONT_DESTROY(nl) \
171 _cleanup_(sd_netlink_unrefp) _unused_ sd_netlink *_dont_destroy_##nl = sd_netlink_ref(nl)
172
173 bool nfproto_is_valid(int nfproto);
174
175 /* nfnl */
176 /* TODO: to be exported later */
177 int sd_nfnl_socket_open(sd_netlink **ret);
178 int sd_nfnl_send_batch(
179 sd_netlink *nfnl,
180 sd_netlink_message **messages,
181 size_t msgcount,
182 uint32_t **ret_serials);
183 int sd_nfnl_call_batch(
184 sd_netlink *nfnl,
185 sd_netlink_message **messages,
186 size_t n_messages,
187 uint64_t usec,
188 sd_netlink_message ***ret_messages);
189 int sd_nfnl_message_new(
190 sd_netlink *nfnl,
191 sd_netlink_message **ret,
192 int nfproto,
193 uint16_t subsys,
194 uint16_t msg_type,
195 uint16_t flags);
196 int sd_nfnl_nft_message_new_table(sd_netlink *nfnl, sd_netlink_message **ret,
197 int nfproto, const char *table);
198 int sd_nfnl_nft_message_new_basechain(sd_netlink *nfnl, sd_netlink_message **ret,
199 int nfproto, const char *table, const char *chain,
200 const char *type, uint8_t hook, int prio);
201 int sd_nfnl_nft_message_new_rule(sd_netlink *nfnl, sd_netlink_message **ret,
202 int nfproto, const char *table, const char *chain);
203 int sd_nfnl_nft_message_new_set(sd_netlink *nfnl, sd_netlink_message **ret,
204 int nfproto, const char *table, const char *set_name,
205 uint32_t setid, uint32_t klen);
206 int sd_nfnl_nft_message_new_setelems(sd_netlink *nfnl, sd_netlink_message **ret,
207 int add, int nfproto, const char *table, const char *set_name);
208 int sd_nfnl_nft_message_append_setelem(sd_netlink_message *m,
209 uint32_t index,
210 const void *key, size_t key_len,
211 const void *data, size_t data_len,
212 uint32_t flags);