Skip to contentSkip to conversation

include: cache a copy of kernel ebtables.h

PATCH In review Arturo Borrero Gonzalez 3 participants 9 messages Apr 8, 2015 – Apr 9, 2015

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

PATCH 1/4 include: cache a copy of kernel ebtables.h

From: Arturo Borrero Gonzalez <[email protected]>

Required for next patches.

---
 include/linux/netfilter_bridge/ebtables.h |  266 +++++++++++++++++++++++++++++
 1 file changed, 266 insertions(+)
 create mode 100644 include/linux/netfilter_bridge/ebtables.h
include/linux/netfilter_bridge/ebtables.h new file +266 -0
new file mode 100644
index 0000000..a225911
@@ -0,0 +1,266 @@
+/*
+ *  ebtables
+ *
+ *	Authors:
+ *	Bart De Schuymer		<[email protected]>
+ *
+ *  ebtables.c,v 2.0, April, 2002
+ *
+ *  This code is stongly inspired on the iptables code which is
+ *  Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
+ */
+
+#ifndef __LINUX_BRIDGE_EFF_H
+#define __LINUX_BRIDGE_EFF_H
+#include <linux/netfilter_bridge.h>
+
+#define EBT_TABLE_MAXNAMELEN 32
+#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN
+#define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN
+
+/* verdicts >0 are "branches" */
+#define EBT_ACCEPT   -1
+#define EBT_DROP     -2
+#define EBT_CONTINUE -3
+#define EBT_RETURN   -4
+#define NUM_STANDARD_TARGETS   4
+/* ebtables target modules store the verdict inside an int. We can
+ * reclaim a part of this int for backwards compatible extensions.
+ * The 4 lsb are more than enough to store the verdict. */
+#define EBT_VERDICT_BITS 0x0000000F
+
+struct xt_match;
+struct xt_target;
+
+struct ebt_counter {
+	uint64_t pcnt;
+	uint64_t bcnt;
+};
+
+struct ebt_replace {
+	char name[EBT_TABLE_MAXNAMELEN];
+	unsigned int valid_hooks;
+	/* nr of rules in the table */
+	unsigned int nentries;
+	/* total size of the entries */
+	unsigned int entries_size;
+	/* start of the chains */
+	struct ebt_entries *hook_entry[NF_BR_NUMHOOKS];
+	/* nr of counters userspace expects back */
+	unsigned int num_counters;
+	/* where the kernel will put the old counters */
+	struct ebt_counter *counters;
+	char *entries;
+};
+
+struct ebt_replace_kernel {
+	char name[EBT_TABLE_MAXNAMELEN];
+	unsigned int valid_hooks;
+	/* nr of rules in the table */
+	unsigned int nentries;
+	/* total size of the entries */
+	unsigned int entries_size;
+	/* start of the chains */
+	struct ebt_entries *hook_entry[NF_BR_NUMHOOKS];
+	/* nr of counters userspace expects back */
+	unsigned int num_counters;
+	/* where the kernel will put the old counters */
+	struct ebt_counter *counters;
+	char *entries;
+};
+
+struct ebt_entries {
+	/* this field is always set to zero
+	 * See EBT_ENTRY_OR_ENTRIES.
+	 * Must be same size as ebt_entry.bitmask */
+	unsigned int distinguisher;
+	/* the chain name */
+	char name[EBT_CHAIN_MAXNAMELEN];
+	/* counter offset for this chain */
+	unsigned int counter_offset;
+	/* one standard (accept, drop, return) per hook */
+	int policy;
+	/* nr. of entries */
+	unsigned int nentries;
+	/* entry list */
+	char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
+};
+
+/* used for the bitmask of struct ebt_entry */
+
+/* This is a hack to make a difference between an ebt_entry struct and an
+ * ebt_entries struct when traversing the entries from start to end.
+ * Using this simplifies the code a lot, while still being able to use
+ * ebt_entries.
+ * Contrary, iptables doesn't use something like ebt_entries and therefore uses
+ * different techniques for naming the policy and such. So, iptables doesn't
+ * need a hack like this.
+ */
+#define EBT_ENTRY_OR_ENTRIES 0x01
+/* these are the normal masks */
+#define EBT_NOPROTO 0x02
+#define EBT_802_3 0x04
+#define EBT_SOURCEMAC 0x08
+#define EBT_DESTMAC 0x10
+#define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \
+   | EBT_ENTRY_OR_ENTRIES)
+
+#define EBT_IPROTO 0x01
+#define EBT_IIN 0x02
+#define EBT_IOUT 0x04
+#define EBT_ISOURCE 0x8
+#define EBT_IDEST 0x10
+#define EBT_ILOGICALIN 0x20
+#define EBT_ILOGICALOUT 0x40
+#define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \
+   | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST)
+
+struct ebt_entry_match {
+	union {
+		char name[EBT_FUNCTION_MAXNAMELEN];
+		struct xt_match *match;
+	} u;
+	/* size of data */
+	unsigned int match_size;
+	unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
+};
+
+struct ebt_entry_watcher {
+	union {
+		char name[EBT_FUNCTION_MAXNAMELEN];
+		struct xt_target *watcher;
+	} u;
+	/* size of data */
+	unsigned int watcher_size;
+	unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
+};
+
+struct ebt_entry_target {
+	union {
+		char name[EBT_FUNCTION_MAXNAMELEN];
+		struct xt_target *target;
+	} u;
+	/* size of data */
+	unsigned int target_size;
+	unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
+};
+
+#define EBT_STANDARD_TARGET "standard"
+struct ebt_standard_target {
+	struct ebt_entry_target target;
+	int verdict;
+};
+
+/* one entry */
+struct ebt_entry {
+	/* this needs to be the first field */
+	unsigned int bitmask;
+	unsigned int invflags;
+	__be16 ethproto;
+	/* the physical in-dev */
+	char in[IFNAMSIZ];
+	/* the logical in-dev */
+	char logical_in[IFNAMSIZ];
+	/* the physical out-dev */
+	char out[IFNAMSIZ];
+	/* the logical out-dev */
+	char logical_out[IFNAMSIZ];
+	unsigned char sourcemac[ETH_ALEN];
+	unsigned char sourcemsk[ETH_ALEN];
+	unsigned char destmac[ETH_ALEN];
+	unsigned char destmsk[ETH_ALEN];
+	/* sizeof ebt_entry + matches */
+	unsigned int watchers_offset;
+	/* sizeof ebt_entry + matches + watchers */
+	unsigned int target_offset;
+	/* sizeof ebt_entry + matches + watchers + target */
+	unsigned int next_offset;
+	unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
+};
+
+/* {g,s}etsockopt numbers */
+#define EBT_BASE_CTL            128
+
+#define EBT_SO_SET_ENTRIES      (EBT_BASE_CTL)
+#define EBT_SO_SET_COUNTERS     (EBT_SO_SET_ENTRIES+1)
+#define EBT_SO_SET_MAX          (EBT_SO_SET_COUNTERS+1)
+
+#define EBT_SO_GET_INFO         (EBT_BASE_CTL)
+#define EBT_SO_GET_ENTRIES      (EBT_SO_GET_INFO+1)
+#define EBT_SO_GET_INIT_INFO    (EBT_SO_GET_ENTRIES+1)
+#define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1)
+#define EBT_SO_GET_MAX          (EBT_SO_GET_INIT_ENTRIES+1)
+
+
+/* blatently stolen from ip_tables.h
+ * fn returns 0 to continue iteration */
+#define EBT_MATCH_ITERATE(e, fn, args...)                   \
+({                                                          \
+	unsigned int __i;                                   \
+	int __ret = 0;                                      \
+	struct ebt_entry_match *__match;                    \
+	                                                    \
+	for (__i = sizeof(struct ebt_entry);                \
+	     __i < (e)->watchers_offset;                    \
+	     __i += __match->match_size +                   \
+	     sizeof(struct ebt_entry_match)) {              \
+		__match = (void *)(e) + __i;                \
+		                                            \
+		__ret = fn(__match , ## args);              \
+		if (__ret != 0)                             \
+			break;                              \
+	}                                                   \
+	if (__ret == 0) {                                   \
+		if (__i != (e)->watchers_offset)            \
+			__ret = -EINVAL;                    \
+	}                                                   \
+	__ret;                                              \
+})
+
+#define EBT_WATCHER_ITERATE(e, fn, args...)                 \
+({                                                          \
+	unsigned int __i;                                   \
+	int __ret = 0;                                      \
+	struct ebt_entry_watcher *__watcher;                \
+	                                                    \
+	for (__i = e->watchers_offset;                      \
+	     __i < (e)->target_offset;                      \
+	     __i += __watcher->watcher_size +               \
+	     sizeof(struct ebt_entry_watcher)) {            \
+		__watcher = (void *)(e) + __i;              \
+		                                            \
+		__ret = fn(__watcher , ## args);            \
+		if (__ret != 0)                             \
+			break;                              \
+	}                                                   \
+	if (__ret == 0) {                                   \
+		if (__i != (e)->target_offset)              \
+			__ret = -EINVAL;                    \
+	}                                                   \
+	__ret;                                              \
+})
+
+#define EBT_ENTRY_ITERATE(entries, size, fn, args...)       \
+({                                                          \
+	unsigned int __i;                                   \
+	int __ret = 0;                                      \
+	struct ebt_entry *__entry;                          \
+	                                                    \
+	for (__i = 0; __i < (size);) {                      \
+		__entry = (void *)(entries) + __i;          \
+		__ret = fn(__entry , ## args);              \
+		if (__ret != 0)                             \
+			break;                              \
+		if (__entry->bitmask != 0)                  \
+			__i += __entry->next_offset;        \
+		else                                        \
+			__i += sizeof(struct ebt_entries);  \
+	}                                                   \
+	if (__ret == 0) {                                   \
+		if (__i != (size))                          \
+			__ret = -EINVAL;                    \
+	}                                                   \
+	__ret;                                              \
+})
+
+#endif /* __LINUX_BRIDGE_EFF_H */
#1 lore raw

PATCH 2/4 src: expose delinearize/linearize structures and stmt_error()

From: Pablo Neira Ayuso <[email protected]>

Needed by the follow up xt compatibility layer patch.

---
 include/erec.h            |   12 ++++++++++++
 include/netlink.h         |   39 +++++++++++++++++++++++++++++++++++++++
 src/erec.c                |   17 +++++++++++++++++
 src/evaluate.c            |   26 ++------------------------
 src/netlink_delinearize.c |   13 -------------
 src/netlink_linearize.c   |    5 -----
 6 files changed, 70 insertions(+), 42 deletions(-)
include/erec.h +12 -0
index 25df1d0..a4422bc 100644
@@ -3,6 +3,7 @@
 
 #include <nftables.h>
 #include <utils.h>
+#include <rule.h>
 
 /**
  * enum error_record_types
@@ -61,4 +62,15 @@ static inline void erec_queue(struct error_record *erec,
 extern void erec_print(FILE *f, const struct error_record *erec);
 extern void erec_print_list(FILE *f, struct list_head *list);
 
+
+int __fmtstring(4, 5) __binary_error(struct eval_ctx *ctx,
+				     const struct location *l1,
+				     const struct location *l2,
+				     const char *fmt, ...);
+
+#define stmt_error(ctx, s1, fmt, args...) \
+	__binary_error(ctx, &(s1)->location, NULL, fmt, ## args)
+#define stmt_binary_error(ctx, s1, s2, fmt, args...) \
+	__binary_error(ctx, &(s1)->location, &(s2)->location, fmt, ## args)
+
 #endif /* NFTABLES_EREC_H */
include/netlink.h +39 -0
index 9f24ea5..34fc085 100644
@@ -12,6 +12,45 @@
 
 #include <rule.h>
 
+/** struct netlink_linearize_ctx
+ *
+ * @nlr:	nftnl rule object
+ * @reg_low:	next spare register
+ */
+struct netlink_linearize_ctx {
+	struct nft_rule		*nlr;
+	unsigned int		reg_low;
+};
+
+/**
+ * struct netlink_parse_ctx
+ *
+ * @msgs:	message queue
+ * @table:	current table
+ * @rule:	pointer to current rule that is being delinearized
+ * @expr:	registers
+ */
+struct netlink_parse_ctx {
+	struct list_head	*msgs;
+	struct table		*table;
+	struct rule		*rule;
+	struct expr		*registers[NFT_REG_MAX + 1];
+};
+
+/**
+ * struct rule_pp_ctx
+ *
+ * @pctx:	protocol context
+ * @pbase:	protocol base
+ * @pdep:	dependency statement
+ */
+struct rule_pp_ctx {
+	struct proto_ctx	pctx;
+	enum proto_bases	pbase;
+	struct stmt		*pdep;
+};
+
+
 extern const struct input_descriptor indesc_netlink;
 extern const struct location netlink_location;
 
src/erec.c +17 -0
index 810e9bf..ba331a5 100644
@@ -166,3 +166,20 @@ void erec_print_list(FILE *f, struct list_head *list)
 		erec_destroy(erec);
 	}
 }
+
+int __fmtstring(4, 5) __binary_error(struct eval_ctx *ctx,
+				     const struct location *l1,
+				     const struct location *l2,
+				     const char *fmt, ...)
+{
+	struct error_record *erec;
+	va_list ap;
+
+	va_start(ap, fmt);
+	erec = erec_vcreate(EREC_ERROR, l1, fmt, ap);
+	if (l2 != NULL)
+		erec_add_location(erec, l2);
+	va_end(ap);
+	erec_queue(erec, ctx->msgs);
+	return -1;
+}
src/evaluate.c +2 -24
index 7ecb793..b216fb1 100644
@@ -36,32 +36,10 @@ static const char *byteorder_names[] = {
 	[BYTEORDER_BIG_ENDIAN]		= "big endian",
 };
 
-static int __fmtstring(4, 5) __stmt_binary_error(struct eval_ctx *ctx,
-						 const struct location *l1,
-						 const struct location *l2,
-						 const char *fmt, ...)
-{
-	struct error_record *erec;
-	va_list ap;
-
-	va_start(ap, fmt);
-	erec = erec_vcreate(EREC_ERROR, l1, fmt, ap);
-	if (l2 != NULL)
-		erec_add_location(erec, l2);
-	va_end(ap);
-	erec_queue(erec, ctx->msgs);
-	return -1;
-
-}
-
-#define stmt_error(ctx, s1, fmt, args...) \
-	__stmt_binary_error(ctx, &(s1)->location, NULL, fmt, ## args)
-#define stmt_binary_error(ctx, s1, s2, fmt, args...) \
-	__stmt_binary_error(ctx, &(s1)->location, &(s2)->location, fmt, ## args)
 #define chain_error(ctx, s1, fmt, args...) \
-	__stmt_binary_error(ctx, &(s1)->location, NULL, fmt, ## args)
+	__binary_error(ctx, &(s1)->location, NULL, fmt, ## args)
 #define monitor_error(ctx, s1, fmt, args...) \
-	__stmt_binary_error(ctx, &(s1)->location, NULL, fmt, ## args)
+	__binary_error(ctx, &(s1)->location, NULL, fmt, ## args)
 
 static int __fmtstring(3, 4) set_error(struct eval_ctx *ctx,
 				       const struct set *set,
src/netlink_delinearize.c +0 -13
index ec1a964..e0bb726 100644
@@ -26,13 +26,6 @@
 #include <erec.h>
 #include <sys/socket.h>
 
-struct netlink_parse_ctx {
-	struct list_head	*msgs;
-	struct table		*table;
-	struct rule		*rule;
-	struct expr		*registers[NFT_REG_MAX + 1];
-};
-
 static void __fmtstring(3, 4) netlink_error(struct netlink_parse_ctx *ctx,
 					    const struct location *loc,
 					    const char *fmt, ...)
@@ -741,12 +734,6 @@ static int netlink_parse_expr(struct nft_rule_expr *nle, void *arg)
 	return 0;
 }
 
-struct rule_pp_ctx {
-	struct proto_ctx	pctx;
-	enum proto_bases	pbase;
-	struct stmt		*pdep;
-};
-
 /*
  * Kill a redundant payload dependecy that is implied by a higher layer payload expression.
  */
src/netlink_linearize.c +0 -5
index 9bef67b..6a637a4 100644
@@ -19,11 +19,6 @@
 #include <gmputil.h>
 #include <utils.h>
 
-struct netlink_linearize_ctx {
-	struct nft_rule		*nlr;
-	unsigned int		reg_low;
-};
-
 static void netlink_put_register(struct nft_rule_expr *nle,
 				 uint32_t attr, uint32_t reg)
 {
#2 lore raw

PATCH 3/4 src: add xt compat support

In reply to Arturo Borrero Gonzalez

From: Pablo Neira Ayuso <[email protected]>

At compilation time, you have to pass this option.

  # ./configure --with-xtables

And libxtables needs to be installed in your system.

This patch allows you to use xt extensions from nft, eg.

  # nft add rule filter output \
	tcp flags syn xt target TCPMSS [ --clamp-mss-to-pmtu ]

This provides access to all existing xt modules from nft. Users can meanwhile use xt extension until we can provide native expressions.

You can build this optionally, if disabled it displays an error:

  # nft add rule filter output tcp flags syn xt target TCPMSS [ --clamp-mss-to-pmtu ]
  <cmdline>:1:38-77: Error: this build does not support xtables
  add rule filter output tcp flags syn xt target TCPMSS [ --clamp-mss-to-pmtu ]
                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

so you know your build doesn't support this.

Limitations:

* Beware of clashes with keywords, eg. state, from bison parser.
* Better xt parsing errors for unknown options.

This is joint work with Arturo Borrero Gonzalez.

---
 configure.ac              |   13 +
 include/statement.h       |    4 
 include/xt.h              |  105 +++++++
 src/Makefile.am           |    8 +
 src/evaluate.c            |    3 
 src/main.c                |   12 +
 src/netlink_delinearize.c |    6 
 src/netlink_linearize.c   |    3 
 src/parser_bison.y        |   57 ++++
 src/rule.c                |    1 
 src/scanner.l             |   15 +
 src/statement.c           |   42 +++
 src/xt.c                  |  673 +++++++++++++++++++++++++++++++++++++++++++++
 13 files changed, 939 insertions(+), 3 deletions(-)
 create mode 100644 include/xt.h
 create mode 100644 src/xt.c
configure.ac +12 -1
index d8f949a..f51acb9 100644
@@ -92,6 +92,16 @@ AC_DEFINE([HAVE_LIBREADLINE], [1], [])
 AC_SUBST(with_cli)
 AM_CONDITIONAL([BUILD_CLI], [test "x$with_cli" != xno])
 
+AC_ARG_WITH([xtables], [AS_HELP_STRING([--with-xtables],
+            [Use libxtables for iptables interaction)])],
+	    [with_libxtables=yes], [with_libxtables=no])
+AS_IF([test "x$with_libxtables" != xno], [
+PKG_CHECK_MODULES([XTABLES], [xtables >= 1.4.21])
+AC_DEFINE([HAVE_LIBXTABLES], [1], [0])
+])
+AC_SUBST(with_libxtables)
+AM_CONDITIONAL([BUILD_XTABLES], [test "x$with_libxtables" == xyes])
+
 # Checks for header files.
 AC_HEADER_STDC
 AC_HEADER_ASSERT
@@ -136,4 +146,5 @@ echo "
 nft configuration:
   cli support:			${with_cli}
   enable debugging:		${with_debug}
-  use mini-gmp:			${with_mini_gmp}"
+  use mini-gmp:			${with_mini_gmp}
+  libxtables support:		${with_libxtables}"
include/statement.h +4 -0
index d143121..1f97116 100644
@@ -3,6 +3,7 @@
 
 #include <list.h>
 #include <expression.h>
+#include <xt.h>
 
 extern struct stmt *expr_stmt_alloc(const struct location *loc,
 				    struct expr *expr);
@@ -120,6 +121,7 @@ extern struct stmt *ct_stmt_alloc(const struct location *loc,
  * @STMT_REDIR:		redirect statement
  * @STMT_QUEUE:		QUEUE statement
  * @STMT_CT:		conntrack statement
+ * @STMT_XT:		XT statement
  */
 enum stmt_types {
 	STMT_INVALID,
@@ -135,6 +137,7 @@ enum stmt_types {
 	STMT_REDIR,
 	STMT_QUEUE,
 	STMT_CT,
+	STMT_XT,
 };
 
 /**
@@ -184,6 +187,7 @@ struct stmt {
 		struct redir_stmt	redir;
 		struct queue_stmt	queue;
 		struct ct_stmt		ct;
+		struct xt_stmt		xt;
 	};
 };
 
include/xt.h new file +105 -0

105 lines not on this page · raw message

src/Makefile.am +8 -0
index fd63219..8c59449 100644
@@ -8,6 +8,9 @@ AM_CPPFLAGS += -DDEFAULT_INCLUDE_PATH="\"${sysconfdir}\"" \
 if BUILD_DEBUG
 AM_CPPFLAGS += -g -DDEBUG
 endif
+if BUILD_XTABLES
+AM_CPPFLAGS += ${XTABLES_CFLAGS}
+endif
 
 AM_CFLAGS = -Wall								\
 	    -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations	\
@@ -59,3 +62,8 @@ nft_SOURCES +=	mini-gmp.c
 endif
 
 nft_LDADD	= ${LIBMNL_LIBS} ${LIBNFTNL_LIBS}
+
+if BUILD_XTABLES
+nft_SOURCES +=	xt.c
+nft_LDADD   +=  ${XTABLES_LIBS}
+endif
src/evaluate.c +3 -0
index b216fb1..f5154e6 100644
@@ -27,6 +27,7 @@
 #include <erec.h>
 #include <gmputil.h>
 #include <utils.h>
+#include <xt.h>
 
 static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr);
 
@@ -1658,6 +1659,8 @@ int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt)
 		return stmt_evaluate_redir(ctx, stmt);
 	case STMT_QUEUE:
 		return stmt_evaluate_queue(ctx, stmt);
+	case STMT_XT:
+		return stmt_evaluate_xt(ctx, stmt);
 	default:
 		BUG("unknown statement type %s\n", stmt->ops->name);
 	}
src/main.c +10 -2
index 4590c30..c560d49 100644
@@ -254,10 +254,18 @@ int main(int argc, char * const *argv)
 	char *buf = NULL, *filename = NULL;
 	unsigned int len;
 	bool interactive = false;
-	int i, val, rc = NFT_EXIT_SUCCESS;
+	int i, val, rc = NFT_EXIT_SUCCESS, fake_argc = argc;
+
+	/* This avoids a clash with libxtables getopt_long parser */
+	for (i = 0; i < argc; i++) {
+		if (argv[i][0] == '[') {
+			fake_argc = i;
+			break;
+		}
+	}
 
 	while (1) {
-		val = getopt_long(argc, argv, OPTSTRING, options, NULL);
+		val = getopt_long(fake_argc, argv, OPTSTRING, options, NULL);
 		if (val == -1)
 			break;
 
src/netlink_delinearize.c +6 -0
index e0bb726..6794a2d 100644
@@ -25,6 +25,7 @@
 #include <utils.h>
 #include <erec.h>
 #include <sys/socket.h>
+#include <xt.h>
 
 static void __fmtstring(3, 4) netlink_error(struct netlink_parse_ctx *ctx,
 					    const struct location *loc,
@@ -710,6 +711,8 @@ static const struct {
 	{ .name = "masq",	.parse = netlink_parse_masq },
 	{ .name = "redir",	.parse = netlink_parse_redir },
 	{ .name = "queue",	.parse = netlink_parse_queue },
+	{ .name = "target",	.parse = netlink_parse_target },
+	{ .name = "match",	.parse = netlink_parse_match },
 };
 
 static int netlink_parse_expr(struct nft_rule_expr *nle, void *arg)
@@ -1124,6 +1127,9 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r
 		case STMT_REJECT:
 			stmt_reject_postprocess(rctx, stmt);
 			break;
+		case STMT_XT:
+			stmt_xt_postprocess(&rctx, stmt, rule);
+			break;
 		default:
 			break;
 		}
src/netlink_linearize.c +3 -0
index 6a637a4..0c84d54 100644
@@ -18,6 +18,7 @@
 #include <netlink.h>
 #include <gmputil.h>
 #include <utils.h>
+#include <xt.h>
 
 static void netlink_put_register(struct nft_rule_expr *nle,
 				 uint32_t attr, uint32_t reg)
@@ -821,6 +822,8 @@ static void netlink_gen_stmt(struct netlink_linearize_ctx *ctx,
 		return netlink_gen_queue_stmt(ctx, stmt);
 	case STMT_CT:
 		return netlink_gen_ct_stmt(ctx, stmt);
+	case STMT_XT:
+		return netlink_gen_xt_stmt(ctx, stmt);
 	default:
 		BUG("unknown statement type %s\n", stmt->ops->name);
 	}
src/parser_bison.y +57 -0

81 lines not on this page · raw message

src/rule.c +1 -0
index 7114380..c7c5e20 100644
@@ -820,6 +820,7 @@ static void table_cleanup(struct table *table)
 	}
 }
 
+#include <xt.h>
 static int do_list_table(struct netlink_ctx *ctx, struct cmd *cmd,
 			 struct table *table)
 {
src/scanner.l +15 -0
index 73c4f8b..f89d27f 100644
@@ -113,6 +113,7 @@ hexstring	0[xX]{hexdigit}+
 range		({decstring}?:{decstring}?)
 letter		[a-zA-Z]
 string		({letter})({letter}|{digit}|[/\-_\.])*
+xtopts		\[({letter}|{digit}|[!/\-_\.\"\:\, ])*\]
 quotedstring	\"[^"]*\"
 comment		#.*$
 slash		\/
@@ -449,6 +450,15 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 "proto-dst"		{ return PROTO_DST; }
 "label"			{ return LABEL; }
 
+"xt"			{ return XT; }
+"match"			{ return MATCH; }
+"target"		{ return TARGET; }
+"watcher"		{ return WATCHER; }
+"802_3"			{
+				yylval->string = xstrdup("802_3");
+				return STRING;
+			}
+
 "xml"			{ return XML; }
 "json"			{ return JSON; }
 
@@ -488,6 +498,11 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 				return STRING;
 			}
 
+{xtopts}		{
+				yylval->string = xstrdup(yytext);
+				return XTOPTS;
+			}
+
 \\{newline}		{
 				reset_pos(yyget_extra(yyscanner), yylloc);
 			}
src/statement.c +42 -0

51 lines not on this page · raw message

src/xt.c new file +673 -0

673 lines not on this page · raw message

#3 lore raw

Re: [nft PATCH 3/4] src: add xt compat support

Quoted 23 lines · Arturo Borrero Gonzalez

From: Pablo Neira Ayuso <[email protected]>

At compilation time, you have to pass this option.

  # ./configure --with-xtables

And libxtables needs to be installed in your system.

This patch allows you to use xt extensions from nft, eg.

  # nft add rule filter output \
	tcp flags syn xt target TCPMSS [ --clamp-mss-to-pmtu ]

This provides access to all existing xt modules from nft. Users can meanwhile use xt extension until we can provide native expressions.

You can build this optionally, if disabled it displays an error:

  # nft add rule filter output tcp flags syn xt target TCPMSS [ --clamp-mss-to-pmtu ]
  <cmdline>:1:38-77: Error: this build does not support xtables
  add rule filter output tcp flags syn xt target TCPMSS [ --clamp-mss-to-pmtu ]
                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Quoted 8 lines

so you know your build doesn't support this.

Limitations:

* Beware of clashes with keywords, eg. state, from bison parser.
* Better xt parsing errors for unknown options.

This is joint work with Arturo Borrero Gonzalez.

$ make
make  all-recursive
make[1]: se ingresa al directorio
`/home/pablo/devel/scm/git-netfilter/nftables'
Making all in src
make[2]: se ingresa al directorio
`/home/pablo/devel/scm/git-netfilter/nftables/src'
make  all-am
make[3]: se ingresa al directorio
`/home/pablo/devel/scm/git-netfilter/nftables/src'
  CC     rule.o
In file included from ../include/statement.h:6:0,
                 from rule.c:19:
../include/xt.h: In function ‘stmt_evaluate_xt’:
../include/xt.h:60:2: warning: implicit declaration of function
‘stmt_error’ [-Wimplicit-function-declaration]
../include/xt.h: At top level:
../include/xt.h:100:34: error: field ‘entry’ has incomplete type
make[3]: *** [rule.o] Error 1
make[3]: se sale del directorio
`/home/pablo/devel/scm/git-netfilter/nftables/src'
make[2]: *** [all] Error 2
make[2]: se sale del directorio
`/home/pablo/devel/scm/git-netfilter/nftables/src'
make[1]: *** [all-recursive] Error 1
make[1]: se sale del directorio
`/home/pablo/devel/scm/git-netfilter/nftables'
make: *** [all] Error 2

This doesn't compile without libxtables support.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#4 lore raw

Re: [nft PATCH 3/4] src: add xt compat support

On Thu, Apr 09, 2015 at 02:58:59PM +0200, Pablo Neira Ayuso wrote:
[...]

Quoted 1 line

This doesn't compile without libxtables support.

I'm revisiting this patch. Please hold on with any change on this, will resend a new spin of this.

#5 lore raw

PATCH 4/4 tests: regression: add xt compat tests

In reply to Arturo Borrero Gonzalez

This patch adds several regression test for the xt compat stuff.

Note the current output is:
ip/xt.t: 25 unit tests, 0 error, 0 warning
ip6/xt.t: 25 unit tests, 0 error, 0 warning
bridge/xt.t: 26 unit tests, 0 error, 0 warning
arp/xt.t: 12 unit tests, 0 error, 0 warning

---
 tests/regression/bridge/xt.t |   45 ++++++++++++++++++++++++++++++++++++++++++
 tests/regression/ip/xt.t     |   45 ++++++++++++++++++++++++++++++++++++++++++
 tests/regression/ip6/xt.t    |   45 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 135 insertions(+)
 create mode 100644 tests/regression/bridge/xt.t
 create mode 100644 tests/regression/ip/xt.t
 create mode 100644 tests/regression/ip6/xt.t
tests/regression/bridge/xt.t new file +45 -0
new file mode 100644
index 0000000..b3f4beb
@@ -0,0 +1,45 @@
+*bridge;test-bridge
+:test-forward;type filter hook forward priority 0
+
+# standard load of match, target, watcher
+xt match 802_3 [ --802_3-sap 0x1 ];ok;xt match 802_3 [--802_3-sap 0x01  ]
+xt target mark [ --mark-set 0x1 ];ok;xt target mark [--mark-set 0x1 --mark-target ACCEPT ]
+xt watcher log [ ];ok;xt watcher log [--log-level notice --log-prefix ""  ]
+xt watcher log;ok;xt watcher log [--log-level notice --log-prefix ""  ]
+
+# more than one argument in a single statement
+xt match 802_3 [ --802_3-sap 0x1 --802_3-type 0x2 ];ok;xt match 802_3 [--802_3-sap 0x01 --802_3-type 0x0002  ]
+xt target mark [ --mark-set 0x1 --mark-target CONTINUE ];ok;xt target mark [--mark-set 0x1 --mark-target CONTINUE ]
+xt watcher log [ --log-level notice --log-prefix "test" ];ok;xt watcher log [--log-level notice --log-prefix "test"  ]
+
+# repeated statement with different argument (also testing final statement flag)
+xt match 802_3 [ --802_3-sap 0x1 --802_3-type 0x2 ] xt match 802_3 [ --802_3-type 0x3 --802_3-sap 0x4 ];ok;xt match 802_3 [--802_3-sap 0x01 --802_3-type 0x0002  ] xt match 802_3 [--802_3-sap 0x04 --802_3-type 0x0003  ]
+xt target mark [ --mark-set 0x1 --mark-target CONTINUE ] xt target mark [ --mark-set 0x1 ];fail
+xt watcher log [ --log-level notice ] xt watcher log [ --log-level notice --log-prefix "test" ];ok;xt watcher log [--log-level notice --log-prefix ""  ] xt watcher log [--log-level notice --log-prefix "test"  ]
+
+# statement with weird/invalid options
+xt match mark_m [ --test ];fail
+xt target mark [];ok;xt target mark [--mark-set 0x0 --mark-target ACCEPT ]
+xt target mark;ok;xt target mark [--mark-set 0x0 --mark-target ACCEPT ]
+xt watcher log [];ok;xt watcher log [--log-level notice --log-prefix ""  ]
+xt watcher log [--test];ok;xt watcher log [--log-level notice --log-prefix ""  ]
+
+# statement with invalid argument
+xt match 802_3 [ --802_3-sap -1 ];fail
+xt target mark [ --mark-target TEST ];fail
+xt watcher log [ --log-level test ];fail
+
+# inversions
+xt match 802_3 [ ! --802_3-sap 0x1 ];ok;xt match 802_3 [--802_3-sap ! 0x01  ]
+xt match 802_3 [ --802_3-sap ! 0x1 ];ok;xt match 802_3 [--802_3-sap ! 0x01  ]
+ether type ip xt match ip [ --ip-src ! 1.1.1.1 ];ok;ether type ip xt match ip [--ip-src ! 1.1.1.1  ]
+
+# protocol context games
+xt match ip [ --ip-src 1.1.1.1 ];fail
+ether type ip xt match ip [ --ip-src 1.1.1.1 ];ok;ether type ip xt match ip [--ip-src 1.1.1.1  ]
+ether type ip6 xt match ip [ --ip-src 1.1.1.1 ];fail
+ether type ip xt match ip [ --ip-proto tcp --ip-sport 123 ];ok;ether type ip xt match ip [--ip-proto tcp --ip-sport 123  ]
+
+# quoted strings
+xt watcher log [ --log-prefix \"test test\" ];ok;xt watcher log [--log-level notice --log-prefix "test test"  ]
+xt watcher log [ --log-prefix \"test test \" ];ok;xt watcher log [--log-level notice --log-prefix "test test "  ]
tests/regression/ip/xt.t new file +45 -0

45 lines not on this page · raw message

tests/regression/ip6/xt.t new file +45 -0

45 lines not on this page · raw message

#6 lore raw

Re: [nft PATCH 4/4] tests: regression: add xt compat tests

Quoted 7 lines · Arturo Borrero Gonzalez

This patch adds several regression test for the xt compat stuff.

Note the current output is:
ip/xt.t: 25 unit tests, 0 error, 0 warning
ip6/xt.t: 25 unit tests, 0 error, 0 warning
bridge/xt.t: 26 unit tests, 0 error, 0 warning
arp/xt.t: 12 unit tests, 0 error, 0 warning

arp/xt.t is missing in the patchset, please resend this.

Quoted 10 lines
---
 tests/regression/bridge/xt.t |   45 ++++++++++++++++++++++++++++++++++++++++++
 tests/regression/ip/xt.t     |   45 ++++++++++++++++++++++++++++++++++++++++++
 tests/regression/ip6/xt.t    |   45 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 135 insertions(+)
 create mode 100644 tests/regression/bridge/xt.t
 create mode 100644 tests/regression/ip/xt.t
 create mode 100644 tests/regression/ip6/xt.t
#7 lore raw
In reply to Arturo Borrero Gonzalez
Quoted 5 lines · On Wed, 08 Apr 2015 19:48:18 +0200 Arturo Borrero Gonzalez…

From: Arturo Borrero Gonzalez <[email protected]>

Required for next patches.

If you are going to import a kernel header, it should be the exact version produced by doing:

  $ make headers_install
in the kernel source directory
the result of that make is files in usr/include/linux

And your version differs:

$ diff -up usr/include/linux/netfilter_bridge/ebtables.h /tmp/ebtables.h 
--- usr/include/linux/netfilter_bridge/ebtables.h	2015-02-05 10:17:17.865621216 -0800
+++ /tmp/ebtables.h	2015-04-08 17:20:40.265458995 -0700
@@ -12,9 +12,7 @@

#ifndef __LINUX_BRIDGE_EFF_H
#define __LINUX_BRIDGE_EFF_H
-#include <linux/if.h>
#include <linux/netfilter_bridge.h>
-#include <linux/if_ether.h>

#define EBT_TABLE_MAXNAMELEN 32
#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN

#8 lore raw
Quoted 11 lines · Stephen Hemminger
Quoted 5 lines · On Wed, 08 Apr 2015 19:48:18 +0200 Arturo Borrero Gonzalez…

From: Arturo Borrero Gonzalez <[email protected]>

Required for next patches.

If you are going to import a kernel header, it should be the exact version produced by doing:

Kernel patch: http://patchwork.ozlabs.org/patch/459393/

Signature · 5 lines
Arturo Borrero González
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html