diff options
-rw-r--r-- | iptables/nft-bridge.c | 4 | ||||
-rw-r--r-- | iptables/nft-shared.c | 16 | ||||
-rw-r--r-- | iptables/nft-shared.h | 5 | ||||
-rw-r--r-- | iptables/nft.c | 6 |
4 files changed, 25 insertions, 6 deletions
diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c index 659c5b58..596dfdf8 100644 --- a/iptables/nft-bridge.c +++ b/iptables/nft-bridge.c @@ -349,7 +349,7 @@ static int lookup_analyze_payloads(struct nft_xt_ctx *ctx, return -1; } - sreg_count += 2; + sreg_count = nft_get_next_reg(sreg_count, ETH_ALEN); reg = nft_xt_ctx_get_sreg(ctx, sreg_count); if (!reg) { @@ -375,7 +375,7 @@ static int lookup_analyze_payloads(struct nft_xt_ctx *ctx, return -1; } break; - case 4: /* ipv4addr */ + case 6: /* ether */ val = lookup_check_ether_payload(reg->payload.base, reg->payload.offset, reg->payload.len); diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c index f8de2b71..909fe648 100644 --- a/iptables/nft-shared.c +++ b/iptables/nft-shared.c @@ -10,6 +10,7 @@ * This code has been sponsored by Sophos Astaro <http://www.sophos.com> */ +#include <assert.h> #include <string.h> #include <stdio.h> #include <stdlib.h> @@ -1603,3 +1604,18 @@ int nft_parse_hl(struct nft_xt_ctx *ctx, return 0; } + +enum nft_registers nft_get_next_reg(enum nft_registers reg, size_t size) +{ + /* convert size to NETLINK_ALIGN-sized chunks */ + size = (size + NETLINK_ALIGN - 1) / NETLINK_ALIGN; + + /* map 16byte reg to 4byte one */ + if (reg < __NFT_REG_MAX) + reg = NFT_REG32_00 + (reg - 1) * NFT_REG_SIZE / NFT_REG32_SIZE; + + reg += size; + assert(reg <= NFT_REG32_15); + + return reg; +} diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h index 8fcedcdd..c07d3270 100644 --- a/iptables/nft-shared.h +++ b/iptables/nft-shared.h @@ -276,4 +276,9 @@ int nft_parse_hl(struct nft_xt_ctx *ctx, struct nftnl_expr *e, struct iptables_c #define min(x, y) ((x) < (y) ? (x) : (y)) #define max(x, y) ((x) > (y) ? (x) : (y)) +/* simplified nftables:include/netlink.h, netlink_padded_len() */ +#define NETLINK_ALIGN 4 + +enum nft_registers nft_get_next_reg(enum nft_registers reg, size_t size); + #endif diff --git a/iptables/nft.c b/iptables/nft.c index 2165733f..09cb19c9 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -1133,9 +1133,6 @@ gen_lookup(uint32_t sreg, const char *set_name, uint32_t set_id, uint32_t flags) return e; } -/* simplified nftables:include/netlink.h, netlink_padded_len() */ -#define NETLINK_ALIGN 4 - /* from nftables:include/datatype.h, TYPE_BITS */ #define CONCAT_TYPE_BITS 6 @@ -1208,8 +1205,9 @@ static int __add_nft_among(struct nft_handle *h, const char *table, nftnl_rule_add_expr(r, e); if (ip) { + reg = nft_get_next_reg(reg, ETH_ALEN); e = __gen_payload(NFT_PAYLOAD_NETWORK_HEADER, ip_addr_off[dst], - sizeof(struct in_addr), NFT_REG32_02); + sizeof(struct in_addr), reg); if (!e) return -ENOMEM; nftnl_rule_add_expr(r, e); |