From b9e00458b9f357f6c9b301f95b276fd019da0692 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 1 May 2022 17:40:01 +0200 Subject: src: add dynamic register allocation infrastructure Starting Linux kernel 5.18-rc, operations on registers that already contain the expected data are turned into noop. Track operation on registers to use the same register through nftnl_reg_get(). This patch introduces an LRU eviction strategy when all the registers are in used. nftnl_reg_get_scratch() is used to allocate a register as scratchpad area: no tracking is performed in this case, although register eviction might occur. Acked-by: Phil Sutter Signed-off-by: Pablo Neira Ayuso --- src/expr/payload.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'src/expr/payload.c') diff --git a/src/expr/payload.c b/src/expr/payload.c index 82747ec..8b41a9d 100644 --- a/src/expr/payload.c +++ b/src/expr/payload.c @@ -203,6 +203,32 @@ nftnl_expr_payload_parse(struct nftnl_expr *e, struct nlattr *attr) return 0; } +static int nftnl_payload_reg_len(const struct nftnl_expr *expr) +{ + const struct nftnl_expr_payload *payload = nftnl_expr_data(expr); + + return payload->len; +} + +static bool nftnl_payload_reg_cmp(const struct nftnl_reg *reg, + const struct nftnl_expr *e) +{ + const struct nftnl_expr_payload *payload = nftnl_expr_data(e); + + return reg->payload.base == payload->base && + reg->payload.offset == payload->offset && + reg->len >= payload->len; +} + +static void nftnl_payload_reg_update(struct nftnl_reg *reg, + const struct nftnl_expr *e) +{ + const struct nftnl_expr_payload *payload = nftnl_expr_data(e); + + reg->payload.base = payload->base; + reg->payload.offset = payload->offset; +} + static const char *base2str_array[NFT_PAYLOAD_INNER_HEADER + 1] = { [NFT_PAYLOAD_LL_HEADER] = "link", [NFT_PAYLOAD_NETWORK_HEADER] = "network", @@ -260,4 +286,9 @@ struct expr_ops expr_ops_payload = { .parse = nftnl_expr_payload_parse, .build = nftnl_expr_payload_build, .snprintf = nftnl_expr_payload_snprintf, + .reg = { + .len = nftnl_payload_reg_len, + .cmp = nftnl_payload_reg_cmp, + .update = nftnl_payload_reg_update, + }, }; -- cgit v1.2.3