Files
wlan-ap/feeds/ucentral/ucode/patches/111-nl80211-add-support-for-multi-attribute-arrays.patch
John Crispin 5ba650cdb1 ucode: update to version used in v4.2
Signed-off-by: John Crispin <john@phrozen.org>
2025-12-11 07:26:39 +01:00

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];