Skip to contentSkip to conversation

xtables: bootstrap xtables-eb for nftables

PATCH In review Giuseppe Longo 2 participants 4 messages Oct 1, 2014

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/3 xtables: bootstrap xtables-eb for nftables

This patch bootstraps xtables-eb for the nftables compatibility layer

---
 include/linux/netfilter_bridge.h            |   33 +
 include/linux/netfilter_bridge/ebtables.h   |  276 +++++++
 include/linux/netfilter_bridge/ethernetdb.h |   58 ++
 iptables/Makefile.am                        |    6 +-
 iptables/getethertype.c                     |  161 ++++
 iptables/nft.c                              |   28 +
 iptables/nft.h                              |    9 +
 iptables/xtables-compat-multi               |  210 +++++
 iptables/xtables-compat-multi.c             |    1 +
 iptables/xtables-eb-standalone.c            |   87 ++
 iptables/xtables-eb.c                       | 1186 +++++++++++++++++++++++++++
 iptables/xtables-ebtables.h                 |   49 ++
 iptables/xtables-multi.c                    |    1 +
 iptables/xtables-multi.h                    |    1 +
 14 files changed, 2104 insertions(+), 2 deletions(-)
 create mode 100644 include/linux/netfilter_bridge.h
 create mode 100644 include/linux/netfilter_bridge/ebtables.h
 create mode 100644 include/linux/netfilter_bridge/ethernetdb.h
 create mode 100644 iptables/getethertype.c
 create mode 100755 iptables/xtables-compat-multi
 create mode 100644 iptables/xtables-eb-standalone.c
 create mode 100644 iptables/xtables-eb.c
 create mode 100644 iptables/xtables-ebtables.h
include/linux/netfilter_bridge.h new file +33 -0
new file mode 100644
index 0000000..71e9299
@@ -0,0 +1,33 @@
+#ifndef __LINUX_BRIDGE_NETFILTER_H
+#define __LINUX_BRIDGE_NETFILTER_H
+
+/* bridge-specific defines for netfilter. 
+ */
+#include <limits.h>
+
+/* Bridge Hooks */
+/* After promisc drops, checksum checks. */
+#define NF_BR_PRE_ROUTING	0
+/* If the packet is destined for this box. */
+#define NF_BR_LOCAL_IN		1
+/* If the packet is destined for another interface. */
+#define NF_BR_FORWARD		2
+/* Packets coming from a local process. */
+#define NF_BR_LOCAL_OUT		3
+/* Packets about to hit the wire. */
+#define NF_BR_POST_ROUTING	4
+/* Not really a hook, but used for the ebtables broute table */
+#define NF_BR_BROUTING		5
+#define NF_BR_NUMHOOKS		6
+
+enum nf_br_hook_priorities {
+	NF_BR_PRI_FIRST = INT_MIN,
+	NF_BR_PRI_FILTER_BRIDGED = -200,
+	NF_BR_PRI_FILTER_OTHER = 200,
+	NF_BR_PRI_NAT_DST_BRIDGED = -300,
+	NF_BR_PRI_NAT_DST_OTHER = 100,
+	NF_BR_PRI_NAT_SRC = 300,
+	NF_BR_PRI_LAST = INT_MAX,
+};
+
+#endif
include/linux/netfilter_bridge/ebtables.h new file +276 -0

276 lines not on this page · raw message

include/linux/netfilter_bridge/ethernetdb.h new file +58 -0

58 lines not on this page · raw message

iptables/Makefile.am +4 -2
index aaaade8..b3e417b 100644
@@ -39,7 +39,9 @@ xtables_compat_multi_SOURCES += xtables-save.c xtables-restore.c \
 				xtables-standalone.c xtables.c nft.c \
 				nft-shared.c nft-ipv4.c nft-ipv6.c nft-arp.c \
 				xtables-config.c xtables-events.c \
