mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-24 16:57:31 +00:00
95 lines
2.4 KiB
Diff
95 lines
2.4 KiB
Diff
From: Felix Fietkau <nbd@nbd.name>
|
|
Date: Sat, 29 Jun 2024 12:05:29 +0200
|
|
Subject: [PATCH] nl80211: add support for multi-attribute arrays
|
|
|
|
For newly added attributes, the kernel prefers to no longer add a nesting
|
|
container attribute. Instead, an attribute with the element type is simply
|
|
added multiple times within the outer container.
|
|
Add support for this array style, which will be used in the pending wiphy
|
|
multi radio support.
|
|
|
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
---
|
|
|
|
--- a/lib/nl80211.c
|
|
+++ b/lib/nl80211.c
|
|
@@ -198,6 +198,7 @@ enum {
|
|
DF_ARRAY = (1 << 5),
|
|
DF_BINARY = (1 << 6),
|
|
DF_RELATED = (1 << 7),
|
|
+ DF_REPEATED = (1 << 8),
|
|
};
|
|
|
|
typedef struct uc_nl_attr_spec {
|
|
@@ -1043,26 +1044,6 @@ uc_nl_get_struct_member_u32(char *base,
|
|
return u32;
|
|
}
|
|
|
|
-static void
|
|
-uc_nl_nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len)
|
|
-{
|
|
- struct nlattr *nla;
|
|
- int rem;
|
|
-
|
|
- memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
|
|
-
|
|
- nla_for_each_attr(nla, head, len, rem) {
|
|
- int type = nla_type(nla);
|
|
-
|
|
- if (type <= maxtype)
|
|
- tb[type] = nla;
|
|
- }
|
|
-
|
|
- if (rem > 0)
|
|
- fprintf(stderr, "netlink: %d bytes leftover after parsing attributes.\n", rem);
|
|
-}
|
|
-
|
|
-
|
|
static bool
|
|
uc_nl_parse_attr(const uc_nl_attr_spec_t *spec, struct nl_msg *msg, char *base, uc_vm_t *vm, uc_value_t *val, size_t idx);
|
|
|
|
@@ -1086,12 +1067,10 @@ uc_nl_convert_attrs(struct nl_msg *msg,
|
|
if (!tb)
|
|
return false;
|
|
|
|
- uc_nl_nla_parse(tb, maxattr, buf + headsize, buflen - headsize);
|
|
-
|
|
nla_for_each_attr(nla, buf + headsize, buflen - headsize, rem) {
|
|
type = nla_type(nla);
|
|
|
|
- if (type <= maxattr)
|
|
+ if (type <= maxattr && !tb[type])
|
|
tb[type] = nla;
|
|
}
|
|
|
|
@@ -1099,7 +1078,28 @@ uc_nl_convert_attrs(struct nl_msg *msg,
|
|
if (attrs[i].attr != 0 && !tb[attrs[i].attr])
|
|
continue;
|
|
|
|
- if (attrs[i].flags & DF_MULTIPLE) {
|
|
+ if (attrs[i].flags & DF_REPEATED) {
|
|
+ arr = ucv_array_new(vm);
|
|
+
|
|
+ nla = tb[attrs[i].attr];
|
|
+ rem = buflen - ((void *)nla - buf);
|
|
+ for (; nla_ok(nla, rem); nla = nla_next(nla, &rem)) {
|
|
+ if (nla_type(nla) != (int)attrs[i].attr)
|
|
+ break;
|
|
+ v = uc_nl_convert_attr(&attrs[i], msg, (char *)buf, nla, NULL, vm);
|
|
+ if (!v)
|
|
+ continue;
|
|
+
|
|
+ ucv_array_push(arr, v);
|
|
+ }
|
|
+ if (!ucv_array_length(arr)) {
|
|
+ ucv_put(arr);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ v = arr;
|
|
+ }
|
|
+ else if (attrs[i].flags & DF_MULTIPLE) {
|
|
arr = ucv_array_new(vm);
|
|
nla_nest = tb[attrs[i].attr];
|
|
|