]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
xtables-compat: ebtables: fix logical interface negation
authorFlorian Westphal <fw@strlen.de>
Tue, 8 May 2018 11:48:44 +0000 (13:48 +0200)
committerFlorian Westphal <fw@strlen.de>
Thu, 10 May 2018 00:31:05 +0000 (02:31 +0200)
before:
Bridge chain: OUTPUT, entries: 4, policy: ACCEPT
-o ! noout -j CONTINUE
-o out -j CONTINUE
--logical-out notlogout -j CONTINUE
--logical-out logout -j CONTINUE

after:
Bridge chain: OUTPUT, entries: 5, policy: ACCEPT
-o ! noout -j CONTINUE
-o out -j CONTINUE
--logical-out ! notlogout -j CONTINUE
--logical-out logout -j CONTINUE

Signed-off-by: Florian Westphal <fw@strlen.de>
iptables/nft-bridge.c
iptables/nft-shared.c

index 5f9a02c297cb6cf048604d9e1371c6d4c104013b..162a87e0bb3bf96cf548767e47053451fd60d1cb 100644 (file)
@@ -86,22 +86,6 @@ static void ebt_print_mac_and_mask(const unsigned char *mac, const unsigned char
        }
 }
 
-static uint16_t ipt_to_ebt_flags(uint8_t invflags)
-{
-       uint16_t result = 0;
-
-       if (invflags & IPT_INV_VIA_IN)
-               result |= EBT_IIN;
-
-       if (invflags & IPT_INV_VIA_OUT)
-               result |= EBT_IOUT;
-
-       if (invflags & IPT_INV_PROTO)
-               result |= EBT_IPROTO;
-
-       return result;
-}
-
 static void add_logical_iniface(struct nftnl_rule *r, char *iface, uint32_t op)
 {
        int iface_len;
@@ -235,53 +219,38 @@ static void nft_bridge_parse_meta(struct nft_xt_ctx *ctx,
 {
        struct iptables_command_state *cs = data;
        struct ebt_entry *fw = &cs->eb;
-       uint8_t flags = 0;
-       int iface = 0;
-       const void *ifname;
-       uint32_t len;
+       uint8_t invflags = 0;
+       char iifname[IFNAMSIZ], oifname[IFNAMSIZ];
+
+       memset(iifname, 0, sizeof(iifname));
+       memset(oifname, 0, sizeof(oifname));
 
-       iface = parse_meta(e, ctx->meta.key, fw->in, fw->in_mask,
-                          fw->out, fw->out_mask, &flags);
-       if (!iface)
-               goto out;
+       parse_meta(e, ctx->meta.key, iifname, NULL, oifname, NULL, &invflags);
 
        switch (ctx->meta.key) {
        case NFT_META_BRI_IIFNAME:
-               ifname = nftnl_expr_get(e, NFTNL_EXPR_CMP_DATA, &len);
-               if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)
-                       flags |= IPT_INV_VIA_IN;
-
-               memcpy(fw->logical_in, ifname, len);
-
-               if (fw->logical_in[len] == '\0')
-                       memset(fw->in_mask, 0xff, len);
-               else {
-                       fw->logical_in[len] = '+';
-                       fw->logical_in[len+1] = '\0';
-                       memset(fw->in_mask, 0xff, len + 1);
-               }
+               if (invflags & IPT_INV_VIA_IN)
+                       cs->eb.invflags |= EBT_ILOGICALIN;
+               snprintf(fw->logical_in, sizeof(fw->logical_in), "%s", iifname);
+               break;
+       case NFT_META_IIFNAME:
+               if (invflags & IPT_INV_VIA_IN)
+                       cs->eb.invflags |= EBT_IIN;
+               snprintf(fw->in, sizeof(fw->in), "%s", iifname);
                break;
        case NFT_META_BRI_OIFNAME:
-               ifname = nftnl_expr_get(e, NFTNL_EXPR_CMP_DATA, &len);
-               if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)
-                       flags |= IPT_INV_VIA_OUT;
-
-               memcpy(fw->logical_out, ifname, len);
-
-               if (fw->logical_out[len] == '\0') 
-                       memset(fw->out_mask, 0xff, len);
-               else {
-                       fw->logical_out[len] = '+';
-                       fw->logical_out[len+1] = '\0';
-                       memset(fw->out_mask, 0xff, len + 1);
-               }
+               if (invflags & IPT_INV_VIA_OUT)
+                       cs->eb.invflags |= EBT_ILOGICALOUT;
+               snprintf(fw->logical_out, sizeof(fw->logical_out), "%s", oifname);
+               break;
+       case NFT_META_OIFNAME:
+               if (invflags & IPT_INV_VIA_OUT)
+                       cs->eb.invflags |= EBT_IOUT;
+               snprintf(fw->out, sizeof(fw->out), "%s", oifname);
                break;
        default:
                break;
        }
-
-out:
-       fw->invflags |= ipt_to_ebt_flags(flags);
 }
 
 static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx,
index 76fd8e495c217429aa2bdf22a958f3c74cba1405..4db2832d459bf865a4e7533ce8c1ca7c364c1f57 100644 (file)
@@ -268,6 +268,7 @@ int parse_meta(struct nftnl_expr *e, uint8_t key, char *iniface,
 
                memset(outiface_mask, 0xff, strlen(outiface)+1);
                break;
+       case NFT_META_BRI_IIFNAME:
        case NFT_META_IIFNAME:
                ifname = nftnl_expr_get(e, NFTNL_EXPR_CMP_DATA, &len);
                if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)
@@ -275,6 +276,7 @@ int parse_meta(struct nftnl_expr *e, uint8_t key, char *iniface,
 
                parse_ifname(ifname, len, iniface, iniface_mask);
                break;
+       case NFT_META_BRI_OIFNAME:
        case NFT_META_OIFNAME:
                ifname = nftnl_expr_get(e, NFTNL_EXPR_CMP_DATA, &len);
                if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)