]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
netlink_delinearize: introduce register translation helper
authorPatrick McHardy <kaber@trash.net>
Sun, 12 Apr 2015 20:10:41 +0000 (21:10 +0100)
committerPatrick McHardy <kaber@trash.net>
Tue, 2 Jun 2015 11:03:58 +0000 (13:03 +0200)
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>
src/netlink_delinearize.c

index e9ce76e28ae72286230bdf9616302f8b3ea4da53..91da85975829a5e9c24fde94589ecfe92daf8706 100644 (file)
@@ -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;
        }