-				xtables-arp-standalone.c xtables-arp.c
+				xtables-arp-standalone.c xtables-arp.c \
+				getethertype.c nft-bridge.c \
+				xtables-eb-standalone.c xtables-eb.c
 xtables_compat_multi_LDADD   += ${libmnl_LIBS} ${libnftnl_LIBS} ../extensions/libext4.a ../extensions/libext6.a
 # yacc and lex generate dirty code
 xtables_compat_multi-xtables-config-parser.o xtables_compat_multi-xtables-config-syntax.o: AM_CFLAGS += -Wno-missing-prototypes -Wno-missing-declarations -Wno-implicit-function-declaration -Wno-nested-externs -Wno-undef -Wno-redundant-decls
@@ -67,7 +69,7 @@ endif
 if ENABLE_NFTABLES
 x_sbin_links  = iptables-compat iptables-compat-restore iptables-compat-save \
 		ip6tables-compat ip6tables-compat-restore ip6tables-compat-save \
-		arptables-compat xtables-config xtables-events
+		arptables-compat ebtables-compat xtables-config xtables-events
 endif
 
 iptables-extensions.8: iptables-extensions.8.tmpl ../extensions/matches.man ../extensions/targets.man
iptables/getethertype.c new file +161 -0

161 lines not on this page · raw message

iptables/nft.c +28 -0
index e3b07e0..fe8e380 100644
@@ -489,6 +489,34 @@ struct builtin_table xtables_arp[TABLES_MAX] = {
 	},
 };
 
+#include <linux/netfilter_bridge.h>
+
+struct builtin_table xtables_bridge[TABLES_MAX] = {
+	[FILTER] = {
+	.name = "filter",
+	.chains = {
+			{
+				.name   = "INPUT",
+				.type   = "filter",
+				.prio   = NF_BR_PRI_FILTER_BRIDGED,
+				.hook   = NF_BR_LOCAL_IN,
+			},
+			{
+				.name   = "FORWARD",
+				.type   = "filter",
+				.prio   = NF_BR_PRI_FILTER_BRIDGED,
+				.hook   = NF_BR_FORWARD,
+			},
+			{
+				.name   = "OUTPUT",
+				.type   = "filter",
+				.prio   = NF_BR_PRI_FILTER_BRIDGED,
+				.hook   = NF_BR_LOCAL_OUT,
+			},
+		},
+	},
+};
+
 int nft_table_add(struct nft_handle *h, struct nft_table *t, uint16_t flags)
 {
 	char buf[MNL_SOCKET_BUFFER_SIZE];
iptables/nft.h +9 -0
index 339d7bc..c4aedd2 100644
@@ -41,6 +41,7 @@ struct nft_handle {
 
 extern struct builtin_table xtables_ipv4[TABLES_MAX];
 extern struct builtin_table xtables_arp[TABLES_MAX];
+extern struct builtin_table xtables_bridge[TABLES_MAX];
 
 int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh,
 	     int (*cb)(const struct nlmsghdr *nlh, void *data),
@@ -138,6 +139,8 @@ const char *nft_strerror(int err);
 int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, bool restore);
 /* For xtables-arptables.c */
 int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table);
+/* For xtables-eb.c */
+int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table);
 
 /*
  * Parse config for tables and chain helper functions
@@ -170,4 +173,10 @@ int nft_arp_rule_insert(struct nft_handle *h, const char *chain,
 
 void nft_rule_to_arpt_entry(struct nft_rule *r, struct arpt_entry *fw);
 
+/*
+ * BRIDGE
+ */
+
+struct ebt_entry;
+
 #endif
iptables/xtables-compat-multi new file +210 -0

210 lines not on this page · raw message

