]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
iptables-compat: unset context flags in netlink delinearize step
authorPablo Neira Ayuso <pablo@netfilter.org>
Wed, 18 Feb 2015 23:15:13 +0000 (00:15 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sun, 22 Feb 2015 18:59:45 +0000 (19:59 +0100)
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 <arturo.borrero.glez@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Tested-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
iptables/nft-arp.c
iptables/nft-ipv4.c
iptables/nft-ipv6.c
iptables/nft-shared.c

index 05672014ce7ede10e4c42c03ec402507c3e31487..523b3ec3d7197b2b39faf391e00f53c887e1be0b 100644 (file)
@@ -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;
index ed3092077cbc9d7b02e27c01a5dd85fab601b01e..140093cd320657410a0e6b12e4cd478b3ac070b2 100644 (file)
@@ -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;
index 37365da19bca55af1ace9e6b6ccf7b93f46bde83..d50b138eded46f2cec63d458dd12c2f29a0b7d34 100644 (file)
@@ -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;
index 620da3e77b39ba3437c26259c824d46c02fc50cc..1182f56029e3820723dc57e0c562931557c6cae2 100644 (file)
@@ -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)