]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-netlink/netlink-internal.h
sd-netlink: revamp message serial handling
[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
59a7a684 13#define RTNL_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC))
3815f36f 14
3815f36f
TG
15#define RTNL_RQUEUE_MAX 64*1024
16
17#define RTNL_CONTAINER_DEPTH 32
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;
23a7f0f7 28 uint16_t type;
8cec01b9
TG
29
30 LIST_FIELDS(struct match_callback, match_callbacks);
31};
32
ee38400b
YW
33typedef enum NetlinkSlotType {
34 NETLINK_REPLY_CALLBACK,
35 NETLINK_MATCH_CALLBACK,
2d93c20e 36 _NETLINK_SLOT_INVALID = -EINVAL,
ee38400b
YW
37} NetlinkSlotType;
38
39struct sd_netlink_slot {
40 unsigned n_ref;
399f74c7
ZJS
41 NetlinkSlotType type:8;
42 bool floating;
ee38400b
YW
43 sd_netlink *netlink;
44 void *userdata;
45 sd_netlink_destroy_t destroy_callback;
ee38400b 46
8190a388 47 char *description;
ee38400b
YW
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
1c4baffc 57struct sd_netlink {
f23ab4dc 58 unsigned n_ref;
65f568bb
TG
59
60 int fd;
61
62 union {
63 struct sockaddr sa;
64 struct sockaddr_nl nl;
65 } sockaddr;
66
05d0c2e3
JT
67 int protocol;
68
9c5a882b
TG
69 Hashmap *broadcast_group_refs;
70 bool broadcast_group_dont_leave:1; /* until we can rely on 4.2 */
71
1c4baffc 72 sd_netlink_message **rqueue;
4555ec72 73 unsigned rqueue_size;
77768cba 74 size_t rqueue_allocated;
4555ec72 75
1c4baffc 76 sd_netlink_message **rqueue_partial;
4e996881
TG
77 unsigned rqueue_partial_size;
78 size_t rqueue_partial_allocated;
79
a88f77c4
TG
80 struct nlmsghdr *rbuffer;
81 size_t rbuffer_allocated;
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
YW
100
101 Hashmap *genl_family_to_nlmsg_type;
102 Hashmap *nlmsg_type_to_genl_family;
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;
115 unsigned short n_attributes; /* number of attributes in container */
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;
f663aeb8 124 struct netlink_container containers[RTNL_CONTAINER_DEPTH];
3815f36f 125 unsigned n_containers; /* number of containers */
3815f36f 126 bool sealed:1;
3f42446d 127 bool broadcast:1;
1403f45a 128
1c4baffc 129 sd_netlink_message *next; /* next in a chain of multi-part messages */
3815f36f 130};
9d0db178 131
1c4baffc 132int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type);
89489ef7 133int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret);
9d0db178 134
05d0c2e3
JT
135int netlink_open_family(sd_netlink **ret, int family);
136
b95cc756
TG
137int socket_open(int family);
138int socket_bind(sd_netlink *nl);
9c5a882b
TG
139int socket_broadcast_group_ref(sd_netlink *nl, unsigned group);
140int socket_broadcast_group_unref(sd_netlink *nl, unsigned group);
1c4baffc 141int socket_write_message(sd_netlink *nl, sd_netlink_message *m);
2d1ad724 142int socket_writev_message(sd_netlink *nl, sd_netlink_message **m, size_t msgcount);
1c4baffc 143int socket_read_message(sd_netlink *nl);
1b89cf56 144
1c4baffc
TG
145int rtnl_rqueue_make_room(sd_netlink *rtnl);
146int rtnl_rqueue_partial_make_room(sd_netlink *rtnl);
e16bcf98
TG
147
148/* Make sure callbacks don't destroy the rtnl connection */
4afd3348
LP
149#define NETLINK_DONT_DESTROY(rtnl) \
150 _cleanup_(sd_netlink_unrefp) _unused_ sd_netlink *_dont_destroy_##rtnl = sd_netlink_ref(rtnl)