1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
5 #include "sd-netlink.h"
7 #include "alloc-util.h"
8 #include "netlink-internal.h"
9 #include "netlink-slot.h"
10 #include "string-util.h"
12 int netlink_slot_allocate(
18 const char *description
,
19 sd_netlink_slot
**ret
) {
21 _cleanup_free_ sd_netlink_slot
*slot
= NULL
;
26 slot
= malloc0(offsetof(sd_netlink_slot
, reply_callback
) + extra
);
32 slot
->userdata
= userdata
;
34 slot
->floating
= floating
;
37 slot
->description
= strdup(description
);
38 if (!slot
->description
)
45 LIST_PREPEND(slots
, nl
->slots
, slot
);
47 *ret
= TAKE_PTR(slot
);
52 void netlink_slot_disconnect(sd_netlink_slot
*slot
, bool unref
) {
63 case NETLINK_REPLY_CALLBACK
:
64 (void) hashmap_remove(nl
->reply_callbacks
, &slot
->reply_callback
.serial
);
66 if (slot
->reply_callback
.timeout
!= USEC_INFINITY
)
67 prioq_remove(nl
->reply_callbacks_prioq
, &slot
->reply_callback
, &slot
->reply_callback
.prioq_idx
);
70 case NETLINK_MATCH_CALLBACK
:
71 LIST_REMOVE(match_callbacks
, nl
->match_callbacks
, &slot
->match_callback
);
73 for (size_t i
= 0; i
< slot
->match_callback
.n_groups
; i
++)
74 (void) socket_broadcast_group_unref(nl
, slot
->match_callback
.groups
[i
]);
76 slot
->match_callback
.n_groups
= 0;
77 slot
->match_callback
.groups
= mfree(slot
->match_callback
.groups
);
84 slot
->type
= _NETLINK_SLOT_INVALID
;
86 LIST_REMOVE(slots
, nl
->slots
, slot
);
91 sd_netlink_slot_unref(slot
);
94 static sd_netlink_slot
* netlink_slot_free(sd_netlink_slot
*slot
) {
97 netlink_slot_disconnect(slot
, false);
99 if (slot
->destroy_callback
)
100 slot
->destroy_callback(slot
->userdata
);
102 free(slot
->description
);
106 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_netlink_slot
, sd_netlink_slot
, netlink_slot_free
);
108 sd_netlink
*sd_netlink_slot_get_netlink(sd_netlink_slot
*slot
) {
109 assert_return(slot
, NULL
);
111 return slot
->netlink
;
114 void *sd_netlink_slot_get_userdata(sd_netlink_slot
*slot
) {
115 assert_return(slot
, NULL
);
117 return slot
->userdata
;
120 void *sd_netlink_slot_set_userdata(sd_netlink_slot
*slot
, void *userdata
) {
123 assert_return(slot
, NULL
);
125 ret
= slot
->userdata
;
126 slot
->userdata
= userdata
;
131 int sd_netlink_slot_get_destroy_callback(sd_netlink_slot
*slot
, sd_netlink_destroy_t
*callback
) {
132 assert_return(slot
, -EINVAL
);
135 *callback
= slot
->destroy_callback
;
137 return !!slot
->destroy_callback
;
140 int sd_netlink_slot_set_destroy_callback(sd_netlink_slot
*slot
, sd_netlink_destroy_t callback
) {
141 assert_return(slot
, -EINVAL
);
143 slot
->destroy_callback
= callback
;
147 int sd_netlink_slot_get_floating(sd_netlink_slot
*slot
) {
148 assert_return(slot
, -EINVAL
);
150 return slot
->floating
;
153 int sd_netlink_slot_set_floating(sd_netlink_slot
*slot
, int b
) {
154 assert_return(slot
, -EINVAL
);
156 if (slot
->floating
== !!b
)
159 if (!slot
->netlink
) /* Already disconnected */
165 sd_netlink_slot_ref(slot
);
166 sd_netlink_unref(slot
->netlink
);
168 sd_netlink_ref(slot
->netlink
);
169 sd_netlink_slot_unref(slot
);
175 int sd_netlink_slot_get_description(sd_netlink_slot
*slot
, const char **description
) {
176 assert_return(slot
, -EINVAL
);
179 *description
= slot
->description
;
181 return !!slot
->description
;
184 int sd_netlink_slot_set_description(sd_netlink_slot
*slot
, const char *description
) {
185 assert_return(slot
, -EINVAL
);
187 return free_and_strdup(&slot
->description
, description
);