All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH nft v5 1/3] include: cache ip_tables.h, ip6_tables.h, arp_tables.h and ebtables.h
@ 2016-07-12 20:04 Pablo M. Bermudo Garay
  2016-07-12 20:04 ` [PATCH nft v5 2/3] src: expose delinearize/linearize structures and stmt_error() Pablo M. Bermudo Garay
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Pablo M. Bermudo Garay @ 2016-07-12 20:04 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

From: Pablo Neira <pablo@netfilter.org>

The xt over nft support that comes in follow up patches need this, and update
the corresponding Makefile.am.

Based on patch from Arturo Borrero Gonzalez.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---

Resubmission of xt compat support preparatory patch.

Changes in v5:
  - None in this patch.

 configure.ac                               |   4 +
 include/linux/Makefile.am                  |   7 +-
 include/linux/netfilter_arp/Makefile.am    |   1 +
 include/linux/netfilter_arp/arp_tables.h   | 204 ++++++++++++++++++++++
 include/linux/netfilter_bridge/Makefile.am |   1 +
 include/linux/netfilter_bridge/ebtables.h  | 266 +++++++++++++++++++++++++++++
 include/linux/netfilter_ipv4/Makefile.am   |   1 +
 include/linux/netfilter_ipv4/ip_tables.h   | 227 ++++++++++++++++++++++++
 include/linux/netfilter_ipv6/Makefile.am   |   1 +
 include/linux/netfilter_ipv6/ip6_tables.h  | 265 ++++++++++++++++++++++++++++
 10 files changed, 976 insertions(+), 1 deletion(-)
 create mode 100644 include/linux/netfilter_arp/Makefile.am
 create mode 100644 include/linux/netfilter_arp/arp_tables.h
 create mode 100644 include/linux/netfilter_bridge/Makefile.am
 create mode 100644 include/linux/netfilter_bridge/ebtables.h
 create mode 100644 include/linux/netfilter_ipv4/Makefile.am
 create mode 100644 include/linux/netfilter_ipv4/ip_tables.h
 create mode 100644 include/linux/netfilter_ipv6/Makefile.am
 create mode 100644 include/linux/netfilter_ipv6/ip6_tables.h

diff --git a/configure.ac b/configure.ac
index 877f530..a1d7723 100644
--- a/configure.ac
+++ b/configure.ac
@@ -132,6 +132,10 @@ AC_CONFIG_FILES([					\
 		include/Makefile			\
 		include/linux/Makefile			\
 		include/linux/netfilter/Makefile	\
+		include/linux/netfilter_arp/Makefile	\
+		include/linux/netfilter_bridge/Makefile	\
+		include/linux/netfilter_ipv4/Makefile	\
+		include/linux/netfilter_ipv6/Makefile	\
 		doc/Makefile				\
 		files/Makefile				\
 		files/nftables/Makefile			\
diff --git a/include/linux/Makefile.am b/include/linux/Makefile.am
index 9fb010b..eb9fc4e 100644
--- a/include/linux/Makefile.am
+++ b/include/linux/Makefile.am
@@ -1,4 +1,9 @@
-SUBDIRS = netfilter
+SUBDIRS =		netfilter		\
+			netfilter_arp		\
+			netfilter_bridge	\
+			netfilter_ipv4		\
+			netfilter_ipv6
+
 noinst_HEADERS =	netfilter_arp.h		\
 			netfilter_bridge.h	\
 			netfilter_decnet.h	\
diff --git a/include/linux/netfilter_arp/Makefile.am b/include/linux/netfilter_arp/Makefile.am
new file mode 100644
index 0000000..0a16c1a
--- /dev/null
+++ b/include/linux/netfilter_arp/Makefile.am
@@ -0,0 +1 @@
+noinst_HEADERS =	arp_tables.h
diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
new file mode 100644
index 0000000..bb1ec64
--- /dev/null
+++ b/include/linux/netfilter_arp/arp_tables.h
@@ -0,0 +1,204 @@
+/*
+ * 	Format of an ARP firewall descriptor
+ *
+ * 	src, tgt, src_mask, tgt_mask, arpop, arpop_mask are always stored in
+ *	network byte order.
+ * 	flags are stored in host byte order (of course).
+ */
+
+#ifndef _ARPTABLES_H
+#define _ARPTABLES_H
+
+#include <linux/types.h>
+
+#include <linux/netfilter_arp.h>
+
+#include <linux/netfilter/x_tables.h>
+
+#define ARPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
+#define ARPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
+#define arpt_entry_target xt_entry_target
+#define arpt_standard_target xt_standard_target
+#define arpt_error_target xt_error_target
+#define ARPT_CONTINUE XT_CONTINUE
+#define ARPT_RETURN XT_RETURN
+#define arpt_counters_info xt_counters_info
+#define arpt_counters xt_counters
+#define ARPT_STANDARD_TARGET XT_STANDARD_TARGET
+#define ARPT_ERROR_TARGET XT_ERROR_TARGET
+#define ARPT_ENTRY_ITERATE(entries, size, fn, args...) \
+	XT_ENTRY_ITERATE(struct arpt_entry, entries, size, fn, ## args)
+
+#define ARPT_DEV_ADDR_LEN_MAX 16
+
+struct arpt_devaddr_info {
+	char addr[ARPT_DEV_ADDR_LEN_MAX];
+	char mask[ARPT_DEV_ADDR_LEN_MAX];
+};
+
+/* Yes, Virginia, you have to zero the padding. */
+struct arpt_arp {
+	/* Source and target IP addr */
+	struct in_addr src, tgt;
+	/* Mask for src and target IP addr */
+	struct in_addr smsk, tmsk;
+
+	/* Device hw address length, src+target device addresses */
+	__u8 arhln, arhln_mask;
+	struct arpt_devaddr_info src_devaddr;
+	struct arpt_devaddr_info tgt_devaddr;
+
+	/* ARP operation code. */
+	__be16 arpop, arpop_mask;
+
+	/* ARP hardware address and protocol address format. */
+	__be16 arhrd, arhrd_mask;
+	__be16 arpro, arpro_mask;
+
+	/* The protocol address length is only accepted if it is 4
+	 * so there is no use in offering a way to do filtering on it.
+	 */
+
+	char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
+	unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
+
+	/* Flags word */
+	__u8 flags;
+	/* Inverse flags */
+	__u16 invflags;
+};
+
+/* Values for "flag" field in struct arpt_ip (general arp structure).
+ * No flags defined yet.
+ */
+#define ARPT_F_MASK		0x00	/* All possible flag bits mask. */
+
+/* Values for "inv" field in struct arpt_arp. */
+#define ARPT_INV_VIA_IN		0x0001	/* Invert the sense of IN IFACE. */
+#define ARPT_INV_VIA_OUT	0x0002	/* Invert the sense of OUT IFACE */
+#define ARPT_INV_SRCIP		0x0004	/* Invert the sense of SRC IP. */
+#define ARPT_INV_TGTIP		0x0008	/* Invert the sense of TGT IP. */
+#define ARPT_INV_SRCDEVADDR	0x0010	/* Invert the sense of SRC DEV ADDR. */
+#define ARPT_INV_TGTDEVADDR	0x0020	/* Invert the sense of TGT DEV ADDR. */
+#define ARPT_INV_ARPOP		0x0040	/* Invert the sense of ARP OP. */
+#define ARPT_INV_ARPHRD		0x0080	/* Invert the sense of ARP HRD. */
+#define ARPT_INV_ARPPRO		0x0100	/* Invert the sense of ARP PRO. */
+#define ARPT_INV_ARPHLN		0x0200	/* Invert the sense of ARP HLN. */
+#define ARPT_INV_MASK		0x03FF	/* All possible flag bits mask. */
+
+/* This structure defines each of the firewall rules.  Consists of 3
+   parts which are 1) general ARP header stuff 2) match specific
+   stuff 3) the target to perform if the rule matches */
+struct arpt_entry
+{
+	struct arpt_arp arp;
+
+	/* Size of arpt_entry + matches */
+	__u16 target_offset;
+	/* Size of arpt_entry + matches + target */
+	__u16 next_offset;
+
+	/* Back pointer */
+	unsigned int comefrom;
+
+	/* Packet and byte counters. */
+	struct xt_counters counters;
+
+	/* The matches (if any), then the target. */
+	unsigned char elems[0];
+};
+
+/*
+ * New IP firewall options for [gs]etsockopt at the RAW IP level.
+ * Unlike BSD Linux inherits IP options so you don't have to use a raw
+ * socket for this. Instead we check rights in the calls.
+ *
+ * ATTENTION: check linux/in.h before adding new number here.
+ */
+#define ARPT_BASE_CTL		96
+
+#define ARPT_SO_SET_REPLACE		(ARPT_BASE_CTL)
+#define ARPT_SO_SET_ADD_COUNTERS	(ARPT_BASE_CTL + 1)
+#define ARPT_SO_SET_MAX			ARPT_SO_SET_ADD_COUNTERS
+
+#define ARPT_SO_GET_INFO		(ARPT_BASE_CTL)
+#define ARPT_SO_GET_ENTRIES		(ARPT_BASE_CTL + 1)
+/* #define ARPT_SO_GET_REVISION_MATCH	(APRT_BASE_CTL + 2) */
+#define ARPT_SO_GET_REVISION_TARGET	(ARPT_BASE_CTL + 3)
+#define ARPT_SO_GET_MAX			(ARPT_SO_GET_REVISION_TARGET)
+
+/* The argument to ARPT_SO_GET_INFO */
+struct arpt_getinfo {
+	/* Which table: caller fills this in. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* Kernel fills these in. */
+	/* Which hook entry points are valid: bitmask */
+	unsigned int valid_hooks;
+
+	/* Hook entry points: one per netfilter hook. */
+	unsigned int hook_entry[NF_ARP_NUMHOOKS];
+
+	/* Underflow points. */
+	unsigned int underflow[NF_ARP_NUMHOOKS];
+
+	/* Number of entries */
+	unsigned int num_entries;
+
+	/* Size of entries. */
+	unsigned int size;
+};
+
+/* The argument to ARPT_SO_SET_REPLACE. */
+struct arpt_replace {
+	/* Which table. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* Which hook entry points are valid: bitmask.  You can't
+           change this. */
+	unsigned int valid_hooks;
+
+	/* Number of entries */
+	unsigned int num_entries;
+
+	/* Total size of new entries */
+	unsigned int size;
+
+	/* Hook entry points. */
+	unsigned int hook_entry[NF_ARP_NUMHOOKS];
+
+	/* Underflow points. */
+	unsigned int underflow[NF_ARP_NUMHOOKS];
+
+	/* Information about old entries: */
+	/* Number of counters (must be equal to current number of entries). */
+	unsigned int num_counters;
+	/* The old entries' counters. */
+	struct xt_counters *counters;
+
+	/* The entries (hang off end: not really an array). */
+	struct arpt_entry entries[0];
+};
+
+/* The argument to ARPT_SO_GET_ENTRIES. */
+struct arpt_get_entries {
+	/* Which table: user fills this in. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* User fills this in: total entry size. */
+	unsigned int size;
+
+	/* The entries. */
+	struct arpt_entry entrytable[0];
+};
+
+/* Helper functions */
+static __inline__ struct xt_entry_target *arpt_get_target(struct arpt_entry *e)
+{
+	return (void *)e + e->target_offset;
+}
+
+/*
+ *	Main firewall chains definitions and global var's definitions.
+ */
+#endif /* _ARPTABLES_H */
diff --git a/include/linux/netfilter_bridge/Makefile.am b/include/linux/netfilter_bridge/Makefile.am
new file mode 100644
index 0000000..d2e8b38
--- /dev/null
+++ b/include/linux/netfilter_bridge/Makefile.am
@@ -0,0 +1 @@
+noinst_HEADERS =	ebtables.h
diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h
new file mode 100644
index 0000000..a225911
--- /dev/null
+++ b/include/linux/netfilter_bridge/ebtables.h
@@ -0,0 +1,266 @@
+/*
+ *  ebtables
+ *
+ *	Authors:
+ *	Bart De Schuymer		<bdschuym@pandora.be>
+ *
+ *  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 */
diff --git a/include/linux/netfilter_ipv4/Makefile.am b/include/linux/netfilter_ipv4/Makefile.am
new file mode 100644
index 0000000..fec4253
--- /dev/null
+++ b/include/linux/netfilter_ipv4/Makefile.am
@@ -0,0 +1 @@
+noinst_HEADERS =	ip_tables.h
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
new file mode 100644
index 0000000..38542b4
--- /dev/null
+++ b/include/linux/netfilter_ipv4/ip_tables.h
@@ -0,0 +1,227 @@
+/*
+ * 25-Jul-1998 Major changes to allow for ip chain table
+ *
+ * 3-Jan-2000 Named tables to allow packet selection for different uses.
+ */
+
+/*
+ * 	Format of an IP firewall descriptor
+ *
+ * 	src, dst, src_mask, dst_mask are always stored in network byte order.
+ * 	flags are stored in host byte order (of course).
+ * 	Port numbers are stored in HOST byte order.
+ */
+
+#ifndef _IPTABLES_H
+#define _IPTABLES_H
+
+#include <linux/types.h>
+
+#include <linux/netfilter_ipv4.h>
+
+#include <linux/netfilter/x_tables.h>
+
+#define IPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
+#define IPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
+#define ipt_match xt_match
+#define ipt_target xt_target
+#define ipt_table xt_table
+#define ipt_get_revision xt_get_revision
+#define ipt_entry_match xt_entry_match
+#define ipt_entry_target xt_entry_target
+#define ipt_standard_target xt_standard_target
+#define ipt_error_target xt_error_target
+#define ipt_counters xt_counters
+#define IPT_CONTINUE XT_CONTINUE
+#define IPT_RETURN XT_RETURN
+
+/* This group is older than old (iptables < v1.4.0-rc1~89) */
+#include <linux/netfilter/xt_tcpudp.h>
+#define ipt_udp xt_udp
+#define ipt_tcp xt_tcp
+#define IPT_TCP_INV_SRCPT	XT_TCP_INV_SRCPT
+#define IPT_TCP_INV_DSTPT	XT_TCP_INV_DSTPT
+#define IPT_TCP_INV_FLAGS	XT_TCP_INV_FLAGS
+#define IPT_TCP_INV_OPTION	XT_TCP_INV_OPTION
+#define IPT_TCP_INV_MASK	XT_TCP_INV_MASK
+#define IPT_UDP_INV_SRCPT	XT_UDP_INV_SRCPT
+#define IPT_UDP_INV_DSTPT	XT_UDP_INV_DSTPT
+#define IPT_UDP_INV_MASK	XT_UDP_INV_MASK
+
+/* The argument to IPT_SO_ADD_COUNTERS. */
+#define ipt_counters_info xt_counters_info
+/* Standard return verdict, or do jump. */
+#define IPT_STANDARD_TARGET XT_STANDARD_TARGET
+/* Error verdict. */
+#define IPT_ERROR_TARGET XT_ERROR_TARGET
+
+/* fn returns 0 to continue iteration */
+#define IPT_MATCH_ITERATE(e, fn, args...) \
+	XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args)
+
+/* fn returns 0 to continue iteration */
+#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \
+	XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args)
+
+/* Yes, Virginia, you have to zero the padding. */
+struct ipt_ip {
+	/* Source and destination IP addr */
+	struct in_addr src, dst;
+	/* Mask for src and dest IP addr */
+	struct in_addr smsk, dmsk;
+	char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
+	unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
+
+	/* Protocol, 0 = ANY */
+	__u16 proto;
+
+	/* Flags word */
+	__u8 flags;
+	/* Inverse flags */
+	__u8 invflags;
+};
+
+/* Values for "flag" field in struct ipt_ip (general ip structure). */
+#define IPT_F_FRAG		0x01	/* Set if rule is a fragment rule */
+#define IPT_F_GOTO		0x02	/* Set if jump is a goto */
+#define IPT_F_MASK		0x03	/* All possible flag bits mask. */
+
+/* Values for "inv" field in struct ipt_ip. */
+#define IPT_INV_VIA_IN		0x01	/* Invert the sense of IN IFACE. */
+#define IPT_INV_VIA_OUT		0x02	/* Invert the sense of OUT IFACE */
+#define IPT_INV_TOS		0x04	/* Invert the sense of TOS. */
+#define IPT_INV_SRCIP		0x08	/* Invert the sense of SRC IP. */
+#define IPT_INV_DSTIP		0x10	/* Invert the sense of DST OP. */
+#define IPT_INV_FRAG		0x20	/* Invert the sense of FRAG. */
+#define IPT_INV_PROTO		XT_INV_PROTO
+#define IPT_INV_MASK		0x7F	/* All possible flag bits mask. */
+
+/* This structure defines each of the firewall rules.  Consists of 3
+   parts which are 1) general IP header stuff 2) match specific
+   stuff 3) the target to perform if the rule matches */
+struct ipt_entry {
+	struct ipt_ip ip;
+
+	/* Mark with fields that we care about. */
+	unsigned int nfcache;
+
+	/* Size of ipt_entry + matches */
+	__u16 target_offset;
+	/* Size of ipt_entry + matches + target */
+	__u16 next_offset;
+
+	/* Back pointer */
+	unsigned int comefrom;
+
+	/* Packet and byte counters. */
+	struct xt_counters counters;
+
+	/* The matches (if any), then the target. */
+	unsigned char elems[0];
+};
+
+/*
+ * New IP firewall options for [gs]etsockopt at the RAW IP level.
+ * Unlike BSD Linux inherits IP options so you don't have to use a raw
+ * socket for this. Instead we check rights in the calls.
+ *
+ * ATTENTION: check linux/in.h before adding new number here.
+ */
+#define IPT_BASE_CTL		64
+
+#define IPT_SO_SET_REPLACE	(IPT_BASE_CTL)
+#define IPT_SO_SET_ADD_COUNTERS	(IPT_BASE_CTL + 1)
+#define IPT_SO_SET_MAX		IPT_SO_SET_ADD_COUNTERS
+
+#define IPT_SO_GET_INFO			(IPT_BASE_CTL)
+#define IPT_SO_GET_ENTRIES		(IPT_BASE_CTL + 1)
+#define IPT_SO_GET_REVISION_MATCH	(IPT_BASE_CTL + 2)
+#define IPT_SO_GET_REVISION_TARGET	(IPT_BASE_CTL + 3)
+#define IPT_SO_GET_MAX			IPT_SO_GET_REVISION_TARGET
+
+/* ICMP matching stuff */
+struct ipt_icmp {
+	__u8 type;				/* type to match */
+	__u8 code[2];				/* range of code */
+	__u8 invflags;				/* Inverse flags */
+};
+
+/* Values for "inv" field for struct ipt_icmp. */
+#define IPT_ICMP_INV	0x01	/* Invert the sense of type/code test */
+
+/* The argument to IPT_SO_GET_INFO */
+struct ipt_getinfo {
+	/* Which table: caller fills this in. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* Kernel fills these in. */
+	/* Which hook entry points are valid: bitmask */
+	unsigned int valid_hooks;
+
+	/* Hook entry points: one per netfilter hook. */
+	unsigned int hook_entry[NF_INET_NUMHOOKS];
+
+	/* Underflow points. */
+	unsigned int underflow[NF_INET_NUMHOOKS];
+
+	/* Number of entries */
+	unsigned int num_entries;
+
+	/* Size of entries. */
+	unsigned int size;
+};
+
+/* The argument to IPT_SO_SET_REPLACE. */
+struct ipt_replace {
+	/* Which table. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* Which hook entry points are valid: bitmask.  You can't
+           change this. */
+	unsigned int valid_hooks;
+
+	/* Number of entries */
+	unsigned int num_entries;
+
+	/* Total size of new entries */
+	unsigned int size;
+
+	/* Hook entry points. */
+	unsigned int hook_entry[NF_INET_NUMHOOKS];
+
+	/* Underflow points. */
+	unsigned int underflow[NF_INET_NUMHOOKS];
+
+	/* Information about old entries: */
+	/* Number of counters (must be equal to current number of entries). */
+	unsigned int num_counters;
+	/* The old entries' counters. */
+	struct xt_counters *counters;
+
+	/* The entries (hang off end: not really an array). */
+	struct ipt_entry entries[0];
+};
+
+/* The argument to IPT_SO_GET_ENTRIES. */
+struct ipt_get_entries {
+	/* Which table: user fills this in. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* User fills this in: total entry size. */
+	unsigned int size;
+
+	/* The entries. */
+	struct ipt_entry entrytable[0];
+};
+
+/* Helper functions */
+static __inline__ struct xt_entry_target *
+ipt_get_target(struct ipt_entry *e)
+{
+	return (void *)e + e->target_offset;
+}
+
+/*
+ *	Main firewall chains definitions and global var's definitions.
+ */
+#endif /* _IPTABLES_H */
diff --git a/include/linux/netfilter_ipv6/Makefile.am b/include/linux/netfilter_ipv6/Makefile.am
new file mode 100644
index 0000000..bec6c3f
--- /dev/null
+++ b/include/linux/netfilter_ipv6/Makefile.am
@@ -0,0 +1 @@
+noinst_HEADERS =	ip6_tables.h
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
new file mode 100644
index 0000000..4432dd1
--- /dev/null
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -0,0 +1,265 @@
+/*
+ * 25-Jul-1998 Major changes to allow for ip chain table
+ *
+ * 3-Jan-2000 Named tables to allow packet selection for different uses.
+ */
+
+/*
+ * 	Format of an IP6 firewall descriptor
+ *
+ * 	src, dst, src_mask, dst_mask are always stored in network byte order.
+ * 	flags are stored in host byte order (of course).
+ * 	Port numbers are stored in HOST byte order.
+ */
+
+#ifndef _IP6_TABLES_H
+#define _IP6_TABLES_H
+
+#include <linux/types.h>
+
+#include <linux/netfilter_ipv6.h>
+
+#include <linux/netfilter/x_tables.h>
+
+#define IP6T_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
+#define IP6T_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
+#define ip6t_match xt_match
+#define ip6t_target xt_target
+#define ip6t_table xt_table
+#define ip6t_get_revision xt_get_revision
+#define ip6t_entry_match xt_entry_match
+#define ip6t_entry_target xt_entry_target
+#define ip6t_standard_target xt_standard_target
+#define ip6t_error_target xt_error_target
+#define ip6t_counters xt_counters
+#define IP6T_CONTINUE XT_CONTINUE
+#define IP6T_RETURN XT_RETURN
+
+/* Pre-iptables-1.4.0 */
+#include <linux/netfilter/xt_tcpudp.h>
+#define ip6t_tcp xt_tcp
+#define ip6t_udp xt_udp
+#define IP6T_TCP_INV_SRCPT	XT_TCP_INV_SRCPT
+#define IP6T_TCP_INV_DSTPT	XT_TCP_INV_DSTPT
+#define IP6T_TCP_INV_FLAGS	XT_TCP_INV_FLAGS
+#define IP6T_TCP_INV_OPTION	XT_TCP_INV_OPTION
+#define IP6T_TCP_INV_MASK	XT_TCP_INV_MASK
+#define IP6T_UDP_INV_SRCPT	XT_UDP_INV_SRCPT
+#define IP6T_UDP_INV_DSTPT	XT_UDP_INV_DSTPT
+#define IP6T_UDP_INV_MASK	XT_UDP_INV_MASK
+
+#define ip6t_counters_info xt_counters_info
+#define IP6T_STANDARD_TARGET XT_STANDARD_TARGET
+#define IP6T_ERROR_TARGET XT_ERROR_TARGET
+#define IP6T_MATCH_ITERATE(e, fn, args...) \
+	XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args)
+#define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \
+	XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args)
+
+/* Yes, Virginia, you have to zero the padding. */
+struct ip6t_ip6 {
+	/* Source and destination IP6 addr */
+	struct in6_addr src, dst;		
+	/* Mask for src and dest IP6 addr */
+	struct in6_addr smsk, dmsk;
+	char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
+	unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
+
+	/* Upper protocol number
+	 * - The allowed value is 0 (any) or protocol number of last parsable
+	 *   header, which is 50 (ESP), 59 (No Next Header), 135 (MH), or
+	 *   the non IPv6 extension headers.
+	 * - The protocol numbers of IPv6 extension headers except of ESP and
+	 *   MH do not match any packets.
+	 * - You also need to set IP6T_FLAGS_PROTO to "flags" to check protocol.
+	 */
+	__u16 proto;
+	/* TOS to match iff flags & IP6T_F_TOS */
+	__u8 tos;
+
+	/* Flags word */
+	__u8 flags;
+	/* Inverse flags */
+	__u8 invflags;
+};
+
+/* Values for "flag" field in struct ip6t_ip6 (general ip6 structure). */
+#define IP6T_F_PROTO		0x01	/* Set if rule cares about upper 
+					   protocols */
+#define IP6T_F_TOS		0x02	/* Match the TOS. */
+#define IP6T_F_GOTO		0x04	/* Set if jump is a goto */
+#define IP6T_F_MASK		0x07	/* All possible flag bits mask. */
+
+/* Values for "inv" field in struct ip6t_ip6. */
+#define IP6T_INV_VIA_IN		0x01	/* Invert the sense of IN IFACE. */
+#define IP6T_INV_VIA_OUT		0x02	/* Invert the sense of OUT IFACE */
+#define IP6T_INV_TOS		0x04	/* Invert the sense of TOS. */
+#define IP6T_INV_SRCIP		0x08	/* Invert the sense of SRC IP. */
+#define IP6T_INV_DSTIP		0x10	/* Invert the sense of DST OP. */
+#define IP6T_INV_FRAG		0x20	/* Invert the sense of FRAG. */
+#define IP6T_INV_PROTO		XT_INV_PROTO
+#define IP6T_INV_MASK		0x7F	/* All possible flag bits mask. */
+
+/* This structure defines each of the firewall rules.  Consists of 3
+   parts which are 1) general IP header stuff 2) match specific
+   stuff 3) the target to perform if the rule matches */
+struct ip6t_entry {
+	struct ip6t_ip6 ipv6;
+
+	/* Mark with fields that we care about. */
+	unsigned int nfcache;
+
+	/* Size of ipt_entry + matches */
+	__u16 target_offset;
+	/* Size of ipt_entry + matches + target */
+	__u16 next_offset;
+
+	/* Back pointer */
+	unsigned int comefrom;
+
+	/* Packet and byte counters. */
+	struct xt_counters counters;
+
+	/* The matches (if any), then the target. */
+	unsigned char elems[0];
+};
+
+/* Standard entry */
+struct ip6t_standard {
+	struct ip6t_entry entry;
+	struct xt_standard_target target;
+};
+
+struct ip6t_error {
+	struct ip6t_entry entry;
+	struct xt_error_target target;
+};
+
+#define IP6T_ENTRY_INIT(__size)						       \
+{									       \
+	.target_offset	= sizeof(struct ip6t_entry),			       \
+	.next_offset	= (__size),					       \
+}
+
+#define IP6T_STANDARD_INIT(__verdict)					       \
+{									       \
+	.entry		= IP6T_ENTRY_INIT(sizeof(struct ip6t_standard)),       \
+	.target		= XT_TARGET_INIT(XT_STANDARD_TARGET,		       \
+					 sizeof(struct xt_standard_target)),   \
+	.target.verdict	= -(__verdict) - 1,				       \
+}
+
+#define IP6T_ERROR_INIT							       \
+{									       \
+	.entry		= IP6T_ENTRY_INIT(sizeof(struct ip6t_error)),	       \
+	.target		= XT_TARGET_INIT(XT_ERROR_TARGET,		       \
+					 sizeof(struct xt_error_target)),      \
+	.target.errorname = "ERROR",					       \
+}
+
+/*
+ * New IP firewall options for [gs]etsockopt at the RAW IP level.
+ * Unlike BSD Linux inherits IP options so you don't have to use
+ * a raw socket for this. Instead we check rights in the calls.
+ *
+ * ATTENTION: check linux/in6.h before adding new number here.
+ */
+#define IP6T_BASE_CTL			64
+
+#define IP6T_SO_SET_REPLACE		(IP6T_BASE_CTL)
+#define IP6T_SO_SET_ADD_COUNTERS	(IP6T_BASE_CTL + 1)
+#define IP6T_SO_SET_MAX			IP6T_SO_SET_ADD_COUNTERS
+
+#define IP6T_SO_GET_INFO		(IP6T_BASE_CTL)
+#define IP6T_SO_GET_ENTRIES		(IP6T_BASE_CTL + 1)
+#define IP6T_SO_GET_REVISION_MATCH	(IP6T_BASE_CTL + 4)
+#define IP6T_SO_GET_REVISION_TARGET	(IP6T_BASE_CTL + 5)
+#define IP6T_SO_GET_MAX			IP6T_SO_GET_REVISION_TARGET
+
+/* ICMP matching stuff */
+struct ip6t_icmp {
+	__u8 type;				/* type to match */
+	__u8 code[2];				/* range of code */
+	__u8 invflags;				/* Inverse flags */
+};
+
+/* Values for "inv" field for struct ipt_icmp. */
+#define IP6T_ICMP_INV	0x01	/* Invert the sense of type/code test */
+
+/* The argument to IP6T_SO_GET_INFO */
+struct ip6t_getinfo {
+	/* Which table: caller fills this in. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* Kernel fills these in. */
+	/* Which hook entry points are valid: bitmask */
+	unsigned int valid_hooks;
+
+	/* Hook entry points: one per netfilter hook. */
+	unsigned int hook_entry[NF_INET_NUMHOOKS];
+
+	/* Underflow points. */
+	unsigned int underflow[NF_INET_NUMHOOKS];
+
+	/* Number of entries */
+	unsigned int num_entries;
+
+	/* Size of entries. */
+	unsigned int size;
+};
+
+/* The argument to IP6T_SO_SET_REPLACE. */
+struct ip6t_replace {
+	/* Which table. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* Which hook entry points are valid: bitmask.  You can't
+           change this. */
+	unsigned int valid_hooks;
+
+	/* Number of entries */
+	unsigned int num_entries;
+
+	/* Total size of new entries */
+	unsigned int size;
+
+	/* Hook entry points. */
+	unsigned int hook_entry[NF_INET_NUMHOOKS];
+
+	/* Underflow points. */
+	unsigned int underflow[NF_INET_NUMHOOKS];
+
+	/* Information about old entries: */
+	/* Number of counters (must be equal to current number of entries). */
+	unsigned int num_counters;
+	/* The old entries' counters. */
+	struct xt_counters *counters;
+
+	/* The entries (hang off end: not really an array). */
+	struct ip6t_entry entries[0];
+};
+
+/* The argument to IP6T_SO_GET_ENTRIES. */
+struct ip6t_get_entries {
+	/* Which table: user fills this in. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* User fills this in: total entry size. */
+	unsigned int size;
+
+	/* The entries. */
+	struct ip6t_entry entrytable[0];
+};
+
+/* Helper functions */
+static __inline__ struct xt_entry_target *
+ip6t_get_target(struct ip6t_entry *e)
+{
+	return (void *)e + e->target_offset;
+}
+
+/*
+ *	Main firewall chains definitions and global var's definitions.
+ */
+
+#endif /* _IP6_TABLES_H */
-- 
2.9.0


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

* [PATCH nft v5 2/3] src: expose delinearize/linearize structures and stmt_error()
  2016-07-12 20:04 [PATCH nft v5 1/3] include: cache ip_tables.h, ip6_tables.h, arp_tables.h and ebtables.h Pablo M. Bermudo Garay
@ 2016-07-12 20:04 ` Pablo M. Bermudo Garay
  2016-07-13  9:53   ` Pablo Neira Ayuso
  2016-07-12 20:04 ` [PATCH nft v5 3/3] src: add xt compat support Pablo M. Bermudo Garay
  2016-07-13  9:52 ` [PATCH nft v5 1/3] include: cache ip_tables.h, ip6_tables.h, arp_tables.h and ebtables.h Pablo Neira Ayuso
  2 siblings, 1 reply; 7+ messages in thread
From: Pablo M. Bermudo Garay @ 2016-07-12 20:04 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo, Arturo Borrero Gonzalez

From: Pablo Neira <pablo@netfilter.org>

Needed by the follow up xt compatibility layer patch.

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---

Resubmission of xt compat support preparatory patch.

Changes in v5:
  - Discard __stmt_binary_error() rename.

 include/erec.h            | 12 ++++++++++++
 include/netlink.h         | 14 ++++++++++++++
 src/erec.c                | 17 +++++++++++++++++
 src/evaluate.c            | 22 ----------------------
 src/netlink_delinearize.c | 14 --------------
 5 files changed, 43 insertions(+), 36 deletions(-)

diff --git a/include/erec.h b/include/erec.h
index 25df1d0..36e0efa 100644
--- a/include/erec.h
+++ b/include/erec.h
@@ -61,4 +61,16 @@ 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);
 
+struct eval_ctx;
+
+extern int __fmtstring(4, 5) __stmt_binary_error(struct eval_ctx *ctx,
+						 const struct location *l1,
+						 const struct location *l2,
+						 const char *fmt, ...);
+
+#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)
+
 #endif /* NFTABLES_EREC_H */
diff --git a/include/netlink.h b/include/netlink.h
index 9f46560..76a9da4 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -12,6 +12,20 @@
 
 #include <rule.h>
 
+struct netlink_parse_ctx {
+	struct list_head	*msgs;
+	struct table		*table;
+	struct rule		*rule;
+	struct stmt		*stmt;
+	struct expr		*registers[1 + NFT_REG32_15 - NFT_REG32_00 + 1];
+};
+
+struct rule_pp_ctx {
+	struct proto_ctx	pctx;
+	struct payload_dep_ctx	pdctx;
+	struct stmt		*stmt;
+};
+
 extern const struct input_descriptor indesc_netlink;
 extern const struct location netlink_location;
 
diff --git a/src/erec.c b/src/erec.c
index d514230..0a1e6c7 100644
--- a/src/erec.c
+++ b/src/erec.c
@@ -176,3 +176,20 @@ void erec_print_list(FILE *f, struct list_head *list)
 		erec_destroy(erec);
 	}
 }
+
+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;
+}
diff --git a/src/evaluate.c b/src/evaluate.c
index f24e5f3..27deb15 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -37,28 +37,6 @@ 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)
 #define monitor_error(ctx, s1, fmt, args...) \
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 7735699..fffbe26 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -27,14 +27,6 @@
 #include <sys/socket.h>
 #include <libnftnl/udata.h>
 
-struct netlink_parse_ctx {
-	struct list_head	*msgs;
-	struct table		*table;
-	struct rule		*rule;
-	struct stmt		*stmt;
-	struct expr		*registers[1 + NFT_REG32_15 - NFT_REG32_00 + 1];
-};
-
 static int netlink_parse_expr(const struct nftnl_expr *nle,
 			      struct netlink_parse_ctx *ctx);
 
@@ -1047,12 +1039,6 @@ struct stmt *netlink_parse_set_expr(const struct set *set,
 	return pctx->stmt;
 }
 
-struct rule_pp_ctx {
-	struct proto_ctx	pctx;
-	struct payload_dep_ctx	pdctx;
-	struct stmt		*stmt;
-};
-
 static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp);
 
 static void integer_type_postprocess(struct expr *expr)
-- 
2.9.0


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

* [PATCH nft v5 3/3] src: add xt compat support
  2016-07-12 20:04 [PATCH nft v5 1/3] include: cache ip_tables.h, ip6_tables.h, arp_tables.h and ebtables.h Pablo M. Bermudo Garay
  2016-07-12 20:04 ` [PATCH nft v5 2/3] src: expose delinearize/linearize structures and stmt_error() Pablo M. Bermudo Garay
