]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/libsystemd/sd-netlink/netlink-internal.h
ci: enable build/unit test jobs on ppc64le
[thirdparty/systemd.git] / src / libsystemd / sd-netlink / netlink-internal.h
... / ...
CommitLineData
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
17struct reply_callback {
18 sd_netlink_message_handler_t callback;
19 usec_t timeout;
20 uint32_t serial;
21 unsigned prioq_idx;
22};
23
24struct 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
34typedef enum NetlinkSlotType {
35 NETLINK_REPLY_CALLBACK,
36 NETLINK_MATCH_CALLBACK,
37 _NETLINK_SLOT_INVALID = -EINVAL,
38} NetlinkSlotType;
39
40typedef 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
58typedef 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
100struct netlink_attribute {
101 size_t offset; /* offset from hdr to attribute */
102 bool nested:1;
103 bool net_byteorder:1;
104};
105
106struct 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
113typedef 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
127int message_new_empty(sd_netlink *nl, sd_netlink_message **ret);
128int 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);
135int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type, uint16_t flags);
136int message_new_synthetic_error(sd_netlink *nl, int error, uint32_t serial, sd_netlink_message **ret);
137
138static inline uint32_t message_get_serial(sd_netlink_message *m) {
139 assert(m);
140 return ASSERT_PTR(m->hdr)->nlmsg_seq;
141}
142
143void message_seal(sd_netlink_message *m);
144
145int netlink_open_family(sd_netlink **ret, int family);
146bool netlink_pid_changed(sd_netlink *nl);
147
148int socket_bind(sd_netlink *nl);
149int socket_broadcast_group_ref(sd_netlink *nl, unsigned group);
150int socket_broadcast_group_unref(sd_netlink *nl, unsigned group);
151int socket_write_message(sd_netlink *nl, sd_netlink_message *m);
152int socket_read_message(sd_netlink *nl);
153
154int 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
170bool nfproto_is_valid(int nfproto);
171
172/* nfnl */
173/* TODO: to be exported later */
174int sd_nfnl_socket_open(sd_netlink **ret);
175int sd_nfnl_send_batch(
176 sd_netlink *nfnl,
177 sd_netlink_message **messages,
178 size_t msgcount,
179 uint32_t **ret_serials);
180int 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);
186int 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);
193int sd_nfnl_nft_message_new_table(sd_netlink *nfnl, sd_netlink_message **ret,
194 int nfproto, const char *table);
195int 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);
198int sd_nfnl_nft_message_new_rule(sd_netlink *nfnl, sd_netlink_message **ret,
199 int nfproto, const char *table, const char *chain);
200int 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);
203int 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);
205int 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);