]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-netlink/netlink-internal.h
sd-netlink: drop sd_genl_family_t and introduce GenericNetlinkFamily
[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;
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
TG
73 unsigned rqueue_size;
74
1c4baffc 75 sd_netlink_message **rqueue_partial;
4e996881 76 unsigned rqueue_partial_size;
4e996881 77
a88f77c4 78 struct nlmsghdr *rbuffer;
a88f77c4 79
4555ec72
TG
80 bool processing:1;
81
d4bbdb77
TG
82 uint32_t serial;
83
e16bcf98
TG
84 struct Prioq *reply_callbacks_prioq;
85 Hashmap *reply_callbacks;
86
8cec01b9
TG
87 LIST_HEAD(struct match_callback, match_callbacks);
88
ee38400b
YW
89 LIST_HEAD(sd_netlink_slot, slots);
90
adf412b9 91 pid_t original_pid;
b4f2a5b1
TG
92
93 sd_event_source *io_event_source;
94 sd_event_source *time_event_source;
6203e07a 95 sd_event_source *exit_event_source;
b4f2a5b1 96 sd_event *event;
4e8f0ef9 97
56fdc16d
YW
98 Hashmap *genl_family_by_name;
99 Hashmap *genl_family_by_id;
65f568bb 100};
98dd77e8 101
f663aeb8 102struct netlink_attribute {
aa6b0ac4 103 size_t offset; /* offset from hdr to attribute */
4c641e99
TG
104 bool nested:1;
105 bool net_byteorder:1;
f663aeb8
TG
106};
107
108struct netlink_container {
109 const struct NLTypeSystem *type_system; /* the type system of the container */
110 size_t offset; /* offset from hdr to the start of the container */
111 struct netlink_attribute *attributes;
112 unsigned short n_attributes; /* number of attributes in container */
113};
114
1c4baffc 115struct sd_netlink_message {
f23ab4dc 116 unsigned n_ref;
4555ec72 117
05d0c2e3
JT
118 int protocol;
119
3815f36f 120 struct nlmsghdr *hdr;
409856d3 121 struct netlink_container containers[NETLINK_CONTAINER_DEPTH];
3815f36f 122 unsigned n_containers; /* number of containers */
3815f36f 123 bool sealed:1;
3f42446d 124 bool broadcast:1;
1403f45a 125
1c4baffc 126 sd_netlink_message *next; /* next in a chain of multi-part messages */
3815f36f 127};
9d0db178 128
409856d3 129int message_new_empty(sd_netlink *nl, sd_netlink_message **ret);
1cedca05
YW
130int message_new_full(
131 sd_netlink *nl,
132 uint16_t nlmsg_type,
133 const NLTypeSystem *type_system,
134 size_t header_size,
135 sd_netlink_message **ret);
136int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type);
409856d3
YW
137int message_new_synthetic_error(sd_netlink *nl, int error, uint32_t serial, sd_netlink_message **ret);
138uint32_t message_get_serial(sd_netlink_message *m);
139void message_seal(sd_netlink_message *m);
9d0db178 140
05d0c2e3 141int netlink_open_family(sd_netlink **ret, int family);
409856d3
YW
142bool netlink_pid_changed(sd_netlink *nl);
143int netlink_rqueue_make_room(sd_netlink *nl);
144int netlink_rqueue_partial_make_room(sd_netlink *nl);
05d0c2e3 145
b95cc756
TG
146int socket_open(int family);
147int socket_bind(sd_netlink *nl);
9c5a882b
TG
148int socket_broadcast_group_ref(sd_netlink *nl, unsigned group);
149int socket_broadcast_group_unref(sd_netlink *nl, unsigned group);
1c4baffc 150int socket_write_message(sd_netlink *nl, sd_netlink_message *m);
2d1ad724 151int socket_writev_message(sd_netlink *nl, sd_netlink_message **m, size_t msgcount);
1c4baffc 152int socket_read_message(sd_netlink *nl);
1b89cf56 153
409856d3
YW
154/* Make sure callbacks don't destroy the netlink connection */
155#define NETLINK_DONT_DESTROY(nl) \
156 _cleanup_(sd_netlink_unrefp) _unused_ sd_netlink *_dont_destroy_##nl = sd_netlink_ref(nl)