sd-netlink: introduce sd_netlink_slot
This commit is contained in:
parent
0c40d13a07
commit
ee38400bba
|
@ -53,7 +53,7 @@ static int start_loopback(sd_netlink *rtnl, struct state *s) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_call_async(rtnl, req, generic_handler, NULL, s, LOOPBACK_SETUP_TIMEOUT_USEC, NULL);
|
r = sd_netlink_call_async(rtnl, NULL, req, generic_handler, NULL, s, LOOPBACK_SETUP_TIMEOUT_USEC);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ static int add_ipv4_address(sd_netlink *rtnl, struct state *s) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_call_async(rtnl, req, generic_handler, NULL, s, USEC_INFINITY, NULL);
|
r = sd_netlink_call_async(rtnl, NULL, req, generic_handler, NULL, s, USEC_INFINITY);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ static int add_ipv6_address(sd_netlink *rtnl, struct state *s) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_call_async(rtnl, req, generic_handler, NULL, s, USEC_INFINITY, NULL);
|
r = sd_netlink_call_async(rtnl, NULL, req, generic_handler, NULL, s, USEC_INFINITY);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,8 @@ libsystemd_sources = files('''
|
||||||
sd-netlink/local-addresses.h
|
sd-netlink/local-addresses.h
|
||||||
sd-netlink/netlink-internal.h
|
sd-netlink/netlink-internal.h
|
||||||
sd-netlink/netlink-message.c
|
sd-netlink/netlink-message.c
|
||||||
|
sd-netlink/netlink-slot.c
|
||||||
|
sd-netlink/netlink-slot.h
|
||||||
sd-netlink/netlink-socket.c
|
sd-netlink/netlink-socket.c
|
||||||
sd-netlink/netlink-types.c
|
sd-netlink/netlink-types.c
|
||||||
sd-netlink/netlink-types.h
|
sd-netlink/netlink-types.h
|
||||||
|
|
|
@ -19,21 +19,41 @@
|
||||||
|
|
||||||
struct reply_callback {
|
struct reply_callback {
|
||||||
sd_netlink_message_handler_t callback;
|
sd_netlink_message_handler_t callback;
|
||||||
void *userdata;
|
|
||||||
usec_t timeout;
|
usec_t timeout;
|
||||||
uint64_t serial;
|
uint64_t serial;
|
||||||
unsigned prioq_idx;
|
unsigned prioq_idx;
|
||||||
sd_netlink_destroy_t destroy_callback;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct match_callback {
|
struct match_callback {
|
||||||
sd_netlink_message_handler_t callback;
|
sd_netlink_message_handler_t callback;
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
void *userdata;
|
|
||||||
|
|
||||||
LIST_FIELDS(struct match_callback, match_callbacks);
|
LIST_FIELDS(struct match_callback, match_callbacks);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum NetlinkSlotType {
|
||||||
|
NETLINK_REPLY_CALLBACK,
|
||||||
|
NETLINK_MATCH_CALLBACK,
|
||||||
|
_NETLINK_SLOT_INVALID = -1,
|
||||||
|
} NetlinkSlotType;
|
||||||
|
|
||||||
|
struct sd_netlink_slot {
|
||||||
|
unsigned n_ref;
|
||||||
|
sd_netlink *netlink;
|
||||||
|
void *userdata;
|
||||||
|
sd_netlink_destroy_t destroy_callback;
|
||||||
|
NetlinkSlotType type:2;
|
||||||
|
|
||||||
|
bool floating:1;
|
||||||
|
|
||||||
|
LIST_FIELDS(sd_netlink_slot, slots);
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct reply_callback reply_callback;
|
||||||
|
struct match_callback match_callback;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
struct sd_netlink {
|
struct sd_netlink {
|
||||||
RefCount n_ref;
|
RefCount n_ref;
|
||||||
|
|
||||||
|
@ -69,6 +89,8 @@ struct sd_netlink {
|
||||||
|
|
||||||
LIST_HEAD(struct match_callback, match_callbacks);
|
LIST_HEAD(struct match_callback, match_callbacks);
|
||||||
|
|
||||||
|
LIST_HEAD(sd_netlink_slot, slots);
|
||||||
|
|
||||||
pid_t original_pid;
|
pid_t original_pid;
|
||||||
|
|
||||||
sd_event_source *io_event_source;
|
sd_event_source *io_event_source;
|
||||||
|
|
109
src/libsystemd/sd-netlink/netlink-slot.c
Normal file
109
src/libsystemd/sd-netlink/netlink-slot.c
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "sd-netlink.h"
|
||||||
|
|
||||||
|
#include "alloc-util.h"
|
||||||
|
#include "netlink-internal.h"
|
||||||
|
#include "netlink-slot.h"
|
||||||
|
|
||||||
|
sd_netlink_slot *netlink_slot_allocate(
|
||||||
|
sd_netlink *nl,
|
||||||
|
bool floating,
|
||||||
|
NetlinkSlotType type,
|
||||||
|
size_t extra,
|
||||||
|
sd_netlink_destroy_t destroy_callback,
|
||||||
|
void *userdata) {
|
||||||
|
|
||||||
|
sd_netlink_slot *slot;
|
||||||
|
|
||||||
|
assert(nl);
|
||||||
|
|
||||||
|
slot = malloc0(offsetof(sd_netlink_slot, reply_callback) + extra);
|
||||||
|
if (!slot)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
slot->n_ref = 1;
|
||||||
|
slot->netlink = nl;
|
||||||
|
slot->userdata = userdata;
|
||||||
|
slot->destroy_callback = destroy_callback;
|
||||||
|
slot->type = type;
|
||||||
|
slot->floating = floating;
|
||||||
|
|
||||||
|
if (!floating)
|
||||||
|
sd_netlink_ref(nl);
|
||||||
|
|
||||||
|
LIST_PREPEND(slots, nl->slots, slot);
|
||||||
|
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
void netlink_slot_disconnect(sd_netlink_slot *slot, bool unref) {
|
||||||
|
sd_netlink *nl;
|
||||||
|
|
||||||
|
assert(slot);
|
||||||
|
|
||||||
|
nl = slot->netlink;
|
||||||
|
if (!nl)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (slot->type) {
|
||||||
|
|
||||||
|
case NETLINK_REPLY_CALLBACK:
|
||||||
|
(void) hashmap_remove(nl->reply_callbacks, &slot->reply_callback.serial);
|
||||||
|
|
||||||
|
if (slot->reply_callback.timeout != 0)
|
||||||
|
prioq_remove(nl->reply_callbacks_prioq, &slot->reply_callback, &slot->reply_callback.prioq_idx);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case NETLINK_MATCH_CALLBACK:
|
||||||
|
LIST_REMOVE(match_callbacks, nl->match_callbacks, &slot->match_callback);
|
||||||
|
|
||||||
|
switch (slot->match_callback.type) {
|
||||||
|
case RTM_NEWLINK:
|
||||||
|
case RTM_DELLINK:
|
||||||
|
(void) socket_broadcast_group_unref(nl, RTNLGRP_LINK);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case RTM_NEWADDR:
|
||||||
|
case RTM_DELADDR:
|
||||||
|
(void) socket_broadcast_group_unref(nl, RTNLGRP_IPV4_IFADDR);
|
||||||
|
(void) socket_broadcast_group_unref(nl, RTNLGRP_IPV6_IFADDR);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case RTM_NEWROUTE:
|
||||||
|
case RTM_DELROUTE:
|
||||||
|
(void) socket_broadcast_group_unref(nl, RTNLGRP_IPV4_ROUTE);
|
||||||
|
(void) socket_broadcast_group_unref(nl, RTNLGRP_IPV6_ROUTE);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert_not_reached("Wut? Unknown slot type?");
|
||||||
|
}
|
||||||
|
|
||||||
|
slot->type = _NETLINK_SLOT_INVALID;
|
||||||
|
slot->netlink = NULL;
|
||||||
|
LIST_REMOVE(slots, nl->slots, slot);
|
||||||
|
|
||||||
|
if (!slot->floating)
|
||||||
|
sd_netlink_unref(nl);
|
||||||
|
else if (unref)
|
||||||
|
sd_netlink_slot_unref(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
static sd_netlink_slot* netlink_slot_free(sd_netlink_slot *slot) {
|
||||||
|
assert(slot);
|
||||||
|
|
||||||
|
netlink_slot_disconnect(slot, false);
|
||||||
|
|
||||||
|
if (slot->destroy_callback)
|
||||||
|
slot->destroy_callback(slot->userdata);
|
||||||
|
|
||||||
|
return mfree(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_netlink_slot, sd_netlink_slot, netlink_slot_free);
|
13
src/libsystemd/sd-netlink/netlink-slot.h
Normal file
13
src/libsystemd/sd-netlink/netlink-slot.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sd-netlink.h"
|
||||||
|
|
||||||
|
sd_netlink_slot *netlink_slot_allocate(
|
||||||
|
sd_netlink *nl,
|
||||||
|
bool floating,
|
||||||
|
NetlinkSlotType type,
|
||||||
|
size_t extra,
|
||||||
|
sd_netlink_destroy_t destroy_callback,
|
||||||
|
void *userdata);
|
||||||
|
void netlink_slot_disconnect(sd_netlink_slot *slot, bool unref);
|
|
@ -11,6 +11,7 @@
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "missing.h"
|
#include "missing.h"
|
||||||
#include "netlink-internal.h"
|
#include "netlink-internal.h"
|
||||||
|
#include "netlink-slot.h"
|
||||||
#include "netlink-util.h"
|
#include "netlink-util.h"
|
||||||
#include "process-util.h"
|
#include "process-util.h"
|
||||||
#include "socket-util.h"
|
#include "socket-util.h"
|
||||||
|
@ -148,8 +149,7 @@ int sd_netlink_inc_rcvbuf(sd_netlink *rtnl, size_t size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static sd_netlink *netlink_free(sd_netlink *rtnl) {
|
static sd_netlink *netlink_free(sd_netlink *rtnl) {
|
||||||
struct reply_callback *c;
|
sd_netlink_slot *s;
|
||||||
struct match_callback *f;
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
assert(rtnl);
|
assert(rtnl);
|
||||||
|
@ -164,10 +164,9 @@ static sd_netlink *netlink_free(sd_netlink *rtnl) {
|
||||||
|
|
||||||
free(rtnl->rbuffer);
|
free(rtnl->rbuffer);
|
||||||
|
|
||||||
while ((c = hashmap_steal_first(rtnl->reply_callbacks))) {
|
while ((s = rtnl->slots)) {
|
||||||
if (c->destroy_callback)
|
assert(s->floating);
|
||||||
c->destroy_callback(c->userdata);
|
netlink_slot_disconnect(s, true);
|
||||||
free(c);
|
|
||||||
}
|
}
|
||||||
hashmap_free(rtnl->reply_callbacks);
|
hashmap_free(rtnl->reply_callbacks);
|
||||||
prioq_free(rtnl->reply_callbacks_prioq);
|
prioq_free(rtnl->reply_callbacks_prioq);
|
||||||
|
@ -176,9 +175,6 @@ static sd_netlink *netlink_free(sd_netlink *rtnl) {
|
||||||
sd_event_source_unref(rtnl->time_event_source);
|
sd_event_source_unref(rtnl->time_event_source);
|
||||||
sd_event_unref(rtnl->event);
|
sd_event_unref(rtnl->event);
|
||||||
|
|
||||||
while ((f = rtnl->match_callbacks))
|
|
||||||
sd_netlink_remove_match(rtnl, f->type, f->callback, f->userdata);
|
|
||||||
|
|
||||||
hashmap_free(rtnl->broadcast_group_refs);
|
hashmap_free(rtnl->broadcast_group_refs);
|
||||||
|
|
||||||
safe_close(rtnl->fd);
|
safe_close(rtnl->fd);
|
||||||
|
@ -281,6 +277,7 @@ static int dispatch_rqueue(sd_netlink *rtnl, sd_netlink_message **message) {
|
||||||
static int process_timeout(sd_netlink *rtnl) {
|
static int process_timeout(sd_netlink *rtnl) {
|
||||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||||
struct reply_callback *c;
|
struct reply_callback *c;
|
||||||
|
sd_netlink_slot *slot;
|
||||||
usec_t n;
|
usec_t n;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -299,22 +296,24 @@ static int process_timeout(sd_netlink *rtnl) {
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
assert_se(prioq_pop(rtnl->reply_callbacks_prioq) == c);
|
assert_se(prioq_pop(rtnl->reply_callbacks_prioq) == c);
|
||||||
|
c->timeout = 0;
|
||||||
hashmap_remove(rtnl->reply_callbacks, &c->serial);
|
hashmap_remove(rtnl->reply_callbacks, &c->serial);
|
||||||
|
|
||||||
r = c->callback(rtnl, m, c->userdata);
|
slot = container_of(c, sd_netlink_slot, reply_callback);
|
||||||
|
|
||||||
|
r = c->callback(rtnl, m, slot->userdata);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_debug_errno(r, "sd-netlink: timedout callback failed: %m");
|
log_debug_errno(r, "sd-netlink: timedout callback failed: %m");
|
||||||
|
|
||||||
if (c->destroy_callback)
|
if (slot->floating)
|
||||||
c->destroy_callback(c->userdata);
|
netlink_slot_disconnect(slot, true);
|
||||||
|
|
||||||
free(c);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_reply(sd_netlink *rtnl, sd_netlink_message *m) {
|
static int process_reply(sd_netlink *rtnl, sd_netlink_message *m) {
|
||||||
_cleanup_free_ struct reply_callback *c = NULL;
|
struct reply_callback *c;
|
||||||
|
sd_netlink_slot *slot;
|
||||||
uint64_t serial;
|
uint64_t serial;
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
int r;
|
int r;
|
||||||
|
@ -327,28 +326,33 @@ static int process_reply(sd_netlink *rtnl, sd_netlink_message *m) {
|
||||||
if (!c)
|
if (!c)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (c->timeout != 0)
|
if (c->timeout != 0) {
|
||||||
prioq_remove(rtnl->reply_callbacks_prioq, c, &c->prioq_idx);
|
prioq_remove(rtnl->reply_callbacks_prioq, c, &c->prioq_idx);
|
||||||
|
c->timeout = 0;
|
||||||
|
}
|
||||||
|
|
||||||
r = sd_netlink_message_get_type(m, &type);
|
r = sd_netlink_message_get_type(m, &type);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return 0;
|
return r;
|
||||||
|
|
||||||
if (type == NLMSG_DONE)
|
if (type == NLMSG_DONE)
|
||||||
m = NULL;
|
m = NULL;
|
||||||
|
|
||||||
r = c->callback(rtnl, m, c->userdata);
|
slot = container_of(c, sd_netlink_slot, reply_callback);
|
||||||
|
|
||||||
|
r = c->callback(rtnl, m, slot->userdata);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_debug_errno(r, "sd-netlink: callback failed: %m");
|
log_debug_errno(r, "sd-netlink: callback failed: %m");
|
||||||
|
|
||||||
if (c->destroy_callback)
|
if (slot->floating)
|
||||||
c->destroy_callback(c->userdata);
|
netlink_slot_disconnect(slot, true);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_match(sd_netlink *rtnl, sd_netlink_message *m) {
|
static int process_match(sd_netlink *rtnl, sd_netlink_message *m) {
|
||||||
struct match_callback *c;
|
struct match_callback *c;
|
||||||
|
sd_netlink_slot *slot;
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -361,7 +365,9 @@ static int process_match(sd_netlink *rtnl, sd_netlink_message *m) {
|
||||||
|
|
||||||
LIST_FOREACH(match_callbacks, c, rtnl->match_callbacks) {
|
LIST_FOREACH(match_callbacks, c, rtnl->match_callbacks) {
|
||||||
if (type == c->type) {
|
if (type == c->type) {
|
||||||
r = c->callback(rtnl, m, c->userdata);
|
slot = container_of(c, sd_netlink_slot, match_callback);
|
||||||
|
|
||||||
|
r = c->callback(rtnl, m, slot->userdata);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_debug_errno(r, "sd-netlink: match callback failed: %m");
|
log_debug_errno(r, "sd-netlink: match callback failed: %m");
|
||||||
|
@ -508,13 +514,13 @@ static int timeout_compare(const void *a, const void *b) {
|
||||||
|
|
||||||
int sd_netlink_call_async(
|
int sd_netlink_call_async(
|
||||||
sd_netlink *nl,
|
sd_netlink *nl,
|
||||||
|
sd_netlink_slot **ret_slot,
|
||||||
sd_netlink_message *m,
|
sd_netlink_message *m,
|
||||||
sd_netlink_message_handler_t callback,
|
sd_netlink_message_handler_t callback,
|
||||||
sd_netlink_destroy_t destroy_callback,
|
sd_netlink_destroy_t destroy_callback,
|
||||||
void *userdata,
|
void *userdata,
|
||||||
uint64_t usec,
|
uint64_t usec) {
|
||||||
uint32_t *serial) {
|
_cleanup_free_ sd_netlink_slot *slot = NULL;
|
||||||
_cleanup_free_ struct reply_callback *c = NULL;
|
|
||||||
uint32_t s;
|
uint32_t s;
|
||||||
int r, k;
|
int r, k;
|
||||||
|
|
||||||
|
@ -533,65 +539,39 @@ int sd_netlink_call_async(
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
c = new(struct reply_callback, 1);
|
slot = netlink_slot_allocate(nl, !ret_slot, NETLINK_REPLY_CALLBACK, sizeof(struct reply_callback), destroy_callback, userdata);
|
||||||
if (!c)
|
if (!slot)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
*c = (struct reply_callback) {
|
slot->reply_callback.callback = callback;
|
||||||
.callback = callback,
|
slot->reply_callback.timeout = calc_elapse(usec);
|
||||||
.userdata = userdata,
|
|
||||||
.timeout = calc_elapse(usec),
|
|
||||||
.destroy_callback = destroy_callback,
|
|
||||||
};
|
|
||||||
|
|
||||||
k = sd_netlink_send(nl, m, &s);
|
k = sd_netlink_send(nl, m, &s);
|
||||||
if (k < 0)
|
if (k < 0)
|
||||||
return k;
|
return k;
|
||||||
|
|
||||||
c->serial = s;
|
slot->reply_callback.serial = s;
|
||||||
|
|
||||||
r = hashmap_put(nl->reply_callbacks, &c->serial, c);
|
r = hashmap_put(nl->reply_callbacks, &slot->reply_callback.serial, &slot->reply_callback);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (c->timeout != 0) {
|
if (slot->reply_callback.timeout != 0) {
|
||||||
r = prioq_put(nl->reply_callbacks_prioq, c, &c->prioq_idx);
|
r = prioq_put(nl->reply_callbacks_prioq, &slot->reply_callback, &slot->reply_callback.prioq_idx);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
(void) hashmap_remove(nl->reply_callbacks, &c->serial);
|
(void) hashmap_remove(nl->reply_callbacks, &slot->reply_callback.serial);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serial)
|
if (ret_slot)
|
||||||
*serial = s;
|
*ret_slot = slot;
|
||||||
|
|
||||||
TAKE_PTR(c);
|
TAKE_PTR(slot);
|
||||||
|
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_netlink_call_async_cancel(sd_netlink *nl, uint32_t serial) {
|
|
||||||
struct reply_callback *c;
|
|
||||||
uint64_t s = serial;
|
|
||||||
|
|
||||||
assert_return(nl, -EINVAL);
|
|
||||||
assert_return(serial != 0, -EINVAL);
|
|
||||||
assert_return(!rtnl_pid_changed(nl), -ECHILD);
|
|
||||||
|
|
||||||
c = hashmap_remove(nl->reply_callbacks, &s);
|
|
||||||
if (!c)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sd_netlink_call(sd_netlink *rtnl,
|
int sd_netlink_call(sd_netlink *rtnl,
|
||||||
sd_netlink_message *message,
|
sd_netlink_message *message,
|
||||||
uint64_t usec,
|
uint64_t usec,
|
||||||
|
@ -834,26 +814,26 @@ int sd_netlink_detach_event(sd_netlink *rtnl) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_netlink_add_match(sd_netlink *rtnl,
|
int sd_netlink_add_match(
|
||||||
uint16_t type,
|
sd_netlink *rtnl,
|
||||||
sd_netlink_message_handler_t callback,
|
sd_netlink_slot **ret_slot,
|
||||||
void *userdata) {
|
uint16_t type,
|
||||||
_cleanup_free_ struct match_callback *c = NULL;
|
sd_netlink_message_handler_t callback,
|
||||||
|
sd_netlink_destroy_t destroy_callback,
|
||||||
|
void *userdata) {
|
||||||
|
_cleanup_free_ sd_netlink_slot *slot = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert_return(rtnl, -EINVAL);
|
assert_return(rtnl, -EINVAL);
|
||||||
assert_return(callback, -EINVAL);
|
assert_return(callback, -EINVAL);
|
||||||
assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
|
assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
|
||||||
|
|
||||||
c = new(struct match_callback, 1);
|
slot = netlink_slot_allocate(rtnl, !ret_slot, NETLINK_MATCH_CALLBACK, sizeof(struct match_callback), destroy_callback, userdata);
|
||||||
if (!c)
|
if (!slot)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
*c = (struct match_callback) {
|
slot->match_callback.callback = callback;
|
||||||
.callback = callback,
|
slot->match_callback.type = type;
|
||||||
.type = type,
|
|
||||||
.userdata = userdata,
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case RTM_NEWLINK:
|
case RTM_NEWLINK:
|
||||||
|
@ -898,64 +878,12 @@ int sd_netlink_add_match(sd_netlink *rtnl,
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
LIST_PREPEND(match_callbacks, rtnl->match_callbacks, c);
|
LIST_PREPEND(match_callbacks, rtnl->match_callbacks, &slot->match_callback);
|
||||||
|
|
||||||
c = NULL;
|
if (ret_slot)
|
||||||
|
*ret_slot = slot;
|
||||||
return 0;
|
|
||||||
}
|
TAKE_PTR(slot);
|
||||||
|
|
||||||
int sd_netlink_remove_match(sd_netlink *rtnl,
|
|
||||||
uint16_t type,
|
|
||||||
sd_netlink_message_handler_t callback,
|
|
||||||
void *userdata) {
|
|
||||||
struct match_callback *c;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert_return(rtnl, -EINVAL);
|
|
||||||
assert_return(callback, -EINVAL);
|
|
||||||
assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
|
|
||||||
|
|
||||||
LIST_FOREACH(match_callbacks, c, rtnl->match_callbacks)
|
|
||||||
if (c->callback == callback && c->type == type && c->userdata == userdata) {
|
|
||||||
LIST_REMOVE(match_callbacks, rtnl->match_callbacks, c);
|
|
||||||
free(c);
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case RTM_NEWLINK:
|
|
||||||
case RTM_DELLINK:
|
|
||||||
r = socket_broadcast_group_unref(rtnl, RTNLGRP_LINK);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case RTM_NEWADDR:
|
|
||||||
case RTM_DELADDR:
|
|
||||||
r = socket_broadcast_group_unref(rtnl, RTNLGRP_IPV4_IFADDR);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = socket_broadcast_group_unref(rtnl, RTNLGRP_IPV6_IFADDR);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case RTM_NEWROUTE:
|
|
||||||
case RTM_DELROUTE:
|
|
||||||
r = socket_broadcast_group_unref(rtnl, RTNLGRP_IPV4_ROUTE);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = socket_broadcast_group_unref(rtnl, RTNLGRP_IPV6_ROUTE);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,7 +201,7 @@ static void test_event_loop(int ifindex) {
|
||||||
assert_se(sd_netlink_open(&rtnl) >= 0);
|
assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
||||||
|
|
||||||
assert_se(sd_netlink_call_async(rtnl, m, link_handler, NULL, ifname, 0, NULL) >= 0);
|
assert_se(sd_netlink_call_async(rtnl, NULL, m, link_handler, NULL, ifname, 0) >= 0);
|
||||||
|
|
||||||
assert_se(sd_event_default(&event) >= 0);
|
assert_se(sd_event_default(&event) >= 0);
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ static void test_event_loop(int ifindex) {
|
||||||
static void test_async(int ifindex) {
|
static void test_async(int ifindex) {
|
||||||
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *r = NULL;
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *r = NULL;
|
||||||
uint32_t serial;
|
_cleanup_(sd_netlink_slot_unrefp) sd_netlink_slot *slot = NULL;
|
||||||
char *ifname;
|
char *ifname;
|
||||||
|
|
||||||
ifname = strdup("lo");
|
ifname = strdup("lo");
|
||||||
|
@ -227,7 +227,7 @@ static void test_async(int ifindex) {
|
||||||
|
|
||||||
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
||||||
|
|
||||||
assert_se(sd_netlink_call_async(rtnl, m, link_handler, NULL, ifname, 0, &serial) >= 0);
|
assert_se(sd_netlink_call_async(rtnl, &slot, m, link_handler, NULL, ifname, 0) >= 0);
|
||||||
|
|
||||||
assert_se(sd_netlink_wait(rtnl, 0) >= 0);
|
assert_se(sd_netlink_wait(rtnl, 0) >= 0);
|
||||||
assert_se(sd_netlink_process(rtnl, &r) >= 0);
|
assert_se(sd_netlink_process(rtnl, &r) >= 0);
|
||||||
|
@ -279,7 +279,7 @@ static void test_async_destroy_callback(int ifindex) {
|
||||||
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *r = NULL;
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *r = NULL;
|
||||||
_cleanup_(test_async_object_unrefp) struct test_async_object *t = NULL;
|
_cleanup_(test_async_object_unrefp) struct test_async_object *t = NULL;
|
||||||
uint32_t serial;
|
_cleanup_(sd_netlink_slot_unrefp) sd_netlink_slot *slot = NULL;
|
||||||
char *ifname;
|
char *ifname;
|
||||||
|
|
||||||
assert_se(t = new(struct test_async_object, 1));
|
assert_se(t = new(struct test_async_object, 1));
|
||||||
|
@ -293,7 +293,7 @@ static void test_async_destroy_callback(int ifindex) {
|
||||||
|
|
||||||
/* destroy callback is called after processing message */
|
/* destroy callback is called after processing message */
|
||||||
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
||||||
assert_se(sd_netlink_call_async(rtnl, m, link_handler2, test_async_object_destroy, t, 0, &serial) >= 0);
|
assert_se(sd_netlink_call_async(rtnl, NULL, m, link_handler2, test_async_object_destroy, t, 0) >= 0);
|
||||||
|
|
||||||
assert_se(t->n_ref == 1);
|
assert_se(t->n_ref == 1);
|
||||||
assert_se(test_async_object_ref(t));
|
assert_se(test_async_object_ref(t));
|
||||||
|
@ -305,22 +305,22 @@ static void test_async_destroy_callback(int ifindex) {
|
||||||
|
|
||||||
assert_se(!sd_netlink_message_unref(m));
|
assert_se(!sd_netlink_message_unref(m));
|
||||||
|
|
||||||
/* destroy callback is called when asynchronous call is cancelled */
|
/* destroy callback is called when asynchronous call is cancelled, that is, slot is freed. */
|
||||||
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
||||||
assert_se(sd_netlink_call_async(rtnl, m, link_handler2, test_async_object_destroy, t, 0, &serial) >= 0);
|
assert_se(sd_netlink_call_async(rtnl, &slot, m, link_handler2, test_async_object_destroy, t, 0) >= 0);
|
||||||
|
|
||||||
assert_se(t->n_ref == 1);
|
assert_se(t->n_ref == 1);
|
||||||
assert_se(test_async_object_ref(t));
|
assert_se(test_async_object_ref(t));
|
||||||
assert_se(t->n_ref == 2);
|
assert_se(t->n_ref == 2);
|
||||||
|
|
||||||
assert_se(sd_netlink_call_async_cancel(rtnl, serial) >= 0);
|
assert_se(!(slot = sd_netlink_slot_unref(slot)));
|
||||||
assert_se(t->n_ref == 1);
|
assert_se(t->n_ref == 1);
|
||||||
|
|
||||||
assert_se(!sd_netlink_message_unref(m));
|
assert_se(!sd_netlink_message_unref(m));
|
||||||
|
|
||||||
/* destroy callback is also called by sd_netlink_unref() */
|
/* destroy callback is also called by sd_netlink_unref() */
|
||||||
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
|
||||||
assert_se(sd_netlink_call_async(rtnl, m, link_handler2, test_async_object_destroy, t, 0, &serial) >= 0);
|
assert_se(sd_netlink_call_async(rtnl, NULL, m, link_handler2, test_async_object_destroy, t, 0) >= 0);
|
||||||
|
|
||||||
assert_se(t->n_ref == 1);
|
assert_se(t->n_ref == 1);
|
||||||
assert_se(test_async_object_ref(t));
|
assert_se(test_async_object_ref(t));
|
||||||
|
@ -356,10 +356,10 @@ static void test_pipe(int ifindex) {
|
||||||
assert_se(sd_rtnl_message_new_link(rtnl, &m2, RTM_GETLINK, ifindex) >= 0);
|
assert_se(sd_rtnl_message_new_link(rtnl, &m2, RTM_GETLINK, ifindex) >= 0);
|
||||||
|
|
||||||
counter++;
|
counter++;
|
||||||
assert_se(sd_netlink_call_async(rtnl, m1, pipe_handler, NULL, &counter, 0, NULL) >= 0);
|
assert_se(sd_netlink_call_async(rtnl, NULL, m1, pipe_handler, NULL, &counter, 0) >= 0);
|
||||||
|
|
||||||
counter++;
|
counter++;
|
||||||
assert_se(sd_netlink_call_async(rtnl, m2, pipe_handler, NULL, &counter, 0, NULL) >= 0);
|
assert_se(sd_netlink_call_async(rtnl, NULL, m2, pipe_handler, NULL, &counter, 0) >= 0);
|
||||||
|
|
||||||
while (counter > 0) {
|
while (counter > 0) {
|
||||||
assert_se(sd_netlink_wait(rtnl, 0) >= 0);
|
assert_se(sd_netlink_wait(rtnl, 0) >= 0);
|
||||||
|
@ -405,16 +405,17 @@ static void test_container(sd_netlink *rtnl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_match(void) {
|
static void test_match(void) {
|
||||||
|
_cleanup_(sd_netlink_slot_unrefp) sd_netlink_slot *s1 = NULL, *s2 = NULL;
|
||||||
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||||
|
|
||||||
assert_se(sd_netlink_open(&rtnl) >= 0);
|
assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||||
|
|
||||||
assert_se(sd_netlink_add_match(rtnl, RTM_NEWLINK, link_handler, NULL) >= 0);
|
assert_se(sd_netlink_add_match(rtnl, &s1, RTM_NEWLINK, link_handler, NULL, NULL) >= 0);
|
||||||
assert_se(sd_netlink_add_match(rtnl, RTM_NEWLINK, link_handler, NULL) >= 0);
|
assert_se(sd_netlink_add_match(rtnl, &s2, RTM_NEWLINK, link_handler, NULL, NULL) >= 0);
|
||||||
|
assert_se(sd_netlink_add_match(rtnl, NULL, RTM_NEWLINK, link_handler, NULL, NULL) >= 0);
|
||||||
|
|
||||||
assert_se(sd_netlink_remove_match(rtnl, RTM_NEWLINK, link_handler, NULL) == 1);
|
assert_se(!(s1 = sd_netlink_slot_unref(s1)));
|
||||||
assert_se(sd_netlink_remove_match(rtnl, RTM_NEWLINK, link_handler, NULL) == 1);
|
assert_se(!(s2 = sd_netlink_slot_unref(s2)));
|
||||||
assert_se(sd_netlink_remove_match(rtnl, RTM_NEWLINK, link_handler, NULL) == 0);
|
|
||||||
|
|
||||||
assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
|
assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,8 +129,8 @@ static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_mess
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
|
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,
|
r = sd_netlink_call_async(netdev->manager->rtnl, NULL, req, netdev_bridge_set_handler,
|
||||||
netdev_netlink_destroy_callback, netdev, 0, NULL);
|
netdev_netlink_destroy_callback, netdev, 0);
|
||||||
if (r < 0)
|
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 send rtnetlink message: %m");
|
||||||
|
|
||||||
|
|
|
@ -136,8 +136,8 @@ static int netdev_geneve_create(NetDev *netdev) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
|
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,
|
r = sd_netlink_call_async(netdev->manager->rtnl, NULL, m, geneve_netdev_create_handler,
|
||||||
netdev_netlink_destroy_callback, netdev, 0, NULL);
|
netdev_netlink_destroy_callback, netdev, 0);
|
||||||
if (r < 0)
|
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 send rtnetlink message: %m");
|
||||||
|
|
||||||
|
|
|
@ -225,8 +225,8 @@ static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_netlink_message_h
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_netdev_error_errno(netdev, r, "Could not append IFLA_MASTER attribute: %m");
|
return log_netdev_error_errno(netdev, r, "Could not append IFLA_MASTER attribute: %m");
|
||||||
|
|
||||||
r = sd_netlink_call_async(netdev->manager->rtnl, req, callback,
|
r = sd_netlink_call_async(netdev->manager->rtnl, NULL, req, callback,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
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 send rtnetlink message: %m");
|
||||||
|
|
||||||
|
@ -534,15 +534,15 @@ static int netdev_create(NetDev *netdev, Link *link,
|
||||||
return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
|
return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
|
||||||
|
|
||||||
if (link) {
|
if (link) {
|
||||||
r = sd_netlink_call_async(netdev->manager->rtnl, m, callback,
|
r = sd_netlink_call_async(netdev->manager->rtnl, NULL, m, callback,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
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 send rtnetlink message: %m");
|
||||||
|
|
||||||
link_ref(link);
|
link_ref(link);
|
||||||
} else {
|
} else {
|
||||||
r = sd_netlink_call_async(netdev->manager->rtnl, m, netdev_create_handler,
|
r = sd_netlink_call_async(netdev->manager->rtnl, NULL, m, netdev_create_handler,
|
||||||
netdev_netlink_destroy_callback, netdev, 0, NULL);
|
netdev_netlink_destroy_callback, netdev, 0);
|
||||||
if (r < 0)
|
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 send rtnetlink message: %m");
|
||||||
|
|
||||||
|
|
|
@ -112,8 +112,8 @@ int address_label_configure(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Could not append IFA_ADDRESS attribute: %m");
|
return log_error_errno(r, "Could not append IFA_ADDRESS attribute: %m");
|
||||||
|
|
||||||
r = sd_netlink_call_async(link->manager->rtnl, req, callback,
|
r = sd_netlink_call_async(link->manager->rtnl, NULL, req, callback,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Could not send rtnetlink message: %m");
|
return log_error_errno(r, "Could not send rtnetlink message: %m");
|
||||||
|
|
||||||
|
|
|
@ -453,8 +453,8 @@ int address_remove(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Could not append IFA_LOCAL attribute: %m");
|
return log_error_errno(r, "Could not append IFA_LOCAL attribute: %m");
|
||||||
|
|
||||||
r = sd_netlink_call_async(link->manager->rtnl, req, callback,
|
r = sd_netlink_call_async(link->manager->rtnl, NULL, req, callback,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Could not send rtnetlink message: %m");
|
return log_error_errno(r, "Could not send rtnetlink message: %m");
|
||||||
|
|
||||||
|
@ -632,8 +632,8 @@ int address_configure(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_call_async(link->manager->rtnl, req, callback,
|
r = sd_netlink_call_async(link->manager->rtnl, NULL, req, callback,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
address_release(address);
|
address_release(address);
|
||||||
return log_error_errno(r, "Could not send rtnetlink message: %m");
|
return log_error_errno(r, "Could not send rtnetlink message: %m");
|
||||||
|
|
|
@ -195,8 +195,8 @@ int br_vlan_configure(Link *link, uint16_t pvid, uint32_t *br_vid_bitmap, uint32
|
||||||
return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
|
return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
|
||||||
|
|
||||||
/* send message to the kernel */
|
/* send message to the kernel */
|
||||||
r = sd_netlink_call_async(rtnl, req, set_brvlan_handler,
|
r = sd_netlink_call_async(rtnl, NULL, req, set_brvlan_handler,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||||
|
|
||||||
|
|
|
@ -134,8 +134,8 @@ int fdb_entry_configure(Link *link, FdbEntry *fdb_entry) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send message to the kernel to update its internal static MAC table. */
|
/* send message to the kernel to update its internal static MAC table. */
|
||||||
r = sd_netlink_call_async(rtnl, req, set_fdb_handler,
|
r = sd_netlink_call_async(rtnl, NULL, req, set_fdb_handler,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||||
|
|
||||||
|
|
|
@ -173,8 +173,8 @@ int ipv6_proxy_ndp_address_configure(Link *link, IPv6ProxyNDPAddress *ipv6_proxy
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return rtnl_log_create_error(r);
|
return rtnl_log_create_error(r);
|
||||||
|
|
||||||
r = sd_netlink_call_async(rtnl, req, set_ipv6_proxy_ndp_address_handler,
|
r = sd_netlink_call_async(rtnl, NULL, req, set_ipv6_proxy_ndp_address_handler,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||||
|
|
||||||
|
|
|
@ -1340,8 +1340,8 @@ int link_set_mtu(Link *link, uint32_t mtu) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not append MTU: %m");
|
return log_link_error_errno(link, r, "Could not append MTU: %m");
|
||||||
|
|
||||||
r = sd_netlink_call_async(link->manager->rtnl, req, set_mtu_handler,
|
r = sd_netlink_call_async(link->manager->rtnl, NULL, req, set_mtu_handler,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||||
|
|
||||||
|
@ -1411,8 +1411,8 @@ static int link_set_flags(Link *link) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not set link flags: %m");
|
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,
|
r = sd_netlink_call_async(link->manager->rtnl, NULL, req, set_flags_handler,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||||
|
|
||||||
|
@ -1487,8 +1487,8 @@ static int link_set_bridge(Link *link) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
|
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,
|
r = sd_netlink_call_async(link->manager->rtnl, NULL, req, link_set_handler,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||||
|
|
||||||
|
@ -1540,8 +1540,8 @@ static int link_bond_set(Link *link) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
|
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,
|
r = sd_netlink_call_async(link->manager->rtnl, NULL, req, set_flags_handler,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||||
|
|
||||||
|
@ -1833,8 +1833,8 @@ int link_up(Link *link) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
|
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,
|
r = sd_netlink_call_async(link->manager->rtnl, NULL, req, link_up_handler,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||||
|
|
||||||
|
@ -1859,8 +1859,8 @@ static int link_up_can(Link *link) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not set link flags: %m");
|
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,
|
r = sd_netlink_call_async(link->manager->rtnl, NULL, req, link_up_handler,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||||
|
|
||||||
|
@ -1949,8 +1949,8 @@ static int link_set_can(Link *link) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Failed to close netlink container: %m");
|
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,
|
r = sd_netlink_call_async(link->manager->rtnl, NULL, m, link_set_handler,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||||
|
|
||||||
|
@ -2007,8 +2007,8 @@ int link_down(Link *link) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not set link flags: %m");
|
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,
|
r = sd_netlink_call_async(link->manager->rtnl, NULL, req, link_down_handler,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||||
|
|
||||||
|
@ -3122,8 +3122,8 @@ int link_initialized(Link *link, sd_device *device) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_call_async(link->manager->rtnl, req, link_initialized_handler,
|
r = sd_netlink_call_async(link->manager->rtnl, NULL, req, link_initialized_handler,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|
|
@ -930,35 +930,35 @@ static int manager_connect_rtnl(Manager *m) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
|
r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWLINK, &manager_rtnl_process_link, NULL, m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
|
r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELLINK, &manager_rtnl_process_link, NULL, m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_add_match(m->rtnl, RTM_NEWADDR, &manager_rtnl_process_address, m);
|
r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWADDR, &manager_rtnl_process_address, NULL, m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_add_match(m->rtnl, RTM_DELADDR, &manager_rtnl_process_address, m);
|
r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELADDR, &manager_rtnl_process_address, NULL, m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_add_match(m->rtnl, RTM_NEWROUTE, &manager_rtnl_process_route, m);
|
r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWROUTE, &manager_rtnl_process_route, NULL, m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_add_match(m->rtnl, RTM_DELROUTE, &manager_rtnl_process_route, m);
|
r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELROUTE, &manager_rtnl_process_route, NULL, m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_add_match(m->rtnl, RTM_NEWRULE, &manager_rtnl_process_rule, m);
|
r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWRULE, &manager_rtnl_process_rule, NULL, m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_add_match(m->rtnl, RTM_DELRULE, &manager_rtnl_process_rule, m);
|
r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELRULE, &manager_rtnl_process_rule, NULL, m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|
|
@ -439,8 +439,8 @@ int route_remove(Route *route, Link *link,
|
||||||
return log_error_errno(r, "Could not append RTA_OIF attribute: %m");
|
return log_error_errno(r, "Could not append RTA_OIF attribute: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
r = sd_netlink_call_async(link->manager->rtnl, req, callback,
|
r = sd_netlink_call_async(link->manager->rtnl, NULL, req, callback,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Could not send rtnetlink message: %m");
|
return log_error_errno(r, "Could not send rtnetlink message: %m");
|
||||||
|
|
||||||
|
@ -620,8 +620,8 @@ int route_configure(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Could not append RTA_METRICS attribute: %m");
|
return log_error_errno(r, "Could not append RTA_METRICS attribute: %m");
|
||||||
|
|
||||||
r = sd_netlink_call_async(link->manager->rtnl, req, callback,
|
r = sd_netlink_call_async(link->manager->rtnl, NULL, req, callback,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Could not send rtnetlink message: %m");
|
return log_error_errno(r, "Could not send rtnetlink message: %m");
|
||||||
|
|
||||||
|
|
|
@ -370,8 +370,8 @@ int routing_policy_rule_remove(RoutingPolicyRule *routing_policy_rule, Link *lin
|
||||||
return log_error_errno(r, "Could not set destination prefix length: %m");
|
return log_error_errno(r, "Could not set destination prefix length: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
r = sd_netlink_call_async(link->manager->rtnl, m, callback,
|
r = sd_netlink_call_async(link->manager->rtnl, NULL, m, callback,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Could not send rtnetlink message: %m");
|
return log_error_errno(r, "Could not send rtnetlink message: %m");
|
||||||
|
|
||||||
|
@ -539,8 +539,8 @@ int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, sd_netlin
|
||||||
|
|
||||||
rule->link = link;
|
rule->link = link;
|
||||||
|
|
||||||
r = sd_netlink_call_async(link->manager->rtnl, m, callback,
|
r = sd_netlink_call_async(link->manager->rtnl, NULL, m, callback,
|
||||||
link_netlink_destroy_callback, link, 0, NULL);
|
link_netlink_destroy_callback, link, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Could not send rtnetlink message: %m");
|
return log_error_errno(r, "Could not send rtnetlink message: %m");
|
||||||
|
|
||||||
|
|
|
@ -169,11 +169,11 @@ static int manager_rtnl_listen(Manager *m) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_add_match(m->rtnl, RTM_NEWLINK, on_rtnl_event, m);
|
r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWLINK, on_rtnl_event, NULL, m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_add_match(m->rtnl, RTM_DELLINK, on_rtnl_event, m);
|
r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELLINK, on_rtnl_event, NULL, m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|
|
@ -209,11 +209,11 @@ int expose_port_watch_rtnl(
|
||||||
return log_error_errno(r, "Failed to create rtnl object: %m");
|
return log_error_errno(r, "Failed to create rtnl object: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
r = sd_netlink_add_match(rtnl, RTM_NEWADDR, handler, exposed);
|
r = sd_netlink_add_match(rtnl, NULL, RTM_NEWADDR, handler, NULL, exposed);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to subscribe to RTM_NEWADDR messages: %m");
|
return log_error_errno(r, "Failed to subscribe to RTM_NEWADDR messages: %m");
|
||||||
|
|
||||||
r = sd_netlink_add_match(rtnl, RTM_DELADDR, handler, exposed);
|
r = sd_netlink_add_match(rtnl, NULL, RTM_DELADDR, handler, NULL, exposed);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to subscribe to RTM_DELADDR messages: %m");
|
return log_error_errno(r, "Failed to subscribe to RTM_DELADDR messages: %m");
|
||||||
|
|
||||||
|
|
|
@ -200,19 +200,19 @@ static int manager_rtnl_listen(Manager *m) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_add_match(m->rtnl, RTM_NEWLINK, manager_process_link, m);
|
r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWLINK, manager_process_link, NULL, m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_add_match(m->rtnl, RTM_DELLINK, manager_process_link, m);
|
r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELLINK, manager_process_link, NULL, m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_add_match(m->rtnl, RTM_NEWADDR, manager_process_address, m);
|
r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWADDR, manager_process_address, NULL, m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_add_match(m->rtnl, RTM_DELADDR, manager_process_address, m);
|
r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELADDR, manager_process_address, NULL, m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ _SD_BEGIN_DECLARATIONS;
|
||||||
typedef struct sd_netlink sd_netlink;
|
typedef struct sd_netlink sd_netlink;
|
||||||
typedef struct sd_genl_socket sd_genl_socket;
|
typedef struct sd_genl_socket sd_genl_socket;
|
||||||
typedef struct sd_netlink_message sd_netlink_message;
|
typedef struct sd_netlink_message sd_netlink_message;
|
||||||
|
typedef struct sd_netlink_slot sd_netlink_slot;
|
||||||
typedef enum {SD_GENL_ID_CTRL, SD_GENL_WIREGUARD, SD_GENL_FOU} sd_genl_family;
|
typedef enum {SD_GENL_ID_CTRL, SD_GENL_WIREGUARD, SD_GENL_FOU} sd_genl_family;
|
||||||
|
|
||||||
/* callback */
|
/* callback */
|
||||||
|
@ -50,11 +51,9 @@ sd_netlink *sd_netlink_ref(sd_netlink *nl);
|
||||||
sd_netlink *sd_netlink_unref(sd_netlink *nl);
|
sd_netlink *sd_netlink_unref(sd_netlink *nl);
|
||||||
|
|
||||||
int sd_netlink_send(sd_netlink *nl, sd_netlink_message *message, uint32_t *serial);
|
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,
|
int sd_netlink_call_async(sd_netlink *nl, sd_netlink_slot **ret_slot, sd_netlink_message *message,
|
||||||
sd_netlink_message_handler_t callback,
|
sd_netlink_message_handler_t callback, sd_netlink_destroy_t destoy_callback,
|
||||||
sd_netlink_destroy_t destoy_callback,
|
void *userdata, uint64_t usec);
|
||||||
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,
|
int sd_netlink_call(sd_netlink *nl, sd_netlink_message *message, uint64_t timeout,
|
||||||
sd_netlink_message **reply);
|
sd_netlink_message **reply);
|
||||||
|
|
||||||
|
@ -63,8 +62,9 @@ int sd_netlink_get_timeout(sd_netlink *nl, uint64_t *timeout);
|
||||||
int sd_netlink_process(sd_netlink *nl, sd_netlink_message **ret);
|
int sd_netlink_process(sd_netlink *nl, sd_netlink_message **ret);
|
||||||
int sd_netlink_wait(sd_netlink *nl, uint64_t timeout);
|
int sd_netlink_wait(sd_netlink *nl, uint64_t timeout);
|
||||||
|
|
||||||
int sd_netlink_add_match(sd_netlink *nl, uint16_t match, sd_netlink_message_handler_t c, void *userdata);
|
int sd_netlink_add_match(sd_netlink *nl, sd_netlink_slot **ret_slot, uint16_t match,
|
||||||
int sd_netlink_remove_match(sd_netlink *nl, uint16_t match, sd_netlink_message_handler_t c, void *userdata);
|
sd_netlink_message_handler_t callback,
|
||||||
|
sd_netlink_destroy_t destroy_callback, void *userdata);
|
||||||
|
|
||||||
int sd_netlink_attach_event(sd_netlink *nl, sd_event *e, int64_t priority);
|
int sd_netlink_attach_event(sd_netlink *nl, sd_event *e, int64_t priority);
|
||||||
int sd_netlink_detach_event(sd_netlink *nl);
|
int sd_netlink_detach_event(sd_netlink *nl);
|
||||||
|
@ -178,13 +178,18 @@ int sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(sd_netlink_message
|
||||||
int sd_rtnl_message_routing_policy_rule_set_rtm_type(sd_netlink_message *m, unsigned char type);
|
int sd_rtnl_message_routing_policy_rule_set_rtm_type(sd_netlink_message *m, unsigned char type);
|
||||||
int sd_rtnl_message_routing_policy_rule_get_rtm_type(sd_netlink_message *m, unsigned char *type);
|
int sd_rtnl_message_routing_policy_rule_get_rtm_type(sd_netlink_message *m, unsigned char *type);
|
||||||
|
|
||||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_netlink, sd_netlink_unref);
|
|
||||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_netlink_message, sd_netlink_message_unref);
|
|
||||||
|
|
||||||
/* genl */
|
/* genl */
|
||||||
int sd_genl_socket_open(sd_netlink **nl);
|
int sd_genl_socket_open(sd_netlink **nl);
|
||||||
int sd_genl_message_new(sd_netlink *nl, sd_genl_family family, uint8_t cmd, sd_netlink_message **m);
|
int sd_genl_message_new(sd_netlink *nl, sd_genl_family family, uint8_t cmd, sd_netlink_message **m);
|
||||||
|
|
||||||
|
/* slot */
|
||||||
|
sd_netlink_slot *sd_netlink_slot_ref(sd_netlink_slot *nl);
|
||||||
|
sd_netlink_slot *sd_netlink_slot_unref(sd_netlink_slot *nl);
|
||||||
|
|
||||||
|
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_netlink, sd_netlink_unref);
|
||||||
|
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_netlink_message, sd_netlink_message_unref);
|
||||||
|
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_netlink_slot, sd_netlink_slot_unref);
|
||||||
|
|
||||||
_SD_END_DECLARATIONS;
|
_SD_END_DECLARATIONS;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue