1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <linux/netlink.h>
6 #include "sd-netlink.h"
9 #include "netlink-types.h"
10 #include "ordered-set.h"
12 #include "time-util.h"
14 #define NETLINK_DEFAULT_TIMEOUT_USEC ((usec_t) (25 * USEC_PER_SEC))
16 #define NETLINK_RQUEUE_MAX 64*1024
18 #define NETLINK_CONTAINER_DEPTH 32
20 struct reply_callback
{
21 sd_netlink_message_handler_t callback
;
27 struct match_callback
{
28 sd_netlink_message_handler_t callback
;
32 uint8_t cmd
; /* used by genl */
34 LIST_FIELDS(struct match_callback
, match_callbacks
);
37 typedef enum NetlinkSlotType
{
38 NETLINK_REPLY_CALLBACK
,
39 NETLINK_MATCH_CALLBACK
,
40 _NETLINK_SLOT_INVALID
= -EINVAL
,
43 struct sd_netlink_slot
{
45 NetlinkSlotType type
:8;
49 sd_netlink_destroy_t destroy_callback
;
53 LIST_FIELDS(sd_netlink_slot
, slots
);
56 struct reply_callback reply_callback
;
57 struct match_callback match_callback
;
68 struct sockaddr_nl nl
;
73 Hashmap
*broadcast_group_refs
;
74 bool broadcast_group_dont_leave
:1; /* until we can rely on 4.2 */
77 Hashmap
*rqueue_by_serial
;
78 Hashmap
*rqueue_partial_by_serial
;
80 struct nlmsghdr
*rbuffer
;
86 struct Prioq
*reply_callbacks_prioq
;
87 Hashmap
*reply_callbacks
;
89 LIST_HEAD(struct match_callback
, match_callbacks
);
91 LIST_HEAD(sd_netlink_slot
, slots
);
95 sd_event_source
*io_event_source
;
96 sd_event_source
*time_event_source
;
97 sd_event_source
*exit_event_source
;
100 Hashmap
*genl_family_by_name
;
101 Hashmap
*genl_family_by_id
;
104 struct netlink_attribute
{
105 size_t offset
; /* offset from hdr to attribute */
107 bool net_byteorder
:1;
110 struct netlink_container
{
111 const struct NLAPolicySet
*policy_set
; /* the policy set of the container */
112 size_t offset
; /* offset from hdr to the start of the container */
113 struct netlink_attribute
*attributes
;
114 uint16_t max_attribute
; /* the maximum attribute in container */
117 struct sd_netlink_message
{
122 struct nlmsghdr
*hdr
;
123 struct netlink_container containers
[NETLINK_CONTAINER_DEPTH
];
124 unsigned n_containers
; /* number of containers */
125 uint32_t multicast_group
;
128 sd_netlink_message
*next
; /* next in a chain of multi-part messages */
131 int message_new_empty(sd_netlink
*nl
, sd_netlink_message
**ret
);
132 int message_new_full(
135 const NLAPolicySet
*policy_set
,
137 sd_netlink_message
**ret
);
138 int message_new(sd_netlink
*nl
, sd_netlink_message
**ret
, uint16_t type
);
139 int message_new_synthetic_error(sd_netlink
*nl
, int error
, uint32_t serial
, sd_netlink_message
**ret
);
141 static inline uint32_t message_get_serial(sd_netlink_message
*m
) {
143 return ASSERT_PTR(m
->hdr
)->nlmsg_seq
;
146 void message_seal(sd_netlink_message
*m
);
148 int netlink_open_family(sd_netlink
**ret
, int family
);
149 bool netlink_pid_changed(sd_netlink
*nl
);
151 int socket_bind(sd_netlink
*nl
);
152 int socket_broadcast_group_ref(sd_netlink
*nl
, unsigned group
);
153 int socket_broadcast_group_unref(sd_netlink
*nl
, unsigned group
);
154 int socket_write_message(sd_netlink
*nl
, sd_netlink_message
*m
);
155 int socket_read_message(sd_netlink
*nl
);
157 int netlink_add_match_internal(
159 sd_netlink_slot
**ret_slot
,
160 const uint32_t *groups
,
164 sd_netlink_message_handler_t callback
,
165 sd_netlink_destroy_t destroy_callback
,
167 const char *description
);
169 /* Make sure callbacks don't destroy the netlink connection */
170 #define NETLINK_DONT_DESTROY(nl) \
171 _cleanup_(sd_netlink_unrefp) _unused_ sd_netlink *_dont_destroy_##nl = sd_netlink_ref(nl)
173 bool nfproto_is_valid(int nfproto
);
176 /* TODO: to be exported later */
177 int sd_nfnl_socket_open(sd_netlink
**ret
);
178 int sd_nfnl_send_batch(
180 sd_netlink_message
**messages
,
182 uint32_t **ret_serials
);
183 int sd_nfnl_call_batch(
185 sd_netlink_message
**messages
,
188 sd_netlink_message
***ret_messages
);
189 int sd_nfnl_message_new(
191 sd_netlink_message
**ret
,
196 int sd_nfnl_nft_message_new_table(sd_netlink
*nfnl
, sd_netlink_message
**ret
,
197 int nfproto
, const char *table
);
198 int sd_nfnl_nft_message_new_basechain(sd_netlink
*nfnl
, sd_netlink_message
**ret
,
199 int nfproto
, const char *table
, const char *chain
,
200 const char *type
, uint8_t hook
, int prio
);
201 int sd_nfnl_nft_message_new_rule(sd_netlink
*nfnl
, sd_netlink_message
**ret
,
202 int nfproto
, const char *table
, const char *chain
);
203 int sd_nfnl_nft_message_new_set(sd_netlink
*nfnl
, sd_netlink_message
**ret
,
204 int nfproto
, const char *table
, const char *set_name
,
205 uint32_t setid
, uint32_t klen
);
206 int sd_nfnl_nft_message_new_setelems(sd_netlink
*nfnl
, sd_netlink_message
**ret
,
207 int add
, int nfproto
, const char *table
, const char *set_name
);
208 int sd_nfnl_nft_message_append_setelem(sd_netlink_message
*m
,
210 const void *key
, size_t key_len
,
211 const void *data
, size_t data_len
,