]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-netlink/netlink-internal.h
ssh-generator: generate /etc/issue.d/ with VSOCK ssh info data (#37819)
[thirdparty/systemd.git] / src / libsystemd / sd-netlink / netlink-internal.h
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
a2cdd907
LP
2#pragma once
3
a33dece5 4#include <linux/netlink.h>
5cdf13c7 5#include <sys/socket.h>
a33dece5 6
5cdf13c7 7#include "forward.h"
07630cea 8#include "list.h"
1c4baffc 9#include "netlink-types.h"
d8e538ec 10
409856d3 11#define NETLINK_DEFAULT_TIMEOUT_USEC ((usec_t) (25 * USEC_PER_SEC))
3815f36f 12
409856d3 13#define NETLINK_RQUEUE_MAX 64*1024
3815f36f 14
409856d3 15#define NETLINK_CONTAINER_DEPTH 32
3815f36f 16
e16bcf98 17struct reply_callback {
1c4baffc 18 sd_netlink_message_handler_t callback;
e16bcf98 19 usec_t timeout;
b522c4b9 20 uint32_t serial;
e16bcf98
TG
21 unsigned prioq_idx;
22};
65f568bb 23
8cec01b9 24struct match_callback {
1c4baffc 25 sd_netlink_message_handler_t callback;
3f60e448
YW
26 uint32_t *groups;
27 size_t n_groups;
23a7f0f7 28 uint16_t type;
e1578f60 29 uint8_t cmd; /* used by genl */
8cec01b9
TG
30
31 LIST_FIELDS(struct match_callback, match_callbacks);
32};
33
ee38400b
YW
34typedef enum NetlinkSlotType {
35 NETLINK_REPLY_CALLBACK,
36 NETLINK_MATCH_CALLBACK,
2d93c20e 37 _NETLINK_SLOT_INVALID = -EINVAL,
ee38400b
YW
38} NetlinkSlotType;
39
5cdf13c7 40typedef struct sd_netlink_slot {
ee38400b 41 unsigned n_ref;
399f74c7
ZJS
42 NetlinkSlotType type:8;
43 bool floating;
ee38400b
YW
44 sd_netlink *netlink;
45 void *userdata;
46 sd_netlink_destroy_t destroy_callback;
ee38400b 47
8190a388 48 char *description;
ee38400b
YW
49
50 LIST_FIELDS(sd_netlink_slot, slots);
51
52 union {
53 struct reply_callback reply_callback;
54 struct match_callback match_callback;
55 };
5cdf13c7 56} sd_netlink_slot;
ee38400b 57
5cdf13c7 58typedef struct sd_netlink {
f23ab4dc 59 unsigned n_ref;
65f568bb
TG
60
61 int fd;
62
63 union {
64 struct sockaddr sa;
65 struct sockaddr_nl nl;
66 } sockaddr;
67
05d0c2e3
JT
68 int protocol;
69
9c5a882b 70 Hashmap *broadcast_group_refs;
9c5a882b 71
e417c4ac 72 OrderedSet *rqueue;
7b34bae3 73 Hashmap *rqueue_by_serial;
e417c4ac 74 Hashmap *rqueue_partial_by_serial;
4e996881 75
a88f77c4 76 struct nlmsghdr *rbuffer;
a88f77c4 77
4555ec72
TG
78 bool processing:1;
79
d4bbdb77
TG
80 uint32_t serial;
81
e16bcf98
TG
82 struct Prioq *reply_callbacks_prioq;
83 Hashmap *reply_callbacks;
84
8cec01b9
TG
85 LIST_HEAD(struct match_callback, match_callbacks);
86
ee38400b
YW
87 LIST_HEAD(sd_netlink_slot, slots);
88
adf412b9 89 pid_t original_pid;
b4f2a5b1
TG
90
91 sd_event_source *io_event_source;
92 sd_event_source *time_event_source;
6203e07a 93 sd_event_source *exit_event_source;
b4f2a5b1 94 sd_event *event;
4e8f0ef9 95
56fdc16d
YW
96 Hashmap *genl_family_by_name;
97 Hashmap *genl_family_by_id;
5cdf13c7 98} sd_netlink;
98dd77e8 99
f663aeb8 100struct netlink_attribute {
aa6b0ac4 101 size_t offset; /* offset from hdr to attribute */
4c641e99
TG
102 bool nested:1;
103 bool net_byteorder:1;
f663aeb8
TG
104};
105
106struct netlink_container {
ebf404a4 107 const struct NLAPolicySet *policy_set; /* the policy set of the container */
f663aeb8
TG
108 size_t offset; /* offset from hdr to the start of the container */
109 struct netlink_attribute *attributes;
416e8419 110 uint16_t max_attribute; /* the maximum attribute in container */
f663aeb8
TG
111};
112
5cdf13c7 113typedef struct sd_netlink_message {
f23ab4dc 114 unsigned n_ref;
4555ec72 115
05d0c2e3
JT
116 int protocol;
117
3815f36f 118 struct nlmsghdr *hdr;
409856d3 119 struct netlink_container containers[NETLINK_CONTAINER_DEPTH];
3815f36f 120 unsigned n_containers; /* number of containers */
4d4d898a 121 uint32_t multicast_group;
3815f36f 122 bool sealed:1;
1403f45a 123
1c4baffc 124 sd_netlink_message *next; /* next in a chain of multi-part messages */
5cdf13c7 125} sd_netlink_message;
9d0db178 126
409856d3 127int message_new_empty(sd_netlink *nl, sd_netlink_message **ret);
1cedca05
YW
128int message_new_full(
129 sd_netlink *nl,
130 uint16_t nlmsg_type,
6e196011 131 uint16_t nlmsg_flags,
ebf404a4 132 const NLAPolicySet *policy_set,
1cedca05
YW
133 size_t header_size,
134 sd_netlink_message **ret);
6e196011 135int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type, uint16_t flags);
409856d3 136int message_new_synthetic_error(sd_netlink *nl, int error, uint32_t serial, sd_netlink_message **ret);
84e10015 137
a6f4a9c0
DDM
138static inline uint32_t message_get_serial(sd_netlink_message *m) {
139 assert(m);
140 return ASSERT_PTR(m->hdr)->nlmsg_seq;
141}
84e10015 142
409856d3 143void message_seal(sd_netlink_message *m);
9d0db178 144
05d0c2e3 145int netlink_open_family(sd_netlink **ret, int family);
409856d3 146bool netlink_pid_changed(sd_netlink *nl);
05d0c2e3 147
b95cc756 148int socket_bind(sd_netlink *nl);
9c5a882b
TG
149int socket_broadcast_group_ref(sd_netlink *nl, unsigned group);
150int socket_broadcast_group_unref(sd_netlink *nl, unsigned group);
1c4baffc
TG
151int socket_write_message(sd_netlink *nl, sd_netlink_message *m);
152int socket_read_message(sd_netlink *nl);
1b89cf56 153
3f60e448
YW
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,
e1578f60 160 uint8_t cmd,
3f60e448
YW
161 sd_netlink_message_handler_t callback,
162 sd_netlink_destroy_t destroy_callback,
163 void *userdata,
164 const char *description);
165
409856d3
YW
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)
84e10015 169
94096580
TM
170bool nfproto_is_valid(int nfproto);
171
84e10015
ZJS
172/* nfnl */
173/* TODO: to be exported later */
174int sd_nfnl_socket_open(sd_netlink **ret);
573bb24d
YW
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);
84e10015 193int sd_nfnl_nft_message_new_table(sd_netlink *nfnl, sd_netlink_message **ret,
64f090a6 194 int nfproto, const char *table);
84e10015 195int sd_nfnl_nft_message_new_basechain(sd_netlink *nfnl, sd_netlink_message **ret,
64f090a6 196 int nfproto, const char *table, const char *chain,
84e10015
ZJS
197 const char *type, uint8_t hook, int prio);
198int sd_nfnl_nft_message_new_rule(sd_netlink *nfnl, sd_netlink_message **ret,
64f090a6 199 int nfproto, const char *table, const char *chain);
84e10015 200int sd_nfnl_nft_message_new_set(sd_netlink *nfnl, sd_netlink_message **ret,
64f090a6 201 int nfproto, const char *table, const char *set_name,
84e10015 202 uint32_t setid, uint32_t klen);
df737170
YW
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);