[PATCH 1/6] netlink: Add l_netlink_iter
Denis Kenzior <[email protected]> Fri, 23 Aug 2024 11:15:45 -0500
| Newsgroups | dev.linux.lists.ell |
|---|---|
| Message-ID | <[email protected]> |
Move netlink attribute iterator out of genl.c and into netlink.c. Both
genl and netlink use the same attribute structure, and is applicable to
both. This makes implementing netlink and rtnl message parsers much
easier.
In order to keep source compatibility, structure the netlink iterator in
the same way as the genl iterator. In the future, the use of genl
iterators will be removed.
---
ell/ell.sym | 5 ++--
ell/genl.c | 76 +++------------------------------------------------
ell/genl.h | 18 +++++++++---
ell/netlink.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++
ell/netlink.h | 15 ++++++++++
5 files changed, 111 insertions(+), 78 deletions(-)
diff --git a/ell/ell.sym b/ell/ell.sym
index c5d1c2a9edea..1499081cb25e 100644
--- a/ell/ell.sym
+++ b/ell/ell.sym
@@ -344,8 +344,6 @@ global:
l_genl_msg_enter_nested;
l_genl_msg_leave_nested;
l_genl_attr_init;
- l_genl_attr_next;
- l_genl_attr_recurse;
l_genl_family_info_can_send;
l_genl_family_info_can_dump;
l_genl_family_info_has_group;
@@ -445,6 +443,9 @@ global:
l_netlink_message_add_header;
l_netlink_message_enter_nested;
l_netlink_message_leave_nested;
+ l_netlink_attr_init;
+ l_netlink_attr_next;
+ l_netlink_attr_recurse;
/* path */
l_basename;
l_path_find;
diff --git a/ell/genl.c b/ell/genl.c
index 5a8dd371a970..ac10cbf07ef0 100644
--- a/ell/genl.c
+++ b/ell/genl.c
@@ -1559,80 +1559,12 @@ LIB_EXPORT bool l_genl_msg_leave_nested(struct l_genl_msg *msg)
LIB_EXPORT bool l_genl_attr_init(struct l_genl_attr *attr,
struct l_genl_msg *msg)
{
- const struct nlattr *nla;
- uint32_t len;
-
- if (unlikely(!attr) || unlikely(!msg))
- return false;
-
- if (!msg->nlm ||
- msg->nlm->hdr->nlmsg_len < NLMSG_HDRLEN + GENL_HDRLEN)
- return false;
-
- nla = msg->nlm->data + NLMSG_HDRLEN + GENL_HDRLEN;
- len = msg->nlm->hdr->nlmsg_len - NLMSG_HDRLEN - GENL_HDRLEN;
-
- if (!NLA_OK(nla, len))
- return false;
-
- attr->data = NULL;
- attr->len = 0;
- attr->next_data = nla;
- attr->next_len = len;
-
- return true;
-}
-
-LIB_EXPORT bool l_genl_attr_next(struct l_genl_attr *attr,
- uint16_t *type,
- uint16_t *len,
- const void **data)
-{
- const struct nlattr *nla;
-
- if (unlikely(!attr))
- return false;
-
- nla = attr->next_data;
-
- if (!NLA_OK(nla, attr->next_len))
+ if (unlikely(!msg) || unlikely(!msg->nlm))
return false;
- if (type)
- *type = nla->nla_type & NLA_TYPE_MASK;
-
- if (len)
- *len = NLA_PAYLOAD(nla);
-
- if (data)
- *data = NLA_DATA(nla);
-
- attr->data = attr->next_data;
- attr->len = attr->next_len;
-
- attr->next_data = NLA_NEXT(nla, attr->next_len);
-
- return true;
-}
-
-LIB_EXPORT bool l_genl_attr_recurse(const struct l_genl_attr *attr,
- struct l_genl_attr *nested)
-{
- const struct nlattr *nla;
-
- if (unlikely(!attr) || unlikely(!nested))
- return false;
-
- nla = attr->data;
- if (!nla)
- return false;
-
- nested->data = NULL;
- nested->len = 0;
- nested->next_data = NLA_DATA(nla);
- nested->next_len = NLA_PAYLOAD(nla);
-
- return true;
+ return l_netlink_attr_init((struct l_netlink_attr *) attr,
+ NLMSG_HDRLEN + GENL_HDRLEN,
+ msg->nlm->data, msg->nlm->hdr->nlmsg_len) == 0;
}
/**
diff --git a/ell/genl.h b/ell/genl.h
index 3f38fd9d5710..ed5f17c4fd2e 100644
--- a/ell/genl.h
+++ b/ell/genl.h
@@ -91,10 +91,20 @@ bool l_genl_msg_enter_nested(struct l_genl_msg *msg, uint16_t type);
bool l_genl_msg_leave_nested(struct l_genl_msg *msg);
bool l_genl_attr_init(struct l_genl_attr *attr, struct l_genl_msg *msg);
-bool l_genl_attr_next(struct l_genl_attr *attr, uint16_t *type,
- uint16_t *len, const void **data);
-bool l_genl_attr_recurse(const struct l_genl_attr *attr,
- struct l_genl_attr *nested);
+
+static inline bool l_genl_attr_next(struct l_genl_attr *attr, uint16_t *type,
+ uint16_t *len, const void **data)
+{
+ return l_netlink_attr_next((struct l_netlink_attr *) attr,
+ type, len, data) == 0;
+}
+
+static inline bool l_genl_attr_recurse(const struct l_genl_attr *attr,
+ struct l_genl_attr *nested)
+{
+ return l_netlink_attr_recurse((struct l_netlink_attr *) attr,
+ (struct l_netlink_attr *) nested) == 0;
+}
bool l_genl_family_info_has_group(const struct l_genl_family_info *info,
const char *group);
diff --git a/ell/netlink.c b/ell/netlink.c
index 121a322fccf5..0be3009c736f 100644
--- a/ell/netlink.c
+++ b/ell/netlink.c
@@ -944,3 +944,78 @@ LIB_EXPORT int l_netlink_message_leave_nested(struct l_netlink_message *message)
return 0;
}
+
+LIB_EXPORT int l_netlink_attr_init(struct l_netlink_attr *iter,
+ size_t header_len,
+ const void *data, uint32_t len)
+{
+ const struct nlattr *nla;
+
+ if (unlikely(!iter) || unlikely(!data))
+ return -EINVAL;
+
+ if (len < NLA_ALIGN(header_len))
+ return -EMSGSIZE;
+
+ nla = data + NLA_ALIGN(header_len);
+ len -= NLA_ALIGN(header_len);
+
+ if (!NLA_OK(nla, len))
+ return -EMSGSIZE;
+
+ iter->data = NULL;
+ iter->len = 0;
+ iter->next_data = nla;
+ iter->next_len = len;
+
+ return 0;
+}
+
+LIB_EXPORT int l_netlink_attr_next(struct l_netlink_attr *iter,
+ uint16_t *type, uint16_t *len,
+ const void **data)
+{
+ const struct nlattr *nla;
+
+ if (unlikely(!iter))
+ return -EINVAL;
+
+ nla = iter->next_data;
+ if (!NLA_OK(nla, iter->next_len))
+ return -EMSGSIZE;
+
+ if (type)
+ *type = nla->nla_type & NLA_TYPE_MASK;
+
+ if (len)
+ *len = NLA_PAYLOAD(nla);
+
+ if (data)
+ *data = NLA_DATA(nla);
+
+ iter->data = iter->next_data;
+ iter->len = iter->next_len;
+
+ iter->next_data = NLA_NEXT(nla, iter->next_len);
+ return 0;
+}
+
+LIB_EXPORT int l_netlink_attr_recurse(const struct l_netlink_attr *iter,
+ struct l_netlink_attr *nested)
+{
+ const struct nlattr *nla;
+
+ if (unlikely(!iter) || unlikely(!nested))
+ return -EINVAL;
+
+ nla = iter->data;
+ if (!nla)
+ return false;
+
+ nested->data = NULL;
+ nested->len = 0;
+ nested->next_data = NLA_DATA(nla);
+ nested->next_len = NLA_PAYLOAD(nla);
+
+ return 0;
+}
diff --git a/ell/netlink.h b/ell/netlink.h
index 08aff74fbac2..f09d42043675 100644
--- a/ell/netlink.h
+++ b/ell/netlink.h
@@ -119,6 +119,21 @@ static inline int l_netlink_message_append_mac(struct l_netlink_message *message
return l_netlink_message_append(message, type, mac, 6);
}
+struct l_netlink_attr {
+ const struct nlattr *data;
+ uint32_t len;
+ const struct nlattr *next_data;
+ uint32_t next_len;
+};
+
+int l_netlink_attr_init(struct l_netlink_attr *attr, size_t header_len,
+ const void *data, uint32_t len);
+int l_netlink_attr_next(struct l_netlink_attr *attr,
+ uint16_t *type, uint16_t *len,
+ const void **data);
+int l_netlink_attr_recurse(const struct l_netlink_attr *iter,
+ struct l_netlink_attr *nested);
+
#ifdef __cplusplus
}
#endif
--
2.45.2