if (r < 0)
return r;
- r = sd_netlink_call_async(rtnl, req, generic_handler, s, LOOPBACK_SETUP_TIMEOUT_USEC, NULL);
+ r = sd_netlink_call_async(rtnl, req, generic_handler, NULL, s, LOOPBACK_SETUP_TIMEOUT_USEC, NULL);
if (r < 0)
return r;
if (r < 0)
return r;
- r = sd_netlink_call_async(rtnl, req, generic_handler, s, USEC_INFINITY, NULL);
+ r = sd_netlink_call_async(rtnl, req, generic_handler, NULL, s, USEC_INFINITY, NULL);
if (r < 0)
return r;
if (r < 0)
return r;
- r = sd_netlink_call_async(rtnl, req, generic_handler, s, USEC_INFINITY, NULL);
+ r = sd_netlink_call_async(rtnl, req, generic_handler, NULL, s, USEC_INFINITY, NULL);
if (r < 0)
return r;
usec_t timeout;
uint64_t serial;
unsigned prioq_idx;
+ sd_netlink_destroy_t destroy_callback;
};
struct match_callback {
}
static sd_netlink *netlink_free(sd_netlink *rtnl) {
+ struct reply_callback *c;
struct match_callback *f;
unsigned i;
free(rtnl->rbuffer);
- hashmap_free_free(rtnl->reply_callbacks);
+ while ((c = hashmap_steal_first(rtnl->reply_callbacks))) {
+ if (c->destroy_callback)
+ c->destroy_callback(c->userdata);
+ free(c);
+ }
+ hashmap_free(rtnl->reply_callbacks);
prioq_free(rtnl->reply_callbacks_prioq);
sd_event_source_unref(rtnl->io_event_source);
if (r < 0)
log_debug_errno(r, "sd-netlink: timedout callback failed: %m");
+ if (c->destroy_callback)
+ c->destroy_callback(c->userdata);
+
free(c);
return 1;
if (r < 0)
log_debug_errno(r, "sd-netlink: callback failed: %m");
+ if (c->destroy_callback)
+ c->destroy_callback(c->userdata);
+
return 1;
}
return CMP(x->timeout, y->timeout);
}
-int sd_netlink_call_async(sd_netlink *nl,
- sd_netlink_message *m,
- sd_netlink_message_handler_t callback,
- void *userdata,
- uint64_t usec,
- uint32_t *serial) {
- struct reply_callback *c;
+int sd_netlink_call_async(
+ sd_netlink *nl,
+ sd_netlink_message *m,
+ sd_netlink_message_handler_t callback,
+ sd_netlink_destroy_t destroy_callback,
+ void *userdata,
+ uint64_t usec,
+ uint32_t *serial) {
+ _cleanup_free_ struct reply_callback *c = NULL;
uint32_t s;
int r, k;
return r;
}
- c = new0(struct reply_callback, 1);
+ c = new(struct reply_callback, 1);
if (!c)
return -ENOMEM;
- c->callback = callback;
- c->userdata = userdata;
- c->timeout = calc_elapse(usec);
+ *c = (struct reply_callback) {
+ .callback = callback,
+ .userdata = userdata,
+ .timeout = calc_elapse(usec),
+ .destroy_callback = destroy_callback,
+ };
k = sd_netlink_send(nl, m, &s);
- if (k < 0) {
- free(c);
+ if (k < 0)
return k;
- }
c->serial = s;
r = hashmap_put(nl->reply_callbacks, &c->serial, c);
- if (r < 0) {
- free(c);
+ if (r < 0)
return r;
- }
if (c->timeout != 0) {
r = prioq_put(nl->reply_callbacks_prioq, c, &c->prioq_idx);
if (r < 0) {
- c->timeout = 0;
- sd_netlink_call_async_cancel(nl, c->serial);
+ (void) hashmap_remove(nl->reply_callbacks, &c->serial);
return r;
}
}
if (serial)
*serial = s;
+ TAKE_PTR(c);
+
return k;
}
if (c->timeout != 0)
prioq_remove(nl->reply_callbacks_prioq, c, &c->prioq_idx);
+ if (c->destroy_callback)
+ c->destroy_callback(c->userdata);
+
free(c);
return 1;
}
assert_se(sd_netlink_open(&rtnl) >= 0);
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
- assert_se(sd_netlink_call_async(rtnl, m, link_handler, ifname, 0, NULL) >= 0);
+ assert_se(sd_netlink_call_async(rtnl, m, link_handler, NULL, ifname, 0, NULL) >= 0);
assert_se(sd_event_default(&event) >= 0);
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
- assert_se(sd_netlink_call_async(rtnl, m, link_handler, ifname, 0, &serial) >= 0);
+ assert_se(sd_netlink_call_async(rtnl, m, link_handler, NULL, ifname, 0, &serial) >= 0);
assert_se(sd_netlink_wait(rtnl, 0) >= 0);
assert_se(sd_netlink_process(rtnl, &r) >= 0);
assert_se(sd_rtnl_message_new_link(rtnl, &m2, RTM_GETLINK, ifindex) >= 0);
counter++;
- assert_se(sd_netlink_call_async(rtnl, m1, pipe_handler, &counter, 0, NULL) >= 0);
+ assert_se(sd_netlink_call_async(rtnl, m1, pipe_handler, NULL, &counter, 0, NULL) >= 0);
counter++;
- assert_se(sd_netlink_call_async(rtnl, m2, pipe_handler, &counter, 0, NULL) >= 0);
+ assert_se(sd_netlink_call_async(rtnl, m2, pipe_handler, NULL, &counter, 0, NULL) >= 0);
while (counter > 0) {
assert_se(sd_netlink_wait(rtnl, 0) >= 0);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
- r = sd_netlink_call_async(netdev->manager->rtnl, req, netdev_bridge_set_handler, netdev, 0, NULL);
+ r = sd_netlink_call_async(netdev->manager->rtnl, req, netdev_bridge_set_handler, NULL, netdev, 0, NULL);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
- r = sd_netlink_call_async(netdev->manager->rtnl, m, geneve_netdev_create_handler, netdev, 0, NULL);
+ r = sd_netlink_call_async(netdev->manager->rtnl, m, geneve_netdev_create_handler, NULL, netdev, 0, NULL);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_MASTER attribute: %m");
- r = sd_netlink_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL);
+ r = sd_netlink_call_async(netdev->manager->rtnl, req, callback, NULL, link, 0, NULL);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
if (link) {
- r = sd_netlink_call_async(netdev->manager->rtnl, m, callback, link, 0, NULL);
+ r = sd_netlink_call_async(netdev->manager->rtnl, m, callback, NULL, link, 0, NULL);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
link_ref(link);
} else {
- r = sd_netlink_call_async(netdev->manager->rtnl, m, netdev_create_handler, netdev, 0, NULL);
+ r = sd_netlink_call_async(netdev->manager->rtnl, m, netdev_create_handler, NULL, netdev, 0, NULL);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
if (r < 0)
return log_error_errno(r, "Could not append IFA_ADDRESS attribute: %m");
- r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
+ r = sd_netlink_call_async(link->manager->rtnl, req, callback, NULL, link, 0, NULL);
if (r < 0)
return log_error_errno(r, "Could not send rtnetlink message: %m");
if (r < 0)
return log_error_errno(r, "Could not append IFA_LOCAL attribute: %m");
- r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
+ r = sd_netlink_call_async(link->manager->rtnl, req, callback, NULL, link, 0, NULL);
if (r < 0)
return log_error_errno(r, "Could not send rtnetlink message: %m");
if (r < 0)
return r;
- r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
+ r = sd_netlink_call_async(link->manager->rtnl, req, callback, NULL, link, 0, NULL);
if (r < 0) {
address_release(address);
return log_error_errno(r, "Could not send rtnetlink message: %m");
return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
/* send message to the kernel */
- r = sd_netlink_call_async(rtnl, req, set_brvlan_handler, link, 0, NULL);
+ r = sd_netlink_call_async(rtnl, req, set_brvlan_handler, NULL, link, 0, NULL);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
}
/* send message to the kernel to update its internal static MAC table. */
- r = sd_netlink_call_async(rtnl, req, set_fdb_handler, link, 0, NULL);
+ r = sd_netlink_call_async(rtnl, req, set_fdb_handler, NULL, link, 0, NULL);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
if (r < 0)
return rtnl_log_create_error(r);
- r = sd_netlink_call_async(rtnl, req, set_ipv6_proxy_ndp_address_handler, link, 0, NULL);
+ r = sd_netlink_call_async(rtnl, req, set_ipv6_proxy_ndp_address_handler, NULL, link, 0, NULL);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
if (r < 0)
return log_link_error_errno(link, r, "Could not append MTU: %m");
- r = sd_netlink_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
+ r = sd_netlink_call_async(link->manager->rtnl, req, set_mtu_handler, NULL, link, 0, NULL);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
if (r < 0)
return log_link_error_errno(link, r, "Could not set link flags: %m");
- r = sd_netlink_call_async(link->manager->rtnl, req, set_flags_handler, link, 0, NULL);
+ r = sd_netlink_call_async(link->manager->rtnl, req, set_flags_handler, NULL, link, 0, NULL);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
- r = sd_netlink_call_async(link->manager->rtnl, req, link_set_handler, link, 0, NULL);
+ r = sd_netlink_call_async(link->manager->rtnl, req, link_set_handler, NULL, link, 0, NULL);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
- r = sd_netlink_call_async(link->manager->rtnl, req, set_flags_handler, link, 0, NULL);
+ r = sd_netlink_call_async(link->manager->rtnl, req, set_flags_handler, NULL, link, 0, NULL);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
if (r < 0)
return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
- r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
+ r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, NULL, link, 0, NULL);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
if (r < 0)
return log_link_error_errno(link, r, "Could not set link flags: %m");
- r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
+ r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, NULL, link, 0, NULL);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
if (r < 0)
return log_link_error_errno(link, r, "Failed to close netlink container: %m");
- r = sd_netlink_call_async(link->manager->rtnl, m, link_set_handler, link, 0, NULL);
+ r = sd_netlink_call_async(link->manager->rtnl, m, link_set_handler, NULL, link, 0, NULL);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
if (r < 0)
return log_link_error_errno(link, r, "Could not set link flags: %m");
- r = sd_netlink_call_async(link->manager->rtnl, req, link_down_handler, link, 0, NULL);
+ r = sd_netlink_call_async(link->manager->rtnl, req, link_down_handler, NULL, link, 0, NULL);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
return r;
r = sd_netlink_call_async(link->manager->rtnl, req,
- link_initialized_and_synced, link, 0, NULL);
+ link_initialized_and_synced,
+ NULL, link, 0, NULL);
if (r < 0)
return r;
return log_error_errno(r, "Could not append RTA_OIF attribute: %m");
}
- r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
+ r = sd_netlink_call_async(link->manager->rtnl, req, callback, NULL, link, 0, NULL);
if (r < 0)
return log_error_errno(r, "Could not send rtnetlink message: %m");
if (r < 0)
return log_error_errno(r, "Could not append RTA_METRICS attribute: %m");
- r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
+ r = sd_netlink_call_async(link->manager->rtnl, req, callback, NULL, link, 0, NULL);
if (r < 0)
return log_error_errno(r, "Could not send rtnetlink message: %m");
return log_error_errno(r, "Could not set destination prefix length: %m");
}
- r = sd_netlink_call_async(link->manager->rtnl, m, callback, link, 0, NULL);
+ r = sd_netlink_call_async(link->manager->rtnl, m, callback, NULL, link, 0, NULL);
if (r < 0)
return log_error_errno(r, "Could not send rtnetlink message: %m");
rule->link = link;
- r = sd_netlink_call_async(link->manager->rtnl, m, callback, link, 0, NULL);
+ r = sd_netlink_call_async(link->manager->rtnl, m, callback, NULL, link, 0, NULL);
if (r < 0)
return log_error_errno(r, "Could not send rtnetlink message: %m");
/* callback */
typedef int (*sd_netlink_message_handler_t)(sd_netlink *nl, sd_netlink_message *m, void *userdata);
+typedef void (*sd_netlink_destroy_t)(void *userdata);
/* bus */
int sd_netlink_new_from_netlink(sd_netlink **nl, int fd);
int sd_netlink_send(sd_netlink *nl, sd_netlink_message *message, uint32_t *serial);
int sd_netlink_call_async(sd_netlink *nl, sd_netlink_message *message,
- sd_netlink_message_handler_t callback,
- void *userdata, uint64_t usec, uint32_t *serial);
+ sd_netlink_message_handler_t callback,
+ sd_netlink_destroy_t destoy_callback,
+ void *userdata, uint64_t usec, uint32_t *serial);
int sd_netlink_call_async_cancel(sd_netlink *nl, uint32_t serial);
int sd_netlink_call(sd_netlink *nl, sd_netlink_message *message, uint64_t timeout,
- sd_netlink_message **reply);
+ sd_netlink_message **reply);
int sd_netlink_get_events(sd_netlink *nl);
int sd_netlink_get_timeout(sd_netlink *nl, uint64_t *timeout);