sd-netlink: rename variables, arguments, and functions
Most changes are 'rtnl' -> 'nl' where the function is not only for rtnl.
This commit is contained in:
@@ -10,11 +10,11 @@
|
||||
#include "prioq.h"
|
||||
#include "time-util.h"
|
||||
|
||||
#define RTNL_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC))
|
||||
#define NETLINK_DEFAULT_TIMEOUT_USEC ((usec_t) (25 * USEC_PER_SEC))
|
||||
|
||||
#define RTNL_RQUEUE_MAX 64*1024
|
||||
#define NETLINK_RQUEUE_MAX 64*1024
|
||||
|
||||
#define RTNL_CONTAINER_DEPTH 32
|
||||
#define NETLINK_CONTAINER_DEPTH 32
|
||||
|
||||
struct reply_callback {
|
||||
sd_netlink_message_handler_t callback;
|
||||
@@ -118,7 +118,7 @@ struct sd_netlink_message {
|
||||
int protocol;
|
||||
|
||||
struct nlmsghdr *hdr;
|
||||
struct netlink_container containers[RTNL_CONTAINER_DEPTH];
|
||||
struct netlink_container containers[NETLINK_CONTAINER_DEPTH];
|
||||
unsigned n_containers; /* number of containers */
|
||||
bool sealed:1;
|
||||
bool broadcast:1;
|
||||
@@ -126,10 +126,16 @@ struct sd_netlink_message {
|
||||
sd_netlink_message *next; /* next in a chain of multi-part messages */
|
||||
};
|
||||
|
||||
int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type);
|
||||
int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret);
|
||||
int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type);
|
||||
int message_new_empty(sd_netlink *nl, sd_netlink_message **ret);
|
||||
int message_new_synthetic_error(sd_netlink *nl, int error, uint32_t serial, sd_netlink_message **ret);
|
||||
uint32_t message_get_serial(sd_netlink_message *m);
|
||||
void message_seal(sd_netlink_message *m);
|
||||
|
||||
int netlink_open_family(sd_netlink **ret, int family);
|
||||
bool netlink_pid_changed(sd_netlink *nl);
|
||||
int netlink_rqueue_make_room(sd_netlink *nl);
|
||||
int netlink_rqueue_partial_make_room(sd_netlink *nl);
|
||||
|
||||
int socket_open(int family);
|
||||
int socket_bind(sd_netlink *nl);
|
||||
@@ -139,9 +145,6 @@ int socket_write_message(sd_netlink *nl, sd_netlink_message *m);
|
||||
int socket_writev_message(sd_netlink *nl, sd_netlink_message **m, size_t msgcount);
|
||||
int socket_read_message(sd_netlink *nl);
|
||||
|
||||
int rtnl_rqueue_make_room(sd_netlink *rtnl);
|
||||
int rtnl_rqueue_partial_make_room(sd_netlink *rtnl);
|
||||
|
||||
/* Make sure callbacks don't destroy the rtnl connection */
|
||||
#define NETLINK_DONT_DESTROY(rtnl) \
|
||||
_cleanup_(sd_netlink_unrefp) _unused_ sd_netlink *_dont_destroy_##rtnl = sd_netlink_ref(rtnl)
|
||||
/* Make sure callbacks don't destroy the netlink connection */
|
||||
#define NETLINK_DONT_DESTROY(nl) \
|
||||
_cleanup_(sd_netlink_unrefp) _unused_ sd_netlink *_dont_destroy_##nl = sd_netlink_ref(nl)
|
||||
|
||||
@@ -20,15 +20,13 @@
|
||||
#define RTA_TYPE(rta) ((rta)->rta_type & NLA_TYPE_MASK)
|
||||
#define RTA_FLAGS(rta) ((rta)->rta_type & ~NLA_TYPE_MASK)
|
||||
|
||||
int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret) {
|
||||
int message_new_empty(sd_netlink *nl, sd_netlink_message **ret) {
|
||||
sd_netlink_message *m;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
/* Note that 'rtnl' is currently unused, if we start using it internally
|
||||
we must take care to avoid problems due to mutual references between
|
||||
buses and their queued messages. See sd-bus.
|
||||
*/
|
||||
/* Note that 'nl' is currently unused, if we start using it internally we must take care to
|
||||
* avoid problems due to mutual references between buses and their queued messages. See sd-bus. */
|
||||
|
||||
m = new(sd_netlink_message, 1);
|
||||
if (!m)
|
||||
@@ -36,7 +34,7 @@ int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret) {
|
||||
|
||||
*m = (sd_netlink_message) {
|
||||
.n_ref = 1,
|
||||
.protocol = rtnl->protocol,
|
||||
.protocol = nl->protocol,
|
||||
.sealed = false,
|
||||
};
|
||||
|
||||
@@ -45,22 +43,22 @@ int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) {
|
||||
int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
const NLType *nl_type;
|
||||
size_t size;
|
||||
int r;
|
||||
|
||||
assert_return(rtnl, -EINVAL);
|
||||
assert_return(nl, -EINVAL);
|
||||
|
||||
r = type_system_root_get_type(rtnl, &nl_type, type);
|
||||
r = type_system_root_get_type(nl, &nl_type, type);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (type_get_type(nl_type) != NETLINK_TYPE_NESTED)
|
||||
return -EINVAL;
|
||||
|
||||
r = message_new_empty(rtnl, &m);
|
||||
r = message_new_empty(nl, &m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -82,6 +80,25 @@ int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int message_new_synthetic_error(sd_netlink *nl, int error, uint32_t serial, sd_netlink_message **ret) {
|
||||
struct nlmsgerr *err;
|
||||
int r;
|
||||
|
||||
assert(error <= 0);
|
||||
|
||||
r = message_new(nl, ret, NLMSG_ERROR);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
message_seal(*ret);
|
||||
(*ret)->hdr->nlmsg_seq = serial;
|
||||
|
||||
err = NLMSG_DATA((*ret)->hdr);
|
||||
err->error = error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_netlink_message_request_dump(sd_netlink_message *m, int dump) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(m->hdr, -EINVAL);
|
||||
@@ -538,7 +555,7 @@ int sd_netlink_message_open_container(sd_netlink_message *m, unsigned short type
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(!m->sealed, -EPERM);
|
||||
/* m->containers[m->n_containers + 1] is accessed both in read and write. Prevent access out of bound */
|
||||
assert_return(m->n_containers < (RTNL_CONTAINER_DEPTH - 1), -ERANGE);
|
||||
assert_return(m->n_containers < (NETLINK_CONTAINER_DEPTH - 1), -ERANGE);
|
||||
|
||||
r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_NESTED);
|
||||
if (r < 0) {
|
||||
@@ -585,7 +602,7 @@ int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned shor
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(!m->sealed, -EPERM);
|
||||
assert_return(m->n_containers < (RTNL_CONTAINER_DEPTH - 1), -ERANGE);
|
||||
assert_return(m->n_containers < (NETLINK_CONTAINER_DEPTH - 1), -ERANGE);
|
||||
|
||||
r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type);
|
||||
if (r < 0)
|
||||
@@ -628,7 +645,7 @@ int sd_netlink_message_open_array(sd_netlink_message *m, uint16_t type) {
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(!m->sealed, -EPERM);
|
||||
assert_return(m->n_containers < (RTNL_CONTAINER_DEPTH - 1), -ERANGE);
|
||||
assert_return(m->n_containers < (NETLINK_CONTAINER_DEPTH - 1), -ERANGE);
|
||||
|
||||
r = add_rtattr(m, type | NLA_F_NESTED, NULL, 0);
|
||||
if (r < 0)
|
||||
@@ -673,7 +690,7 @@ static int netlink_message_read_internal(
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(m->sealed, -EPERM);
|
||||
|
||||
assert(m->n_containers < RTNL_CONTAINER_DEPTH);
|
||||
assert(m->n_containers < NETLINK_CONTAINER_DEPTH);
|
||||
|
||||
if (!m->containers[m->n_containers].attributes)
|
||||
return -ENODATA;
|
||||
@@ -1008,7 +1025,7 @@ int sd_netlink_message_read_strv(sd_netlink_message *m, unsigned short container
|
||||
int r;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL);
|
||||
assert_return(m->n_containers < NETLINK_CONTAINER_DEPTH, -EINVAL);
|
||||
|
||||
r = type_system_get_type(m->containers[m->n_containers].type_system,
|
||||
&nl_type,
|
||||
@@ -1079,7 +1096,7 @@ static int netlink_container_parse(sd_netlink_message *m,
|
||||
return -ENOMEM;
|
||||
|
||||
if (attributes[type].offset != 0)
|
||||
log_debug("rtnl: message parse - overwriting repeated attribute");
|
||||
log_debug("sd-netlink: message parse - overwriting repeated attribute");
|
||||
|
||||
attributes[type].offset = (uint8_t *) rta - (uint8_t *) m->hdr;
|
||||
attributes[type].nested = RTA_FLAGS(rta) & NLA_F_NESTED;
|
||||
@@ -1104,7 +1121,7 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ
|
||||
int r;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(m->n_containers < (RTNL_CONTAINER_DEPTH - 1), -EINVAL);
|
||||
assert_return(m->n_containers < (NETLINK_CONTAINER_DEPTH - 1), -EINVAL);
|
||||
|
||||
r = type_system_get_type(m->containers[m->n_containers].type_system,
|
||||
&nl_type,
|
||||
@@ -1195,7 +1212,7 @@ int sd_netlink_message_enter_array(sd_netlink_message *m, unsigned short type_id
|
||||
int r;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(m->n_containers < (RTNL_CONTAINER_DEPTH - 1), -EINVAL);
|
||||
assert_return(m->n_containers < (NETLINK_CONTAINER_DEPTH - 1), -EINVAL);
|
||||
|
||||
r = netlink_message_read_internal(m, type_id, &container, NULL);
|
||||
if (r < 0)
|
||||
@@ -1231,7 +1248,7 @@ int sd_netlink_message_exit_container(sd_netlink_message *m) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t rtnl_message_get_serial(sd_netlink_message *m) {
|
||||
uint32_t message_get_serial(sd_netlink_message *m) {
|
||||
assert(m);
|
||||
assert(m->hdr);
|
||||
|
||||
@@ -1291,7 +1308,7 @@ int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *genl) {
|
||||
|
||||
/* don't allow appending to message once parsed */
|
||||
if (!m->sealed)
|
||||
rtnl_message_seal(m);
|
||||
message_seal(m);
|
||||
|
||||
for (unsigned i = 1; i <= m->n_containers; i++)
|
||||
m->containers[i].attributes = mfree(m->containers[i].attributes);
|
||||
@@ -1332,7 +1349,7 @@ int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *genl) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtnl_message_seal(sd_netlink_message *m) {
|
||||
void message_seal(sd_netlink_message *m) {
|
||||
assert(m);
|
||||
assert(!m->sealed);
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_gr
|
||||
|
||||
n = recvmsg_safe(fd, &msg, MSG_TRUNC | (peek ? MSG_PEEK : 0));
|
||||
if (n == -ENOBUFS)
|
||||
return log_debug_errno(n, "rtnl: kernel receive buffer overrun");
|
||||
return log_debug_errno(n, "sd-netlink: kernel receive buffer overrun");
|
||||
if (IN_SET(n, -EAGAIN, -EINTR))
|
||||
return 0;
|
||||
if (n < 0)
|
||||
@@ -246,7 +246,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_gr
|
||||
|
||||
if (sender.nl.nl_pid != 0) {
|
||||
/* not from the kernel, ignore */
|
||||
log_debug("rtnl: ignoring message from PID %"PRIu32, sender.nl.nl_pid);
|
||||
log_debug("sd-netlink: ignoring message from PID %"PRIu32, sender.nl.nl_pid);
|
||||
|
||||
if (peek) {
|
||||
/* drop the message */
|
||||
@@ -276,7 +276,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_gr
|
||||
* If nothing useful was received 0 is returned.
|
||||
* On failure, a negative error code is returned.
|
||||
*/
|
||||
int socket_read_message(sd_netlink *rtnl) {
|
||||
int socket_read_message(sd_netlink *nl) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *first = NULL;
|
||||
bool multi_part = false, done = false;
|
||||
size_t len, allocated;
|
||||
@@ -285,25 +285,25 @@ int socket_read_message(sd_netlink *rtnl) {
|
||||
unsigned i = 0;
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(rtnl->rbuffer);
|
||||
assert(nl);
|
||||
assert(nl->rbuffer);
|
||||
|
||||
/* read nothing, just get the pending message size */
|
||||
r = socket_recv_message(rtnl->fd, &iov, NULL, true);
|
||||
r = socket_recv_message(nl->fd, &iov, NULL, true);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
else
|
||||
len = (size_t) r;
|
||||
|
||||
/* make room for the pending message */
|
||||
if (!greedy_realloc((void **)&rtnl->rbuffer, len, sizeof(uint8_t)))
|
||||
if (!greedy_realloc((void**) &nl->rbuffer, len, sizeof(uint8_t)))
|
||||
return -ENOMEM;
|
||||
|
||||
allocated = MALLOC_SIZEOF_SAFE(rtnl->rbuffer);
|
||||
iov = IOVEC_MAKE(rtnl->rbuffer, allocated);
|
||||
allocated = MALLOC_SIZEOF_SAFE(nl->rbuffer);
|
||||
iov = IOVEC_MAKE(nl->rbuffer, allocated);
|
||||
|
||||
/* read the pending message */
|
||||
r = socket_recv_message(rtnl->fd, &iov, &group, false);
|
||||
r = socket_recv_message(nl->fd, &iov, &group, false);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
else
|
||||
@@ -313,22 +313,22 @@ int socket_read_message(sd_netlink *rtnl) {
|
||||
/* message did not fit in read buffer */
|
||||
return -EIO;
|
||||
|
||||
if (NLMSG_OK(rtnl->rbuffer, len) && rtnl->rbuffer->nlmsg_flags & NLM_F_MULTI) {
|
||||
if (NLMSG_OK(nl->rbuffer, len) && nl->rbuffer->nlmsg_flags & NLM_F_MULTI) {
|
||||
multi_part = true;
|
||||
|
||||
for (i = 0; i < rtnl->rqueue_partial_size; i++)
|
||||
if (rtnl_message_get_serial(rtnl->rqueue_partial[i]) ==
|
||||
rtnl->rbuffer->nlmsg_seq) {
|
||||
first = rtnl->rqueue_partial[i];
|
||||
for (i = 0; i < nl->rqueue_partial_size; i++)
|
||||
if (message_get_serial(nl->rqueue_partial[i]) ==
|
||||
nl->rbuffer->nlmsg_seq) {
|
||||
first = nl->rqueue_partial[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (struct nlmsghdr *new_msg = rtnl->rbuffer; NLMSG_OK(new_msg, len) && !done; new_msg = NLMSG_NEXT(new_msg, len)) {
|
||||
for (struct nlmsghdr *new_msg = nl->rbuffer; NLMSG_OK(new_msg, len) && !done; new_msg = NLMSG_NEXT(new_msg, len)) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
const NLType *nl_type;
|
||||
|
||||
if (!group && new_msg->nlmsg_pid != rtnl->sockaddr.nl.nl_pid)
|
||||
if (!group && new_msg->nlmsg_pid != nl->sockaddr.nl.nl_pid)
|
||||
/* not broadcast and not for us */
|
||||
continue;
|
||||
|
||||
@@ -346,7 +346,7 @@ int socket_read_message(sd_netlink *rtnl) {
|
||||
}
|
||||
|
||||
/* check that we support this message type */
|
||||
r = type_system_root_get_type(rtnl, &nl_type, new_msg->nlmsg_type);
|
||||
r = type_system_root_get_type(nl, &nl_type, new_msg->nlmsg_type);
|
||||
if (r < 0) {
|
||||
if (r == -EOPNOTSUPP)
|
||||
log_debug("sd-netlink: ignored message with unknown type: %i",
|
||||
@@ -361,7 +361,7 @@ int socket_read_message(sd_netlink *rtnl) {
|
||||
continue;
|
||||
}
|
||||
|
||||
r = message_new_empty(rtnl, &m);
|
||||
r = message_new_empty(nl, &m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -372,7 +372,7 @@ int socket_read_message(sd_netlink *rtnl) {
|
||||
return -ENOMEM;
|
||||
|
||||
/* seal and parse the top-level message */
|
||||
r = sd_netlink_message_rewind(m, rtnl);
|
||||
r = sd_netlink_message_rewind(m, nl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -390,31 +390,31 @@ int socket_read_message(sd_netlink *rtnl) {
|
||||
|
||||
if (!multi_part || done) {
|
||||
/* we got a complete message, push it on the read queue */
|
||||
r = rtnl_rqueue_make_room(rtnl);
|
||||
r = netlink_rqueue_make_room(nl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
rtnl->rqueue[rtnl->rqueue_size++] = TAKE_PTR(first);
|
||||
nl->rqueue[nl->rqueue_size++] = TAKE_PTR(first);
|
||||
|
||||
if (multi_part && (i < rtnl->rqueue_partial_size)) {
|
||||
if (multi_part && (i < nl->rqueue_partial_size)) {
|
||||
/* remove the message form the partial read queue */
|
||||
memmove(rtnl->rqueue_partial + i,rtnl->rqueue_partial + i + 1,
|
||||
sizeof(sd_netlink_message*) * (rtnl->rqueue_partial_size - i - 1));
|
||||
rtnl->rqueue_partial_size--;
|
||||
memmove(nl->rqueue_partial + i, nl->rqueue_partial + i + 1,
|
||||
sizeof(sd_netlink_message*) * (nl->rqueue_partial_size - i - 1));
|
||||
nl->rqueue_partial_size--;
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
/* we only got a partial multi-part message, push it on the
|
||||
partial read queue */
|
||||
if (i < rtnl->rqueue_partial_size)
|
||||
rtnl->rqueue_partial[i] = TAKE_PTR(first);
|
||||
if (i < nl->rqueue_partial_size)
|
||||
nl->rqueue_partial[i] = TAKE_PTR(first);
|
||||
else {
|
||||
r = rtnl_rqueue_partial_make_room(rtnl);
|
||||
r = netlink_rqueue_partial_make_room(nl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
rtnl->rqueue_partial[rtnl->rqueue_partial_size++] = TAKE_PTR(first);
|
||||
nl->rqueue_partial[nl->rqueue_partial_size++] = TAKE_PTR(first);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -400,25 +400,6 @@ int rtnl_get_link_info(sd_netlink **rtnl, int ifindex, unsigned short *ret_iftyp
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret) {
|
||||
struct nlmsgerr *err;
|
||||
int r;
|
||||
|
||||
assert(error <= 0);
|
||||
|
||||
r = message_new(rtnl, ret, NLMSG_ERROR);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
rtnl_message_seal(*ret);
|
||||
(*ret)->hdr->nlmsg_seq = serial;
|
||||
|
||||
err = NLMSG_DATA((*ret)->hdr);
|
||||
err->error = error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtnl_log_parse_error(int r) {
|
||||
return log_error_errno(r, "Failed to parse netlink message: %m");
|
||||
}
|
||||
|
||||
@@ -29,10 +29,6 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(MultipathRoute*, multipath_route_free);
|
||||
|
||||
int multipath_route_dup(const MultipathRoute *m, MultipathRoute **ret);
|
||||
|
||||
int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret);
|
||||
uint32_t rtnl_message_get_serial(sd_netlink_message *m);
|
||||
void rtnl_message_seal(sd_netlink_message *m);
|
||||
|
||||
static inline bool rtnl_message_type_is_neigh(uint16_t type) {
|
||||
return IN_SET(type, RTM_NEWNEIGH, RTM_GETNEIGH, RTM_DELNEIGH);
|
||||
}
|
||||
|
||||
@@ -13,9 +13,7 @@
|
||||
#include "format-util.h"
|
||||
#include "netlink-internal.h"
|
||||
#include "netlink-types.h"
|
||||
#include "netlink-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static int nft_message_new(sd_netlink *nfnl, sd_netlink_message **ret, int family, uint16_t type, uint16_t flags) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
@@ -66,7 +64,7 @@ static int nft_message_new(sd_netlink *nfnl, sd_netlink_message **ret, int famil
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_nfnl_message_batch(sd_netlink *nfnl, sd_netlink_message **ret, int v) {
|
||||
static int nfnl_message_batch(sd_netlink *nfnl, sd_netlink_message **ret, int v) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
int r;
|
||||
|
||||
@@ -85,11 +83,11 @@ static int sd_nfnl_message_batch(sd_netlink *nfnl, sd_netlink_message **ret, int
|
||||
}
|
||||
|
||||
int sd_nfnl_message_batch_begin(sd_netlink *nfnl, sd_netlink_message **ret) {
|
||||
return sd_nfnl_message_batch(nfnl, ret, NFNL_MSG_BATCH_BEGIN);
|
||||
return nfnl_message_batch(nfnl, ret, NFNL_MSG_BATCH_BEGIN);
|
||||
}
|
||||
|
||||
int sd_nfnl_message_batch_end(sd_netlink *nfnl, sd_netlink_message **ret) {
|
||||
return sd_nfnl_message_batch(nfnl, ret, NFNL_MSG_BATCH_END);
|
||||
return nfnl_message_batch(nfnl, ret, NFNL_MSG_BATCH_END);
|
||||
}
|
||||
|
||||
int sd_nfnl_nft_message_new_basechain(sd_netlink *nfnl, sd_netlink_message **ret,
|
||||
|
||||
@@ -271,13 +271,13 @@ int sd_rtnl_message_new_route(sd_netlink *rtnl, sd_netlink_message **ret,
|
||||
}
|
||||
|
||||
int sd_rtnl_message_new_nexthop(sd_netlink *rtnl, sd_netlink_message **ret,
|
||||
uint16_t nhmsg_type, int nh_family,
|
||||
uint16_t nlmsg_type, int nh_family,
|
||||
unsigned char nh_protocol) {
|
||||
struct nhmsg *nhm;
|
||||
int r;
|
||||
|
||||
assert_return(rtnl_message_type_is_nexthop(nhmsg_type), -EINVAL);
|
||||
switch(nhmsg_type) {
|
||||
assert_return(rtnl_message_type_is_nexthop(nlmsg_type), -EINVAL);
|
||||
switch(nlmsg_type) {
|
||||
case RTM_DELNEXTHOP:
|
||||
assert_return(nh_family == AF_UNSPEC, -EINVAL);
|
||||
_fallthrough_;
|
||||
@@ -292,11 +292,11 @@ int sd_rtnl_message_new_nexthop(sd_netlink *rtnl, sd_netlink_message **ret,
|
||||
}
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
r = message_new(rtnl, ret, nhmsg_type);
|
||||
r = message_new(rtnl, ret, nlmsg_type);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (nhmsg_type == RTM_NEWNEXTHOP)
|
||||
if (nlmsg_type == RTM_NEWNEXTHOP)
|
||||
(*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND;
|
||||
|
||||
nhm = NLMSG_DATA((*ret)->hdr);
|
||||
|
||||
@@ -11,25 +11,23 @@
|
||||
#include "macro.h"
|
||||
#include "netlink-internal.h"
|
||||
#include "netlink-slot.h"
|
||||
#include "netlink-util.h"
|
||||
#include "process-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "string-util.h"
|
||||
#include "util.h"
|
||||
|
||||
/* Some really high limit, to catch programming errors */
|
||||
#define REPLY_CALLBACKS_MAX UINT16_MAX
|
||||
|
||||
static int sd_netlink_new(sd_netlink **ret) {
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||
static int netlink_new(sd_netlink **ret) {
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *nl = NULL;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
rtnl = new(sd_netlink, 1);
|
||||
if (!rtnl)
|
||||
nl = new(sd_netlink, 1);
|
||||
if (!nl)
|
||||
return -ENOMEM;
|
||||
|
||||
*rtnl = (sd_netlink) {
|
||||
*nl = (sd_netlink) {
|
||||
.n_ref = 1,
|
||||
.fd = -1,
|
||||
.sockaddr.nl.nl_family = AF_NETLINK,
|
||||
@@ -61,60 +59,48 @@ static int sd_netlink_new(sd_netlink **ret) {
|
||||
.serial = (uint32_t) (now(CLOCK_MONOTONIC) % UINT32_MAX) + 1,
|
||||
};
|
||||
|
||||
/* We guarantee that the read buffer has at least space for
|
||||
* a message header */
|
||||
if (!greedy_realloc((void**)&rtnl->rbuffer, sizeof(struct nlmsghdr), sizeof(uint8_t)))
|
||||
/* We guarantee that the read buffer has at least space for a message header */
|
||||
if (!greedy_realloc((void**) &nl->rbuffer, sizeof(struct nlmsghdr), sizeof(uint8_t)))
|
||||
return -ENOMEM;
|
||||
|
||||
*ret = TAKE_PTR(rtnl);
|
||||
|
||||
*ret = TAKE_PTR(nl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_netlink_new_from_netlink(sd_netlink **ret, int fd) {
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||
int sd_netlink_new_from_fd(sd_netlink **ret, int fd) {
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *nl = NULL;
|
||||
socklen_t addrlen;
|
||||
int r;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
r = sd_netlink_new(&rtnl);
|
||||
r = netlink_new(&nl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
addrlen = sizeof(rtnl->sockaddr);
|
||||
addrlen = sizeof(nl->sockaddr);
|
||||
|
||||
r = getsockname(fd, &rtnl->sockaddr.sa, &addrlen);
|
||||
r = getsockname(fd, &nl->sockaddr.sa, &addrlen);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
if (rtnl->sockaddr.nl.nl_family != AF_NETLINK)
|
||||
if (nl->sockaddr.nl.nl_family != AF_NETLINK)
|
||||
return -EINVAL;
|
||||
|
||||
rtnl->fd = fd;
|
||||
|
||||
*ret = TAKE_PTR(rtnl);
|
||||
nl->fd = fd;
|
||||
|
||||
*ret = TAKE_PTR(nl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool rtnl_pid_changed(const sd_netlink *rtnl) {
|
||||
assert(rtnl);
|
||||
|
||||
/* We don't support people creating an rtnl connection and
|
||||
* keeping it around over a fork(). Let's complain. */
|
||||
|
||||
return rtnl->original_pid != getpid_cached();
|
||||
}
|
||||
|
||||
int sd_netlink_open_fd(sd_netlink **ret, int fd) {
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *nl = NULL;
|
||||
int r, protocol;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(fd >= 0, -EBADF);
|
||||
|
||||
r = sd_netlink_new(&rtnl);
|
||||
r = netlink_new(&nl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -122,8 +108,8 @@ int sd_netlink_open_fd(sd_netlink **ret, int fd) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
rtnl->fd = fd;
|
||||
rtnl->protocol = protocol;
|
||||
nl->fd = fd;
|
||||
nl->protocol = protocol;
|
||||
|
||||
r = setsockopt_int(fd, SOL_NETLINK, NETLINK_EXT_ACK, true);
|
||||
if (r < 0)
|
||||
@@ -133,14 +119,14 @@ int sd_netlink_open_fd(sd_netlink **ret, int fd) {
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "sd-netlink: Failed to enable NETLINK_GET_STRICT_CHK option, ignoring: %m");
|
||||
|
||||
r = socket_bind(rtnl);
|
||||
r = socket_bind(nl);
|
||||
if (r < 0) {
|
||||
rtnl->fd = -1; /* on failure, the caller remains owner of the fd, hence don't close it here */
|
||||
rtnl->protocol = -1;
|
||||
nl->fd = -1; /* on failure, the caller remains owner of the fd, hence don't close it here */
|
||||
nl->protocol = -1;
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(rtnl);
|
||||
*ret = TAKE_PTR(nl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -165,91 +151,102 @@ int sd_netlink_open(sd_netlink **ret) {
|
||||
return netlink_open_family(ret, NETLINK_ROUTE);
|
||||
}
|
||||
|
||||
int sd_netlink_inc_rcvbuf(sd_netlink *rtnl, size_t size) {
|
||||
assert_return(rtnl, -EINVAL);
|
||||
assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
|
||||
bool netlink_pid_changed(sd_netlink *nl) {
|
||||
assert(nl);
|
||||
|
||||
return fd_inc_rcvbuf(rtnl->fd, size);
|
||||
/* We don't support people creating an nl connection and
|
||||
* keeping it around over a fork(). Let's complain. */
|
||||
|
||||
return nl->original_pid != getpid_cached();
|
||||
}
|
||||
|
||||
static sd_netlink *netlink_free(sd_netlink *rtnl) {
|
||||
int sd_netlink_inc_rcvbuf(sd_netlink *nl, size_t size) {
|
||||
assert_return(nl, -EINVAL);
|
||||
assert_return(!netlink_pid_changed(nl), -ECHILD);
|
||||
|
||||
return fd_inc_rcvbuf(nl->fd, size);
|
||||
}
|
||||
|
||||
static sd_netlink *netlink_free(sd_netlink *nl) {
|
||||
sd_netlink_slot *s;
|
||||
unsigned i;
|
||||
|
||||
assert(rtnl);
|
||||
assert(nl);
|
||||
|
||||
for (i = 0; i < rtnl->rqueue_size; i++)
|
||||
sd_netlink_message_unref(rtnl->rqueue[i]);
|
||||
free(rtnl->rqueue);
|
||||
for (i = 0; i < nl->rqueue_size; i++)
|
||||
sd_netlink_message_unref(nl->rqueue[i]);
|
||||
free(nl->rqueue);
|
||||
|
||||
for (i = 0; i < rtnl->rqueue_partial_size; i++)
|
||||
sd_netlink_message_unref(rtnl->rqueue_partial[i]);
|
||||
free(rtnl->rqueue_partial);
|
||||
for (i = 0; i < nl->rqueue_partial_size; i++)
|
||||
sd_netlink_message_unref(nl->rqueue_partial[i]);
|
||||
free(nl->rqueue_partial);
|
||||
|
||||
free(rtnl->rbuffer);
|
||||
free(nl->rbuffer);
|
||||
|
||||
while ((s = rtnl->slots)) {
|
||||
while ((s = nl->slots)) {
|
||||
assert(s->floating);
|
||||
netlink_slot_disconnect(s, true);
|
||||
}
|
||||
hashmap_free(rtnl->reply_callbacks);
|
||||
prioq_free(rtnl->reply_callbacks_prioq);
|
||||
hashmap_free(nl->reply_callbacks);
|
||||
prioq_free(nl->reply_callbacks_prioq);
|
||||
|
||||
sd_event_source_unref(rtnl->io_event_source);
|
||||
sd_event_source_unref(rtnl->time_event_source);
|
||||
sd_event_unref(rtnl->event);
|
||||
sd_event_source_unref(nl->io_event_source);
|
||||
sd_event_source_unref(nl->time_event_source);
|
||||
sd_event_unref(nl->event);
|
||||
|
||||
hashmap_free(rtnl->broadcast_group_refs);
|
||||
hashmap_free(nl->broadcast_group_refs);
|
||||
|
||||
hashmap_free(rtnl->genl_family_to_nlmsg_type);
|
||||
hashmap_free(rtnl->nlmsg_type_to_genl_family);
|
||||
hashmap_free(nl->genl_family_to_nlmsg_type);
|
||||
hashmap_free(nl->nlmsg_type_to_genl_family);
|
||||
|
||||
safe_close(rtnl->fd);
|
||||
return mfree(rtnl);
|
||||
safe_close(nl->fd);
|
||||
return mfree(nl);
|
||||
}
|
||||
|
||||
DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_netlink, sd_netlink, netlink_free);
|
||||
|
||||
static void rtnl_seal_message(sd_netlink *rtnl, sd_netlink_message *m) {
|
||||
static void netlink_seal_message(sd_netlink *nl, sd_netlink_message *m) {
|
||||
uint32_t picked;
|
||||
|
||||
assert(rtnl);
|
||||
assert(!rtnl_pid_changed(rtnl));
|
||||
assert(nl);
|
||||
assert(!netlink_pid_changed(nl));
|
||||
assert(m);
|
||||
assert(m->hdr);
|
||||
|
||||
/* Avoid collisions with outstanding requests */
|
||||
do {
|
||||
picked = rtnl->serial;
|
||||
picked = nl->serial;
|
||||
|
||||
/* Don't use seq == 0, as that is used for broadcasts, so we would get confused by replies to
|
||||
such messages */
|
||||
rtnl->serial = rtnl->serial == UINT32_MAX ? 1 : rtnl->serial + 1;
|
||||
nl->serial = nl->serial == UINT32_MAX ? 1 : nl->serial + 1;
|
||||
|
||||
} while (hashmap_contains(rtnl->reply_callbacks, UINT32_TO_PTR(picked)));
|
||||
} while (hashmap_contains(nl->reply_callbacks, UINT32_TO_PTR(picked)));
|
||||
|
||||
m->hdr->nlmsg_seq = picked;
|
||||
rtnl_message_seal(m);
|
||||
message_seal(m);
|
||||
}
|
||||
|
||||
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 r;
|
||||
|
||||
assert_return(nl, -EINVAL);
|
||||
assert_return(!rtnl_pid_changed(nl), -ECHILD);
|
||||
assert_return(!netlink_pid_changed(nl), -ECHILD);
|
||||
assert_return(message, -EINVAL);
|
||||
assert_return(!message->sealed, -EPERM);
|
||||
|
||||
rtnl_seal_message(nl, message);
|
||||
netlink_seal_message(nl, message);
|
||||
|
||||
r = socket_write_message(nl, message);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (serial)
|
||||
*serial = rtnl_message_get_serial(message);
|
||||
*serial = message_get_serial(message);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -264,7 +261,7 @@ int sd_netlink_sendv(
|
||||
int r;
|
||||
|
||||
assert_return(nl, -EINVAL);
|
||||
assert_return(!rtnl_pid_changed(nl), -ECHILD);
|
||||
assert_return(!netlink_pid_changed(nl), -ECHILD);
|
||||
assert_return(messages, -EINVAL);
|
||||
assert_return(msgcount > 0, -EINVAL);
|
||||
|
||||
@@ -277,9 +274,9 @@ int sd_netlink_sendv(
|
||||
for (unsigned i = 0; i < msgcount; i++) {
|
||||
assert_return(!messages[i]->sealed, -EPERM);
|
||||
|
||||
rtnl_seal_message(nl, messages[i]);
|
||||
netlink_seal_message(nl, messages[i]);
|
||||
if (serials)
|
||||
serials[i] = rtnl_message_get_serial(messages[i]);
|
||||
serials[i] = message_get_serial(messages[i]);
|
||||
}
|
||||
|
||||
r = socket_writev_message(nl, messages, msgcount);
|
||||
@@ -292,45 +289,45 @@ int sd_netlink_sendv(
|
||||
return r;
|
||||
}
|
||||
|
||||
int rtnl_rqueue_make_room(sd_netlink *rtnl) {
|
||||
assert(rtnl);
|
||||
int netlink_rqueue_make_room(sd_netlink *nl) {
|
||||
assert(nl);
|
||||
|
||||
if (rtnl->rqueue_size >= RTNL_RQUEUE_MAX)
|
||||
if (nl->rqueue_size >= NETLINK_RQUEUE_MAX)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ENOBUFS),
|
||||
"rtnl: exhausted the read queue size (%d)",
|
||||
RTNL_RQUEUE_MAX);
|
||||
"sd-netlink: exhausted the read queue size (%d)",
|
||||
NETLINK_RQUEUE_MAX);
|
||||
|
||||
if (!GREEDY_REALLOC(rtnl->rqueue, rtnl->rqueue_size + 1))
|
||||
if (!GREEDY_REALLOC(nl->rqueue, nl->rqueue_size + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtnl_rqueue_partial_make_room(sd_netlink *rtnl) {
|
||||
assert(rtnl);
|
||||
int netlink_rqueue_partial_make_room(sd_netlink *nl) {
|
||||
assert(nl);
|
||||
|
||||
if (rtnl->rqueue_partial_size >= RTNL_RQUEUE_MAX)
|
||||
if (nl->rqueue_partial_size >= NETLINK_RQUEUE_MAX)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ENOBUFS),
|
||||
"rtnl: exhausted the partial read queue size (%d)",
|
||||
RTNL_RQUEUE_MAX);
|
||||
"sd-netlink: exhausted the partial read queue size (%d)",
|
||||
NETLINK_RQUEUE_MAX);
|
||||
|
||||
if (!GREEDY_REALLOC(rtnl->rqueue_partial, rtnl->rqueue_partial_size + 1))
|
||||
if (!GREEDY_REALLOC(nl->rqueue_partial, nl->rqueue_partial_size + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dispatch_rqueue(sd_netlink *rtnl, sd_netlink_message **message) {
|
||||
static int dispatch_rqueue(sd_netlink *nl, sd_netlink_message **message) {
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(nl);
|
||||
assert(message);
|
||||
|
||||
if (rtnl->rqueue_size <= 0) {
|
||||
if (nl->rqueue_size <= 0) {
|
||||
/* Try to read a new message */
|
||||
r = socket_read_message(rtnl);
|
||||
r = socket_read_message(nl);
|
||||
if (r == -ENOBUFS) { /* FIXME: ignore buffer overruns for now */
|
||||
log_debug_errno(r, "Got ENOBUFS from netlink socket, ignoring.");
|
||||
log_debug_errno(r, "sd-netlink: Got ENOBUFS from netlink socket, ignoring.");
|
||||
return 1;
|
||||
}
|
||||
if (r <= 0)
|
||||
@@ -338,23 +335,23 @@ static int dispatch_rqueue(sd_netlink *rtnl, sd_netlink_message **message) {
|
||||
}
|
||||
|
||||
/* Dispatch a queued message */
|
||||
*message = rtnl->rqueue[0];
|
||||
rtnl->rqueue_size--;
|
||||
memmove(rtnl->rqueue, rtnl->rqueue + 1, sizeof(sd_netlink_message*) * rtnl->rqueue_size);
|
||||
*message = nl->rqueue[0];
|
||||
nl->rqueue_size--;
|
||||
memmove(nl->rqueue, nl->rqueue + 1, sizeof(sd_netlink_message*) * nl->rqueue_size);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int process_timeout(sd_netlink *rtnl) {
|
||||
static int process_timeout(sd_netlink *nl) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
struct reply_callback *c;
|
||||
sd_netlink_slot *slot;
|
||||
usec_t n;
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(nl);
|
||||
|
||||
c = prioq_peek(rtnl->reply_callbacks_prioq);
|
||||
c = prioq_peek(nl->reply_callbacks_prioq);
|
||||
if (!c)
|
||||
return 0;
|
||||
|
||||
@@ -362,17 +359,17 @@ static int process_timeout(sd_netlink *rtnl) {
|
||||
if (c->timeout > n)
|
||||
return 0;
|
||||
|
||||
r = rtnl_message_new_synthetic_error(rtnl, -ETIMEDOUT, c->serial, &m);
|
||||
r = message_new_synthetic_error(nl, -ETIMEDOUT, c->serial, &m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
assert_se(prioq_pop(rtnl->reply_callbacks_prioq) == c);
|
||||
assert_se(prioq_pop(nl->reply_callbacks_prioq) == c);
|
||||
c->timeout = 0;
|
||||
hashmap_remove(rtnl->reply_callbacks, UINT32_TO_PTR(c->serial));
|
||||
hashmap_remove(nl->reply_callbacks, UINT32_TO_PTR(c->serial));
|
||||
|
||||
slot = container_of(c, sd_netlink_slot, reply_callback);
|
||||
|
||||
r = c->callback(rtnl, m, slot->userdata);
|
||||
r = c->callback(nl, m, slot->userdata);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "sd-netlink: timedout callback %s%s%sfailed: %m",
|
||||
slot->description ? "'" : "",
|
||||
@@ -385,23 +382,23 @@ static int process_timeout(sd_netlink *rtnl) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int process_reply(sd_netlink *rtnl, sd_netlink_message *m) {
|
||||
static int process_reply(sd_netlink *nl, sd_netlink_message *m) {
|
||||
struct reply_callback *c;
|
||||
sd_netlink_slot *slot;
|
||||
uint32_t serial;
|
||||
uint16_t type;
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(nl);
|
||||
assert(m);
|
||||
|
||||
serial = rtnl_message_get_serial(m);
|
||||
c = hashmap_remove(rtnl->reply_callbacks, UINT32_TO_PTR(serial));
|
||||
serial = message_get_serial(m);
|
||||
c = hashmap_remove(nl->reply_callbacks, UINT32_TO_PTR(serial));
|
||||
if (!c)
|
||||
return 0;
|
||||
|
||||
if (c->timeout != 0) {
|
||||
prioq_remove(rtnl->reply_callbacks_prioq, c, &c->prioq_idx);
|
||||
prioq_remove(nl->reply_callbacks_prioq, c, &c->prioq_idx);
|
||||
c->timeout = 0;
|
||||
}
|
||||
|
||||
@@ -414,7 +411,7 @@ static int process_reply(sd_netlink *rtnl, sd_netlink_message *m) {
|
||||
|
||||
slot = container_of(c, sd_netlink_slot, reply_callback);
|
||||
|
||||
r = c->callback(rtnl, m, slot->userdata);
|
||||
r = c->callback(nl, m, slot->userdata);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "sd-netlink: reply callback %s%s%sfailed: %m",
|
||||
slot->description ? "'" : "",
|
||||
@@ -427,26 +424,26 @@ static int process_reply(sd_netlink *rtnl, sd_netlink_message *m) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int process_match(sd_netlink *rtnl, sd_netlink_message *m) {
|
||||
static int process_match(sd_netlink *nl, sd_netlink_message *m) {
|
||||
struct match_callback *c;
|
||||
sd_netlink_slot *slot;
|
||||
uint16_t type;
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(nl);
|
||||
assert(m);
|
||||
|
||||
r = sd_netlink_message_get_type(m, &type);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
LIST_FOREACH(match_callbacks, c, rtnl->match_callbacks) {
|
||||
LIST_FOREACH(match_callbacks, c, nl->match_callbacks) {
|
||||
if (type != c->type)
|
||||
continue;
|
||||
|
||||
slot = container_of(c, sd_netlink_slot, match_callback);
|
||||
|
||||
r = c->callback(rtnl, m, slot->userdata);
|
||||
r = c->callback(nl, m, slot->userdata);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "sd-netlink: match callback %s%s%sfailed: %m",
|
||||
slot->description ? "'" : "",
|
||||
@@ -459,28 +456,28 @@ static int process_match(sd_netlink *rtnl, sd_netlink_message *m) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int process_running(sd_netlink *rtnl, sd_netlink_message **ret) {
|
||||
static int process_running(sd_netlink *nl, sd_netlink_message **ret) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(nl);
|
||||
|
||||
r = process_timeout(rtnl);
|
||||
r = process_timeout(nl);
|
||||
if (r != 0)
|
||||
goto null_message;
|
||||
|
||||
r = dispatch_rqueue(rtnl, &m);
|
||||
r = dispatch_rqueue(nl, &m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (!m)
|
||||
goto null_message;
|
||||
|
||||
if (sd_netlink_message_is_broadcast(m)) {
|
||||
r = process_match(rtnl, m);
|
||||
r = process_match(nl, m);
|
||||
if (r != 0)
|
||||
goto null_message;
|
||||
} else {
|
||||
r = process_reply(rtnl, m);
|
||||
r = process_reply(nl, m);
|
||||
if (r != 0)
|
||||
goto null_message;
|
||||
}
|
||||
@@ -500,17 +497,17 @@ null_message:
|
||||
return r;
|
||||
}
|
||||
|
||||
int sd_netlink_process(sd_netlink *rtnl, sd_netlink_message **ret) {
|
||||
NETLINK_DONT_DESTROY(rtnl);
|
||||
int sd_netlink_process(sd_netlink *nl, sd_netlink_message **ret) {
|
||||
NETLINK_DONT_DESTROY(nl);
|
||||
int r;
|
||||
|
||||
assert_return(rtnl, -EINVAL);
|
||||
assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
|
||||
assert_return(!rtnl->processing, -EBUSY);
|
||||
assert_return(nl, -EINVAL);
|
||||
assert_return(!netlink_pid_changed(nl), -ECHILD);
|
||||
assert_return(!nl->processing, -EBUSY);
|
||||
|
||||
rtnl->processing = true;
|
||||
r = process_running(rtnl, ret);
|
||||
rtnl->processing = false;
|
||||
nl->processing = true;
|
||||
r = process_running(nl, ret);
|
||||
nl->processing = false;
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -520,18 +517,18 @@ static usec_t calc_elapse(uint64_t usec) {
|
||||
return 0;
|
||||
|
||||
if (usec == 0)
|
||||
usec = RTNL_DEFAULT_TIMEOUT;
|
||||
usec = NETLINK_DEFAULT_TIMEOUT_USEC;
|
||||
|
||||
return usec_add(now(CLOCK_MONOTONIC), usec);
|
||||
}
|
||||
|
||||
static int rtnl_poll(sd_netlink *rtnl, bool need_more, usec_t timeout_usec) {
|
||||
static int netlink_poll(sd_netlink *nl, bool need_more, usec_t timeout_usec) {
|
||||
usec_t m = USEC_INFINITY;
|
||||
int r, e;
|
||||
|
||||
assert(rtnl);
|
||||
assert(nl);
|
||||
|
||||
e = sd_netlink_get_events(rtnl);
|
||||
e = sd_netlink_get_events(nl);
|
||||
if (e < 0)
|
||||
return e;
|
||||
|
||||
@@ -545,14 +542,14 @@ static int rtnl_poll(sd_netlink *rtnl, bool need_more, usec_t timeout_usec) {
|
||||
/* Caller wants to process if there is something to
|
||||
* process, but doesn't care otherwise */
|
||||
|
||||
r = sd_netlink_get_timeout(rtnl, &until);
|
||||
r = sd_netlink_get_timeout(nl, &until);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
m = usec_sub_unsigned(until, now(CLOCK_MONOTONIC));
|
||||
}
|
||||
|
||||
r = fd_wait_for_event(rtnl->fd, e, MIN(m, timeout_usec));
|
||||
r = fd_wait_for_event(nl->fd, e, MIN(m, timeout_usec));
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@@ -561,12 +558,12 @@ static int rtnl_poll(sd_netlink *rtnl, bool need_more, usec_t timeout_usec) {
|
||||
|
||||
int sd_netlink_wait(sd_netlink *nl, uint64_t timeout_usec) {
|
||||
assert_return(nl, -EINVAL);
|
||||
assert_return(!rtnl_pid_changed(nl), -ECHILD);
|
||||
assert_return(!netlink_pid_changed(nl), -ECHILD);
|
||||
|
||||
if (nl->rqueue_size > 0)
|
||||
return 0;
|
||||
|
||||
return rtnl_poll(nl, false, timeout_usec);
|
||||
return netlink_poll(nl, false, timeout_usec);
|
||||
}
|
||||
|
||||
static int timeout_compare(const void *a, const void *b) {
|
||||
@@ -597,7 +594,7 @@ int sd_netlink_call_async(
|
||||
assert_return(nl, -EINVAL);
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(callback, -EINVAL);
|
||||
assert_return(!rtnl_pid_changed(nl), -ECHILD);
|
||||
assert_return(!netlink_pid_changed(nl), -ECHILD);
|
||||
|
||||
if (hashmap_size(nl->reply_callbacks) >= REPLY_CALLBACKS_MAX)
|
||||
return -ERANGE;
|
||||
@@ -647,7 +644,7 @@ int sd_netlink_call_async(
|
||||
}
|
||||
|
||||
int sd_netlink_read(
|
||||
sd_netlink *rtnl,
|
||||
sd_netlink *nl,
|
||||
uint32_t serial,
|
||||
uint64_t usec,
|
||||
sd_netlink_message **ret) {
|
||||
@@ -655,29 +652,29 @@ int sd_netlink_read(
|
||||
usec_t timeout;
|
||||
int r;
|
||||
|
||||
assert_return(rtnl, -EINVAL);
|
||||
assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
|
||||
assert_return(nl, -EINVAL);
|
||||
assert_return(!netlink_pid_changed(nl), -ECHILD);
|
||||
|
||||
timeout = calc_elapse(usec);
|
||||
|
||||
for (;;) {
|
||||
usec_t left;
|
||||
|
||||
for (unsigned i = 0; i < rtnl->rqueue_size; i++) {
|
||||
for (unsigned i = 0; i < nl->rqueue_size; i++) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *incoming = NULL;
|
||||
uint32_t received_serial;
|
||||
uint16_t type;
|
||||
|
||||
received_serial = rtnl_message_get_serial(rtnl->rqueue[i]);
|
||||
received_serial = message_get_serial(nl->rqueue[i]);
|
||||
if (received_serial != serial)
|
||||
continue;
|
||||
|
||||
incoming = rtnl->rqueue[i];
|
||||
incoming = nl->rqueue[i];
|
||||
|
||||
/* found a match, remove from rqueue and return it */
|
||||
memmove(rtnl->rqueue + i,rtnl->rqueue + i + 1,
|
||||
sizeof(sd_netlink_message*) * (rtnl->rqueue_size - i - 1));
|
||||
rtnl->rqueue_size--;
|
||||
memmove(nl->rqueue + i, nl->rqueue + i + 1,
|
||||
sizeof(sd_netlink_message*) * (nl->rqueue_size - i - 1));
|
||||
nl->rqueue_size--;
|
||||
|
||||
r = sd_netlink_message_get_errno(incoming);
|
||||
if (r < 0)
|
||||
@@ -697,7 +694,7 @@ int sd_netlink_read(
|
||||
return 1;
|
||||
}
|
||||
|
||||
r = socket_read_message(rtnl);
|
||||
r = socket_read_message(nl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0)
|
||||
@@ -715,7 +712,7 @@ int sd_netlink_read(
|
||||
} else
|
||||
left = USEC_INFINITY;
|
||||
|
||||
r = rtnl_poll(rtnl, true, left);
|
||||
r = netlink_poll(nl, true, left);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
@@ -724,7 +721,7 @@ int sd_netlink_read(
|
||||
}
|
||||
|
||||
int sd_netlink_call(
|
||||
sd_netlink *rtnl,
|
||||
sd_netlink *nl,
|
||||
sd_netlink_message *message,
|
||||
uint64_t usec,
|
||||
sd_netlink_message **ret) {
|
||||
@@ -732,37 +729,37 @@ int sd_netlink_call(
|
||||
uint32_t serial;
|
||||
int r;
|
||||
|
||||
assert_return(rtnl, -EINVAL);
|
||||
assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
|
||||
assert_return(nl, -EINVAL);
|
||||
assert_return(!netlink_pid_changed(nl), -ECHILD);
|
||||
assert_return(message, -EINVAL);
|
||||
|
||||
r = sd_netlink_send(rtnl, message, &serial);
|
||||
r = sd_netlink_send(nl, message, &serial);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return sd_netlink_read(rtnl, serial, usec, ret);
|
||||
return sd_netlink_read(nl, serial, usec, ret);
|
||||
}
|
||||
|
||||
int sd_netlink_get_events(sd_netlink *rtnl) {
|
||||
assert_return(rtnl, -EINVAL);
|
||||
assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
|
||||
int sd_netlink_get_events(sd_netlink *nl) {
|
||||
assert_return(nl, -EINVAL);
|
||||
assert_return(!netlink_pid_changed(nl), -ECHILD);
|
||||
|
||||
return rtnl->rqueue_size == 0 ? POLLIN : 0;
|
||||
return nl->rqueue_size == 0 ? POLLIN : 0;
|
||||
}
|
||||
|
||||
int sd_netlink_get_timeout(sd_netlink *rtnl, uint64_t *timeout_usec) {
|
||||
int sd_netlink_get_timeout(sd_netlink *nl, uint64_t *timeout_usec) {
|
||||
struct reply_callback *c;
|
||||
|
||||
assert_return(rtnl, -EINVAL);
|
||||
assert_return(nl, -EINVAL);
|
||||
assert_return(timeout_usec, -EINVAL);
|
||||
assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
|
||||
assert_return(!netlink_pid_changed(nl), -ECHILD);
|
||||
|
||||
if (rtnl->rqueue_size > 0) {
|
||||
if (nl->rqueue_size > 0) {
|
||||
*timeout_usec = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
c = prioq_peek(rtnl->reply_callbacks_prioq);
|
||||
c = prioq_peek(nl->reply_callbacks_prioq);
|
||||
if (!c) {
|
||||
*timeout_usec = UINT64_MAX;
|
||||
return 0;
|
||||
@@ -774,12 +771,12 @@ int sd_netlink_get_timeout(sd_netlink *rtnl, uint64_t *timeout_usec) {
|
||||
}
|
||||
|
||||
static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
|
||||
sd_netlink *rtnl = userdata;
|
||||
sd_netlink *nl = userdata;
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(nl);
|
||||
|
||||
r = sd_netlink_process(rtnl, NULL);
|
||||
r = sd_netlink_process(nl, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -787,12 +784,12 @@ static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userd
|
||||
}
|
||||
|
||||
static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) {
|
||||
sd_netlink *rtnl = userdata;
|
||||
sd_netlink *nl = userdata;
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(nl);
|
||||
|
||||
r = sd_netlink_process(rtnl, NULL);
|
||||
r = sd_netlink_process(nl, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -800,100 +797,100 @@ static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) {
|
||||
}
|
||||
|
||||
static int prepare_callback(sd_event_source *s, void *userdata) {
|
||||
sd_netlink *rtnl = userdata;
|
||||
sd_netlink *nl = userdata;
|
||||
int r, e;
|
||||
usec_t until;
|
||||
|
||||
assert(s);
|
||||
assert(rtnl);
|
||||
assert(nl);
|
||||
|
||||
e = sd_netlink_get_events(rtnl);
|
||||
e = sd_netlink_get_events(nl);
|
||||
if (e < 0)
|
||||
return e;
|
||||
|
||||
r = sd_event_source_set_io_events(rtnl->io_event_source, e);
|
||||
r = sd_event_source_set_io_events(nl->io_event_source, e);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_get_timeout(rtnl, &until);
|
||||
r = sd_netlink_get_timeout(nl, &until);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0) {
|
||||
int j;
|
||||
|
||||
j = sd_event_source_set_time(rtnl->time_event_source, until);
|
||||
j = sd_event_source_set_time(nl->time_event_source, until);
|
||||
if (j < 0)
|
||||
return j;
|
||||
}
|
||||
|
||||
r = sd_event_source_set_enabled(rtnl->time_event_source, r > 0);
|
||||
r = sd_event_source_set_enabled(nl->time_event_source, r > 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sd_netlink_attach_event(sd_netlink *rtnl, sd_event *event, int64_t priority) {
|
||||
int sd_netlink_attach_event(sd_netlink *nl, sd_event *event, int64_t priority) {
|
||||
int r;
|
||||
|
||||
assert_return(rtnl, -EINVAL);
|
||||
assert_return(!rtnl->event, -EBUSY);
|
||||
assert_return(nl, -EINVAL);
|
||||
assert_return(!nl->event, -EBUSY);
|
||||
|
||||
assert(!rtnl->io_event_source);
|
||||
assert(!rtnl->time_event_source);
|
||||
assert(!nl->io_event_source);
|
||||
assert(!nl->time_event_source);
|
||||
|
||||
if (event)
|
||||
rtnl->event = sd_event_ref(event);
|
||||
nl->event = sd_event_ref(event);
|
||||
else {
|
||||
r = sd_event_default(&rtnl->event);
|
||||
r = sd_event_default(&nl->event);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_event_add_io(rtnl->event, &rtnl->io_event_source, rtnl->fd, 0, io_callback, rtnl);
|
||||
r = sd_event_add_io(nl->event, &nl->io_event_source, nl->fd, 0, io_callback, nl);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
r = sd_event_source_set_priority(rtnl->io_event_source, priority);
|
||||
r = sd_event_source_set_priority(nl->io_event_source, priority);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
r = sd_event_source_set_description(rtnl->io_event_source, "rtnl-receive-message");
|
||||
r = sd_event_source_set_description(nl->io_event_source, "netlink-receive-message");
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
r = sd_event_source_set_prepare(rtnl->io_event_source, prepare_callback);
|
||||
r = sd_event_source_set_prepare(nl->io_event_source, prepare_callback);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
r = sd_event_add_time(rtnl->event, &rtnl->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, rtnl);
|
||||
r = sd_event_add_time(nl->event, &nl->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, nl);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
r = sd_event_source_set_priority(rtnl->time_event_source, priority);
|
||||
r = sd_event_source_set_priority(nl->time_event_source, priority);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
r = sd_event_source_set_description(rtnl->time_event_source, "rtnl-timer");
|
||||
r = sd_event_source_set_description(nl->time_event_source, "netlink-timer");
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
sd_netlink_detach_event(rtnl);
|
||||
sd_netlink_detach_event(nl);
|
||||
return r;
|
||||
}
|
||||
|
||||
int sd_netlink_detach_event(sd_netlink *rtnl) {
|
||||
assert_return(rtnl, -EINVAL);
|
||||
assert_return(rtnl->event, -ENXIO);
|
||||
int sd_netlink_detach_event(sd_netlink *nl) {
|
||||
assert_return(nl, -EINVAL);
|
||||
assert_return(nl->event, -ENXIO);
|
||||
|
||||
rtnl->io_event_source = sd_event_source_unref(rtnl->io_event_source);
|
||||
nl->io_event_source = sd_event_source_unref(nl->io_event_source);
|
||||
|
||||
rtnl->time_event_source = sd_event_source_unref(rtnl->time_event_source);
|
||||
nl->time_event_source = sd_event_source_unref(nl->time_event_source);
|
||||
|
||||
rtnl->event = sd_event_unref(rtnl->event);
|
||||
nl->event = sd_event_unref(nl->event);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -906,12 +903,13 @@ int sd_netlink_add_match(
|
||||
sd_netlink_destroy_t destroy_callback,
|
||||
void *userdata,
|
||||
const char *description) {
|
||||
|
||||
_cleanup_free_ sd_netlink_slot *slot = NULL;
|
||||
int r;
|
||||
|
||||
assert_return(rtnl, -EINVAL);
|
||||
assert_return(callback, -EINVAL);
|
||||
assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
|
||||
assert_return(!netlink_pid_changed(rtnl), -ECHILD);
|
||||
|
||||
r = netlink_slot_allocate(rtnl, !ret_slot, NETLINK_MATCH_CALLBACK, sizeof(struct match_callback), userdata, description, &slot);
|
||||
if (r < 0)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "alloc-util.h"
|
||||
#include "ether-addr-util.h"
|
||||
#include "macro.h"
|
||||
#include "netlink-internal.h"
|
||||
#include "netlink-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "stdio-util.h"
|
||||
@@ -502,7 +503,7 @@ static void test_message(sd_netlink *rtnl) {
|
||||
|
||||
log_debug("/* %s */", __func__);
|
||||
|
||||
assert_se(rtnl_message_new_synthetic_error(rtnl, -ETIMEDOUT, 1, &m) >= 0);
|
||||
assert_se(message_new_synthetic_error(rtnl, -ETIMEDOUT, 1, &m) >= 0);
|
||||
assert_se(sd_netlink_message_get_errno(m) == -ETIMEDOUT);
|
||||
}
|
||||
|
||||
@@ -528,7 +529,7 @@ static void test_array(void) {
|
||||
}
|
||||
assert_se(sd_netlink_message_close_container(m) >= 0);
|
||||
|
||||
rtnl_message_seal(m);
|
||||
message_seal(m);
|
||||
assert_se(sd_netlink_message_rewind(m, genl) >= 0);
|
||||
|
||||
assert_se(sd_netlink_message_enter_container(m, CTRL_ATTR_MCAST_GROUPS) >= 0);
|
||||
@@ -569,7 +570,7 @@ static void test_strv(sd_netlink *rtnl) {
|
||||
assert_se(sd_netlink_message_append_strv(m, IFLA_ALT_IFNAME, names_in) >= 0);
|
||||
assert_se(sd_netlink_message_close_container(m) >= 0);
|
||||
|
||||
rtnl_message_seal(m);
|
||||
message_seal(m);
|
||||
assert_se(sd_netlink_message_rewind(m, NULL) >= 0);
|
||||
|
||||
assert_se(sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &names_out) >= 0);
|
||||
|
||||
+10
-10
@@ -50,12 +50,11 @@ typedef enum sd_genl_family_t {
|
||||
} sd_genl_family_t;
|
||||
|
||||
/* callback */
|
||||
|
||||
typedef int (*sd_netlink_message_handler_t)(sd_netlink *nl, sd_netlink_message *m, void *userdata);
|
||||
typedef _sd_destroy_t sd_netlink_destroy_t;
|
||||
|
||||
/* bus */
|
||||
int sd_netlink_new_from_netlink(sd_netlink **nl, int fd);
|
||||
int sd_netlink_new_from_fd(sd_netlink **nl, int fd);
|
||||
int sd_netlink_open(sd_netlink **nl);
|
||||
int sd_netlink_open_fd(sd_netlink **nl, int fd);
|
||||
int sd_netlink_inc_rcvbuf(sd_netlink *nl, const size_t size);
|
||||
@@ -85,6 +84,7 @@ int sd_netlink_add_match(sd_netlink *nl, sd_netlink_slot **ret_slot, uint16_t ma
|
||||
int sd_netlink_attach_event(sd_netlink *nl, sd_event *e, int64_t priority);
|
||||
int sd_netlink_detach_event(sd_netlink *nl);
|
||||
|
||||
/* message */
|
||||
int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, const char *data);
|
||||
int sd_netlink_message_append_strv(sd_netlink_message *m, unsigned short type, char * const *data);
|
||||
int sd_netlink_message_append_flag(sd_netlink_message *m, unsigned short type);
|
||||
@@ -181,12 +181,12 @@ int sd_rtnl_message_route_get_dst_prefixlen(sd_netlink_message *m, unsigned char
|
||||
int sd_rtnl_message_route_get_src_prefixlen(sd_netlink_message *m, unsigned char *src_len);
|
||||
int sd_rtnl_message_route_get_type(sd_netlink_message *m, unsigned char *type);
|
||||
|
||||
int sd_rtnl_message_new_nexthop(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nhmsg_type, int nh_family, unsigned char nh_protocol);
|
||||
int sd_rtnl_message_new_nexthop(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int nh_family, unsigned char nh_protocol);
|
||||
int sd_rtnl_message_nexthop_set_flags(sd_netlink_message *m, uint8_t flags);
|
||||
int sd_rtnl_message_nexthop_get_family(sd_netlink_message *m, uint8_t *family);
|
||||
int sd_rtnl_message_nexthop_get_protocol(sd_netlink_message *m, uint8_t *protocol);
|
||||
|
||||
int sd_rtnl_message_new_neigh(sd_netlink *nl, sd_netlink_message **ret, uint16_t msg_type, int index, int nda_family);
|
||||
int sd_rtnl_message_new_neigh(sd_netlink *nl, sd_netlink_message **ret, uint16_t nlmsg_type, int index, int nda_family);
|
||||
int sd_rtnl_message_neigh_set_flags(sd_netlink_message *m, uint8_t flags);
|
||||
int sd_rtnl_message_neigh_set_state(sd_netlink_message *m, uint16_t state);
|
||||
int sd_rtnl_message_neigh_get_family(sd_netlink_message *m, int *family);
|
||||
@@ -223,7 +223,7 @@ int sd_rtnl_message_set_tclass_handle(sd_netlink_message *m, uint32_t handle);
|
||||
int sd_rtnl_message_new_mdb(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int mdb_ifindex);
|
||||
|
||||
/* nfnl */
|
||||
int sd_nfnl_socket_open(sd_netlink **nl);
|
||||
int sd_nfnl_socket_open(sd_netlink **ret);
|
||||
int sd_nfnl_message_batch_begin(sd_netlink *nfnl, sd_netlink_message **ret);
|
||||
int sd_nfnl_message_batch_end(sd_netlink *nfnl, sd_netlink_message **ret);
|
||||
int sd_nfnl_nft_message_del_table(sd_netlink *nfnl, sd_netlink_message **ret,
|
||||
@@ -249,13 +249,13 @@ int sd_nfnl_nft_message_add_setelem(sd_netlink_message *m,
|
||||
int sd_nfnl_nft_message_add_setelem_end(sd_netlink_message *m);
|
||||
|
||||
/* genl */
|
||||
int sd_genl_socket_open(sd_netlink **nl);
|
||||
int sd_genl_message_new(sd_netlink *nl, sd_genl_family_t family, uint8_t cmd, sd_netlink_message **ret);
|
||||
int sd_genl_message_get_family(sd_netlink *nl, sd_netlink_message *m, sd_genl_family_t *ret);
|
||||
int sd_genl_socket_open(sd_netlink **ret);
|
||||
int sd_genl_message_new(sd_netlink *genl, sd_genl_family_t family, uint8_t cmd, sd_netlink_message **ret);
|
||||
int sd_genl_message_get_family(sd_netlink *genl, sd_netlink_message *m, sd_genl_family_t *ret);
|
||||
|
||||
/* slot */
|
||||
sd_netlink_slot *sd_netlink_slot_ref(sd_netlink_slot *nl);
|
||||
sd_netlink_slot *sd_netlink_slot_unref(sd_netlink_slot *nl);
|
||||
sd_netlink_slot *sd_netlink_slot_ref(sd_netlink_slot *slot);
|
||||
sd_netlink_slot *sd_netlink_slot_unref(sd_netlink_slot *slot);
|
||||
|
||||
sd_netlink *sd_netlink_slot_get_netlink(sd_netlink_slot *slot);
|
||||
void *sd_netlink_slot_get_userdata(sd_netlink_slot *slot);
|
||||
|
||||
Reference in New Issue
Block a user