--dst-ip checks the first four octets of the target mac. Format of ipv4 arp is: arphdr (htype, ptype...) src mac src ip target mac target ip So we need to add hlen (6 bytes) a second time (arphdr + 6 + 4 + 6) to get correct offset. Signed-off-by: Florian Westphal <fw@xxxxxxxxx> --- iptables/nft-arp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c index 21adc5dbb1fe..c8b52ae051f3 100644 --- a/iptables/nft-arp.c +++ b/iptables/nft-arp.c @@ -214,7 +214,7 @@ static int nft_arp_add(struct nftnl_rule *r, void *data) fw->arp.tmsk.s_addr != 0 || fw->arp.invflags & ARPT_INV_TGTIP) { op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTIP); - add_addr(r, sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr), + add_addr(r, sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr) + fw->arp.arhln, &fw->arp.tgt.s_addr, &fw->arp.tmsk.s_addr, sizeof(struct in_addr), op); } @@ -346,7 +346,8 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, fw->arp.invflags |= ARPT_INV_SRCIP; } else if (ctx->payload.offset == sizeof(struct arphdr) + fw->arp.arhln + - sizeof(struct in_addr)) { + sizeof(struct in_addr) + + fw->arp.arhln) { get_cmp_data(e, &addr, sizeof(addr), &inv); fw->arp.tgt.s_addr = addr.s_addr; if (ctx->flags & NFT_XT_CTX_BITWISE) { -- 2.18.1