@ 2016-07-12 20:04 ` Pablo M. Bermudo Garay
  2016-07-13  9:53   ` Pablo Neira Ayuso
  2016-07-13  9:52 ` [PATCH nft v5 1/3] include: cache ip_tables.h, ip6_tables.h, arp_tables.h and ebtables.h Pablo Neira Ayuso
  2 siblings, 1 reply; 7+ messages in thread
From: Pablo M. Bermudo Garay @ 2016-07-12 20:04 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo, Arturo Borrero Gonzalez, Pablo M . Bermudo Garay

From: Pablo Neira <pablo@netfilter.org>

At compilation time, you have to pass this option.

  # ./configure --with-xtables

And libxtables needs to be installed in your system.

This patch allows to list a ruleset containing xt extensions loaded
through iptables-compat-restore tool.

Example:

$ iptables-save > ruleset

$ cat ruleset
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -p tcp -m multiport --dports 80,81 -j REJECT
COMMIT

$ sudo iptables-compat-restore ruleset

$ sudo nft list rulseset
table ip filter {
    chain INPUT {
        type filter hook input priority 0; policy accept;
        ip protocol tcp tcp dport { 80,81} counter packets 0 bytes 0 reject
    }

    chain FORWARD {
        type filter hook forward priority 0; policy drop;
    }

    chain OUTPUT {
        type filter hook output priority 0; policy accept;
    }
}

A translation of the extension is shown if this is available. In other
case, match or target definition is preceded by a hash. For example,
classify target has not translation:

$ sudo nft list chain mangle POSTROUTING
table ip mangle {
    chain POSTROUTING {
        type filter hook postrouting priority -150; policy accept;
        ip protocol tcp tcp dport 80 counter packets 0 bytes 0 # CLASSIFY set 20:10
                                                              ^^^
    }
}

If the whole ruleset is translatable, the users can (re)load it using
"nft -f" and get nft native support for all their rules.

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Pablo M. Bermudo Garay <pablombg@gmail.com>
---

New version of the original work made by Arturo and Pablo.

Changes in v4:
  - Remove unused code.

Changes in v5:
  - Improve commit message.

Related work:
  - Fix extra space between matches. DONE 
  - Fix escaped quotation marks issue. WIP
  - Mark rules using xt compat support. WIP

 configure.ac                               |  13 +-
 include/linux/netfilter/nf_tables_compat.h |  38 ++++
 include/statement.h                        |  34 +++
 include/xt.h                               |  39 ++++
 src/Makefile.am                            |   8 +
 src/evaluate.c                             |   1 +
 src/netlink_delinearize.c                  |   6 +
 src/statement.c                            |  25 +++
 src/xt.c                                   | 348 +++++++++++++++++++++++++++++
 9 files changed, 511 insertions(+), 1 deletion(-)
 create mode 100644 include/linux/netfilter/nf_tables_compat.h
 create mode 100644 include/xt.h
 create mode 100644 src/xt.c

diff --git a/configure.ac b/configure.ac
index a1d7723..f281f21 100644
--- a/configure.ac
+++ b/configure.ac
@@ -98,6 +98,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
@@ -147,4 +157,5 @@ nft configuration:
   cli support:			${with_cli}
   enable debugging:		${with_debug}
   use mini-gmp:			${with_mini_gmp}
-  enable pdf documentation:	${enable_pdf_doc}"
+  enable pdf documentation:	${enable_pdf_doc}
+  libxtables support:		${with_libxtables}"
diff --git a/include/linux/netfilter/nf_tables_compat.h b/include/linux/netfilter/nf_tables_compat.h
new file mode 100644
index 0000000..8310f5f
--- /dev/null
+++ b/include/linux/netfilter/nf_tables_compat.h
@@ -0,0 +1,38 @@
+#ifndef _NFT_COMPAT_NFNETLINK_H_
+#define _NFT_COMPAT_NFNETLINK_H_
+
+enum nft_target_attributes {
+	NFTA_TARGET_UNSPEC,
+	NFTA_TARGET_NAME,
+	NFTA_TARGET_REV,
+	NFTA_TARGET_INFO,
+	__NFTA_TARGET_MAX
+};
+#define NFTA_TARGET_MAX		(__NFTA_TARGET_MAX - 1)
+
+enum nft_match_attributes {
+	NFTA_MATCH_UNSPEC,
+	NFTA_MATCH_NAME,
+	NFTA_MATCH_REV,
+	NFTA_MATCH_INFO,
+	__NFTA_MATCH_MAX
+};
+#define NFTA_MATCH_MAX		(__NFTA_MATCH_MAX - 1)
+
+#define NFT_COMPAT_NAME_MAX	32
+
+enum {
+	NFNL_MSG_COMPAT_GET,
+	NFNL_MSG_COMPAT_MAX
+};
+
+enum {
+	NFTA_COMPAT_UNSPEC = 0,
+	NFTA_COMPAT_NAME,
+	NFTA_COMPAT_REV,
+	NFTA_COMPAT_TYPE,
+	__NFTA_COMPAT_MAX,
+};
+#define NFTA_COMPAT_MAX (__NFTA_COMPAT_MAX - 1)
+
+#endif
diff --git a/include/statement.h b/include/statement.h
index e9313ca..1b21551 100644
--- a/include/statement.h
+++ b/include/statement.h
@@ -148,6 +148,37 @@ struct flow_stmt {
 extern struct stmt *flow_stmt_alloc(const struct location *loc);
 
 /**
+ * enum nft_xt_type - xtables statement types
+ *
+ * @NFT_XT_MATCH:	match
+ * @NFT_XT_TARGET:	target
+ * @NFT_XT_WATCHER:	watcher (only for the bridge family)
+ */
+enum nft_xt_type {
+	NFT_XT_MATCH = 0,
+	NFT_XT_TARGET,
+	NFT_XT_WATCHER,
+	NFT_XT_MAX
+};
+
+struct xtables_match;
+struct xtables_target;
+
+struct xt_stmt {
+	const char			*name;
+	enum nft_xt_type		type;
+	uint32_t			proto;
+	union {
+		struct xtables_match	*match;
+		struct xtables_target	*target;
+	};
+	const char			*opts;
+	void				*entry;
+};
+
+extern struct stmt *xt_stmt_alloc(const struct location *loc);
+
+/**
  * enum stmt_types - statement types
  *
  * @STMT_INVALID:	uninitialised
@@ -168,6 +199,7 @@ extern struct stmt *flow_stmt_alloc(const struct location *loc);
  * @STMT_SET:		set statement
  * @STMT_DUP:		dup statement
  * @STMT_FWD:		forward statement
+ * @STMT_XT:		XT statement
  */
 enum stmt_types {
 	STMT_INVALID,
@@ -188,6 +220,7 @@ enum stmt_types {
 	STMT_SET,
 	STMT_DUP,
 	STMT_FWD,
+	STMT_XT,
 };
 
 /**
@@ -243,6 +276,7 @@ struct stmt {
 		struct set_stmt		set;
 		struct dup_stmt		dup;
 		struct fwd_stmt		fwd;
+		struct xt_stmt		xt;
 	};
 };
 
diff --git a/include/xt.h b/include/xt.h
new file mode 100644
index 0000000..753511e
--- /dev/null
+++ b/include/xt.h
@@ -0,0 +1,39 @@
+#ifndef _NFT_XT_H_
+#define _NFT_XT_H_
+
+struct netlink_linearize_ctx;
+struct netlink_parse_ctx;
+struct nftnl_expr;
+struct rule_pp_ctx;
+struct rule;
+
+#ifdef HAVE_LIBXTABLES
+void xt_stmt_xlate(const struct stmt *stmt);
+void xt_stmt_release(const struct stmt *stmt);
+
+void netlink_parse_target(struct netlink_parse_ctx *ctx,
+			  const struct location *loc,
+			  const struct nftnl_expr *nle);
+void netlink_parse_match(struct netlink_parse_ctx *ctx,
+			 const struct location *loc,
+			 const struct nftnl_expr *nle);
+void stmt_xt_postprocess(struct rule_pp_ctx *rctx, struct stmt *stmt,
+			 struct rule *rule);
+#else
+static inline void xt_stmt_xlate(const struct stmt *stmt) {}
+static inline void xt_stmt_release(const struct stmt *stmt) {}
+
+#include <erec.h>
+
+static inline void netlink_parse_target(struct netlink_parse_ctx *ctx,
+					const struct location *loc,
+					const struct nftnl_expr *nle) {}
+static inline void netlink_parse_match(struct netlink_parse_ctx *ctx,
+				       const struct location *loc,
+				       const struct nftnl_expr *nle) {}
+static inline void stmt_xt_postprocess(struct rule_pp_ctx *rctx,
+				       struct stmt *stmt, struct rule *rule) {}
+
+#endif
+
+#endif /* _NFT_XT_H_ */
diff --git a/src/Makefile.am b/src/Makefile.am
index fd63219..8c59449 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -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
diff --git a/src/evaluate.c b/src/evaluate.c
index 27deb15..8116735 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -28,6 +28,7 @@
 #include <erec.h>
 #include <gmputil.h>
 #include <utils.h>
+#include <xt.h>
 
 static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr);
 
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index fffbe26..257473a 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -26,6 +26,7 @@
 #include <erec.h>
 #include <sys/socket.h>
 #include <libnftnl/udata.h>
+#include <xt.h>
 
 static int netlink_parse_expr(const struct nftnl_expr *nle,
 			      struct netlink_parse_ctx *ctx);
@@ -986,6 +987,8 @@ static const struct {
 	{ .name = "queue",	.parse = netlink_parse_queue },
 	{ .name = "dynset",	.parse = netlink_parse_dynset },
 	{ .name = "fwd",	.parse = netlink_parse_fwd },
+	{ .name = "target",	.parse = netlink_parse_target },
+	{ .name = "match",	.parse = netlink_parse_match },
 };
 
 static int netlink_parse_expr(const struct nftnl_expr *nle,
@@ -1798,6 +1801,9 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r
 			if (stmt->fwd.to != NULL)
 				expr_postprocess(&rctx, &stmt->fwd.to);
 			break;
+		case STMT_XT:
+			stmt_xt_postprocess(&rctx, stmt, rule);
+			break;
 		default:
 			break;
 		}
diff --git a/src/statement.c b/src/statement.c
index 76f528b..7778a95 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -23,6 +23,7 @@
 #include <statement.h>
 #include <utils.h>
 #include <list.h>
+#include <xt.h>
 
 #include <netinet/in.h>
 #include <linux/netfilter/nf_nat.h>
@@ -567,3 +568,27 @@ struct stmt *fwd_stmt_alloc(const struct location *loc)
 {
 	return stmt_alloc(loc, &fwd_stmt_ops);
 }
+
+static void xt_stmt_print(const struct stmt *stmt)
+{
+	xt_stmt_xlate(stmt);
+}
+
+static void xt_stmt_destroy(struct stmt *stmt)
+{
+	xfree(stmt->xt.name);
+	xfree(stmt->xt.opts);
+	xt_stmt_release(stmt);
+}
+
+static const struct stmt_ops xt_stmt_ops = {
+	.type		= STMT_XT,
+	.name		= "xt",
+	.print		= xt_stmt_print,
+	.destroy	= xt_stmt_destroy,
+};
+
+struct stmt *xt_stmt_alloc(const struct location *loc)
+{
+	return stmt_alloc(loc, &xt_stmt_ops);
+}
diff --git a/src/xt.c b/src/xt.c
new file mode 100644
index 0000000..afcc836
--- /dev/null
+++ b/src/xt.c
@@ -0,0 +1,348 @@
+/*
+ * Copyright (c) 2013-2015 Pablo Neira Ayuso <pablo@netfilter.org>
+ * Copyright (c) 2015 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modifyi
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <xtables.h>
+#include <getopt.h>
+#include <ctype.h>	/* for isspace */
+#include <statement.h>
+#include <netlink.h>
+#include <xt.h>
+#include <erec.h>
+
+#include <libmnl/libmnl.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nf_tables_compat.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_arp/arp_tables.h>
+#include <linux/netfilter_bridge/ebtables.h>
+
+void xt_stmt_xlate(const struct stmt *stmt)
+{
+	struct xt_xlate *xl = xt_xlate_alloc(10240);
+
+	switch (stmt->xt.type) {
+	case NFT_XT_MATCH:
+		if (stmt->xt.match == NULL && stmt->xt.opts) {
+			printf("%s", stmt->xt.opts);
+		} else if (stmt->xt.match->xlate) {
+			stmt->xt.match->xlate(stmt->xt.entry,
+					      stmt->xt.match->m, xl, 0);
+				printf("%s", xt_xlate_get(xl));
+		} else if (stmt->xt.match->print) {
+			printf("#");
+			stmt->xt.match->print(&stmt->xt.entry,
+					      stmt->xt.match->m, 0);
+		}
+		break;
+	case NFT_XT_WATCHER:
+	case NFT_XT_TARGET:
+		if (stmt->xt.target == NULL && stmt->xt.opts) {
+			printf("%s", stmt->xt.opts);
+		} else if (stmt->xt.target->xlate) {
+			stmt->xt.target->xlate(stmt->xt.entry,
+					       stmt->xt.target->t, xl, 0);
+			printf("%s", xt_xlate_get(xl));
+		} else if (stmt->xt.target->print) {
+			printf("#");
+			stmt->xt.target->print(NULL, stmt->xt.target->t, 0);
+		}
+		break;
+	default:
+		break;
+	}
+
+	xt_xlate_free(xl);
+}
+
+void xt_stmt_release(const struct stmt *stmt)
+{
+	switch (stmt->xt.type) {
+	case NFT_XT_MATCH:
+		if (!stmt->xt.match)
+			break;
+		if (stmt->xt.match->m)
+			xfree(stmt->xt.match->m);
+		xfree(stmt->xt.match);
+		break;
+	case NFT_XT_WATCHER:
+	case NFT_XT_TARGET:
+		if (!stmt->xt.target)
+			break;
+		if (stmt->xt.target->t)
+			xfree(stmt->xt.target->t);
+		xfree(stmt->xt.target);
+		break;
+	default:
+		break;
+	}
+	xfree(stmt->xt.entry);
+}
+
+static void *xt_entry_alloc(struct xt_stmt *xt, uint32_t af)
+{
+	union nft_entry {
+		struct ipt_entry ipt;
+		struct ip6t_entry ip6t;
+		struct arpt_entry arpt;
+		struct ebt_entry ebt;
+	} *entry;
+
+	entry = xmalloc(sizeof(union nft_entry));
+
+	switch (af) {
+	case NFPROTO_IPV4:
+		entry->ipt.ip.proto = xt->proto;
+		break;
+	case NFPROTO_IPV6:
+		entry->ip6t.ipv6.proto = xt->proto;
+		break;
+	case NFPROTO_BRIDGE:
+		entry->ebt.ethproto = xt->proto;
+		break;
+	case NFPROTO_ARP:
+		entry->arpt.arp.arhln_mask = 0xff;
+		entry->arpt.arp.arhln = 6;
+		break;
+	default:
+		break;
+	}
+
+	return entry;
+}
+
+static uint32_t xt_proto(const struct proto_ctx *pctx)
+{
+	const struct proto_desc *desc = NULL;
+
+	if (pctx->family == NFPROTO_BRIDGE) {
+		desc = pctx->protocol[PROTO_BASE_NETWORK_HDR].desc;
+		if (desc == NULL)
+			return 0;
+		if (strcmp(desc->name, "ip") == 0)
+			return __constant_htons(ETH_P_IP);
+		if (strcmp(desc->name, "ip6") == 0)
+			return __constant_htons(ETH_P_IPV6);
+		return 0;
+	}
+
+	desc = pctx->protocol[PROTO_BASE_TRANSPORT_HDR].desc;
+	if (desc == NULL)
+		return 0;
+	if (strcmp(desc->name, "tcp") == 0)
+		return IPPROTO_TCP;
+	else if (strcmp(desc->name, "udp") == 0)
+		return IPPROTO_UDP;
+	else if (strcmp(desc->name, "udplite") == 0)
+		return IPPROTO_UDPLITE;
+	else if (strcmp(desc->name, "sctp") == 0)
+		return IPPROTO_SCTP;
+	else if (strcmp(desc->name, "dccp") == 0)
+		return IPPROTO_DCCP;
+	else if (strcmp(desc->name, "esp") == 0)
+		return IPPROTO_ESP;
+	else if (strcmp(desc->name, "ah") == 0)
+		return IPPROTO_AH;
+
+	return 0;
+}
+
+static struct xtables_target *xt_target_clone(struct xtables_target *t)
+{
+	struct xtables_target *clone;
+
+	clone = xzalloc(sizeof(struct xtables_target));
+	memcpy(clone, t, sizeof(struct xtables_target));
+	return clone;
+}
+
+static struct xtables_match *xt_match_clone(struct xtables_match *m)
+{
+	struct xtables_match *clone;
+
+	clone = xzalloc(sizeof(struct xtables_match));
+	memcpy(clone, m, sizeof(struct xtables_match));
+	return clone;
+}
+
+/*
+ * Delinearization
+ */
+
+void netlink_parse_match(struct netlink_parse_ctx *ctx,
+			 const struct location *loc,
+			 const struct nftnl_expr *nle)
+{
+	struct stmt *stmt;
+	const char *name;
+	struct xtables_match *mt;
+	const char *mtinfo;
+	struct xt_entry_match *m;
+	uint32_t mt_len;
+
+	xtables_set_nfproto(ctx->table->handle.family);
+
+	name = nftnl_expr_get_str(nle, NFT_EXPR_MT_NAME);
+
+	mt = xtables_find_match(name, XTF_TRY_LOAD, NULL);
+	if (!mt)
+		BUG("XT match %s not found\n", name);
+
+	mtinfo = nftnl_expr_get(nle, NFT_EXPR_MT_INFO, &mt_len);
+
+	m = xzalloc(sizeof(struct xt_entry_match) + mt_len);
+	memcpy(&m->data, mtinfo, mt_len);
+
+	m->u.match_size = mt_len + XT_ALIGN(sizeof(struct xt_entry_match));
+	m->u.user.revision = nftnl_expr_get_u32(nle, NFT_EXPR_MT_REV);
+
+	stmt = xt_stmt_alloc(loc);
+	stmt->xt.name = strdup(name);
+	stmt->xt.type = NFT_XT_MATCH;
+	stmt->xt.match = xt_match_clone(mt);
+	stmt->xt.match->m = m;
+
+	list_add_tail(&stmt->list, &ctx->rule->stmts);
+}
+
+void netlink_parse_target(struct netlink_parse_ctx *ctx,
+			  const struct location *loc,
+			  const struct nftnl_expr *nle)
+{
+	struct stmt *stmt;
+	const char *name;
+	struct xtables_target *tg;
+	const void *tginfo;
+	struct xt_entry_target *t;
+	size_t size;
+	uint32_t tg_len;
+
+	xtables_set_nfproto(ctx->table->handle.family);
+
+	name = nftnl_expr_get_str(nle, NFT_EXPR_TG_NAME);
+	tg = xtables_find_target(name, XTF_TRY_LOAD);
+	if (!tg)
+		BUG("XT target %s not found\n", name);
+
+	tginfo = nftnl_expr_get(nle, NFT_EXPR_TG_INFO, &tg_len);
+
+	size = XT_ALIGN(sizeof(struct xt_entry_target)) + tg_len;
+	t = xzalloc(size);
+	memcpy(&t->data, tginfo, tg_len);
+	t->u.target_size = size;
+	t->u.user.revision = nftnl_expr_get_u32(nle, NFT_EXPR_TG_REV);
+	strcpy(t->u.user.name, tg->name);
+
+	stmt = xt_stmt_alloc(loc);
+	stmt->xt.name = strdup(name);
+	stmt->xt.type = NFT_XT_TARGET;
+	stmt->xt.target = xt_target_clone(tg);
+	stmt->xt.target->t = t;
+
+	list_add_tail(&stmt->list, &ctx->rule->stmts);
+}
+
+static bool is_watcher(uint32_t family, struct stmt *stmt)
+{
+	if (family != NFPROTO_BRIDGE ||
+	    stmt->xt.type != NFT_XT_TARGET)
+		return false;
+
+	/* this has to be hardcoded :-( */
+	if (strcmp(stmt->xt.name, "log") == 0)
+		return true;
+	else if (strcmp(stmt->xt.name, "nflog") == 0)
+		return true;
+
+	return false;
+}
+
+void stmt_xt_postprocess(struct rule_pp_ctx *rctx, struct stmt *stmt,
+			 struct rule *rule)
+{
+	if (is_watcher(rctx->pctx.family, stmt))
+		stmt->xt.type = NFT_XT_WATCHER;
+
+	stmt->xt.proto = xt_proto(&rctx->pctx);
+	stmt->xt.entry = xt_entry_alloc(&stmt->xt, rctx->pctx.family);
+}
+
+static int nft_xt_compatible_revision(const char *name, uint8_t rev, int opt)
+{
+	struct mnl_socket *nl;
+	char buf[MNL_SOCKET_BUFFER_SIZE];
+	struct nlmsghdr *nlh;
+	uint32_t portid, seq, type;
+	struct nfgenmsg *nfg;
+	int ret = 0;
+
+	if (opt == IPT_SO_GET_REVISION_MATCH)
+		type = 0;
+	else
+		type = 1;
+
+	nlh = mnl_nlmsg_put_header(buf);
+	nlh->nlmsg_type = (NFNL_SUBSYS_NFT_COMPAT << 8) | NFNL_MSG_COMPAT_GET;
+	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+	nlh->nlmsg_seq = seq = time(NULL);
+
+	nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
+	nfg->nfgen_family = AF_INET;
+	nfg->version = NFNETLINK_V0;
+	nfg->res_id = 0;
+
+	mnl_attr_put_strz(nlh, NFTA_COMPAT_NAME, name);
+	mnl_attr_put_u32(nlh, NFTA_COMPAT_REV, htonl(rev));
+	mnl_attr_put_u32(nlh, NFTA_COMPAT_TYPE, htonl(type));
+
+	nl = mnl_socket_open(NETLINK_NETFILTER);
+	if (nl == NULL)
+		return 0;
+
+	if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0)
+		goto err;
+
+	portid = mnl_socket_get_portid(nl);
+
+	if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0)
+		goto err;
+
+	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
+	if (ret == -1)
+		goto err;
+
+	ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
+	if (ret == -1)
+		goto err;
+
+err:
+	mnl_socket_close(nl);
+
+	return ret < 0 ? 0 : 1;
+}
+
+static struct option original_opts[] = {
+	{ NULL },
+};
+
+static struct xtables_globals xt_nft_globals = {
+	.program_name		= "nft",
+	.program_version	= PACKAGE_VERSION,
+	.orig_opts		= original_opts,
+	.compat_rev		= nft_xt_compatible_revision,
+};
+
+static void __init xt_init(void)
+{
+	/* Default to IPv4, but this changes in runtime */
+	xtables_init_all(&xt_nft_globals, NFPROTO_IPV4);
+}
-- 
2.9.0


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

* Re: [PATCH nft v5 1/3] include: cache ip_tables.h, ip6_tables.h, arp_tables.h and ebtables.h
  2016-07-12 20:04 [PATCH nft v5 1/3] include: cache ip_tables.h, ip6_tables.h, arp_tables.h and ebtables.h Pablo M. Bermudo Garay
  2016-07-12 20:04 ` [PATCH nft v5 2/3] src: expose delinearize/linearize structures and stmt_error() Pablo M. Bermudo Garay
  2016-07-12 20:04 ` [PATCH nft v5 3/3] src: add xt compat support Pablo M. Bermudo Garay
@ 2016-07-13  9:52 ` Pablo Neira Ayuso
  2 siblings, 0 replies; 7+ messages in thread
