]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-netlink/netlink-internal.h
Merge pull request #18007 from fw-strlen/ipv6_masq_and_dnat
[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 "prioq.h"
11 #include "time-util.h"
12
13 #define RTNL_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC))
14
15 #define RTNL_RQUEUE_MAX 64*1024
16
17 #define RTNL_CONTAINER_DEPTH 32
18
19 struct reply_callback {
20 sd_netlink_message_handler_t callback;
21 usec_t timeout;
22 uint32_t serial;
23 unsigned prioq_idx;
24 };
25
26 struct match_callback {
27 sd_netlink_message_handler_t callback;
28 uint16_t type;
29
30 LIST_FIELDS(struct match_callback, match_callbacks);
31 };
32
33 typedef enum NetlinkSlotType {
34 NETLINK_REPLY_CALLBACK,
35 NETLINK_MATCH_CALLBACK,
36 _NETLINK_SLOT_INVALID = -EINVAL,
37 } NetlinkSlotType;
38
39 struct sd_netlink_slot {
40 unsigned n_ref;
41 NetlinkSlotType type:8;
42 bool floating;
43 sd_netlink *netlink;
44 void *userdata;
45 sd_netlink_destroy_t destroy_callback;
46
47 char *description;
48
49 LIST_FIELDS(sd_netlink_slot, slots);
50
51 union {
52 struct reply_callback reply_callback;
53 struct match_callback match_callback;
54 };
55 };
56
57 struct sd_netlink {
58 unsigned n_ref;
59
60 int fd;
61
62 union {
63 struct sockaddr sa;
64 struct sockaddr_nl nl;
65 } sockaddr;
66
67 int protocol;
68
69 Hashmap *broadcast_group_refs;
70 bool broadcast_group_dont_leave:1; /* until we can rely on 4.2 */
71
72 sd_netlink_message **rqueue;
73 unsigned rqueue_size;
74 size_t rqueue_allocated;
75
76 sd_netlink_message **rqueue_partial;
77 unsigned rqueue_partial_size;
78 size_t rqueue_partial_allocated;
79
80 struct nlmsghdr *rbuffer;
81 size_t rbuffer_allocated;
82
83 bool processing:1;
84
85 uint32_t serial;
86
87 struct Prioq *reply_callbacks_prioq;
88 Hashmap *reply_callbacks;
89
90 LIST_HEAD(struct match_callback, match_callbacks);
91
92 LIST_HEAD(sd_netlink_slot, slots);
93
94 pid_t original_pid;
95
96 sd_event_source *io_event_source;
97 sd_event_source *time_event_source;
98 sd_event_source *exit_event_source;
99 sd_event *event;
100
101 Hashmap *genl_family_to_nlmsg_type;
102 Hashmap *nlmsg_type_to_genl_family;
103 };
104
105 struct netlink_attribute {
106 size_t offset; /* offset from hdr to attribute */
107 bool nested:1;
108 bool net_byteorder:1;
109 };
110
111 struct 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;
115 unsigned short n_attributes; /* number of attributes in container */
116 };
117
118 struct sd_netlink_message {
119 unsigned n_ref;
120
121 int protocol;
122
123 struct nlmsghdr *hdr;
124 struct netlink_container containers[RTNL_CONTAINER_DEPTH];
125 unsigned n_containers; /* number of containers */
126 bool sealed:1;
127 bool broadcast:1;
128
129 sd_netlink_message *next; /* next in a chain of multi-part messages */
130 };
131
132 int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type);
133 int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret);
134
135 int netlink_open_family(sd_netlink **ret, int family);
136
137 int socket_open(int family);
138 int socket_bind(sd_netlink *nl);
139 int socket_broadcast_group_ref(sd_netlink *nl, unsigned group);
140 int socket_broadcast_group_unref(sd_netlink *nl, unsigned group);
141 int socket_write_message(sd_netlink *nl, sd_netlink_message *m);
142 int socket_writev_message(sd_netlink *nl, sd_netlink_message **m, size_t msgcount);
143 int socket_read_message(sd_netlink *nl);
144
145 int rtnl_rqueue_make_room(sd_netlink *rtnl);
146 int rtnl_rqueue_partial_make_room(sd_netlink *rtnl);
147
148 /* Make sure callbacks don't destroy the rtnl connection */
149 #define NETLINK_DONT_DESTROY(rtnl) \
150 _cleanup_(sd_netlink_unrefp) _unused_ sd_netlink *_dont_destroy_##rtnl = sd_netlink_ref(rtnl)