memcpy(info->mask, ctx->bitwise.mask, ETH_ALEN);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
- memset(info->mask, 0xff, ETH_ALEN);
+ memset(info->mask, 0xff,
+ min(ctx->payload.len, ETH_ALEN));
}
return inv;
parse_mask_ipv4(ctx, &fw->arp.smsk);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
- fw->arp.smsk.s_addr = 0xffffffff;
+ memset(&fw->arp.smsk, 0xff,
+ min(ctx->payload.len,
+ sizeof(struct in_addr)));
}
if (inv)
parse_mask_ipv4(ctx, &fw->arp.tmsk);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
- fw->arp.tmsk.s_addr = 0xffffffff;
+ memset(&fw->arp.tmsk, 0xff,
+ min(ctx->payload.len,
+ sizeof(struct in_addr)));
}
if (inv)
parse_mask_ipv4(ctx, &cs->fw.ip.smsk);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
- cs->fw.ip.smsk.s_addr = 0xffffffff;
+ memset(&cs->fw.ip.smsk, 0xff,
+ min(ctx->payload.len, sizeof(struct in_addr)));
}
if (inv)
parse_mask_ipv4(ctx, &cs->fw.ip.dmsk);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
- cs->fw.ip.dmsk.s_addr = 0xffffffff;
+ memset(&cs->fw.ip.dmsk, 0xff,
+ min(ctx->payload.len, sizeof(struct in_addr)));
}
if (inv)
parse_mask_ipv6(ctx, &cs->fw6.ipv6.smsk);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
- memset(&cs->fw6.ipv6.smsk, 0xff, sizeof(struct in6_addr));
+ memset(&cs->fw6.ipv6.smsk, 0xff,
+ min(ctx->payload.len, sizeof(struct in6_addr)));
}
if (inv)
parse_mask_ipv6(ctx, &cs->fw6.ipv6.dmsk);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
- memset(&cs->fw6.ipv6.dmsk, 0xff, sizeof(struct in6_addr));
+ memset(&cs->fw6.ipv6.dmsk, 0xff,
+ min(ctx->payload.len, sizeof(struct in6_addr)));
}
if (inv)
void *data, void *mask, size_t len, uint32_t op)
{
const unsigned char *m = mask;
+ bool bitwise = false;
int i;
- add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER);
-
for (i = 0; i < len; i++) {
- if (m[i] != 0xff)
+ if (m[i] != 0xff) {
+ bitwise = m[i] != 0;
break;
+ }
}
- if (i != len)
+ if (!bitwise)
+ len = i;
+
+ add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER);
+
+ if (bitwise)
add_bitwise(r, mask, len);
add_cmp_ptr(r, op, data, len);
const struct nft_xt_restore_parse *p);
void nft_check_xt_legacy(int family, bool is_ipt_save);
+
+#define min(x, y) ((x) < (y) ? (x) : (y))
+#define max(x, y) ((x) > (y) ? (x) : (y))
+
#endif