diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-08-27 16:30:19 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-08-31 21:18:34 +0900 |
commit | 416e84192a0739de6ada3214fe84183f669aa8a9 (patch) | |
tree | 9b9c57bd504e59e800a0b6e282d4fa04ce4111ba | |
parent | e0df8e99935cc87886b4d700b89c53eb4eee1ca5 (diff) | |
download | systemd-416e84192a0739de6ada3214fe84183f669aa8a9.tar.gz |
sd-netlink: introduce sd_netlink_message_get_max_attribute()
-rw-r--r-- | src/libsystemd/sd-netlink/netlink-internal.h | 2 | ||||
-rw-r--r-- | src/libsystemd/sd-netlink/netlink-message.c | 44 | ||||
-rw-r--r-- | src/systemd/sd-netlink.h | 1 |
3 files changed, 29 insertions, 18 deletions
diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h index 050edaec78..299b7d660b 100644 --- a/src/libsystemd/sd-netlink/netlink-internal.h +++ b/src/libsystemd/sd-netlink/netlink-internal.h @@ -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 { diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index e422d5699c..2bfaff7ce0 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -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); diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h index 5965780fbb..ee1b32fddb 100644 --- a/src/systemd/sd-netlink.h +++ b/src/systemd/sd-netlink.h @@ -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); |