1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <linux/netlink.h>
5 #include <sys/socket.h>
9 #include "netlink-types.h"
11 #define NETLINK_DEFAULT_TIMEOUT_USEC ((usec_t) (25 * USEC_PER_SEC))
13 #define NETLINK_RQUEUE_MAX 64*1024
15 #define NETLINK_CONTAINER_DEPTH 32
17 struct reply_callback
{
18 sd_netlink_message_handler_t callback
;
24 struct match_callback
{
25 sd_netlink_message_handler_t callback
;
29 uint8_t cmd
; /* used by genl */
31 LIST_FIELDS(struct match_callback
, match_callbacks
);
34 typedef enum NetlinkSlotType
{
35 NETLINK_REPLY_CALLBACK
,
36 NETLINK_MATCH_CALLBACK
,
37 _NETLINK_SLOT_INVALID
= -EINVAL
,
40 typedef struct sd_netlink_slot
{
42 NetlinkSlotType type
:8;
46 sd_netlink_destroy_t destroy_callback
;
50 LIST_FIELDS(sd_netlink_slot
, slots
);
53 struct reply_callback reply_callback
;
54 struct match_callback match_callback
;
58 typedef struct sd_netlink
{
65 struct sockaddr_nl nl
;
70 Hashmap
*broadcast_group_refs
;
73 Hashmap
*rqueue_by_serial
;
74 Hashmap
*rqueue_partial_by_serial
;
76 struct nlmsghdr
*rbuffer
;
82 struct Prioq
*reply_callbacks_prioq
;
83 Hashmap
*reply_callbacks
;
85 LIST_HEAD(struct match_callback
, match_callbacks
);
87 LIST_HEAD(sd_netlink_slot
, slots
);
91 sd_event_source
*io_event_source
;
92 sd_event_source
*time_event_source
;
93 sd_event_source
*exit_event_source
;
96 Hashmap
*genl_family_by_name
;
97 Hashmap
*genl_family_by_id
;
100 struct netlink_attribute
{
101 size_t offset
; /* offset from hdr to attribute */
103 bool net_byteorder
:1;
106 struct netlink_container
{
107 const struct NLAPolicySet
*policy_set
; /* the policy set of the container */
108 size_t offset
; /* offset from hdr to the start of the container */
109 struct netlink_attribute
*attributes
;
110 uint16_t max_attribute
; /* the maximum attribute in container */
113 typedef struct sd_netlink_message
{
118 struct nlmsghdr
*hdr
;
119 struct netlink_container containers
[NETLINK_CONTAINER_DEPTH
];
120 unsigned n_containers
; /* number of containers */
121 uint32_t multicast_group
;
124 sd_netlink_message
*next
; /* next in a chain of multi-part messages */
125 } sd_netlink_message
;
127 int message_new_empty(sd_netlink
*nl
, sd_netlink_message
**ret
);
128 int message_new_full(
131 uint16_t nlmsg_flags
,
132 const NLAPolicySet
*policy_set
,
134 sd_netlink_message
**ret
);
135 int message_new(sd_netlink
*nl
, sd_netlink_message
**ret
, uint16_t type
, uint16_t flags
);
136 int message_new_synthetic_error(sd_netlink
*nl
, int error
, uint32_t serial
, sd_netlink_message
**ret
);
138 static inline uint32_t message_get_serial(sd_netlink_message
*m
) {
140 return ASSERT_PTR(m
->hdr
)->nlmsg_seq
;
143 void message_seal(sd_netlink_message
*m
);
145 int netlink_open_family(sd_netlink
**ret
, int family
);
146 bool netlink_pid_changed(sd_netlink
*nl
);
148 int socket_bind(sd_netlink
*nl
);
149 int socket_broadcast_group_ref(sd_netlink
*nl
, unsigned group
);
150 int socket_broadcast_group_unref(sd_netlink
*nl
, unsigned group
);
151 int socket_write_message(sd_netlink
*nl
, sd_netlink_message
*m
);
152 int socket_read_message(sd_netlink
*nl
);
154 int netlink_add_match_internal(
156 sd_netlink_slot
**ret_slot
,
157 const uint32_t *groups
,
161 sd_netlink_message_handler_t callback
,
162 sd_netlink_destroy_t destroy_callback
,
164 const char *description
);
166 /* Make sure callbacks don't destroy the netlink connection */
167 #define NETLINK_DONT_DESTROY(nl) \
168 _cleanup_(sd_netlink_unrefp) _unused_ sd_netlink *_dont_destroy_##nl = sd_netlink_ref(nl)
170 bool nfproto_is_valid(int nfproto
);
173 /* TODO: to be exported later */
174 int sd_nfnl_socket_open(sd_netlink
**ret
);
175 int sd_nfnl_send_batch(
177 sd_netlink_message
**messages
,
179 uint32_t **ret_serials
);
180 int sd_nfnl_call_batch(
182 sd_netlink_message
**messages
,
185 sd_netlink_message
***ret_messages
);
186 int sd_nfnl_message_new(
188 sd_netlink_message
**ret
,
193 int sd_nfnl_nft_message_new_table(sd_netlink
*nfnl
, sd_netlink_message
**ret
,
194 int nfproto
, const char *table
);
195 int sd_nfnl_nft_message_new_basechain(sd_netlink
*nfnl
, sd_netlink_message
**ret
,
196 int nfproto
, const char *table
, const char *chain
,
197 const char *type
, uint8_t hook
, int prio
);
198 int sd_nfnl_nft_message_new_rule(sd_netlink
*nfnl
, sd_netlink_message
**ret
,
199 int nfproto
, const char *table
, const char *chain
);
200 int sd_nfnl_nft_message_new_set(sd_netlink
*nfnl
, sd_netlink_message
**ret
,
201 int nfproto
, const char *table
, const char *set_name
,
202 uint32_t setid
, uint32_t klen
);
203 int sd_nfnl_nft_message_new_setelems(sd_netlink
*nfnl
, sd_netlink_message
**ret
,
204 int add
, int nfproto
, const char *table
, const char *set_name
);
205 int sd_nfnl_nft_message_append_setelem(sd_netlink_message
*m
,
207 const void *key
, size_t key_len
,
208 const void *data
, size_t data_len
,