@@ -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;
@@ -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;
}
/**
@@ -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);
@@ -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;
+}
@@ -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