From: Pablo Neira Ayuso @ 2016-07-13  9:52 UTC (permalink / raw)
  To: Pablo M. Bermudo Garay; +Cc: netfilter-devel

On Tue, Jul 12, 2016 at 10:04:15PM +0200, Pablo M. Bermudo Garay wrote:
> From: Pablo Neira <pablo@netfilter.org>
> 
> The xt over nft support that comes in follow up patches need this, and update
> the corresponding Makefile.am.
> 
> Based on patch from Arturo Borrero Gonzalez.

Applied, thanks.

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

* Re: [PATCH nft v5 2/3] src: expose delinearize/linearize structures and stmt_error()
  2016-07-12 20:04 ` [PATCH nft v5 2/3] src: expose delinearize/linearize structures and stmt_error() Pablo M. Bermudo Garay
@ 2016-07-13  9:53   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 7+ messages in thread
From: Pablo Neira Ayuso @ 2016-07-13  9:53 UTC (permalink / raw)
  To: Pablo M. Bermudo Garay; +Cc: netfilter-devel, Arturo Borrero Gonzalez

On Tue, Jul 12, 2016 at 10:04:16PM +0200, Pablo M. Bermudo Garay wrote:
> From: Pablo Neira <pablo@netfilter.org>
> 
> Needed by the follow up xt compatibility layer patch.

Applied, thanks.

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

* Re: [PATCH nft v5 3/3] src: add xt compat support
  2016-07-12 20:04 ` [PATCH nft v5 3/3] src: add xt compat support Pablo M. Bermudo Garay
