]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
netlink_delinearize: allow postprocessing on concatenated elements
authorFlorian Westphal <fw@strlen.de>
Tue, 14 Jun 2022 19:57:58 +0000 (21:57 +0200)
committerFlorian Westphal <fw@strlen.de>
Thu, 4 Aug 2022 23:46:39 +0000 (01:46 +0200)
Currently there is no case where the individual expressions inside a
mapped concatenation need to be munged.

However, to support proper delinearization for an input like
'rule netdev nt nc set update ether saddr . vlan id timeout 5s @macset'

we need to allow this.

Right now, this gets listed as:

update @macset { @ll,48,48 . @ll,112,16 & 0xfff timeout 5s }

because the ethernet protocol is replaced by vlan beforehand,
so we fail to map @ll,48,48 to a vlan protocol.

Likewise, we can't map the vlan info either because we cannot
cope with the 'and' operation properly, nor is it removed.

Prepare for this by deleting and re-adding so that we do not
corrupt the linked list.

After this, the list can be safely changed and a followup patch
can start to delete/reallocate expressions.

Signed-off-by: Florian Westphal <fw@strlen.de>
src/netlink_delinearize.c

index 3bdd98d47eb0188ab4da8fab3b5d5d0603d63fbd..3835b3e522b9b5ce9c3198c12a0e78f3adbeb8e9 100644 (file)
@@ -2539,16 +2539,21 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
                unsigned int type = expr->dtype->type, ntype = 0;
                int off = expr->dtype->subtypes;
                const struct datatype *dtype;
+               LIST_HEAD(tmp);
+               struct expr *n;
 
-               list_for_each_entry(i, &expr->expressions, list) {
+               list_for_each_entry_safe(i, n, &expr->expressions, list) {
                        if (type) {
                                dtype = concat_subtype_lookup(type, --off);
                                expr_set_type(i, dtype, dtype->byteorder);
                        }
+                       list_del(&i->list);
                        expr_postprocess(ctx, &i);
+                       list_add_tail(&i->list, &tmp);
 
                        ntype = concat_subtype_add(ntype, i->dtype->type);
                }
+               list_splice(&tmp, &expr->expressions);
                datatype_set(expr, concat_type_alloc(ntype));
                break;
        }