1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <linux/netlink.h>
6 #include "sd-netlink.h"
9 #include "netlink-types.h"
11 #include "time-util.h"
13 #define RTNL_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC))
15 #define RTNL_RQUEUE_MAX 64*1024
17 #define RTNL_CONTAINER_DEPTH 32
19 struct reply_callback
{
20 sd_netlink_message_handler_t callback
;
26 struct match_callback
{
27 sd_netlink_message_handler_t callback
;
30 LIST_FIELDS(struct match_callback
, match_callbacks
);
33 typedef enum NetlinkSlotType
{
34 NETLINK_REPLY_CALLBACK
,
35 NETLINK_MATCH_CALLBACK
,
36 _NETLINK_SLOT_INVALID
= -EINVAL
,
39 struct sd_netlink_slot
{
41 NetlinkSlotType type
:8;
45 sd_netlink_destroy_t destroy_callback
;
49 LIST_FIELDS(sd_netlink_slot
, slots
);
52 struct reply_callback reply_callback
;
53 struct match_callback match_callback
;
64 struct sockaddr_nl nl
;
69 Hashmap
*broadcast_group_refs
;
70 bool broadcast_group_dont_leave
:1; /* until we can rely on 4.2 */
72 sd_netlink_message
**rqueue
;
74 size_t rqueue_allocated
;
76 sd_netlink_message
**rqueue_partial
;
77 unsigned rqueue_partial_size
;
78 size_t rqueue_partial_allocated
;
80 struct nlmsghdr
*rbuffer
;
81 size_t rbuffer_allocated
;
87 struct Prioq
*reply_callbacks_prioq
;
88 Hashmap
*reply_callbacks
;
90 LIST_HEAD(struct match_callback
, match_callbacks
);
92 LIST_HEAD(sd_netlink_slot
, slots
);
96 sd_event_source
*io_event_source
;
97 sd_event_source
*time_event_source
;
98 sd_event_source
*exit_event_source
;
101 Hashmap
*genl_family_to_nlmsg_type
;
102 Hashmap
*nlmsg_type_to_genl_family
;
105 struct netlink_attribute
{
106 size_t offset
; /* offset from hdr to attribute */
108 bool net_byteorder
:1;
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 */
118 struct sd_netlink_message
{
123 struct nlmsghdr
*hdr
;
124 struct netlink_container containers
[RTNL_CONTAINER_DEPTH
];
125 unsigned n_containers
; /* number of containers */
129 sd_netlink_message
*next
; /* next in a chain of multi-part messages */
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
);
135 int netlink_open_family(sd_netlink
**ret
, int family
);
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
);
145 int rtnl_rqueue_make_room(sd_netlink
*rtnl
);
146 int rtnl_rqueue_partial_make_room(sd_netlink
*rtnl
);
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)