@ 2016-07-13  9:53   ` Pablo Neira Ayuso
  2016-07-13 10:03     ` Arturo Borrero Gonzalez
  0 siblings, 1 reply; 7+ messages in thread
From: Pablo Neira Ayuso @ 2016-07-13  9:53 UTC (permalink / raw)
  To: Pablo M. Bermudo Garay; +Cc: netfilter-devel, Arturo Borrero Gonzalez

On Tue, Jul 12, 2016 at 10:04:17PM +0200, Pablo M. Bermudo Garay wrote:
> From: Pablo Neira <pablo@netfilter.org>
> 
> At compilation time, you have to pass this option.
> 
>   # ./configure --with-xtables
> 
> And libxtables needs to be installed in your system.
> 
> This patch allows to list a ruleset containing xt extensions loaded
> through iptables-compat-restore tool.
> 
> Example:
> 
> $ iptables-save > ruleset
> 
> $ cat ruleset
> *filter
> :INPUT ACCEPT [0:0]
> :FORWARD ACCEPT [0:0]
> :OUTPUT ACCEPT [0:0]
> -A INPUT -p tcp -m multiport --dports 80,81 -j REJECT
> COMMIT
> 
> $ sudo iptables-compat-restore ruleset
> 
> $ sudo nft list rulseset
> table ip filter {
>     chain INPUT {
>         type filter hook input priority 0; policy accept;
>         ip protocol tcp tcp dport { 80,81} counter packets 0 bytes 0 reject
>     }
> 
>     chain FORWARD {
>         type filter hook forward priority 0; policy drop;
>     }
> 
>     chain OUTPUT {
>         type filter hook output priority 0; policy accept;
>     }
> }
> 
> A translation of the extension is shown if this is available. In other
> case, match or target definition is preceded by a hash. For example,
> classify target has not translation:
> 
> $ sudo nft list chain mangle POSTROUTING
> table ip mangle {
>     chain POSTROUTING {
>         type filter hook postrouting priority -150; policy accept;
>         ip protocol tcp tcp dport 80 counter packets 0 bytes 0 # CLASSIFY set 20:10
>                                                               ^^^
>     }
> }
> 
> If the whole ruleset is translatable, the users can (re)load it using
> "nft -f" and get nft native support for all their rules.

