netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [ebtables-compat PATCH 1/7] include: cache copy of Linux header uapi/linux/netfilter_bridge/ebt_802_3.h
@ 2015-01-19 13:27 Arturo Borrero Gonzalez
  2015-01-19 13:27 ` [ebtables-compat PATCH 2/7] ebtables-compat: add nft rule compat information to bridge rules Arturo Borrero Gonzalez
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Arturo Borrero Gonzalez @ 2015-01-19 13:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: giuseppelng, pablo

Cache a copy of Linux header uapi/linux/netfilter_bridge/ebt_802_3.h
which contains the struct ebt_802_3_info definition.

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
 include/linux/netfilter_bridge/ebt_802_3.h |   63 ++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)
 create mode 100644 include/linux/netfilter_bridge/ebt_802_3.h

diff --git a/include/linux/netfilter_bridge/ebt_802_3.h b/include/linux/netfilter_bridge/ebt_802_3.h
new file mode 100644
index 0000000..f37522a
--- /dev/null
+++ b/include/linux/netfilter_bridge/ebt_802_3.h
@@ -0,0 +1,63 @@
+#ifndef _UAPI__LINUX_BRIDGE_EBT_802_3_H
+#define _UAPI__LINUX_BRIDGE_EBT_802_3_H
+
+#include <linux/types.h>
+#include <linux/if_ether.h>
+
+#define EBT_802_3_SAP 0x01
+#define EBT_802_3_TYPE 0x02
+
+#define EBT_802_3_MATCH "802_3"
+
+/*
+ * If frame has DSAP/SSAP value 0xaa you must check the SNAP type
+ * to discover what kind of packet we're carrying. 
+ */
+#define CHECK_TYPE 0xaa
+
+/*
+ * Control field may be one or two bytes.  If the first byte has
+ * the value 0x03 then the entire length is one byte, otherwise it is two.
+ * One byte controls are used in Unnumbered Information frames.
+ * Two byte controls are used in Numbered Information frames.
+ */
+#define IS_UI 0x03
+
+#define EBT_802_3_MASK (EBT_802_3_SAP | EBT_802_3_TYPE | EBT_802_3)
+
+/* ui has one byte ctrl, ni has two */
+struct hdr_ui {
+	__u8 dsap;
+	__u8 ssap;
+	__u8 ctrl;
+	__u8 orig[3];
+	__be16 type;
+};
+
+struct hdr_ni {
+	__u8 dsap;
+	__u8 ssap;
+	__be16 ctrl;
+	__u8  orig[3];
+	__be16 type;
+};
+
+struct ebt_802_3_hdr {
+	__u8  daddr[ETH_ALEN];
+	__u8  saddr[ETH_ALEN];
+	__be16 len;
+	union {
+		struct hdr_ui ui;
+		struct hdr_ni ni;
+	} llc;
+};
+
+
+struct ebt_802_3_info {
+	__u8  sap;
+	__be16 type;
+	__u8  bitmask;
+	__u8  invflags;
+};
+
+#endif /* _UAPI__LINUX_BRIDGE_EBT_802_3_H */


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [ebtables-compat PATCH 2/7] ebtables-compat: add nft rule compat information to bridge rules
  2015-01-19 13:27 [ebtables-compat PATCH 1/7] include: cache copy of Linux header uapi/linux/netfilter_bridge/ebt_802_3.h Arturo Borrero Gonzalez
@ 2015-01-19 13:27 ` Arturo Borrero Gonzalez
  2015-01-19 13:27 ` [ebtables-compat PATCH 3/7] ebtables-compat: prevent options overwrite Arturo Borrero Gonzalez
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Arturo Borrero Gonzalez @ 2015-01-19 13:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: giuseppelng, pablo

The compat information is required by some ebtables extensions to properly
work.

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
 iptables/nft-bridge.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c
index 9747405..af67a5a 100644
--- a/iptables/nft-bridge.c
+++ b/iptables/nft-bridge.c
@@ -184,6 +184,8 @@ static int nft_bridge_add(struct nft_rule *r, void *data)
 		add_cmp_u16(r, fw->ethproto, op);
 	}
 
+	add_compat(r, fw->ethproto, fw->invflags);
+
 	for (matchp = cs->matches; matchp; matchp = matchp->next) {
 		if (add_match(r, matchp->match->m) < 0)
 			break;


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [ebtables-compat PATCH 3/7] ebtables-compat: prevent options overwrite
  2015-01-19 13:27 [ebtables-compat PATCH 1/7] include: cache copy of Linux header uapi/linux/netfilter_bridge/ebt_802_3.h Arturo Borrero Gonzalez
  2015-01-19 13:27 ` [ebtables-compat PATCH 2/7] ebtables-compat: add nft rule compat information to bridge rules Arturo Borrero Gonzalez