iptables/xtables-compat-multi.c +1 -0
index 4781052..ed8ad07 100644
@@ -28,6 +28,7 @@ static const struct subcommand multi_subcommands[] = {
 	{"ip6tables-compat-restore",	xtables_ip6_restore_main},
 	{"arptables",			xtables_arp_main},
 	{"arptables-compat",		xtables_arp_main},
+	{"ebtables-compat",		xtables_eb_main},
 	{"xtables-config",		xtables_config_main},
 	{"xtables-events",		xtables_events_main},
 	{NULL},
iptables/xtables-eb-standalone.c new file +87 -0

87 lines not on this page · raw message

iptables/xtables-eb.c new file +1186 -0

1,186 lines not on this page · raw message

iptables/xtables-ebtables.h new file +49 -0

49 lines not on this page · raw message

iptables/xtables-multi.c +1 -0
index 5f48735..47e16f2 100644
@@ -43,6 +43,7 @@ static const struct subcommand multi_subcommands[] = {
 	{"xtables-config",      xtables_config_main},
 	{"xtables-events",      xtables_events_main},
 	{"xtables-arp",		xtables_arp_main},
+	{"xtables-eb",		xtables_eb_main},
 #endif
 	{NULL},
 };
iptables/xtables-multi.h +1 -0
index e706894..21e60b2 100644
@@ -10,6 +10,7 @@ extern int xtables_ip6_main(int, char **);
 extern int xtables_ip6_save_main(int, char **);
 extern int xtables_ip6_restore_main(int, char **);
 extern int xtables_arp_main(int, char **);
+extern int xtables_eb_main(int, char **);
 extern int xtables_config_main(int, char **);
 extern int xtables_events_main(int, char **);
 #endif
Signature · 1 line
1.8.3.2
#1 lore raw

PATCH 2/3 nft-shared: make compare_matches as public

This permits to compare two xtables_ebt_entry's matches reusing compare_matches.

---
 iptables/nft-shared.c | 4 ++--
 iptables/nft-shared.h | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)
iptables/nft-shared.c +2 -2
index 03f15b4..db1424f 100644
@@ -720,8 +720,8 @@ struct nft_family_ops *nft_family_ops_lookup(int family)
 	return NULL;
 }
 
