]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-netlink/netlink-internal.h
sd-netlink: several cleanups for netfilter
[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
LP
4#include <linux/netlink.h>
5
1c4baffc 6#include "sd-netlink.h"
e16bcf98 7
07630cea 8#include "list.h"
1c4baffc 9#include "netlink-types.h"
07630cea 10#include "prioq.h"
ca78ad1d 11#include "time-util.h"
d8e538ec 12
409856d3 13#define NETLINK_DEFAULT_TIMEOUT_USEC ((usec_t) (25 * USEC_PER_SEC))
3815f36f 14
409856d3 15#define NETLINK_RQUEUE_MAX 64*1024
3815f36f 16
409856d3 17#define NETLINK_CONTAINER_DEPTH 32
3815f36f 18
e16bcf98 19struct reply_callback {
1c4baffc 20 sd_netlink_message_handler_t callback;
e16bcf98 21 usec_t timeout;
b522c4b9 22 uint32_t serial;
e16bcf98
TG
23 unsigned prioq_idx;
24};
65f568bb 25
8cec01b9 26struct match_callback {
1c4baffc 27 sd_netlink_message_handler_t callback;
3f60e448
YW
28 uint32_t *groups;
29 size_t n_groups;
23a7f0f7 30 uint16_t type;
e1578f60 31 uint8_t cmd; /* used by genl */
8cec01b9
TG
32
33 LIST_FIELDS(struct match_callback, match_callbacks);
34};
35
ee38400b
YW
36typedef enum NetlinkSlotType {
37 NETLINK_REPLY_CALLBACK,
38 NETLINK_MATCH_CALLBACK,
2d93c20e 39 _NETLINK_SLOT_INVALID = -EINVAL,
ee38400b
YW
40} NetlinkSlotType;
41
42struct sd_netlink_slot {
43 unsigned n_ref;
399f74c7
ZJS
44 NetlinkSlotType type:8;
45 bool floating;
ee38400b
YW
46 sd_netlink *netlink;
47 void *userdata;
48 sd_netlink_destroy_t destroy_callback;
ee38400b 49
8190a388 50 char *description;
ee38400b
YW
51
52 LIST_FIELDS(sd_netlink_slot, slots);
53
54 union {
55 struct reply_callback reply_callback;
56 struct match_callback match_callback;
57 };
58};
59
1c4baffc 60struct sd_netlink {
f23ab4dc 61 unsigned n_ref;
65f568bb
TG
62
63 int fd;
64
65 union {
66 struct sockaddr sa;
67 struct sockaddr_nl nl;
68 } sockaddr;
69
05d0c2e3
JT
70 int protocol;
71
9c5a882b
TG
72 Hashmap *broadcast_group_refs;
73 bool broadcast_group_dont_leave:1; /* until we can rely on 4.2 */
74
1c4baffc 75 sd_netlink_message **rqueue;
4555ec72
TG
76 unsigned rqueue_size;
77
1c4baffc 78 sd_netlink_message **rqueue_partial;
4e996881 79 unsigned rqueue_partial_size;
4e996881 80
a88f77c4 81 struct nlmsghdr *rbuffer;
a88f77c4 82
4555ec72
TG
83 bool processing:1;
84
d4bbdb77
TG
85 uint32_t serial;
86
e16bcf98
TG
87 struct Prioq *reply_callbacks_prioq;
88 Hashmap *reply_callbacks;
89
8cec01b9
TG
90 LIST_HEAD(struct match_callback, match_callbacks);
91
ee38400b
YW
92 LIST_HEAD(sd_netlink_slot, slots);
93
adf412b9 94 pid_t original_pid;
b4f2a5b1
TG
95
96 sd_event_source *io_event_source;
97 sd_event_source *time_event_source;
6203e07a 98 sd_event_source *exit_event_source;
b4f2a5b1 99 sd_event *event;
4e8f0ef9 100
56fdc16d
YW
101 Hashmap *genl_family_by_name;
102 Hashmap *genl_family_by_id;
65f568bb 103};
98dd77e8 104
f663aeb8 105struct netlink_attribute {
aa6b0ac4 106 size_t offset; /* offset from hdr to attribute */
4c641e99
TG
107 bool nested:1;
108 bool net_byteorder:1;
f663aeb8
TG
109};
110
111struct netlink_container {
112 const struct NLTypeSystem *type_system; /* the type system of the container */
113 size_t offset; /* offset from hdr to the start of the container */
114 struct netlink_attribute *attributes;
416e8419 115 uint16_t max_attribute; /* the maximum attribute in container */
f663aeb8
TG
116};
117
1c4baffc 118struct sd_netlink_message {
f23ab4dc 119 unsigned n_ref;
4555ec72 120
05d0c2e3
JT
121 int protocol;
122
3815f36f 123 struct nlmsghdr *hdr;
409856d3 124 struct netlink_container containers[NETLINK_CONTAINER_DEPTH];
3815f36f 125 unsigned n_containers; /* number of containers */
4d4d898a 126 uint32_t multicast_group;
3815f36f 127 bool sealed:1;
1403f45a 128
1c4baffc 129 sd_netlink_message *next; /* next in a chain of multi-part messages */
3815f36f 130};
9d0db178 131
409856d3 132int message_new_empty(sd_netlink *nl, sd_netlink_message **ret);
1cedca05
YW
133int message_new_full(
134 sd_netlink *nl,
135 uint16_t nlmsg_type,
136 const NLTypeSystem *type_system,
137 size_t header_size,
138 sd_netlink_message **ret);
139int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type);
409856d3 140int message_new_synthetic_error(sd_netlink *nl, int error, uint32_t serial, sd_netlink_message **ret);
84e10015
ZJS
141
142static inline uint32_t message_get_serial(sd_netlink_message *m) {
143 assert(m);
144 return ASSERT_PTR(m->hdr)->nlmsg_seq;
145}
146
409856d3 147void message_seal(sd_netlink_message *m);
9d0db178 148
05d0c2e3 149int netlink_open_family(sd_netlink **ret, int family);
409856d3
YW
150bool netlink_pid_changed(sd_netlink *nl);
151int netlink_rqueue_make_room(sd_netlink *nl);
152int netlink_rqueue_partial_make_room(sd_netlink *nl);
05d0c2e3 153
b95cc756 154int socket_bind(sd_netlink *nl);
9c5a882b
TG
155int socket_broadcast_group_ref(sd_netlink *nl, unsigned group);
156int socket_broadcast_group_unref(sd_netlink *nl, unsigned group);
1c4baffc
TG
157int socket_write_message(sd_netlink *nl, sd_netlink_message *m);
158int socket_read_message(sd_netlink *nl);
1b89cf56 159
3f60e448
YW
160int netlink_add_match_internal(
161 sd_netlink *nl,
162 sd_netlink_slot **ret_slot,
163 const uint32_t *groups,
164 size_t n_groups,
165 uint16_t type,
e1578f60 166 uint8_t cmd,
3f60e448
YW
167 sd_netlink_message_handler_t callback,
168 sd_netlink_destroy_t destroy_callback,
169 void *userdata,
170 const char *description);
171
409856d3
YW
172/* Make sure callbacks don't destroy the netlink connection */
173#define NETLINK_DONT_DESTROY(nl) \
174 _cleanup_(sd_netlink_unrefp) _unused_ sd_netlink *_dont_destroy_##nl = sd_netlink_ref(nl)
84e10015
ZJS
175
176/* nfnl */
177/* TODO: to be exported later */
178int sd_nfnl_socket_open(sd_netlink **ret);
179int sd_nfnl_message_batch_begin(sd_netlink *nfnl, sd_netlink_message **ret);
180int sd_nfnl_message_batch_end(sd_netlink *nfnl, sd_netlink_message **ret);
181int sd_nfnl_nft_message_del_table(sd_netlink *nfnl, sd_netlink_message **ret,
64f090a6 182 int nfproto, const char *table);
84e10015 183int sd_nfnl_nft_message_new_table(sd_netlink *nfnl, sd_netlink_message **ret,
64f090a6 184 int nfproto, const char *table);
84e10015 185int sd_nfnl_nft_message_new_basechain(sd_netlink *nfnl, sd_netlink_message **ret,
64f090a6 186 int nfproto, const char *table, const char *chain,
84e10015
ZJS
187 const char *type, uint8_t hook, int prio);
188int sd_nfnl_nft_message_new_rule(sd_netlink *nfnl, sd_netlink_message **ret,
64f090a6 189 int nfproto, const char *table, const char *chain);
84e10015 190int sd_nfnl_nft_message_new_set(sd_netlink *nfnl, sd_netlink_message **ret,
64f090a6 191 int nfproto, const char *table, const char *set_name,
84e10015
ZJS
192 uint32_t setid, uint32_t klen);
193int sd_nfnl_nft_message_new_setelems_begin(sd_netlink *nfnl, sd_netlink_message **ret,
64f090a6 194 int nfproto, const char *table, const char *set_name);
84e10015 195int sd_nfnl_nft_message_del_setelems_begin(sd_netlink *nfnl, sd_netlink_message **ret,
64f090a6 196 int nfproto, const char *table, const char *set_name);
84e10015 197int sd_nfnl_nft_message_add_setelem(sd_netlink_message *m,
64f090a6
YW
198 uint32_t index,
199 const void *key, size_t key_len,
200 const void *data, size_t data_len);
84e10015 201int sd_nfnl_nft_message_add_setelem_end(sd_netlink_message *m);