@ 2015-01-19 13:27 ` Arturo Borrero Gonzalez
  2015-01-19 13:27 ` [ebtables-compat PATCH 4/7] ebtables-compat: prevent same matches to be included multiple times Arturo Borrero Gonzalez
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Arturo Borrero Gonzalez @ 2015-01-19 13:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: giuseppelng, pablo

Parsing options will be overwritten if every time we load a match
the extension options are merged to the original options.

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
 iptables/xtables-eb.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index d0f6a3e..b559a53 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -618,7 +618,6 @@ static void ebt_load_match(const char *name)
 {
 	struct xtables_match *m;
 	size_t size;
-	opts = ebt_original_options;
 
 	m = xtables_find_match(name, XTF_LOAD_MUST_SUCCEED, NULL);
 	if (m == NULL)
@@ -638,6 +637,7 @@ static void ebt_load_match(const char *name)
 
 static void ebt_load_matches(void)
 {
+	opts = ebt_original_options;
 	ebt_load_match("802_3");
 }
 


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [ebtables-compat PATCH 4/7] ebtables-compat: prevent same matches to be included multiple times
  2015-01-19 13:27 [ebtables-compat PATCH 1/7] include: cache copy of Linux header uapi/linux/netfilter_bridge/ebt_802_3.h Arturo Borrero Gonzalez
  2015-01-19 13:27 ` [ebtables-compat PATCH 2/7] ebtables-compat: add nft rule compat information to bridge rules Arturo Borrero Gonzalez
  2015-01-19 13:27 ` [ebtables-compat PATCH 3/7] ebtables-compat: prevent options overwrite Arturo Borrero Gonzalez
@ 2015-01-19 13:27 ` Arturo Borrero Gonzalez
  2015-01-19 13:27 ` [ebtables-compat PATCH 5/7] ebtables-compat: include rule counters in ebtables rules Arturo Borrero Gonzalez
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Arturo Borrero Gonzalez @ 2015-01-19 13:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: giuseppelng, pablo

Using two matches options results in two copies of the match being included
in the nft rule.

Example before this patch:
 % ebtables-compat -A FORWARD -p 0x0800 --ip-src 10.0.0.1 --ip-dst 10.0.0.2 -j ACCEPT
 % ebtables-compat -L
 [...]
 -p 0x0800 --ip-src 10.0.0.1 --ip-dst 10.0.0.2 --ip-src 10.0.0.1 --ip-dst 10.0.0.2 -j ACCEPT

Example with this patch:
 % ebtables-compat -A FORWARD -p 0x0800 --ip-src 10.0.0.1 --ip-dst 10.0.0.2 -j ACCEPT
 % ebtables-compat -L
 [...]
 % -p 0x0800 --ip-src 10.0.0.1 --ip-dst 10.0.0.2 -j ACCEPT

[Note: the br_ip extension comes in a follow-up patch]

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
 iptables/xtables-eb.c |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index b559a53..a078679 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -644,6 +644,14 @@ static void ebt_load_matches(void)
 static void ebt_add_match(struct xtables_match *m,
 			  struct xtables_rule_match **rule_matches)
 {
+	struct xtables_rule_match *i;
+
+	/* match already in rule_matches, skip inclusion */
+	for (i = *rule_matches; i; i = i->next) {
+		if (strcmp(m->name, i->match->name) == 0)
+			return;
+	}
+
 	if (xtables_find_match(m->name, XTF_LOAD_MUST_SUCCEED, rule_matches) == NULL)
 		xtables_error(OTHER_PROBLEM,
 			      "Unable to add match %s", m->name);


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [ebtables-compat PATCH 5/7] ebtables-compat: include rule counters in ebtables rules
  2015-01-19 13:27 [ebtables-compat PATCH 1/7] include: cache copy of Linux header uapi/linux/netfilter_bridge/ebt_802_3.h Arturo Borrero Gonzalez
                   ` (2 preceding siblings ...)
  2015-01-19 13:27 ` [ebtables-compat PATCH 4/7] ebtables-compat: prevent same matches to be included multiple times Arturo Borrero Gonzalez
@ 2015-01-19 13:27 ` Arturo Borrero Gonzalez
  2015-01-19 13:28 ` [ebtables-compat PATCH 6/7] ebtables-compat: fix nft payload bases Arturo Borrero Gonzalez
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Arturo Borrero Gonzalez @ 2015-01-19 13:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: giuseppelng, pablo

Counters are missing in ebtables rules.

This patch includes them just before the target, so counters are incremented
when the rule is about to take his action.

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
 iptables/nft-bridge.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c
index af67a5a..3ef1357 100644
--- a/iptables/nft-bridge.c
+++ b/iptables/nft-bridge.c
@@ -191,6 +191,9 @@ static int nft_bridge_add(struct nft_rule *r, void *data)
 			break;
 	}
 
+	if (add_counters(r, cs->counters.pcnt, cs->counters.bcnt) < 0)
+		return -1;
+
 	return _add_action(r, cs);
 }
 


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [ebtables-compat PATCH 6/7] ebtables-compat: fix nft payload bases
  2015-01-19 13:27 [ebtables-compat PATCH 1/7] include: cache copy of Linux header uapi/linux/netfilter_bridge/ebt_802_3.h Arturo Borrero Gonzalez
                   ` (3 preceding siblings ...)
  2015-01-19 13:27 ` [ebtables-compat PATCH 5/7] ebtables-compat: include rule counters in ebtables rules Arturo Borrero Gonzalez