Applied, thanks!

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

* Re: [PATCH nft v5 3/3] src: add xt compat support
  2016-07-13  9:53   ` Pablo Neira Ayuso
@ 2016-07-13 10:03     ` Arturo Borrero Gonzalez
  0 siblings, 0 replies; 7+ messages in thread
From: Arturo Borrero Gonzalez @ 2016-07-13 10:03 UTC (permalink / raw)
  To: Pablo M. Bermudo Garay
  Cc: Netfilter Development Mailing list, Pablo Neira Ayuso

good to see this finally merged :-)

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

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

end of thread, other threads:[~2016-07-13 10:04 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-12 20:04 [PATCH nft v5 1/3] include: cache ip_tables.h, ip6_tables.h, arp_tables.h and ebtables.h Pablo M. Bermudo Garay
2016-07-12 20:04 ` [PATCH nft v5 2/3] src: expose delinearize/linearize structures and stmt_error() Pablo M. Bermudo Garay
2016-07-13  9:53   ` Pablo Neira Ayuso
2016-07-12 20:04 ` [PATCH nft v5 3/3] src: add xt compat support Pablo M. Bermudo Garay
2016-07-13  9:53   ` Pablo Neira Ayuso
2016-07-13 10:03     ` Arturo Borrero Gonzalez
2016-07-13  9:52 ` [PATCH nft v5 1/3] include: cache ip_tables.h, ip6_tables.h, arp_tables.h and ebtables.h Pablo Neira Ayuso

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.