[PATCH xtables 07/10] xtables-compat: ebtables: fix logical interface negation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx>
---
 iptables/nft-bridge.c | 75 +++++++++++++++------------------------------------
 iptables/nft-shared.c |  2 ++
 2 files changed, 24 insertions(+), 53 deletions(-)

diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c
index 5f9a02c297cb..162a87e0bb3b 100644
--- a/iptables/nft-bridge.c
+++ b/iptables/nft-bridge.c
@@ -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,
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
index 76fd8e495c21..4db2832d459b 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -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)
-- 
2.16.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux