]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-netlink: introduce sd_genl_message_get_command()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 2 Jul 2021 21:21:45 +0000 (06:21 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 29 Aug 2021 09:10:47 +0000 (18:10 +0900)
src/libsystemd/sd-netlink/netlink-genl.c
src/libsystemd/sd-netlink/test-netlink.c
src/systemd/sd-netlink.h

index 8537e13316c78d91b5f1e19e2612b845b491bc6d..9f0ebba3df1a186db3472d0867d913e4d4ea469a 100644 (file)
@@ -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);
 }
index 6cc6cdad450f8815c38b60e8a3b7a95dfe3485b1..945f5b7bd5bcbc503b0fbb5c42d31e39d8f527aa 100644 (file)
@@ -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);
index 6bb93fdf17af30fe28924be66438a11170159a41..d7565d41e9803cab1634eb6e0a9611734b12a6c2 100644 (file)
@@ -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);