summaryrefslogtreecommitdiffstats
path: root/src/netlink_delinearize.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2015-04-12 21:10:41 +0100
committerPatrick McHardy <kaber@trash.net>2015-06-02 13:03:58 +0200
commit8ede6005f41afb69e415e1227fc7800308a63819 (patch)
treeffafc83b6e8a0eb454ec7b48fa77620e6afa85ff /src/netlink_delinearize.c
parent9c641885afea6f46b62f591ed9b0e3006fb23701 (diff)
netlink_delinearize: introduce register translation helper
Introduce a helper function to translate register numbers from the kernel from the compat values to the NFT_REG32 values. Internally we use the register numbers 0-16: * 0 is the verdict register in both old and new addressing modes. * 1-16 are the 32 bit data registers The NFT_REG32_00 values are mapped to 1-16, the NFT_REG_1-NFT_REG_4 values are each use up 4 registers starting at 1 (1, 5, 9, 13). Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'src/netlink_delinearize.c')
-rw-r--r--src/netlink_delinearize.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index e9ce76e2..91da8597 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -30,7 +30,7 @@ struct netlink_parse_ctx {
struct list_head *msgs;
struct table *table;
struct rule *rule;
- struct expr *registers[NFT_REG_MAX + 1];
+ struct expr *registers[1 + NFT_REG32_15 - NFT_REG32_00 + 1];
};
static void __fmtstring(3, 4) netlink_error(struct netlink_parse_ctx *ctx,
@@ -49,14 +49,23 @@ static void __fmtstring(3, 4) netlink_error(struct netlink_parse_ctx *ctx,
static unsigned int netlink_parse_register(const struct nft_rule_expr *nle,
unsigned int attr)
{
- return nft_rule_expr_get_u32(nle, attr);
+ unsigned int reg;
+
+ reg = nft_rule_expr_get_u32(nle, attr);
+ /* Translate 128bit registers to corresponding 32bit registers */
+ if (reg >= NFT_REG_1 && reg <= NFT_REG_4)
+ reg = 1 + (reg - NFT_REG_1) * (NFT_REG_SIZE / NFT_REG32_SIZE);
+ else if (reg >= NFT_REG32_00)
+ reg = 1 + reg - NFT_REG32_00;
+
+ return reg;
}
static void netlink_set_register(struct netlink_parse_ctx *ctx,
enum nft_registers reg,
struct expr *expr)
{
- if (reg > NFT_REG_MAX) {
+ if (reg == NFT_REG_VERDICT || reg > 1 + NFT_REG32_15 - NFT_REG32_00) {
netlink_error(ctx, &expr->location,
"Invalid destination register %u", reg);
expr_free(expr);
@@ -75,7 +84,7 @@ static struct expr *netlink_get_register(struct netlink_parse_ctx *ctx,
{
struct expr *expr;
- if (reg == NFT_REG_VERDICT || reg > NFT_REG_MAX) {
+ if (reg == NFT_REG_VERDICT || reg > 1 + NFT_REG32_15 - NFT_REG32_00) {
netlink_error(ctx, loc, "Invalid source register %u", reg);
return NULL;
}