From: Yu Watanabe Date: Wed, 31 Jul 2024 04:21:08 +0000 (+0900) Subject: socket-util: introduce netlink_socket_get_multicast_groups() X-Git-Tag: v257-rc1~772^2~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=029709f93210072a1c3dae8e851a76e3b2c3e857;p=thirdparty%2Fsystemd.git socket-util: introduce netlink_socket_get_multicast_groups() No functional change. Preparation for later commits. --- diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index 5849799f05d..c59c6a16a14 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -1767,3 +1767,38 @@ int vsock_get_local_cid(unsigned *ret) { return 0; } + +int netlink_socket_get_multicast_groups(int fd, size_t *ret_len, uint32_t **ret_groups) { + _cleanup_free_ uint32_t *groups = NULL; + socklen_t len = 0, old_len; + + assert(fd >= 0); + + /* This returns ENOPROTOOPT if the kernel is older than 4.2. */ + + if (getsockopt(fd, SOL_NETLINK, NETLINK_LIST_MEMBERSHIPS, NULL, &len) < 0) + return -errno; + + if (len == 0) + goto finalize; + + groups = new0(uint32_t, len); + if (!groups) + return -ENOMEM; + + old_len = len; + + if (getsockopt(fd, SOL_NETLINK, NETLINK_LIST_MEMBERSHIPS, groups, &len) < 0) + return -errno; + + if (old_len != len) + return -EIO; + +finalize: + if (ret_len) + *ret_len = len; + if (ret_groups) + *ret_groups = TAKE_PTR(groups); + + return 0; +} diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h index c784125ccb4..18699a5349e 100644 --- a/src/basic/socket-util.h +++ b/src/basic/socket-util.h @@ -396,3 +396,5 @@ int socket_address_parse_vsock(SocketAddress *ret_address, const char *s); #define SOMAXCONN_DELUXE INT_MAX int vsock_get_local_cid(unsigned *ret); + +int netlink_socket_get_multicast_groups(int fd, size_t *ret_len, uint32_t **ret_groups); diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c index d09dc31fa32..79729decbc2 100644 --- a/src/libsystemd/sd-netlink/netlink-socket.c +++ b/src/libsystemd/sd-netlink/netlink-socket.c @@ -17,36 +17,21 @@ static int broadcast_groups_get(sd_netlink *nl) { _cleanup_free_ uint32_t *groups = NULL; - socklen_t len = 0, old_len; + size_t len; int r; assert(nl); assert(nl->fd >= 0); - if (getsockopt(nl->fd, SOL_NETLINK, NETLINK_LIST_MEMBERSHIPS, NULL, &len) < 0) { - if (errno != ENOPROTOOPT) - return -errno; - + r = netlink_socket_get_multicast_groups(nl->fd, &len, &groups); + if (r == -ENOPROTOOPT) { nl->broadcast_group_dont_leave = true; return 0; } + if (r < 0) + return r; - if (len == 0) - return 0; - - groups = new0(uint32_t, len); - if (!groups) - return -ENOMEM; - - old_len = len; - - if (getsockopt(nl->fd, SOL_NETLINK, NETLINK_LIST_MEMBERSHIPS, groups, &len) < 0) - return -errno; - - if (old_len != len) - return -EIO; - - for (unsigned i = 0; i < len; i++) + for (size_t i = 0; i < len; i++) for (unsigned j = 0; j < sizeof(uint32_t) * 8; j++) if (groups[i] & (1U << j)) { unsigned group = i * sizeof(uint32_t) * 8 + j + 1;