diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-11-26 01:17:14 +0100 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-11-26 03:28:27 +0100 |
commit | 9482429af9696ce16b90b2de97b15336235bcd30 (patch) | |
tree | e4570fb3e517b5e15ec0f803db42450c9fd504a9 | |
parent | sd-netlink: do not use serials currently queued (diff) | |
download | systemd-9482429af9696ce16b90b2de97b15336235bcd30.tar.xz systemd-9482429af9696ce16b90b2de97b15336235bcd30.zip |
sd-netlink: split out parse_message_one() from socket_read_message()
No functional change, just refactoring and preparation for later
commits.
-rw-r--r-- | src/libsystemd/sd-netlink/netlink-socket.c | 99 |
1 files changed, 60 insertions, 39 deletions
diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c index 3c7447c73c..1aaa4b712c 100644 --- a/src/libsystemd/sd-netlink/netlink-socket.c +++ b/src/libsystemd/sd-netlink/netlink-socket.c @@ -316,6 +316,60 @@ static int netlink_queue_partially_received_message(sd_netlink *nl, sd_netlink_m return 0; } +static int parse_message_one(sd_netlink *nl, uint32_t group, const struct nlmsghdr *hdr, sd_netlink_message **ret) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; + size_t size; + int r; + + assert(nl); + assert(hdr); + assert(ret); + + /* not broadcast and not for us */ + if (group == 0 && hdr->nlmsg_pid != nl->sockaddr.nl.nl_pid) + goto finalize; + + /* silently drop noop messages */ + if (hdr->nlmsg_type == NLMSG_NOOP) + goto finalize; + + /* check that we support this message type */ + r = netlink_get_policy_set_and_header_size(nl, hdr->nlmsg_type, NULL, &size); + if (r == -EOPNOTSUPP) { + log_debug("sd-netlink: ignored message with unknown type: %i", hdr->nlmsg_type); + goto finalize; + } + if (r < 0) + return r; + + /* check that the size matches the message type */ + if (hdr->nlmsg_len < NLMSG_LENGTH(size)) { + log_debug("sd-netlink: message is shorter than expected, dropping."); + goto finalize; + } + + r = message_new_empty(nl, &m); + if (r < 0) + return r; + + m->multicast_group = group; + m->hdr = memdup(hdr, hdr->nlmsg_len); + if (!m->hdr) + return -ENOMEM; + + /* seal and parse the top-level message */ + r = sd_netlink_message_rewind(m, nl); + if (r < 0) + return r; + + *ret = TAKE_PTR(m); + return 1; + +finalize: + *ret = NULL; + return 0; +} + /* On success, the number of bytes received is returned and *ret points to the received message * which has a valid header and the correct size. * If nothing useful was received 0 is returned. @@ -356,19 +410,16 @@ int socket_read_message(sd_netlink *nl) { first = hashmap_remove(nl->rqueue_partial_by_serial, UINT32_TO_PTR(nl->rbuffer->nlmsg_seq)); } - for (struct nlmsghdr *new_msg = nl->rbuffer; NLMSG_OK(new_msg, len) && !done; new_msg = NLMSG_NEXT(new_msg, len)) { + for (struct nlmsghdr *hdr = nl->rbuffer; NLMSG_OK(hdr, len) && !done; hdr = NLMSG_NEXT(hdr, len)) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; - size_t size; - - if (group == 0 && new_msg->nlmsg_pid != nl->sockaddr.nl.nl_pid) - /* not broadcast and not for us */ - continue; - if (new_msg->nlmsg_type == NLMSG_NOOP) - /* silently drop noop messages */ + r = parse_message_one(nl, group, hdr, &m); + if (r < 0) + return r; + if (r == 0) continue; - if (new_msg->nlmsg_type == NLMSG_DONE) { + if (hdr->nlmsg_type == NLMSG_DONE) { /* finished reading multi-part message */ done = true; @@ -377,36 +428,6 @@ int socket_read_message(sd_netlink *nl) { continue; } - /* check that we support this message type */ - r = netlink_get_policy_set_and_header_size(nl, new_msg->nlmsg_type, NULL, &size); - if (r < 0) { - if (r == -EOPNOTSUPP) - log_debug("sd-netlink: ignored message with unknown type: %i", - new_msg->nlmsg_type); - - continue; - } - - /* check that the size matches the message type */ - if (new_msg->nlmsg_len < NLMSG_LENGTH(size)) { - log_debug("sd-netlink: message is shorter than expected, dropping"); - continue; - } - - r = message_new_empty(nl, &m); - if (r < 0) - return r; - - m->multicast_group = group; - m->hdr = memdup(new_msg, new_msg->nlmsg_len); - if (!m->hdr) - return -ENOMEM; - - /* seal and parse the top-level message */ - r = sd_netlink_message_rewind(m, nl); - if (r < 0) - return r; - /* push the message onto the multi-part message stack */ if (first) m->next = first; |