]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-netlink: introduce sd_netlink_message_get_max_attribute()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 27 Aug 2021 07:30:19 +0000 (16:30 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 31 Aug 2021 12:18:34 +0000 (21:18 +0900)
src/libsystemd/sd-netlink/netlink-internal.h
src/libsystemd/sd-netlink/netlink-message.c
src/systemd/sd-netlink.h

index 050edaec78cb8ccac4ac11284d5d2798c96baf55..299b7d660bca5bd7f9e14d8fbfb8618e5c64e7bc 100644 (file)
@@ -112,7 +112,7 @@ struct netlink_container {
         const struct NLTypeSystem *type_system; /* the type system of the container */
         size_t offset; /* offset from hdr to the start of the container */
         struct netlink_attribute *attributes;
-        unsigned short n_attributes; /* number of attributes in container */
+        uint16_t max_attribute; /* the maximum attribute in container */
 };
 
 struct sd_netlink_message {
index e422d5699c83306ff341383c62859d80a4bc0bdb..2bfaff7ce0e7d1c052d7d0c537479bc826c76e88 100644 (file)
@@ -712,7 +712,7 @@ static int netlink_message_read_internal(
         if (!m->containers[m->n_containers].attributes)
                 return -ENODATA;
 
-        if (type >= m->containers[m->n_containers].n_attributes)
+        if (type > m->containers[m->n_containers].max_attribute)
                 return -ENODATA;
 
         attribute = &m->containers[m->n_containers].attributes[type];
@@ -1093,38 +1093,38 @@ int sd_netlink_message_read_strv(sd_netlink_message *m, unsigned short container
         return 0;
 }
 
-static int netlink_container_parse(sd_netlink_message *m,
-                                   struct netlink_container *container,
-                                   struct rtattr *rta,
-                                   size_t rt_len) {
+static int netlink_container_parse(
+                sd_netlink_message *m,
+                struct netlink_container *container,
+                struct rtattr *rta,
+                size_t rt_len) {
+
         _cleanup_free_ struct netlink_attribute *attributes = NULL;
-        size_t n = 0;
+        uint16_t max_attr = 0;
 
         /* RTA_OK() macro compares with rta->rt_len, which is unsigned short, and
          * LGTM.com analysis does not like the type difference. Hence, here we
          * introduce an unsigned short variable as a workaround. */
         unsigned short len = rt_len;
         for (; RTA_OK(rta, len); rta = RTA_NEXT(rta, len)) {
-                unsigned short type;
+                uint16_t attr;
 
-                type = RTA_TYPE(rta);
+                attr = RTA_TYPE(rta);
+                max_attr = MAX(max_attr, attr);
 
-                if (!GREEDY_REALLOC0(attributes, type + 1))
+                if (!GREEDY_REALLOC0(attributes, (size_t) max_attr + 1))
                         return -ENOMEM;
 
-                if (attributes[type].offset != 0)
+                if (attributes[attr].offset != 0)
                         log_debug("sd-netlink: message parse - overwriting repeated attribute");
 
-                attributes[type].offset = (uint8_t *) rta - (uint8_t *) m->hdr;
-                attributes[type].nested = RTA_FLAGS(rta) & NLA_F_NESTED;
-                attributes[type].net_byteorder = RTA_FLAGS(rta) & NLA_F_NET_BYTEORDER;
-
-                if (type + 1U > n)
-                        n = type + 1U;
+                attributes[attr].offset = (uint8_t *) rta - (uint8_t *) m->hdr;
+                attributes[attr].nested = RTA_FLAGS(rta) & NLA_F_NESTED;
+                attributes[attr].net_byteorder = RTA_FLAGS(rta) & NLA_F_NET_BYTEORDER;
         }
 
         container->attributes = TAKE_PTR(attributes);
-        container->n_attributes = n;
+        container->max_attribute = max_attr;
 
         return 0;
 }
@@ -1259,6 +1259,7 @@ int sd_netlink_message_exit_container(sd_netlink_message *m) {
         assert_return(m->n_containers > 0, -EINVAL);
 
         m->containers[m->n_containers].attributes = mfree(m->containers[m->n_containers].attributes);
+        m->containers[m->n_containers].max_attribute = 0;
         m->containers[m->n_containers].type_system = NULL;
 
         m->n_containers--;
@@ -1266,6 +1267,15 @@ int sd_netlink_message_exit_container(sd_netlink_message *m) {
         return 0;
 }
 
+int sd_netlink_message_get_max_attribute(sd_netlink_message *m, uint16_t *ret) {
+        assert_return(m, -EINVAL);
+        assert_return(m->sealed, -EINVAL);
+        assert_return(ret, -EINVAL);
+
+        *ret = m->containers[m->n_containers].max_attribute;
+        return 0;
+}
+
 uint32_t message_get_serial(sd_netlink_message *m) {
         assert(m);
         assert(m->hdr);
index 5965780fbb725d7982303a66fcf036b5b334f961..ee1b32fddb8c4f8bf4c073116bd78de0d615c42b 100644 (file)
@@ -126,6 +126,7 @@ int sd_netlink_message_get_errno(sd_netlink_message *m);
 int sd_netlink_message_get_type(sd_netlink_message *m, uint16_t *type);
 int sd_netlink_message_set_flags(sd_netlink_message *m, uint16_t flags);
 int sd_netlink_message_is_broadcast(sd_netlink_message *m);
+int sd_netlink_message_get_max_attribute(sd_netlink_message *m, uint16_t *ret);
 
 /* rtnl */
 int sd_rtnl_message_get_family(sd_netlink_message *m, int *family);