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