summaryrefslogtreecommitdiffstats
path: root/src/regs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/regs.c')
-rw-r--r--src/regs.c239
1 files changed, 0 insertions, 239 deletions
diff --git a/src/regs.c b/src/regs.c
deleted file mode 100644
index 1551aa7..0000000
--- a/src/regs.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * (C) 2012-2022 by Pablo Neira Ayuso <pablo@netfilter.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-/* Funded through the NGI0 PET Fund established by NLnet (https://nlnet.nl)
- * with support from the European Commission's Next Generation Internet
- * programme.
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <assert.h>
-
-#include <libnftnl/regs.h>
-
-#include "internal.h"
-
-EXPORT_SYMBOL(nftnl_regs_alloc);
-struct nftnl_regs *nftnl_regs_alloc(uint32_t num_regs)
-{
- struct nftnl_regs *regs;
-
- if (num_regs < 16)
- num_regs = 16;
-
- regs = calloc(1, sizeof(struct nftnl_regs));
- if (!regs)
- return NULL;
-
- regs->reg = calloc(num_regs, sizeof(struct nftnl_reg));
- if (!regs->reg) {
- free(regs->reg);
- return NULL;
- }
-
- regs->num_regs = num_regs;
-
- return regs;
-}
-
-EXPORT_SYMBOL(nftnl_regs_free);
-void nftnl_regs_free(const struct nftnl_regs *regs)
-{
- xfree(regs->reg);
- xfree(regs);
-}
-
-static enum nftnl_expr_type nftnl_expr_type(const struct nftnl_expr *expr)
-{
- if (!strcmp(expr->ops->name, "ct"))
- return NFT_EXPR_CT;
- else if (!strcmp(expr->ops->name, "exthdr"))
- return NFT_EXPR_EXTHDR;
- else if (!strcmp(expr->ops->name, "fib"))
- return NFT_EXPR_FIB;
- else if (!strcmp(expr->ops->name, "meta"))
- return NFT_EXPR_META;
- else if (!strcmp(expr->ops->name, "osf"))
- return NFT_EXPR_OSF;
- else if (!strcmp(expr->ops->name, "payload"))
- return NFT_EXPR_PAYLOAD;
- else if (!strcmp(expr->ops->name, "rt"))
- return NFT_EXPR_RT;
- else if (!strcmp(expr->ops->name, "socket"))
- return NFT_EXPR_SOCKET;
- else if (!strcmp(expr->ops->name, "xfrm"))
- return NFT_EXPR_XFRM;
-
- assert(0);
- return NFT_EXPR_UNSPEC;
-}
-
-static int nftnl_expr_reg_len(const struct nftnl_expr *expr)
-{
- return expr->ops->reg.len(expr);
-}
-
-static bool nftnl_expr_reg_cmp(const struct nftnl_regs *regs,
- const struct nftnl_expr *expr, int i)
-{
- if (regs->reg[i].type != nftnl_expr_type(expr))
- return false;
-
- return expr->ops->reg.cmp(&regs->reg[i], expr);
-}
-
-static void nft_expr_reg_update(struct nftnl_regs *regs,
- const struct nftnl_expr *expr, int i)
-{
- return expr->ops->reg.update(&regs->reg[i], expr);
-}
-
-static int reg_space(const struct nftnl_regs *regs, int i)
-{
- return sizeof(uint32_t) * regs->num_regs - sizeof(uint32_t) * i;
-}
-
-struct nftnl_reg_ctx {
- uint64_t genid;
- int reg;
- int evict;
-};
-
-static void register_track(struct nftnl_reg_ctx *ctx,
- const struct nftnl_regs *regs, int i, int len)
-{
- if (ctx->reg >= 0 || regs->reg[i].word || reg_space(regs, i) < len)
- return;
-
- if (regs->reg[i].type == NFT_EXPR_UNSPEC) {
- ctx->genid = regs->genid;
- ctx->reg = i;
- } else if (regs->reg[i].genid < ctx->genid) {
- ctx->genid = regs->reg[i].genid;
- ctx->evict = i;
- }
-}
-
-static void register_evict(struct nftnl_reg_ctx *ctx)
-{
- if (ctx->reg < 0) {
- assert(ctx->evict >= 0);
- ctx->reg = ctx->evict;
- }
-}
-
-static void __register_update(struct nftnl_regs *regs, uint8_t reg,
- int type, uint32_t len, uint8_t word,
- uint64_t genid, const struct nftnl_expr *expr)
-{
- regs->reg[reg].type = type;
- regs->reg[reg].genid = genid;
- regs->reg[reg].len = len;
- regs->reg[reg].word = word;
- nft_expr_reg_update(regs, expr, reg);
-}
-
-static void __register_cancel(struct nftnl_regs *regs, int i)
-{
- regs->reg[i].type = NFT_EXPR_UNSPEC;
- regs->reg[i].word = 0;
- regs->reg[i].len = 0;
- regs->reg[i].genid = 0;
-}
-
-static void register_cancel(struct nftnl_reg_ctx *ctx, struct nftnl_regs *regs,
- int len)
-{
- int i;
-
- for (i = ctx->reg; len > 0; i++, len -= sizeof(uint32_t)) {
- if (regs->reg[i].type == NFT_EXPR_UNSPEC)
- continue;
-
- __register_cancel(regs, i);
- }
-
- while (i < regs->num_regs && regs->reg[i].word != 0) {
- __register_cancel(regs, i);
- i++;
- }
-}
-
-static void register_update(struct nftnl_reg_ctx *ctx, struct nftnl_regs *regs,
- int type, uint32_t len, uint64_t genid,
- const struct nftnl_expr *expr)
-{
- register_cancel(ctx, regs, len);
- __register_update(regs, ctx->reg, type, len, 0, genid, expr);
-}
-
-static uint64_t reg_genid(struct nftnl_regs *regs)
-{
- return ++regs->genid;
-}
-
-EXPORT_SYMBOL(nftnl_reg_get);
-uint32_t nftnl_reg_get(struct nftnl_regs *regs, const struct nftnl_expr *expr)
-{
- struct nftnl_reg_ctx ctx = {
- .reg = -1,
- .evict = -1,
- .genid = UINT64_MAX,
- };
- enum nftnl_expr_type type;
- uint64_t genid;
- int i, j, len;
-
- type = nftnl_expr_type(expr);
- len = nftnl_expr_reg_len(expr);
-
- for (i = 0; i < regs->num_regs; i++) {
- register_track(&ctx, regs, i, len);
-
- if (!nftnl_expr_reg_cmp(regs, expr, i))
- continue;
-
- regs->reg[i].genid = reg_genid(regs);
- return i + NFT_REG32_00;
- }
-
- register_evict(&ctx);
- genid = reg_genid(regs);
- register_update(&ctx, regs, type, len, genid, expr);
-
- len -= sizeof(uint32_t);
- j = 1;
- for (i = ctx.reg + 1; len > 0; i++, len -= sizeof(uint32_t))
- __register_update(regs, i, type, len, j++, genid, expr);
-
- return ctx.reg + NFT_REG32_00;
-}
-
-EXPORT_SYMBOL(nftnl_reg_get_scratch);
-uint32_t nftnl_reg_get_scratch(struct nftnl_regs *regs, uint32_t len)
-{
- struct nftnl_reg_ctx ctx = {
- .reg = -1,
- .evict = -1,
- .genid = UINT64_MAX,
- };
- int i;
-
- for (i = 0; i < regs->num_regs; i++)
- register_track(&ctx, regs, i, len);
-
- register_evict(&ctx);
- register_cancel(&ctx, regs, len);
-
- return ctx.reg + NFT_REG32_00;
-}