Skip to content

Commit

Permalink
nl80211: add support for multi-attribute arrays
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
nbd168 committed Jul 7, 2024
1 parent 73644a0 commit 6e3cf83
Showing 1 changed file with 24 additions and 24 deletions.
48 changes: 24 additions & 24 deletions lib/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ enum {
DF_ARRAY = (1 << 5),
DF_BINARY = (1 << 6),
DF_RELATED = (1 << 7),
DF_REPEATED = (1 << 8),
};

typedef struct uc_nl_attr_spec {
Expand Down Expand Up @@ -1008,26 +1009,6 @@ uc_nl_get_struct_member_u32(char *base, const void *offset)
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);

Expand All @@ -1051,20 +1032,39 @@ uc_nl_convert_attrs(struct nl_msg *msg, void *buf, size_t buflen, size_t headsiz
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;
}

for (i = 0; i < nattrs; i++) {
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];

Expand Down

0 comments on commit 6e3cf83

Please sign in to comment.