From 0ab58e397ca613a1996cb9767e221f71e752812e Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 4 May 2018 22:33:35 +0200 Subject: xtables-compat: ebtables: handle mac masks properly Signed-off-by: Florian Westphal --- iptables/nft-bridge.c | 15 +++++++++++++++ iptables/nft-shared.c | 2 +- iptables/nft-shared.h | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c index 3fdac9cc..e1c82f03 100644 --- a/iptables/nft-bridge.c +++ b/iptables/nft-bridge.c @@ -184,6 +184,7 @@ static int nft_bridge_add(struct nftnl_rule *r, void *data) op = nft_invflags2cmp(fw->invflags, EBT_ISOURCE); add_payload(r, offsetof(struct ethhdr, h_source), 6, NFT_PAYLOAD_LL_HEADER); + add_bitwise(r, fw->sourcemsk, 6); add_cmp_ptr(r, op, fw->sourcemac, 6); } @@ -192,6 +193,7 @@ static int nft_bridge_add(struct nftnl_rule *r, void *data) op = nft_invflags2cmp(fw->invflags, EBT_IDEST); add_payload(r, offsetof(struct ethhdr, h_dest), 6, NFT_PAYLOAD_LL_HEADER); + add_bitwise(r, fw->destmsk, 6); add_cmp_ptr(r, op, fw->destmac, 6); } @@ -291,6 +293,13 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx, fw->destmac[i] = addr[i]; if (inv) fw->invflags |= EBT_IDEST; + + if (ctx->flags & NFT_XT_CTX_BITWISE) { + memcpy(fw->destmsk, ctx->bitwise.mask, ETH_ALEN); + ctx->flags &= ~NFT_XT_CTX_BITWISE; + } else { + memset(&fw->destmsk, 0xff, ETH_ALEN); + } break; case offsetof(struct ethhdr, h_source): get_cmp_data(e, addr, sizeof(addr), &inv); @@ -298,6 +307,12 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx, fw->sourcemac[i] = addr[i]; if (inv) fw->invflags |= EBT_ISOURCE; + if (ctx->flags & NFT_XT_CTX_BITWISE) { + memcpy(fw->sourcemsk, ctx->bitwise.mask, ETH_ALEN); + ctx->flags &= ~NFT_XT_CTX_BITWISE; + } else { + memset(&fw->sourcemsk, 0xff, ETH_ALEN); + } break; case offsetof(struct ethhdr, h_proto): get_cmp_data(e, ðproto, sizeof(ethproto), &inv); diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c index 68e5c55d..e2fc226c 100644 --- a/iptables/nft-shared.c +++ b/iptables/nft-shared.c @@ -83,7 +83,7 @@ void add_bitwise_u16(struct nftnl_rule *r, int mask, int xor) nftnl_rule_add_expr(r, expr); } -static void add_bitwise(struct nftnl_rule *r, uint8_t *mask, size_t len) +void add_bitwise(struct nftnl_rule *r, uint8_t *mask, size_t len) { struct nftnl_expr *expr; uint32_t xor[4] = { 0 }; diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h index e13a1a85..525f3f0e 100644 --- a/iptables/nft-shared.h +++ b/iptables/nft-shared.h @@ -107,6 +107,7 @@ struct nft_family_ops { void add_meta(struct nftnl_rule *r, uint32_t key); void add_payload(struct nftnl_rule *r, int offset, int len, uint32_t base); +void add_bitwise(struct nftnl_rule *r, uint8_t *mask, size_t len); void add_bitwise_u16(struct nftnl_rule *r, int mask, int xor); void add_cmp_ptr(struct nftnl_rule *r, uint32_t op, void *data, size_t len); void add_cmp_u8(struct nftnl_rule *r, uint8_t val, uint32_t op); -- cgit v1.2.3