From 6c8db125b258da070313f20cdf9bc4124bba5383 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 19 Feb 2015 00:15:13 +0100 Subject: iptables-compat: unset context flags in netlink delinearize step Once the data that the compare expression provides have been digested. For example: -A INPUT -i noexist -p udplite -s 10.10.10.10/32 -d 10.0.0.10/32 -j ACCEPT doesn't show anymore the following broken output via iptables-compat-save: -A INPUT -i +t -p udplite -s 10.10.10.10/32 -d 10.0.0.10/32 -j ACCEPT Reported-by: Arturo Borrero Gonzalez Signed-off-by: Pablo Neira Ayuso Tested-by: Arturo Borrero Gonzalez --- iptables/nft-arp.c | 12 ++++++++---- iptables/nft-ipv4.c | 14 ++++++++++---- iptables/nft-ipv6.c | 20 ++++++++++++-------- iptables/nft-shared.c | 8 ++++++-- 4 files changed, 36 insertions(+), 18 deletions(-) (limited to 'iptables') diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c index 05672014..523b3ec3 100644 --- a/iptables/nft-arp.c +++ b/iptables/nft-arp.c @@ -337,10 +337,12 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, fw->arp.arhln) { get_cmp_data(e, &addr, sizeof(addr), &inv); fw->arp.src.s_addr = addr.s_addr; - if (ctx->flags & NFT_XT_CTX_BITWISE) + if (ctx->flags & NFT_XT_CTX_BITWISE) { parse_mask_ipv4(ctx, &fw->arp.smsk); - else + ctx->flags &= ~NFT_XT_CTX_BITWISE; + } else { fw->arp.smsk.s_addr = 0xffffffff; + } if (inv) fw->arp.invflags |= ARPT_INV_SRCIP; @@ -349,10 +351,12 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, sizeof(struct in_addr)) { get_cmp_data(e, &addr, sizeof(addr), &inv); fw->arp.tgt.s_addr = addr.s_addr; - if (ctx->flags & NFT_XT_CTX_BITWISE) + if (ctx->flags & NFT_XT_CTX_BITWISE) { parse_mask_ipv4(ctx, &fw->arp.tmsk); - else + ctx->flags &= ~NFT_XT_CTX_BITWISE; + } else { fw->arp.tmsk.s_addr = 0xffffffff; + } if (inv) fw->arp.invflags |= ARPT_INV_TGTIP; diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c index ed309207..140093cd 100644 --- a/iptables/nft-ipv4.c +++ b/iptables/nft-ipv4.c @@ -123,6 +123,8 @@ static void get_frag(struct nft_xt_ctx *ctx, struct nft_rule_expr *e, bool *inv) *inv = true; else *inv = false; + + ctx->flags &= ~NFT_XT_CTX_BITWISE; } static const char *mask_to_str(uint32_t mask) @@ -178,10 +180,12 @@ static void nft_ipv4_parse_payload(struct nft_xt_ctx *ctx, case offsetof(struct iphdr, saddr): get_cmp_data(e, &addr, sizeof(addr), &inv); cs->fw.ip.src.s_addr = addr.s_addr; - if (ctx->flags & NFT_XT_CTX_BITWISE) + if (ctx->flags & NFT_XT_CTX_BITWISE) { parse_mask_ipv4(ctx, &cs->fw.ip.smsk); - else + ctx->flags &= ~NFT_XT_CTX_BITWISE; + } else { cs->fw.ip.smsk.s_addr = 0xffffffff; + } if (inv) cs->fw.ip.invflags |= IPT_INV_SRCIP; @@ -189,10 +193,12 @@ static void nft_ipv4_parse_payload(struct nft_xt_ctx *ctx, case offsetof(struct iphdr, daddr): get_cmp_data(e, &addr, sizeof(addr), &inv); cs->fw.ip.dst.s_addr = addr.s_addr; - if (ctx->flags & NFT_XT_CTX_BITWISE) + if (ctx->flags & NFT_XT_CTX_BITWISE) { parse_mask_ipv4(ctx, &cs->fw.ip.dmsk); - else + ctx->flags &= ~NFT_XT_CTX_BITWISE; + } else { cs->fw.ip.dmsk.s_addr = 0xffffffff; + } if (inv) cs->fw.ip.invflags |= IPT_INV_DSTIP; diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c index 37365da1..d50b138e 100644 --- a/iptables/nft-ipv6.c +++ b/iptables/nft-ipv6.c @@ -126,10 +126,12 @@ static void nft_ipv6_parse_payload(struct nft_xt_ctx *ctx, case offsetof(struct ip6_hdr, ip6_src): get_cmp_data(e, &addr, sizeof(addr), &inv); memcpy(cs->fw6.ipv6.src.s6_addr, &addr, sizeof(addr)); - if (ctx->flags & NFT_XT_CTX_BITWISE) - parse_mask_ipv6(ctx, &cs->fw6.ipv6.smsk); - else - memset(&cs->fw.ip.smsk, 0xff, sizeof(struct in6_addr)); + if (ctx->flags & NFT_XT_CTX_BITWISE) { + parse_mask_ipv6(ctx, &cs->fw6.ipv6.smsk); + ctx->flags &= ~NFT_XT_CTX_BITWISE; + } else { + memset(&cs->fw.ip.smsk, 0xff, sizeof(struct in6_addr)); + } if (inv) cs->fw6.ipv6.invflags |= IPT_INV_SRCIP; @@ -137,10 +139,12 @@ static void nft_ipv6_parse_payload(struct nft_xt_ctx *ctx, case offsetof(struct ip6_hdr, ip6_dst): get_cmp_data(e, &addr, sizeof(addr), &inv); memcpy(cs->fw6.ipv6.dst.s6_addr, &addr, sizeof(addr)); - if (ctx->flags & NFT_XT_CTX_BITWISE) - parse_mask_ipv6(ctx, &cs->fw6.ipv6.dmsk); - else - memset(&cs->fw.ip.dmsk, 0xff, sizeof(struct in6_addr)); + if (ctx->flags & NFT_XT_CTX_BITWISE) { + parse_mask_ipv6(ctx, &cs->fw6.ipv6.dmsk); + ctx->flags &= ~NFT_XT_CTX_BITWISE; + } else { + memset(&cs->fw.ip.dmsk, 0xff, sizeof(struct in6_addr)); + } if (inv) cs->fw6.ipv6.invflags |= IPT_INV_DSTIP; diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c index 620da3e7..1182f560 100644 --- a/iptables/nft-shared.c +++ b/iptables/nft-shared.c @@ -434,11 +434,15 @@ void nft_parse_cmp(struct nft_xt_ctx *ctx, struct nft_rule_expr *e) if (ctx->reg && reg != ctx->reg) return; - if (ctx->flags & NFT_XT_CTX_META) + if (ctx->flags & NFT_XT_CTX_META) { ops->parse_meta(ctx, e, data); + ctx->flags &= ~NFT_XT_CTX_META; + } /* bitwise context is interpreted from payload */ - if (ctx->flags & NFT_XT_CTX_PAYLOAD) + if (ctx->flags & NFT_XT_CTX_PAYLOAD) { ops->parse_payload(ctx, e, data); + ctx->flags &= ~NFT_XT_CTX_PAYLOAD; + } } void nft_parse_counter(struct nft_rule_expr *e, struct xt_counters *counters) -- cgit v1.2.3