@ 2015-01-19 13:28 ` Arturo Borrero Gonzalez
  2015-01-19 13:28 ` [ebtables-compat PATCH 7/7] ebtables-compat: add 'ip' match extension Arturo Borrero Gonzalez
  2015-01-28 16:24 ` [ebtables-compat PATCH 1/7] include: cache copy of Linux header uapi/linux/netfilter_bridge/ebt_802_3.h Pablo Neira Ayuso
  6 siblings, 0 replies; 8+ messages in thread
From: Arturo Borrero Gonzalez @ 2015-01-19 13:28 UTC (permalink / raw)
  To: netfilter-devel; +Cc: giuseppelng, pablo

ebtables should use NFT_PAYLOAD_LL_HEADER to fetch basic payload information
from packets in the bridge family.

Let's allow the add_payload() function to know in which base it should work.

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
 iptables/nft-arp.c    |   15 ++++++++++-----
 iptables/nft-bridge.c |    9 ++++++---
 iptables/nft-ipv4.c   |    3 ++-
 iptables/nft-shared.c |    9 ++++-----
 iptables/nft-shared.h |    2 +-
 5 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
index b10b45f..24b31c5 100644
--- a/iptables/nft-arp.c
+++ b/iptables/nft-arp.c
@@ -156,13 +156,15 @@ static int nft_arp_add(struct nft_rule *r, void *data)
 
 	if (fw->arp.arhrd != 0) {
 		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPHRD);
-		add_payload(r, offsetof(struct arphdr, ar_hrd), 2);
+		add_payload(r, offsetof(struct arphdr, ar_hrd), 2,
+			    NFT_PAYLOAD_NETWORK_HEADER);
 		add_cmp_u16(r, fw->arp.arhrd, op);
 	}
 
 	if (fw->arp.arpro != 0) {
 		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPPRO);
-	        add_payload(r, offsetof(struct arphdr, ar_pro), 2);
+	        add_payload(r, offsetof(struct arphdr, ar_pro), 2,
+			    NFT_PAYLOAD_NETWORK_HEADER);
 		add_cmp_u16(r, fw->arp.arpro, op);
 	}
 
@@ -176,13 +178,15 @@ static int nft_arp_add(struct nft_rule *r, void *data)
 
 	if (fw->arp.arpop != 0) {
 		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPOP);
-		add_payload(r, offsetof(struct arphdr, ar_op), 2);
+		add_payload(r, offsetof(struct arphdr, ar_op), 2,
+			    NFT_PAYLOAD_NETWORK_HEADER);
 		add_cmp_u16(r, fw->arp.arpop, op);
 	}
 
 	if (fw->arp.src_devaddr.addr[0] != '\0') {
 		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCDEVADDR);
-		add_payload(r, sizeof(struct arphdr), fw->arp.arhln);
+		add_payload(r, sizeof(struct arphdr), fw->arp.arhln,
+			    NFT_PAYLOAD_NETWORK_HEADER);
 		add_cmp_ptr(r, op, fw->arp.src_devaddr.addr, fw->arp.arhln);
 	}
 
@@ -195,7 +199,8 @@ static int nft_arp_add(struct nft_rule *r, void *data)
 
 	if (fw->arp.tgt_devaddr.addr[0] != '\0') {
 		op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTDEVADDR);
-		add_payload(r, sizeof(struct arphdr) + fw->arp.arhln + 4, fw->arp.arhln);
+		add_payload(r, sizeof(struct arphdr) + fw->arp.arhln + 4,
+			    fw->arp.arhln, NFT_PAYLOAD_NETWORK_HEADER);
 		add_cmp_ptr(r, op, fw->arp.tgt_devaddr.addr, fw->arp.arhln);
 	}
 
diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c
index 3ef1357..62aab04 100644
--- a/iptables/nft-bridge.c
+++ b/iptables/nft-bridge.c
@@ -167,20 +167,23 @@ static int nft_bridge_add(struct nft_rule *r, void *data)
 	addr = ether_ntoa((struct ether_addr *) fw->sourcemac);
 	if (strcmp(addr, "0:0:0:0:0:0") != 0) {
 		op = nft_invflags2cmp(fw->invflags, EBT_ISOURCE);
-		add_payload(r, offsetof(struct ethhdr, h_source), 6);
+		add_payload(r, offsetof(struct ethhdr, h_source), 6,
+			    NFT_PAYLOAD_LL_HEADER);
 		add_cmp_ptr(r, op, fw->sourcemac, 6);
 	}
 
 	addr = ether_ntoa((struct ether_addr *) fw->destmac);
 	if (strcmp(addr, "0:0:0:0:0:0") != 0) {
 		op = nft_invflags2cmp(fw->invflags, EBT_IDEST);
-		add_payload(r, offsetof(struct ethhdr, h_dest), 6);
+		add_payload(r, offsetof(struct ethhdr, h_dest), 6,
+			    NFT_PAYLOAD_LL_HEADER);
 		add_cmp_ptr(r, op, fw->destmac, 6);
 	}
 
 	if (fw->ethproto != 0) {
 		op = nft_invflags2cmp(fw->invflags, EBT_IPROTO);
-		add_payload(r, offsetof(struct ethhdr, h_proto), 2);
+		add_payload(r, offsetof(struct ethhdr, h_proto), 2,
+			    NFT_PAYLOAD_LL_HEADER);
 		add_cmp_u16(r, fw->ethproto, op);
 	}
 
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
index 1b0dc2a..ed30920 100644
--- a/iptables/nft-ipv4.c
+++ b/iptables/nft-ipv4.c
@@ -60,7 +60,8 @@ static int nft_ipv4_add(struct nft_rule *r, void *data)
 			 sizeof(struct in_addr), op);
 	}
 	if (cs->fw.ip.flags & IPT_F_FRAG) {
-		add_payload(r, offsetof(struct iphdr, frag_off), 2);
+		add_payload(r, offsetof(struct iphdr, frag_off), 2,
+			    NFT_PAYLOAD_NETWORK_HEADER);
 		/* get the 13 bits that contain the fragment offset */
 		add_bitwise_u16(r, 0x1fff, !0x1fff);
 
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
index dd1dfca..76984e8 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -49,7 +49,7 @@ void add_meta(struct nft_rule *r, uint32_t key)
 	nft_rule_add_expr(r, expr);
 }
 
-void add_payload(struct nft_rule *r, int offset, int len)
+void add_payload(struct nft_rule *r, int offset, int len, uint32_t base)
 {
 	struct nft_rule_expr *expr;
 
@@ -57,8 +57,7 @@ void add_payload(struct nft_rule *r, int offset, int len)
 	if (expr == NULL)
 		return;
 
-	nft_rule_expr_set_u32(expr, NFT_EXPR_PAYLOAD_BASE,
-			      NFT_PAYLOAD_NETWORK_HEADER);
+	nft_rule_expr_set_u32(expr, NFT_EXPR_PAYLOAD_BASE, base);
 	nft_rule_expr_set_u32(expr, NFT_EXPR_PAYLOAD_DREG, NFT_REG_1);
 	nft_rule_expr_set_u32(expr, NFT_EXPR_PAYLOAD_OFFSET, offset);
 	nft_rule_expr_set_u32(expr, NFT_EXPR_PAYLOAD_LEN, len);
@@ -161,7 +160,7 @@ void add_outiface(struct nft_rule *r, char *iface, uint32_t op)
 void add_addr(struct nft_rule *r, int offset,
 	      void *data, void *mask, size_t len, uint32_t op)
 {
-	add_payload(r, offset, len);
+	add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER);
 	add_bitwise(r, mask, len);
 
 	add_cmp_ptr(r, op, data, len);
@@ -170,7 +169,7 @@ void add_addr(struct nft_rule *r, int offset,
 void add_proto(struct nft_rule *r, int offset, size_t len,
 	       uint8_t proto, uint32_t op)
 {
-	add_payload(r, offset, len);
+	add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER);
 	add_cmp_u8(r, proto, op);
 }
 
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index feef24f..33582aa 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -103,7 +103,7 @@ struct nft_family_ops {
 };
 
 void add_meta(struct nft_rule *r, uint32_t key);
-void add_payload(struct nft_rule *r, int offset, int len);
+void add_payload(struct nft_rule *r, int offset, int len, uint32_t base);
 void add_bitwise_u16(struct nft_rule *r, int mask, int xor);
 void add_cmp_ptr(struct nft_rule *r, uint32_t op, void *data, size_t len);
 void add_cmp_u8(struct nft_rule *r, uint8_t val, uint32_t op);


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [ebtables-compat PATCH 7/7] ebtables-compat: add 'ip' match extension
  2015-01-19 13:27 [ebtables-compat PATCH 1/7] include: cache copy of Linux header uapi/linux/netfilter_bridge/ebt_802_3.h Arturo Borrero Gonzalez
                   ` (4 preceding siblings ...)
  2015-01-19 13:28 ` [ebtables-compat PATCH 6/7] ebtables-compat: fix nft payload bases Arturo Borrero Gonzalez
@ 2015-01-19 13:28 ` Arturo Borrero Gonzalez
  2015-01-28 16:24 ` [ebtables-compat PATCH 1/7] include: cache copy of Linux header uapi/linux/netfilter_bridge/ebt_802_3.h Pablo Neira Ayuso
  6 siblings, 0 replies; 8+ messages in thread
From: Arturo Borrero Gonzalez @ 2015-01-19 13:28 UTC (permalink / raw)
  To: netfilter-devel; +Cc: giuseppelng, pablo

This patch adds the 'ip' match extension to ebtables-compat.

It involves adapting old ebtables extension code to the xtables-compat
environment.

For testing:
% sudo ebtables-compat -p 0x0800 --ip-src 1.1.1.1 -j ACCEPT

The patch includes a cached copy of the extension kernel header.

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
 extensions/libebt_ip.c                  |  326 +++++++++++++++++++++++++++++++
 include/linux/netfilter_bridge/ebt_ip.h |   44 ++++
 iptables/xtables-eb.c                   |    1 
 3 files changed, 371 insertions(+)
 create mode 100644 extensions/libebt_ip.c
 create mode 100644 include/linux/netfilter_bridge/ebt_ip.h

diff --git a/extensions/libebt_ip.c b/extensions/libebt_ip.c
new file mode 100644
index 0000000..ffb7ed6
--- /dev/null
+++ b/extensions/libebt_ip.c
@@ -0,0 +1,326 @@
+/* ebt_ip
+ *
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
+ *
+ * Changes:
+ *    added ip-sport and ip-dport; parsing of port arguments is
+ *    based on code from iptables-1.2.7a
+ *    Innominate Security Technologies AG <mhopf@innominate.com>
+ *    September, 2002
+ *
+ * Adapted by Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
+ * to use libxtables for ebtables-compat in 2015.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <netdb.h>
+#include <xtables.h>
+#include <linux/netfilter_bridge/ebt_ip.h>
+
+#define IP_SOURCE	'1'
+#define IP_DEST		'2'
+#define IP_EBT_TOS	'3' /* include/bits/in.h seems to already define IP_TOS */
+#define IP_PROTO	'4'
+#define IP_SPORT	'5'
+#define IP_DPORT	'6'
+
+static const struct option brip_opts[] = {
+	{ .name = "ip-source",		.has_arg = true, .val = IP_SOURCE },
+	{ .name = "ip-src",		.has_arg = true, .val = IP_SOURCE },
+	{ .name = "ip-destination",	.has_arg = true, .val = IP_DEST },
+	{ .name = "ip-dst",		.has_arg = true, .val = IP_DEST },
+	{ .name = "ip-tos",		.has_arg = true, .val = IP_EBT_TOS },
+	{ .name = "ip-protocol",	.has_arg = true, .val = IP_PROTO },
+	{ .name = "ip-proto",		.has_arg = true, .val = IP_PROTO },
+	{ .name = "ip-source-port",	.has_arg = true, .val = IP_SPORT },
+	{ .name = "ip-sport",		.has_arg = true, .val = IP_SPORT },
+	{ .name = "ip-destination-port",.has_arg = true, .val = IP_DPORT },
+	{ .name = "ip-dport",		.has_arg = true, .val = IP_DPORT },
+	XT_GETOPT_TABLEEND,
+};
+
+static void brip_print_help(void)
+{
+	printf(
+"ip options:\n"
+"--ip-src    [!] address[/mask]: ip source specification\n"
+"--ip-dst    [!] address[/mask]: ip destination specification\n"
+"--ip-tos    [!] tos           : ip tos specification\n"
+"--ip-proto  [!] protocol      : ip protocol specification\n"
+"--ip-sport  [!] port[:port]   : tcp/udp source port or port range\n"
+"--ip-dport  [!] port[:port]   : tcp/udp destination port or port range\n");
+}
+
+static void brip_init(struct xt_entry_match *match)
+{
+	struct ebt_ip_info *info = (struct ebt_ip_info *)match->data;
+
+	info->invflags = 0;
+	info->bitmask = 0;
+}
+
+static void
+parse_port_range(const char *protocol, const char *portstring, uint16_t *ports)
+{
+	char *buffer;
+	char *cp;
+
+	buffer = strdup(portstring);
+	if ((cp = strchr(buffer, ':')) == NULL)
+		ports[0] = ports[1] = xtables_parse_port(buffer, NULL);
+	else {
+		*cp = '\0';
+		cp++;
+
+		ports[0] = buffer[0] ? xtables_parse_port(buffer, NULL) : 0;
+		ports[1] = cp[0] ? xtables_parse_port(cp, NULL) : 0xFFFF;
+
+		if (ports[0] > ports[1])
+			xtables_error(PARAMETER_PROBLEM,
+				      "invalid portrange (min > max)");
+	}
+	free(buffer);
+}
+
+/* original code from ebtables: useful_functions.c */
+static int undot_ip(char *ip, unsigned char *ip2)
+{
+	char *p, *q, *end;
+	long int onebyte;
+	int i;
+	char buf[20];
+
+	strncpy(buf, ip, sizeof(buf) - 1);
+
+	p = buf;
+	for (i = 0; i < 3; i++) {
+		if ((q = strchr(p, '.')) == NULL)
+			return -1;
+		*q = '\0';
+		onebyte = strtol(p, &end, 10);
+		if (*end != '\0' || onebyte > 255 || onebyte < 0)
+			return -1;
+		ip2[i] = (unsigned char)onebyte;
+		p = q + 1;
+	}
+
+	onebyte = strtol(p, &end, 10);
+	if (*end != '\0' || onebyte > 255 || onebyte < 0)
+		return -1;
+	ip2[3] = (unsigned char)onebyte;
+
+	return 0;
+}
+
+static int ip_mask(char *mask, unsigned char *mask2)
+{
+	char *end;
+	long int bits;
+	uint32_t mask22;
+
+	if (undot_ip(mask, mask2)) {
+		/* not the /a.b.c.e format, maybe the /x format */
+		bits = strtol(mask, &end, 10);
+		if (*end != '\0' || bits > 32 || bits < 0)
+			return -1;
+		if (bits != 0) {
+			mask22 = htonl(0xFFFFFFFF << (32 - bits));
+			memcpy(mask2, &mask22, 4);
+		} else {
+			mask22 = 0xFFFFFFFF;
+			memcpy(mask2, &mask22, 4);
+		}
+	}
+	return 0;
+}
+
+static void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk)
+{
+	char *p;
+
+	/* first the mask */
+	if ((p = strrchr(address, '/')) != NULL) {
+		*p = '\0';
+		if (ip_mask(p + 1, (unsigned char *)msk)) {
+			xtables_error(PARAMETER_PROBLEM,
+				      "Problem with the IP mask '%s'", p + 1);
+			return;
+		}
+	} else
+		*msk = 0xFFFFFFFF;
+
+	if (undot_ip(address, (unsigned char *)addr)) {
+		xtables_error(PARAMETER_PROBLEM,
+			      "Problem with the IP address '%s'", address);
+		return;
+	}
+	*addr = *addr & *msk;
+}
+
+static int
+brip_parse(int c, char **argv, int invert, unsigned int *flags,
+	   const void *entry, struct xt_entry_match **match)
+{
+	struct ebt_ip_info *info = (struct ebt_ip_info *)(*match)->data;
+
+	switch (c) {
+	case IP_SOURCE:
+		if (invert)
+			info->invflags |= EBT_IP_SOURCE;
+		ebt_parse_ip_address(optarg, &info->saddr, &info->smsk);
+		info->bitmask |= EBT_IP_SOURCE;
+		break;
+	case IP_DEST:
+		if (invert)
+			info->invflags |= EBT_IP_DEST;
+		ebt_parse_ip_address(optarg, &info->daddr, &info->dmsk);
+		info->bitmask |= EBT_IP_DEST;
+		break;
+	case IP_SPORT:
+		if (invert)
+			info->invflags |= EBT_IP_SPORT;
+		parse_port_range(NULL, optarg, info->sport);
+		info->bitmask |= EBT_IP_SPORT;
+		break;
+	case IP_DPORT:
+		if (invert)
+			info->invflags |= EBT_IP_DPORT;
+		parse_port_range(NULL, optarg, info->dport);
+		info->bitmask |= EBT_IP_DPORT;
+		break;
+	case IP_EBT_TOS:
+		if (invert)
+			info->invflags |= EBT_IP_TOS;
+		if (!xtables_strtoul(optarg, NULL, (uintmax_t *)&info->tos,
+				     0, 255))
+			xtables_error(PARAMETER_PROBLEM,
+				      "Problem with specified IP tos");
+		info->bitmask |= EBT_IP_TOS;
+		break;
+	case IP_PROTO:
+		if (invert)
+			info->invflags |= EBT_IP_PROTO;
+		info->protocol = xtables_parse_protocol(optarg);
+		if (info->protocol == -1)
+			xtables_error(PARAMETER_PROBLEM,
+				      "Unknown specified IP protocol - %s",
+				      optarg);
+		info->bitmask |= EBT_IP_PROTO;
+		break;
+	default:
+		return 0;
+	}
+	return 1;
+}
+
+static void brip_final_check(unsigned int flags)
+{
+/*	struct ebt_ip_info *ipinfo = (struct ebt_ip_info *)match->data;
+
+	if (entry->ethproto != ETH_P_IP || entry->invflags & EBT_IPROTO) {
+		ebt_print_error("For IP filtering the protocol must be "
+		            "specified as IPv4");
+	} else if (info->bitmask & (EBT_IP_SPORT|EBT_IP_DPORT) &&
+		(!(info->bitmask & EBT_IP_PROTO) ||
+		info->invflags & EBT_IP_PROTO ||
+		(info->protocol!=IPPROTO_TCP &&
+		 info->protocol!=IPPROTO_UDP &&
+		 info->protocol!=IPPROTO_SCTP &&
+		 info->protocol!=IPPROTO_DCCP)))
+		ebt_print_error("For port filtering the IP protocol must be "
+				"either 6 (tcp), 17 (udp), 33 (dccp) or "
+				"132 (sctp)");
+*/
+	if (!flags)
+		xtables_error(PARAMETER_PROBLEM,
+			      "You must specify proper arguments");
+}
+
+static void print_port_range(uint16_t *ports)
+{
+	if (ports[0] == ports[1])
+		printf("%d ", ports[0]);
+	else
+		printf("%d:%d ", ports[0], ports[1]);
+}
+
+static void brip_print(const void *ip, const struct xt_entry_match *match,
+		       int numeric)
+{
+	struct ebt_ip_info *info = (struct ebt_ip_info *)match->data;
+	struct in_addr *addrp, *maskp;
+
+	if (info->bitmask & EBT_IP_SOURCE) {
+		printf("--ip-src ");
+		if (info->invflags & EBT_IP_SOURCE)
+			printf("! ");
+		addrp = (struct in_addr *)&info->saddr;
+		maskp = (struct in_addr *)&info->smsk;
+		printf("%s%s ", xtables_ipaddr_to_numeric(addrp),
+		       xtables_ipmask_to_numeric(maskp));
+	}
+	if (info->bitmask & EBT_IP_DEST) {
+		printf("--ip-dst ");
+		if (info->invflags & EBT_IP_DEST)
+			printf("! ");
+		addrp = (struct in_addr *)&info->daddr;
+		maskp = (struct in_addr *)&info->dmsk;
+		printf("%s%s ", xtables_ipaddr_to_numeric(addrp),
+		       xtables_ipmask_to_numeric(maskp));
+	}
+	if (info->bitmask & EBT_IP_TOS) {
+		printf("--ip-tos ");
+		if (info->invflags & EBT_IP_TOS)
+			printf("! ");
+		printf("0x%02X ", info->tos);
+	}
+	if (info->bitmask & EBT_IP_PROTO) {
+		struct protoent *pe;
+
+		printf("--ip-proto ");
+		if (info->invflags & EBT_IP_PROTO)
+			printf("! ");
+		pe = getprotobynumber(info->protocol);
+		if (pe == NULL) {
+			printf("%d ", info->protocol);
+		} else {
+			printf("%s ", pe->p_name);
+		}
+	}
+	if (info->bitmask & EBT_IP_SPORT) {
+		printf("--ip-sport ");
+		if (info->invflags & EBT_IP_SPORT)
+			printf("! ");
+		print_port_range(info->sport);
+	}
+	if (info->bitmask & EBT_IP_DPORT) {
+		printf("--ip-dport ");
+		if (info->invflags & EBT_IP_DPORT)
+			printf("! ");
+		print_port_range(info->dport);
+	}
+}
+
+static struct xtables_match brip_match = {
+	.name		= "ip",
+	.revision	= 0,
+	.version	= XTABLES_VERSION,
+	.family		= NFPROTO_BRIDGE,
+	.size		= XT_ALIGN(sizeof(struct ebt_ip_info)),
+	.userspacesize	= XT_ALIGN(sizeof(struct ebt_ip_info)),
+	.init		= brip_init,
+	.help		= brip_print_help,
+	.parse		= brip_parse,
+	.final_check	= brip_final_check,
+	.print		= brip_print,
+	.extra_opts	= brip_opts,
+};
+
+void _init(void)
+{
+	xtables_register_match(&brip_match);
+}
diff --git a/include/linux/netfilter_bridge/ebt_ip.h b/include/linux/netfilter_bridge/ebt_ip.h
new file mode 100644
index 0000000..c4bbc41
--- /dev/null
+++ b/include/linux/netfilter_bridge/ebt_ip.h
@@ -0,0 +1,44 @@
+/*
+ *  ebt_ip
+ *
+ *	Authors:
+ *	Bart De Schuymer <bart.de.schuymer@pandora.be>
+ *
+ *  April, 2002
+ *
+ *  Changes:
+ *    added ip-sport and ip-dport
+ *    Innominate Security Technologies AG <mhopf@innominate.com>
+ *    September, 2002
+ */
+
+#ifndef __LINUX_BRIDGE_EBT_IP_H
+#define __LINUX_BRIDGE_EBT_IP_H
+
+#include <linux/types.h>
+
+#define EBT_IP_SOURCE 0x01
+#define EBT_IP_DEST 0x02
+#define EBT_IP_TOS 0x04
+#define EBT_IP_PROTO 0x08
+#define EBT_IP_SPORT 0x10
+#define EBT_IP_DPORT 0x20
+#define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\
+ EBT_IP_SPORT | EBT_IP_DPORT )
+#define EBT_IP_MATCH "ip"
+
+/* the same values are used for the invflags */
+struct ebt_ip_info {
+	__be32 saddr;
+	__be32 daddr;
+	__be32 smsk;
+	__be32 dmsk;
+	__u8  tos;
+	__u8  protocol;
+	__u8  bitmask;
+	__u8  invflags;
+	__u16 sport[2];
+	__u16 dport[2];
+};
+
+#endif
diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index a078679..27a1c16 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -639,6 +639,7 @@ static void ebt_load_matches(void)
 {
 	opts = ebt_original_options;
 	ebt_load_match("802_3");
+	ebt_load_match("ip");
 }
 
 static void ebt_add_match(struct xtables_match *m,


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [ebtables-compat PATCH 1/7] include: cache copy of Linux header uapi/linux/netfilter_bridge/ebt_802_3.h
  2015-01-19 13:27 [ebtables-compat PATCH 1/7] include: cache copy of Linux header uapi/linux/netfilter_bridge/ebt_802_3.h Arturo Borrero Gonzalez
                   ` (5 preceding siblings ...)
  2015-01-19 13:28 ` [ebtables-compat PATCH 7/7] ebtables-compat: add 'ip' match extension Arturo Borrero Gonzalez
@ 2015-01-28 16:24 ` Pablo Neira Ayuso
  6 siblings, 0 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2015-01-28 16:24 UTC (permalink / raw)
  To: Arturo Borrero Gonzalez; +Cc: netfilter-devel, giuseppelng

