From: Yu Watanabe Date: Fri, 2 Jul 2021 21:21:45 +0000 (+0900) Subject: sd-netlink: introduce sd_genl_message_get_command() X-Git-Tag: v250-rc1~763^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ef90beb1c5c4041db8c33e28cea236567d40d1fd;p=thirdparty%2Fsystemd.git sd-netlink: introduce sd_genl_message_get_command() --- diff --git a/src/libsystemd/sd-netlink/netlink-genl.c b/src/libsystemd/sd-netlink/netlink-genl.c index 8537e13316c..9f0ebba3df1 100644 --- a/src/libsystemd/sd-netlink/netlink-genl.c +++ b/src/libsystemd/sd-netlink/netlink-genl.c @@ -60,6 +60,7 @@ static int genl_family_new( _cleanup_(genl_family_freep) GenericNetlinkFamily *f = NULL; const char *family_name; + uint8_t cmd; int r; assert(nl); @@ -105,6 +106,13 @@ static int genl_family_new( if (!streq(family_name, CTRL_GENL_NAME)) return -EINVAL; + r = sd_genl_message_get_command(nl, message, &cmd); + if (r < 0) + return r; + + if (cmd != CTRL_CMD_NEWFAMILY) + return -EINVAL; + r = sd_netlink_message_read_u16(message, CTRL_ATTR_FAMILY_ID, &f->id); if (r < 0) return r; @@ -335,6 +343,36 @@ int sd_genl_message_get_family_name(sd_netlink *nl, sd_netlink_message *m, const return 0; } +int sd_genl_message_get_command(sd_netlink *nl, sd_netlink_message *m, uint8_t *ret) { + struct genlmsghdr *h; + uint16_t nlmsg_type; + size_t size; + int r; + + assert_return(nl, -EINVAL); + assert_return(nl->protocol == NETLINK_GENERIC, -EINVAL); + assert_return(m, -EINVAL); + assert_return(m->protocol == NETLINK_GENERIC, -EINVAL); + assert_return(m->hdr, -EINVAL); + assert_return(ret, -EINVAL); + + r = sd_netlink_message_get_type(m, &nlmsg_type); + if (r < 0) + return r; + + r = genl_get_type_system_and_header_size(nl, nlmsg_type, NULL, &size); + if (r < 0) + return r; + + if (m->hdr->nlmsg_len < NLMSG_LENGTH(size)) + return -EBADMSG; + + h = NLMSG_DATA(m->hdr); + + *ret = h->cmd; + return 0; +} + int sd_genl_socket_open(sd_netlink **ret) { return netlink_open_family(ret, NETLINK_GENERIC); } diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c index 6cc6cdad450..945f5b7bd5b 100644 --- a/src/libsystemd/sd-netlink/test-netlink.c +++ b/src/libsystemd/sd-netlink/test-netlink.c @@ -587,6 +587,7 @@ static void test_genl(void) { _cleanup_(sd_netlink_unrefp) sd_netlink *genl = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; const char *name; + uint8_t cmd; log_debug("/* %s */", __func__); @@ -594,6 +595,8 @@ static void test_genl(void) { assert_se(sd_genl_message_new(genl, CTRL_GENL_NAME, CTRL_CMD_GETFAMILY, &m) >= 0); assert_se(sd_genl_message_get_family_name(genl, m, &name) >= 0); assert_se(streq(name, CTRL_GENL_NAME)); + assert_se(sd_genl_message_get_command(genl, m, &cmd) >= 0); + assert_se(cmd == CTRL_CMD_GETFAMILY); m = sd_netlink_message_unref(m); assert_se(sd_genl_message_new(genl, "should-not-exist", CTRL_CMD_GETFAMILY, &m) < 0); diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h index 6bb93fdf17a..d7565d41e98 100644 --- a/src/systemd/sd-netlink.h +++ b/src/systemd/sd-netlink.h @@ -237,6 +237,7 @@ int sd_nfnl_nft_message_add_setelem_end(sd_netlink_message *m); int sd_genl_socket_open(sd_netlink **ret); int sd_genl_message_new(sd_netlink *genl, const char *family_name, uint8_t cmd, sd_netlink_message **ret); int sd_genl_message_get_family_name(sd_netlink *genl, sd_netlink_message *m, const char **ret); +int sd_genl_message_get_command(sd_netlink *genl, sd_netlink_message *m, uint8_t *ret); /* slot */ sd_netlink_slot *sd_netlink_slot_ref(sd_netlink_slot *slot);