From 026c5165a28f82099e7bebd2dc7dde7de2d7c7a4 Mon Sep 17 00:00:00 2001 From: Wen Gu Date: Thu, 15 Aug 2024 19:37:17 +0800 Subject: [PATCH] lib/attr: add nla functions for variable-length integers The NLA_{UINT|SINT} attributes are introduced for variable-length integers, whose length are 32bits or 64bits. So add appropriate functions to get or put NLA_{UINT|SINT} attributes. Signed-off-by: Wen Gu --- include/netlink/attr.h | 4 +++ lib/attr.c | 64 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/include/netlink/attr.h b/include/netlink/attr.h index 2cd32ee10..bc4464e97 100644 --- a/include/netlink/attr.h +++ b/include/netlink/attr.h @@ -118,6 +118,10 @@ extern int64_t nla_get_s64(const struct nlattr *); extern int nla_put_s64(struct nl_msg *, int, int64_t); extern uint64_t nla_get_u64(const struct nlattr *); extern int nla_put_u64(struct nl_msg *, int, uint64_t); +extern int64_t nla_get_sint(const struct nlattr *); +extern int nla_put_sint(struct nl_msg *, int, int64_t); +extern uint64_t nla_get_uint(const struct nlattr *); +extern int nla_put_uint(struct nl_msg *, int, uint64_t); /* String attribute */ extern char * nla_get_string(const struct nlattr *); diff --git a/lib/attr.c b/lib/attr.c index a365cf2a5..f14cb8111 100644 --- a/lib/attr.c +++ b/lib/attr.c @@ -774,6 +774,70 @@ uint64_t nla_get_u64(const struct nlattr *nla) return tmp; } +/** + * Add variable-length signed integer attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg value Numeric value to store as payload. + * + * @see nla_put + * @return 0 on success or a negative error code. + */ +int nla_put_sint(struct nl_msg *msg, int attrtype, int64_t value) +{ + int64_t tmp64 = value; + int32_t tmp32 = value; + + if (tmp64 == tmp32) + nla_put_s32(msg, attrtype, tmp32); + return nla_put(msg, attrtype, sizeof(int64_t), &value); +} + +/** + * Return payload of variable-length signed integer attribute + * @arg nla variable-length signed integer attribute + * + * @return Payload as 64 bit integer. + */ +int64_t nla_get_sint(const struct nlattr *nla) +{ + if (nla && _nla_len(nla) == sizeof(int32_t)) + return nla_get_s32(nla); + return nla_get_s64(nla); +} + +/** + * Add variable-length unsigned integer attribute to netlink message. + * @arg msg Netlink message. + * @arg attrtype Attribute type. + * @arg value Numeric value to store as payload. + * + * @see nla_put + * @return 0 on success or a negative error code. + */ +int nla_put_uint(struct nl_msg *msg, int attrtype, uint64_t value) +{ + uint64_t tmp64 = value; + uint32_t tmp32 = value; + + if (tmp64 == tmp32) + nla_put_u32(msg, attrtype, tmp32); + return nla_put(msg, attrtype, sizeof(uint64_t), &value); +} + +/** + * Return payload of variable-length unsigned integer attribute + * @arg nla variable-length unsigned integer attribute + * + * @return Payload as 64 bit integer. + */ +uint64_t nla_get_uint(const struct nlattr *nla) +{ + if (nla && _nla_len(nla) == sizeof(uint32_t)) + return nla_get_u32(nla); + return nla_get_u64(nla); +} + /** @} */ /**