From: Patrick McHardy Date: Sun, 12 Apr 2015 20:10:41 +0000 (+0100) Subject: netlink_delinearize: introduce register translation helper X-Git-Tag: v0.5~50^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8ede6005f41afb69e415e1227fc7800308a63819;p=thirdparty%2Fnftables.git 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 --- diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index e9ce76e28..91da85975 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; }