-static bool
-compare_matches(struct xtables_rule_match *mt1, struct xtables_rule_match *mt2)
+bool compare_matches(struct xtables_rule_match *mt1,
+		     struct xtables_rule_match *mt2)
 {
 	struct xtables_rule_match *mp1;
 	struct xtables_rule_match *mp2;
iptables/nft-shared.h +1 -0
index ecb486c..789aaeb 100644
@@ -134,6 +134,7 @@ struct nft_handle;
 bool nft_ipv46_rule_find(struct nft_family_ops *ops, struct nft_rule *r,
 			 struct iptables_command_state *cs);
 
+bool compare_matches(struct xtables_rule_match *mt1, struct xtables_rule_match *mt2);
 bool compare_targets(struct xtables_target *tg1, struct xtables_target *tg2);
 
 struct addr_mask {
Signature · 1 line
1.8.3.2
#2 lore raw

PATCH 3/3 Operations for bridge family

In reply to Giuseppe Longo

The following patch implements the operations for bridge family.

---
 include/linux/netfilter/nf_tables.h |   4 +
 iptables/nft-bridge.c               | 545 ++++++++++++++++++++++++++++++++++++
 iptables/nft-shared.c               |  10 +-
 iptables/nft-shared.h               |   2 +-
 iptables/nft.h                      |   5 +-
 5 files changed, 561 insertions(+), 5 deletions(-)
 create mode 100644 iptables/nft-bridge.c
include/linux/netfilter/nf_tables.h +4 -0
index fbfd229..8b41d04 100644
@@ -529,6 +529,8 @@ enum nft_exthdr_attributes {
  * @NFT_META_NFTRACE: packet nftrace bit
  * @NFT_META_RTCLASSID: realm value of packet's route (skb->dst->tclassid)
  * @NFT_META_SECMARK: packet secmark (skb->secmark)
+ * @NFT_META_BRI_IIFNAME: packet input bridge interface name
+ * @NFT_META_BRI_OIFNAME: packet output bridge interface name
  */
 enum nft_meta_keys {
 	NFT_META_LEN,
@@ -546,6 +548,8 @@ enum nft_meta_keys {
 	NFT_META_NFTRACE,
 	NFT_META_RTCLASSID,
 	NFT_META_SECMARK,
+	NFT_META_BRI_IIFNAME,
+	NFT_META_BRI_OIFNAME,
 };
 
 /**
iptables/nft-bridge.c new file +545 -0

545 lines not on this page · raw message

iptables/nft-shared.c +7 -3
index db1424f..e583f78 100644
@@ -32,6 +32,7 @@
 extern struct nft_family_ops nft_family_ops_ipv4;
 extern struct nft_family_ops nft_family_ops_ipv6;
 extern struct nft_family_ops nft_family_ops_arp;
+extern struct nft_family_ops nft_family_ops_bridge;
 
 void add_meta(struct nft_rule *r, uint32_t key)
 {
@@ -236,7 +237,7 @@ bool is_same_interfaces(const char *a_iniface, const char *a_outiface,
 	return true;
 }
 
-void parse_meta(struct nft_rule_expr *e, uint8_t key, char *iniface,
+int parse_meta(struct nft_rule_expr *e, uint8_t key, char *iniface,
 		unsigned char *iniface_mask, char *outiface,
 		unsigned char *outiface_mask, uint8_t *invflags)
 {
@@ -294,9 +295,10 @@ void parse_meta(struct nft_rule_expr *e, uint8_t key, char *iniface,
 		}
 		break;
 	default:
-		DEBUGP("unknown meta key %d\n", key);
-		break;
+		return -1;
 	}
+
+	return 0;
 }
 
 static void *nft_get_data(struct nft_xt_ctx *ctx)
@@ -713,6 +715,8 @@ struct nft_family_ops *nft_family_ops_lookup(int family)
 		return &nft_family_ops_ipv6;
 	case NFPROTO_ARP:
 		return &nft_family_ops_arp;
+	case NFPROTO_BRIDGE:
+		return &nft_family_ops_bridge;
 	default:
 		break;
 	}
iptables/nft-shared.h +1 -1
index 789aaeb..9b46342 100644
@@ -95,7 +95,7 @@ bool is_same_interfaces(const char *a_iniface, const char *a_outiface,
 			unsigned const char *b_iniface_mask,
 			unsigned const char *b_outiface_mask);
 
-void parse_meta(struct nft_rule_expr *e, uint8_t key, char *iniface,
+int parse_meta(struct nft_rule_expr *e, uint8_t key, char *iniface,
 		unsigned char *iniface_mask, char *outiface,
 		unsigned char *outiface_mask, uint8_t *invflags);
 void print_proto(uint16_t proto, int invert);
iptables/nft.h +4 -1
index c4aedd2..838e859 100644
@@ -177,6 +177,9 @@ void nft_rule_to_arpt_entry(struct nft_rule *r, struct arpt_entry *fw);
  * BRIDGE
  */
 
-struct ebt_entry;
+#include "xtables-ebtables.h"
 
+struct xtables_ebt_entry;
+
+void nft_rule_to_xtables_ebt_entry(struct nft_rule *r, struct xtables_ebt_entry *fw);
 #endif
Signature · 1 line
1.8.3.2
#3 lore raw
In reply to Giuseppe Longo

Hi Giuseppe,

Quoted 1 line · Giuseppe Longo

This patch bootstraps xtables-eb for the nftables compatibility layer

I have pushed these patches to this branch in iptables:

http://git.netfilter.org/iptables/log/?h=ebtables-compat-experimental

I have forward-ported the patchset to run on top of the recent nft_xt_ctx changes.

There is still a good amount of work to be done to get this in good shape:

1) The output of ebtables-compat -L should look the same like ebtables -L.

1) Fix segfaults. I detected one when you use -h, and another if you don't pass any target. Those should be easy to fix IMO.

2) Fix listing. If I add:

ebtables-compat -I INPUT --logical-in br0 -j ACCEPT

shows:

-d 62:72:30:0:0:0 --logical-in br0 -j ACCEPT

Note the -d seem incorrect.

3) I have added ebtables NAT table support. It's basically a filter table. I needed a small kernel patch though since the bridge filter chain type is not allowing to filter at prerouting and postrouting.

4) Add support for matches and targets.

I'll have a look at this later again, but it would be great if you can send incremental patches to resolve the existing issues. Thanks.