Series applied to ebtables-compat-experimental6, thanks Arturo.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-01-28 20:21 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-01-19 13:27 [ebtables-compat PATCH 1/7] include: cache copy of Linux header uapi/linux/netfilter_bridge/ebt_802_3.h Arturo Borrero Gonzalez
2015-01-19 13:27 ` [ebtables-compat PATCH 2/7] ebtables-compat: add nft rule compat information to bridge rules Arturo Borrero Gonzalez
2015-01-19 13:27 ` [ebtables-compat PATCH 3/7] ebtables-compat: prevent options overwrite Arturo Borrero Gonzalez
2015-01-19 13:27 ` [ebtables-compat PATCH 4/7] ebtables-compat: prevent same matches to be included multiple times Arturo Borrero Gonzalez
2015-01-19 13:27 ` [ebtables-compat PATCH 5/7] ebtables-compat: include rule counters in ebtables rules Arturo Borrero Gonzalez
2015-01-19 13:28 ` [ebtables-compat PATCH 6/7] ebtables-compat: fix nft payload bases Arturo Borrero Gonzalez
2015-01-19 13:28 ` [ebtables-compat PATCH 7/7] ebtables-compat: add 'ip' match extension Arturo Borrero Gonzalez
2015-01-28 16:24 ` [ebtables-compat PATCH 1/7] include: cache copy of Linux header uapi/linux/netfilter_bridge/ebt_802_3.h Pablo Neira Ayuso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).