mirror of
https://github.com/systemd/systemd
synced 2026-03-19 19:44:48 +01:00
Compare commits
8 Commits
e8f4bf33d8
...
d3a047b9d1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3a047b9d1 | ||
|
|
6cf4f7d10e | ||
|
|
11537375e3 | ||
|
|
2b01228800 | ||
|
|
7bb9f0d014 | ||
|
|
0f97cfb9be | ||
|
|
eee15fff40 | ||
|
|
db4735b7db |
@ -1720,7 +1720,7 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
|||||||
|
|
||||||
<para>This option should only be set to true when <varname>MACAddressPolicy=</varname> is
|
<para>This option should only be set to true when <varname>MACAddressPolicy=</varname> is
|
||||||
set to <option>random</option> (see
|
set to <option>random</option> (see
|
||||||
<citerefentry project='man-pages'><refentrytitle>systemd.link</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
|
<citerefentry><refentrytitle>systemd.link</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>When true, <varname>SendHostname=</varname>, <varname>ClientIdentifier=</varname>,
|
<para>When true, <varname>SendHostname=</varname>, <varname>ClientIdentifier=</varname>,
|
||||||
|
|||||||
@ -34,7 +34,9 @@ static int genl_message_new(sd_netlink *nl, sd_genl_family_t family, uint16_t nl
|
|||||||
size_t size;
|
size_t size;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert_return(nl->protocol == NETLINK_GENERIC, -EINVAL);
|
assert(nl);
|
||||||
|
assert(nl->protocol == NETLINK_GENERIC);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
r = type_system_get_type(&genl_family_type_system_root, &genl_cmd_type, family);
|
r = type_system_get_type(&genl_family_type_system_root, &genl_cmd_type, family);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -72,24 +74,28 @@ static int genl_message_new(sd_netlink *nl, sd_genl_family_t family, uint16_t nl
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lookup_id(sd_netlink *nl, sd_genl_family_t family, uint16_t *id) {
|
static int lookup_nlmsg_type(sd_netlink *nl, sd_genl_family_t family, uint16_t *ret) {
|
||||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
|
||||||
uint16_t u;
|
uint16_t u;
|
||||||
void *v;
|
void *v;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
assert(nl);
|
||||||
|
assert(nl->protocol == NETLINK_GENERIC);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
if (family == SD_GENL_ID_CTRL) {
|
if (family == SD_GENL_ID_CTRL) {
|
||||||
*id = GENL_ID_CTRL;
|
*ret = GENL_ID_CTRL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
v = hashmap_get(nl->genl_family_to_nlmsg_type, INT_TO_PTR(family));
|
v = hashmap_get(nl->genl_family_to_nlmsg_type, INT_TO_PTR(family));
|
||||||
if (v) {
|
if (v) {
|
||||||
*id = PTR_TO_UINT(v);
|
*ret = PTR_TO_UINT(v);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = sd_genl_message_new(nl, SD_GENL_ID_CTRL, CTRL_CMD_GETFAMILY, &req);
|
r = genl_message_new(nl, SD_GENL_ID_CTRL, GENL_ID_CTRL, CTRL_CMD_GETFAMILY, &req);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -113,36 +119,40 @@ static int lookup_id(sd_netlink *nl, sd_genl_family_t family, uint16_t *id) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
*id = u;
|
*ret = u;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_genl_message_new(sd_netlink *nl, sd_genl_family_t family, uint8_t cmd, sd_netlink_message **ret) {
|
int sd_genl_message_new(sd_netlink *nl, sd_genl_family_t family, uint8_t cmd, sd_netlink_message **ret) {
|
||||||
uint16_t id = 0; /* Unnecessary initialization to appease gcc */
|
uint16_t nlmsg_type = 0; /* Unnecessary initialization to appease gcc */
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = lookup_id(nl, family, &id);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
return genl_message_new(nl, family, id, cmd, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
int nlmsg_type_to_genl_family(const sd_netlink *nl, uint16_t type, sd_genl_family_t *ret) {
|
|
||||||
void *p;
|
|
||||||
|
|
||||||
assert_return(nl, -EINVAL);
|
assert_return(nl, -EINVAL);
|
||||||
assert_return(nl->protocol == NETLINK_GENERIC, -EINVAL);
|
assert_return(nl->protocol == NETLINK_GENERIC, -EINVAL);
|
||||||
|
assert_return(ret, -EINVAL);
|
||||||
|
|
||||||
|
r = lookup_nlmsg_type(nl, family, &nlmsg_type);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return genl_message_new(nl, family, nlmsg_type, cmd, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int nlmsg_type_to_genl_family(const sd_netlink *nl, uint16_t nlmsg_type, sd_genl_family_t *ret) {
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
assert(nl);
|
||||||
|
assert(nl->protocol == NETLINK_GENERIC);
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
if (type == NLMSG_ERROR)
|
if (nlmsg_type == NLMSG_ERROR)
|
||||||
*ret = SD_GENL_ERROR;
|
*ret = SD_GENL_ERROR;
|
||||||
else if (type == NLMSG_DONE)
|
else if (nlmsg_type == NLMSG_DONE)
|
||||||
*ret = SD_GENL_DONE;
|
*ret = SD_GENL_DONE;
|
||||||
else if (type == GENL_ID_CTRL)
|
else if (nlmsg_type == GENL_ID_CTRL)
|
||||||
*ret = SD_GENL_ID_CTRL;
|
*ret = SD_GENL_ID_CTRL;
|
||||||
else {
|
else {
|
||||||
p = hashmap_get(nl->nlmsg_type_to_genl_family, UINT_TO_PTR(type));
|
p = hashmap_get(nl->nlmsg_type_to_genl_family, UINT_TO_PTR(nlmsg_type));
|
||||||
if (!p)
|
if (!p)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
@ -152,18 +162,18 @@ int nlmsg_type_to_genl_family(const sd_netlink *nl, uint16_t type, sd_genl_famil
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_genl_message_get_family(sd_netlink *nl, sd_netlink_message *m, sd_genl_family_t *family) {
|
int sd_genl_message_get_family(sd_netlink *nl, sd_netlink_message *m, sd_genl_family_t *ret) {
|
||||||
uint16_t type;
|
uint16_t nlmsg_type;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert_return(m, -EINVAL);
|
|
||||||
assert_return(nl, -EINVAL);
|
assert_return(nl, -EINVAL);
|
||||||
assert_return(nl->protocol == NETLINK_GENERIC, -EINVAL);
|
assert_return(nl->protocol == NETLINK_GENERIC, -EINVAL);
|
||||||
assert_return(family, -EINVAL);
|
assert_return(m, -EINVAL);
|
||||||
|
assert_return(ret, -EINVAL);
|
||||||
|
|
||||||
r = sd_netlink_message_get_type(m, &type);
|
r = sd_netlink_message_get_type(m, &nlmsg_type);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
return nlmsg_type_to_genl_family(nl, type, family);
|
return nlmsg_type_to_genl_family(nl, nlmsg_type, ret);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,8 +35,7 @@ static int broadcast_groups_get(sd_netlink *nl) {
|
|||||||
assert(nl);
|
assert(nl);
|
||||||
assert(nl->fd >= 0);
|
assert(nl->fd >= 0);
|
||||||
|
|
||||||
r = getsockopt(nl->fd, SOL_NETLINK, NETLINK_LIST_MEMBERSHIPS, NULL, &len);
|
if (getsockopt(nl->fd, SOL_NETLINK, NETLINK_LIST_MEMBERSHIPS, NULL, &len) < 0) {
|
||||||
if (r < 0) {
|
|
||||||
if (errno != ENOPROTOOPT)
|
if (errno != ENOPROTOOPT)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
@ -53,23 +52,18 @@ static int broadcast_groups_get(sd_netlink *nl) {
|
|||||||
|
|
||||||
old_len = len;
|
old_len = len;
|
||||||
|
|
||||||
r = getsockopt(nl->fd, SOL_NETLINK, NETLINK_LIST_MEMBERSHIPS, groups, &len);
|
if (getsockopt(nl->fd, SOL_NETLINK, NETLINK_LIST_MEMBERSHIPS, groups, &len) < 0)
|
||||||
if (r < 0)
|
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (old_len != len)
|
if (old_len != len)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
r = hashmap_ensure_allocated(&nl->broadcast_group_refs, NULL);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < len; i++)
|
for (unsigned i = 0; i < len; i++)
|
||||||
for (unsigned j = 0; j < sizeof(uint32_t) * 8; j++)
|
for (unsigned j = 0; j < sizeof(uint32_t) * 8; j++)
|
||||||
if (groups[i] & (1U << j)) {
|
if (groups[i] & (1U << j)) {
|
||||||
unsigned group = i * sizeof(uint32_t) * 8 + j + 1;
|
unsigned group = i * sizeof(uint32_t) * 8 + j + 1;
|
||||||
|
|
||||||
r = hashmap_put(nl->broadcast_group_refs, UINT_TO_PTR(group), UINT_TO_PTR(1));
|
r = hashmap_ensure_put(&nl->broadcast_group_refs, NULL, UINT_TO_PTR(group), UINT_TO_PTR(1));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -88,7 +82,7 @@ int socket_bind(sd_netlink *nl) {
|
|||||||
addrlen = sizeof(nl->sockaddr);
|
addrlen = sizeof(nl->sockaddr);
|
||||||
|
|
||||||
r = bind(nl->fd, &nl->sockaddr.sa, addrlen);
|
r = bind(nl->fd, &nl->sockaddr.sa, addrlen);
|
||||||
/* ignore EINVAL to allow opening an already bound socket */
|
/* ignore EINVAL to allow binding an already bound socket */
|
||||||
if (r < 0 && errno != EINVAL)
|
if (r < 0 && errno != EINVAL)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
@ -110,11 +104,11 @@ static int broadcast_group_set_ref(sd_netlink *nl, unsigned group, unsigned n_re
|
|||||||
|
|
||||||
assert(nl);
|
assert(nl);
|
||||||
|
|
||||||
r = hashmap_replace(nl->broadcast_group_refs, UINT_TO_PTR(group), UINT_TO_PTR(n_ref));
|
r = hashmap_ensure_allocated(&nl->broadcast_group_refs, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
return 0;
|
return hashmap_replace(nl->broadcast_group_refs, UINT_TO_PTR(group), UINT_TO_PTR(n_ref));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int broadcast_group_join(sd_netlink *nl, unsigned group) {
|
static int broadcast_group_join(sd_netlink *nl, unsigned group) {
|
||||||
@ -136,23 +130,15 @@ int socket_broadcast_group_ref(sd_netlink *nl, unsigned group) {
|
|||||||
|
|
||||||
n_ref++;
|
n_ref++;
|
||||||
|
|
||||||
r = hashmap_ensure_allocated(&nl->broadcast_group_refs, NULL);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = broadcast_group_set_ref(nl, group, n_ref);
|
r = broadcast_group_set_ref(nl, group, n_ref);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (n_ref > 1)
|
if (n_ref > 1)
|
||||||
/* not yet in the group */
|
/* already in the group */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = broadcast_group_join(nl, group);
|
return broadcast_group_join(nl, group);
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int broadcast_group_leave(sd_netlink *nl, unsigned group) {
|
static int broadcast_group_leave(sd_netlink *nl, unsigned group) {
|
||||||
@ -174,8 +160,8 @@ int socket_broadcast_group_unref(sd_netlink *nl, unsigned group) {
|
|||||||
assert(nl);
|
assert(nl);
|
||||||
|
|
||||||
n_ref = broadcast_group_get_ref(nl, group);
|
n_ref = broadcast_group_get_ref(nl, group);
|
||||||
|
if (n_ref == 0)
|
||||||
assert(n_ref > 0);
|
return 0;
|
||||||
|
|
||||||
n_ref--;
|
n_ref--;
|
||||||
|
|
||||||
@ -187,19 +173,12 @@ int socket_broadcast_group_unref(sd_netlink *nl, unsigned group) {
|
|||||||
/* still refs left */
|
/* still refs left */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = broadcast_group_leave(nl, group);
|
return broadcast_group_leave(nl, group);
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns the number of bytes sent, or a negative error code */
|
/* returns the number of bytes sent, or a negative error code */
|
||||||
int socket_write_message(sd_netlink *nl, sd_netlink_message *m) {
|
int socket_write_message(sd_netlink *nl, sd_netlink_message *m) {
|
||||||
union {
|
union sockaddr_union addr = {
|
||||||
struct sockaddr sa;
|
|
||||||
struct sockaddr_nl nl;
|
|
||||||
} addr = {
|
|
||||||
.nl.nl_family = AF_NETLINK,
|
.nl.nl_family = AF_NETLINK,
|
||||||
};
|
};
|
||||||
ssize_t k;
|
ssize_t k;
|
||||||
@ -208,8 +187,7 @@ int socket_write_message(sd_netlink *nl, sd_netlink_message *m) {
|
|||||||
assert(m);
|
assert(m);
|
||||||
assert(m->hdr);
|
assert(m->hdr);
|
||||||
|
|
||||||
k = sendto(nl->fd, m->hdr, m->hdr->nlmsg_len,
|
k = sendto(nl->fd, m->hdr, m->hdr->nlmsg_len, 0, &addr.sa, sizeof(addr));
|
||||||
0, &addr.sa, sizeof(addr));
|
|
||||||
if (k < 0)
|
if (k < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
@ -218,22 +196,24 @@ 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_writev_message(sd_netlink *nl, sd_netlink_message **m, size_t msgcount) {
|
||||||
_cleanup_free_ struct iovec *iovs = NULL;
|
_cleanup_free_ struct iovec *iovs = NULL;
|
||||||
|
ssize_t k;
|
||||||
|
|
||||||
assert(nl);
|
assert(nl);
|
||||||
assert(m);
|
assert(m);
|
||||||
assert(msgcount > 0);
|
assert(msgcount > 0);
|
||||||
|
|
||||||
iovs = new0(struct iovec, msgcount);
|
iovs = new(struct iovec, msgcount);
|
||||||
if (!iovs)
|
if (!iovs)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
for (size_t i = 0; i < msgcount; i++) {
|
for (size_t i = 0; i < msgcount; i++) {
|
||||||
assert(m[i]->hdr != NULL);
|
assert(m[i]->hdr);
|
||||||
assert(m[i]->hdr->nlmsg_len > 0);
|
assert(m[i]->hdr->nlmsg_len > 0);
|
||||||
|
|
||||||
iovs[i] = IOVEC_MAKE(m[i]->hdr, m[i]->hdr->nlmsg_len);
|
iovs[i] = IOVEC_MAKE(m[i]->hdr, m[i]->hdr->nlmsg_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t k = writev(nl->fd, iovs, msgcount);
|
k = writev(nl->fd, iovs, msgcount);
|
||||||
if (k < 0)
|
if (k < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
@ -266,7 +246,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_gr
|
|||||||
|
|
||||||
if (sender.nl.nl_pid != 0) {
|
if (sender.nl.nl_pid != 0) {
|
||||||
/* not from the kernel, ignore */
|
/* not from the kernel, ignore */
|
||||||
log_debug("rtnl: ignoring message from portid %"PRIu32, sender.nl.nl_pid);
|
log_debug("rtnl: ignoring message from PID %"PRIu32, sender.nl.nl_pid);
|
||||||
|
|
||||||
if (peek) {
|
if (peek) {
|
||||||
/* drop the message */
|
/* drop the message */
|
||||||
@ -336,14 +316,13 @@ int socket_read_message(sd_netlink *rtnl) {
|
|||||||
if (NLMSG_OK(rtnl->rbuffer, len) && rtnl->rbuffer->nlmsg_flags & NLM_F_MULTI) {
|
if (NLMSG_OK(rtnl->rbuffer, len) && rtnl->rbuffer->nlmsg_flags & NLM_F_MULTI) {
|
||||||
multi_part = true;
|
multi_part = true;
|
||||||
|
|
||||||
for (i = 0; i < rtnl->rqueue_partial_size; i++) {
|
for (i = 0; i < rtnl->rqueue_partial_size; i++)
|
||||||
if (rtnl_message_get_serial(rtnl->rqueue_partial[i]) ==
|
if (rtnl_message_get_serial(rtnl->rqueue_partial[i]) ==
|
||||||
rtnl->rbuffer->nlmsg_seq) {
|
rtnl->rbuffer->nlmsg_seq) {
|
||||||
first = rtnl->rqueue_partial[i];
|
first = rtnl->rqueue_partial[i];
|
||||||
break;
|
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 = rtnl->rbuffer; NLMSG_OK(new_msg, len) && !done; new_msg = NLMSG_NEXT(new_msg, len)) {
|
||||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||||
|
|||||||
@ -254,12 +254,13 @@ int sd_netlink_send(sd_netlink *nl,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_netlink_sendv(sd_netlink *nl,
|
int sd_netlink_sendv(
|
||||||
|
sd_netlink *nl,
|
||||||
sd_netlink_message **messages,
|
sd_netlink_message **messages,
|
||||||
size_t msgcount,
|
size_t msgcount,
|
||||||
uint32_t **ret_serial) {
|
uint32_t **ret_serial) {
|
||||||
|
|
||||||
_cleanup_free_ uint32_t *serials = NULL;
|
_cleanup_free_ uint32_t *serials = NULL;
|
||||||
unsigned i;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert_return(nl, -EINVAL);
|
assert_return(nl, -EINVAL);
|
||||||
@ -268,13 +269,14 @@ int sd_netlink_sendv(sd_netlink *nl,
|
|||||||
assert_return(msgcount > 0, -EINVAL);
|
assert_return(msgcount > 0, -EINVAL);
|
||||||
|
|
||||||
if (ret_serial) {
|
if (ret_serial) {
|
||||||
serials = new0(uint32_t, msgcount);
|
serials = new(uint32_t, msgcount);
|
||||||
if (!serials)
|
if (!serials)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < msgcount; i++) {
|
for (unsigned i = 0; i < msgcount; i++) {
|
||||||
assert_return(!messages[i]->sealed, -EPERM);
|
assert_return(!messages[i]->sealed, -EPERM);
|
||||||
|
|
||||||
rtnl_seal_message(nl, messages[i]);
|
rtnl_seal_message(nl, messages[i]);
|
||||||
if (serials)
|
if (serials)
|
||||||
serials[i] = rtnl_message_get_serial(messages[i]);
|
serials[i] = rtnl_message_get_serial(messages[i]);
|
||||||
@ -523,7 +525,7 @@ static usec_t calc_elapse(uint64_t usec) {
|
|||||||
return usec_add(now(CLOCK_MONOTONIC), usec);
|
return usec_add(now(CLOCK_MONOTONIC), usec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rtnl_poll(sd_netlink *rtnl, bool need_more, uint64_t timeout_usec) {
|
static int rtnl_poll(sd_netlink *rtnl, bool need_more, usec_t timeout_usec) {
|
||||||
usec_t m = USEC_INFINITY;
|
usec_t m = USEC_INFINITY;
|
||||||
int r, e;
|
int r, e;
|
||||||
|
|
||||||
@ -539,23 +541,18 @@ static int rtnl_poll(sd_netlink *rtnl, bool need_more, uint64_t timeout_usec) {
|
|||||||
e |= POLLIN;
|
e |= POLLIN;
|
||||||
else {
|
else {
|
||||||
usec_t until;
|
usec_t until;
|
||||||
|
|
||||||
/* Caller wants to process if there is something to
|
/* Caller wants to process if there is something to
|
||||||
* process, but doesn't care otherwise */
|
* process, but doesn't care otherwise */
|
||||||
|
|
||||||
r = sd_netlink_get_timeout(rtnl, &until);
|
r = sd_netlink_get_timeout(rtnl, &until);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (r > 0) {
|
|
||||||
usec_t nw;
|
m = usec_sub_unsigned(until, now(CLOCK_MONOTONIC));
|
||||||
nw = now(CLOCK_MONOTONIC);
|
|
||||||
m = until > nw ? until - nw : 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeout_usec != UINT64_MAX && (m == USEC_INFINITY || timeout_usec < m))
|
r = fd_wait_for_event(rtnl->fd, e, MIN(m, timeout_usec));
|
||||||
m = timeout_usec;
|
|
||||||
|
|
||||||
r = fd_wait_for_event(rtnl->fd, e, m);
|
|
||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -593,6 +590,7 @@ int sd_netlink_call_async(
|
|||||||
void *userdata,
|
void *userdata,
|
||||||
uint64_t usec,
|
uint64_t usec,
|
||||||
const char *description) {
|
const char *description) {
|
||||||
|
|
||||||
_cleanup_free_ sd_netlink_slot *slot = NULL;
|
_cleanup_free_ sd_netlink_slot *slot = NULL;
|
||||||
int r, k;
|
int r, k;
|
||||||
|
|
||||||
@ -648,10 +646,12 @@ int sd_netlink_call_async(
|
|||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_netlink_read(sd_netlink *rtnl,
|
int sd_netlink_read(
|
||||||
|
sd_netlink *rtnl,
|
||||||
uint32_t serial,
|
uint32_t serial,
|
||||||
uint64_t usec,
|
uint64_t usec,
|
||||||
sd_netlink_message **ret) {
|
sd_netlink_message **ret) {
|
||||||
|
|
||||||
usec_t timeout;
|
usec_t timeout;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -662,16 +662,15 @@ int sd_netlink_read(sd_netlink *rtnl,
|
|||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
usec_t left;
|
usec_t left;
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < rtnl->rqueue_size; i++) {
|
for (unsigned i = 0; i < rtnl->rqueue_size; i++) {
|
||||||
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *incoming = NULL;
|
||||||
uint32_t received_serial;
|
uint32_t received_serial;
|
||||||
|
uint16_t type;
|
||||||
|
|
||||||
received_serial = rtnl_message_get_serial(rtnl->rqueue[i]);
|
received_serial = rtnl_message_get_serial(rtnl->rqueue[i]);
|
||||||
|
if (received_serial != serial)
|
||||||
if (received_serial == serial) {
|
continue;
|
||||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *incoming = NULL;
|
|
||||||
uint16_t type;
|
|
||||||
|
|
||||||
incoming = rtnl->rqueue[i];
|
incoming = rtnl->rqueue[i];
|
||||||
|
|
||||||
@ -695,10 +694,8 @@ int sd_netlink_read(sd_netlink *rtnl,
|
|||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
*ret = TAKE_PTR(incoming);
|
*ret = TAKE_PTR(incoming);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
r = socket_read_message(rtnl);
|
r = socket_read_message(rtnl);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -714,22 +711,24 @@ int sd_netlink_read(sd_netlink *rtnl,
|
|||||||
if (n >= timeout)
|
if (n >= timeout)
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
|
|
||||||
left = timeout - n;
|
left = usec_sub_unsigned(timeout, n);
|
||||||
} else
|
} else
|
||||||
left = UINT64_MAX;
|
left = USEC_INFINITY;
|
||||||
|
|
||||||
r = rtnl_poll(rtnl, true, left);
|
r = rtnl_poll(rtnl, true, left);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
else if (r == 0)
|
if (r == 0)
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
sd_netlink_message **ret) {
|
sd_netlink_message **ret) {
|
||||||
|
|
||||||
uint32_t serial;
|
uint32_t serial;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -748,10 +747,7 @@ int sd_netlink_get_events(sd_netlink *rtnl) {
|
|||||||
assert_return(rtnl, -EINVAL);
|
assert_return(rtnl, -EINVAL);
|
||||||
assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
|
assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
|
||||||
|
|
||||||
if (rtnl->rqueue_size == 0)
|
return rtnl->rqueue_size == 0 ? POLLIN : 0;
|
||||||
return POLLIN;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_netlink_get_timeout(sd_netlink *rtnl, uint64_t *timeout_usec) {
|
int sd_netlink_get_timeout(sd_netlink *rtnl, uint64_t *timeout_usec) {
|
||||||
|
|||||||
@ -251,8 +251,8 @@ int sd_nfnl_nft_message_add_setelem_end(sd_netlink_message *m);
|
|||||||
|
|
||||||
/* 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_t family, uint8_t cmd, sd_netlink_message **m);
|
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 *family);
|
int sd_genl_message_get_family(sd_netlink *nl, sd_netlink_message *m, sd_genl_family_t *ret);
|
||||||
|
|
||||||
/* slot */
|
/* slot */
|
||||||
sd_netlink_slot *sd_netlink_slot_ref(sd_netlink_slot *nl);
|
sd_netlink_slot *sd_netlink_slot_ref(sd_netlink_slot *nl);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user