netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* NF [PATCH 1/4] xt_owner
@ 2007-11-25 19:05 Jan Engelhardt
  2007-11-25 19:06 ` NF [PATCH 2/4] xt_TEE Jan Engelhardt
                   ` (4 more replies)
  0 siblings, 5 replies; 35+ messages in thread
From: Jan Engelhardt @ 2007-11-25 19:05 UTC (permalink / raw)
  To: kaber; +Cc: Netfilter Developer Mailing List


Netfilter: Import xt_owner


xt_owner merges ipt_owner and ip6t_owner, and adds a flag to match
on socket (non-)existence.

Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>

---
 Delete net/ipv4/netfilter/ipt_owner.c
 Delete net/ipv6/netfilter/ip6t_owner.c

 include/linux/netfilter/Kbuild     |    1 
 include/linux/netfilter/xt_owner.h |   16 ++
 net/ipv4/netfilter/Kconfig         |    9 -
 net/ipv4/netfilter/Makefile        |    1 
 net/ipv4/netfilter/ipt_owner.c     |   87 ---------------
 net/ipv6/netfilter/Kconfig         |    9 -
 net/ipv6/netfilter/Makefile        |    1 
 net/ipv6/netfilter/ip6t_owner.c    |   87 ---------------
 net/netfilter/Kconfig              |    8 +
 net/netfilter/Makefile             |    1 
 net/netfilter/xt_owner.c           |  211 +++++++++++++++++++++++++++++++++++++
 11 files changed, 237 insertions(+), 194 deletions(-)

Index: linux-2.6/include/linux/netfilter/Kbuild
===================================================================
--- linux-2.6.orig/include/linux/netfilter/Kbuild
+++ linux-2.6/include/linux/netfilter/Kbuild
@@ -26,6 +26,7 @@ header-y += xt_limit.h
 header-y += xt_mac.h
 header-y += xt_mark.h
 header-y += xt_multiport.h
+header-y += xt_owner.h
 header-y += xt_pkttype.h
 header-y += xt_policy.h
 header-y += xt_realm.h
Index: linux-2.6/include/linux/netfilter/xt_owner.h
===================================================================
--- /dev/null
+++ linux-2.6/include/linux/netfilter/xt_owner.h
@@ -0,0 +1,16 @@
+#ifndef _XT_OWNER_MATCH_H
+#define _XT_OWNER_MATCH_H
+
+enum {
+	XT_OWNER_UID    = 1 << 0,
+	XT_OWNER_GID    = 1 << 1,
+	XT_OWNER_SOCKET = 1 << 2,
+};
+
+struct xt_owner_match_info {
+	u_int32_t uid;
+	u_int32_t gid;
+	u_int8_t match, invert;
+};
+
+#endif /* _XT_OWNER_MATCH_H */
Index: linux-2.6/net/ipv4/netfilter/Kconfig
===================================================================
--- linux-2.6.orig/net/ipv4/netfilter/Kconfig
+++ linux-2.6/net/ipv4/netfilter/Kconfig
@@ -111,15 +111,6 @@ config IP_NF_MATCH_TTL
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
-config IP_NF_MATCH_OWNER
-	tristate "Owner match support"
-	depends on IP_NF_IPTABLES
-	help
-	  Packet owner matching allows you to match locally-generated packets
-	  based on who created them: the user, group, process or session.
-
-	  To compile it as a module, choose M here.  If unsure, say N.
-
 config IP_NF_MATCH_ADDRTYPE
 	tristate  'address type match support'
 	depends on IP_NF_IPTABLES
Index: linux-2.6/net/ipv4/netfilter/Makefile
===================================================================
--- linux-2.6.orig/net/ipv4/netfilter/Makefile
+++ linux-2.6/net/ipv4/netfilter/Makefile
@@ -45,7 +45,6 @@ obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ip
 obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
-obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
 obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
 obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
Index: linux-2.6/net/ipv4/netfilter/ipt_owner.c
===================================================================
--- linux-2.6.orig/net/ipv4/netfilter/ipt_owner.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Kernel module to match various things tied to sockets associated with
-   locally generated outgoing packets. */
-
-/* (C) 2000 Marc Boucher <marc@mbsi.ca>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/skbuff.h>
-#include <linux/file.h>
-#include <linux/rcupdate.h>
-#include <net/sock.h>
-
-#include <linux/netfilter_ipv4/ipt_owner.h>
-#include <linux/netfilter/x_tables.h>
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
-MODULE_DESCRIPTION("iptables owner match");
-
-static bool
-owner_mt(const struct sk_buff *skb, const struct net_device *in,
-         const struct net_device *out, const struct xt_match *match,
-         const void *matchinfo, int offset, unsigned int protoff,
-         bool *hotdrop)
-{
-	const struct ipt_owner_info *info = matchinfo;
-
-	if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
-		return false;
-
-	if(info->match & IPT_OWNER_UID) {
-		if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
-		    !!(info->invert & IPT_OWNER_UID))
-			return false;
-	}
-
-	if(info->match & IPT_OWNER_GID) {
-		if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
-		    !!(info->invert & IPT_OWNER_GID))
-			return false;
-	}
-
-	return true;
-}
-
-static bool
-owner_mt_check(const char *tablename, const void *ip,
-               const struct xt_match *match, void *matchinfo,
-               unsigned int hook_mask)
-{
-	const struct ipt_owner_info *info = matchinfo;
-
-	if (info->match & (IPT_OWNER_PID|IPT_OWNER_SID|IPT_OWNER_COMM)) {
-		printk("ipt_owner: pid, sid and command matching "
-		       "not supported anymore\n");
-		return false;
-	}
-	return true;
-}
-
-static struct xt_match owner_mt_reg __read_mostly = {
-	.name		= "owner",
-	.family		= AF_INET,
-	.match		= owner_mt,
-	.matchsize	= sizeof(struct ipt_owner_info),
-	.hooks		= (1 << NF_INET_LOCAL_OUT) |
-			  (1 << NF_INET_POST_ROUTING),
-	.checkentry	= owner_mt_check,
-	.me		= THIS_MODULE,
-};
-
-static int __init owner_mt_init(void)
-{
-	return xt_register_match(&owner_mt_reg);
-}
-
-static void __exit owner_mt_exit(void)
-{
-	xt_unregister_match(&owner_mt_reg);
-}
-
-module_init(owner_mt_init);
-module_exit(owner_mt_exit);
Index: linux-2.6/net/ipv6/netfilter/Kconfig
===================================================================
--- linux-2.6.orig/net/ipv6/netfilter/Kconfig
+++ linux-2.6/net/ipv6/netfilter/Kconfig
@@ -89,15 +89,6 @@ config IP6_NF_MATCH_HL
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
-config IP6_NF_MATCH_OWNER
-	tristate "Owner match support"
-	depends on IP6_NF_IPTABLES
-	help
-	  Packet owner matching allows you to match locally-generated packets
-	  based on who created them: the user, group, process or session.
-
-	  To compile it as a module, choose M here.  If unsure, say N.
-
 config IP6_NF_MATCH_IPV6HEADER
 	tristate "IPv6 Extension Headers Match"
 	depends on IP6_NF_IPTABLES
Index: linux-2.6/net/ipv6/netfilter/Makefile
===================================================================
--- linux-2.6.orig/net/ipv6/netfilter/Makefile
+++ linux-2.6/net/ipv6/netfilter/Makefile
@@ -23,7 +23,6 @@ obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl
 obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
 obj-$(CONFIG_IP6_NF_MATCH_MH) += ip6t_mh.o
 obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o
-obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
 obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
 
 # targets
Index: linux-2.6/net/ipv6/netfilter/ip6t_owner.c
===================================================================
--- linux-2.6.orig/net/ipv6/netfilter/ip6t_owner.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Kernel module to match various things tied to sockets associated with
-   locally generated outgoing packets. */
-
-/* (C) 2000-2001 Marc Boucher <marc@mbsi.ca>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/skbuff.h>
-#include <linux/file.h>
-#include <linux/rcupdate.h>
-#include <net/sock.h>
-
-#include <linux/netfilter_ipv6/ip6t_owner.h>
-#include <linux/netfilter_ipv6/ip6_tables.h>
-#include <linux/netfilter/x_tables.h>
-
-MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
-MODULE_DESCRIPTION("IP6 tables owner matching module");
-MODULE_LICENSE("GPL");
-
-
-static bool
-owner_mt6(const struct sk_buff *skb, const struct net_device *in,
-          const struct net_device *out, const struct xt_match *match,
-          const void *matchinfo, int offset, unsigned int protoff,
-          bool *hotdrop)
-{
-	const struct ip6t_owner_info *info = matchinfo;
-
-	if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
-		return false;
-
-	if (info->match & IP6T_OWNER_UID)
-		if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
-		    !!(info->invert & IP6T_OWNER_UID))
-			return false;
-
-	if (info->match & IP6T_OWNER_GID)
-		if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
-		    !!(info->invert & IP6T_OWNER_GID))
-			return false;
-
-	return true;
-}
-
-static bool
-owner_mt6_check(const char *tablename, const void *ip,
-                const struct xt_match *match, void *matchinfo,
-                unsigned int hook_mask)
-{
-	const struct ip6t_owner_info *info = matchinfo;
-
-	if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) {
-		printk("ipt_owner: pid and sid matching "
-		       "not supported anymore\n");
-		return false;
-	}
-	return true;
-}
-
-static struct xt_match owner_mt6_reg __read_mostly = {
-	.name		= "owner",
-	.family		= AF_INET6,
-	.match		= owner_mt6,
-	.matchsize	= sizeof(struct ip6t_owner_info),
-	.hooks		= (1 << NF_INET_LOCAL_OUT) |
-			  (1 << NF_INET_POST_ROUTING),
-	.checkentry	= owner_mt6_check,
-	.me		= THIS_MODULE,
-};
-
-static int __init owner_mt6_init(void)
-{
-	return xt_register_match(&owner_mt6_reg);
-}
-
-static void __exit owner_mt6_exit(void)
-{
-	xt_unregister_match(&owner_mt6_reg);
-}
-
-module_init(owner_mt6_init);
-module_exit(owner_mt6_exit);
Index: linux-2.6/net/netfilter/Kconfig
===================================================================
--- linux-2.6.orig/net/netfilter/Kconfig
+++ linux-2.6/net/netfilter/Kconfig
@@ -546,6 +546,14 @@ config NETFILTER_XT_MATCH_MARK
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
+config NETFILTER_XT_MATCH_OWNER
+	tristate '"owner" match support'
+	depends on NETFILTER_XTABLES
+	---help---
+	Socket owner matching allows you to match locally-generated packets
+	based on who created the socket: the user or group. It is also
+	possible to check whether a socket actually exists.
+
 config NETFILTER_XT_MATCH_POLICY
 	tristate 'IPsec "policy" match support'
 	depends on NETFILTER_XTABLES && XFRM
Index: linux-2.6/net/netfilter/Makefile
===================================================================
--- linux-2.6.orig/net/netfilter/Makefile
+++ linux-2.6/net/netfilter/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) +
 obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_OWNER) += xt_owner.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o
Index: linux-2.6/net/netfilter/xt_owner.c
===================================================================
--- /dev/null
+++ linux-2.6/net/netfilter/xt_owner.c
@@ -0,0 +1,211 @@
+/*
+ * Kernel module to match various things tied to sockets associated with
+ * locally generated outgoing packets.
+ *
+ * (C) 2000 Marc Boucher <marc@mbsi.ca>
+ *
+ * Copyright © CC Computer Consultants GmbH, 2007
+ * Contact: <jengelh@computergmbh.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/file.h>
+#include <net/sock.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_owner.h>
+#include <linux/netfilter_ipv4/ipt_owner.h>
+#include <linux/netfilter_ipv6/ip6t_owner.h>
+
+static bool
+owner_mt_v0(const struct sk_buff *skb, const struct net_device *in,
+            const struct net_device *out, const struct xt_match *match,
+            const void *matchinfo, int offset, unsigned int protoff,
+            bool *hotdrop)
+{
+	const struct ipt_owner_info *info = matchinfo;
+	const struct file *filp;
+
+	if (skb->sk == NULL || skb->sk->sk_socket == NULL)
+		return false;
+
+	filp = skb->sk->sk_socket->file;
+	if (filp == NULL)
+		return false;
+
+	if (info->match & IPT_OWNER_UID)
+		if ((filp->f_uid != info->uid) ^
+		    !!(info->invert & IPT_OWNER_UID))
+			return false;
+
+	if (info->match & IPT_OWNER_GID)
+		if ((filp->f_gid != info->gid) ^
+		    !!(info->invert & IPT_OWNER_GID))
+			return false;
+
+	return true;
+}
+
+static bool
+owner_mt6_v0(const struct sk_buff *skb, const struct net_device *in,
+             const struct net_device *out, const struct xt_match *match,
+             const void *matchinfo, int offset, unsigned int protoff,
+             bool *hotdrop)
+{
+	const struct ip6t_owner_info *info = matchinfo;
+	const struct file *filp;
+
+	if (skb->sk == NULL || skb->sk->sk_socket == NULL)
+		return false;
+
+	filp = skb->sk->sk_socket->file;
+	if (filp == NULL)
+		return false;
+
+	if (info->match & IP6T_OWNER_UID)
+		if ((filp->f_uid != info->uid) ^
+		    !!(info->invert & IP6T_OWNER_UID))
+			return false;
+
+	if (info->match & IP6T_OWNER_GID)
+		if ((filp->f_gid != info->gid) ^
+		    !!(info->invert & IP6T_OWNER_GID))
+			return false;
+
+	return true;
+}
+
+static bool
+owner_mt(const struct sk_buff *skb, const struct net_device *in,
+         const struct net_device *out, const struct xt_match *match,
+         const void *matchinfo, int offset, unsigned int protoff,
+         bool *hotdrop)
+{
+	const struct xt_owner_match_info *info = matchinfo;
+	const struct file *filp;
+
+	if (skb->sk == NULL || skb->sk->sk_socket == NULL)
+		return (info->match ^ info->invert) == 0;
+	else if (info->match & info->invert & XT_OWNER_SOCKET)
+		/*
+		 * Socket exists but user wanted ! --socket-exists.
+		 * (Single ampersands intended.)
+		 */
+		return false;
+
+	filp = skb->sk->sk_socket->file;
+	if (filp == NULL)
+		return ((info->match ^ info->invert) &
+		       (XT_OWNER_UID | XT_OWNER_GID)) == 0;
+
+	if (info->match & XT_OWNER_UID)
+		if ((filp->f_uid != info->uid) ^
+		    !!(info->invert & XT_OWNER_UID))
+			return false;
+
+	if (info->match & XT_OWNER_GID)
+		if ((filp->f_gid != info->gid) ^
+		    !!(info->invert & XT_OWNER_GID))
+			return false;
+
+	return true;
+}
+
+static bool
+owner_mt_check_v0(const char *tablename, const void *ip,
+                  const struct xt_match *match, void *matchinfo,
+                  unsigned int hook_mask)
+{
+	const struct ipt_owner_info *info = matchinfo;
+
+	if (info->match & (IPT_OWNER_PID | IPT_OWNER_SID | IPT_OWNER_COMM)) {
+		printk(KERN_WARNING KBUILD_MODNAME
+		       ": PID, SID and command matching is not "
+		       "supported anymore\n");
+		return false;
+	}
+
+	return true;
+}
+
+static bool
+owner_mt6_check_v0(const char *tablename, const void *ip,
+                   const struct xt_match *match, void *matchinfo,
+                   unsigned int hook_mask)
+{
+	const struct ip6t_owner_info *info = matchinfo;
+
+	if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) {
+		printk(KERN_WARNING KBUILD_MODNAME
+		       ": PID and SID matching is not supported anymore\n");
+		return false;
+	}
+
+	return true;
+}
+
+static struct xt_match owner_mt_reg[] __read_mostly = {
+	{
+		.name       = "owner",
+		.revision   = 0,
+		.family     = AF_INET,
+		.match      = owner_mt_v0,
+		.matchsize  = sizeof(struct ipt_owner_info),
+		.checkentry = owner_mt_check_v0,
+		.hooks      = (1 << NF_INET_LOCAL_OUT) |
+		              (1 << NF_INET_POST_ROUTING),
+		.me         = THIS_MODULE,
+	},
+	{
+		.name       = "owner",
+		.revision   = 0,
+		.family     = AF_INET6,
+		.match      = owner_mt6_v0,
+		.matchsize  = sizeof(struct ip6t_owner_info),
+		.checkentry = owner_mt6_check_v0,
+		.hooks      = (1 << NF_INET_LOCAL_OUT) |
+		              (1 << NF_INET_POST_ROUTING),
+		.me         = THIS_MODULE,
+	},
+	{
+		.name       = "owner",
+		.revision   = 1,
+		.family     = AF_INET,
+		.match      = owner_mt,
+		.matchsize  = sizeof(struct xt_owner_match_info),
+		.hooks      = (1 << NF_INET_LOCAL_OUT) |
+		              (1 << NF_INET_POST_ROUTING),
+		.me         = THIS_MODULE,
+	},
+	{
+		.name       = "owner",
+		.revision   = 1,
+		.family     = AF_INET6,
+		.match      = owner_mt,
+		.matchsize  = sizeof(struct xt_owner_match_info),
+		.hooks      = (1 << NF_INET_LOCAL_OUT) |
+		              (1 << NF_INET_POST_ROUTING),
+		.me         = THIS_MODULE,
+	},
+};
+
+static int __init owner_mt_init(void)
+{
+	return xt_register_matches(owner_mt_reg, ARRAY_SIZE(owner_mt_reg));
+}
+
+static void __exit owner_mt_exit(void)
+{
+	xt_unregister_matches(owner_mt_reg, ARRAY_SIZE(owner_mt_reg));
+}
+
+module_init(owner_mt_init);
+module_exit(owner_mt_exit);
+MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
+MODULE_DESCRIPTION("netfilter \"owner\" match module");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_owner");
+MODULE_ALIAS("ip6t_owner");

-
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] 35+ messages in thread

* NF [PATCH 2/4] xt_TEE
  2007-11-25 19:05 NF [PATCH 1/4] xt_owner Jan Engelhardt
@ 2007-11-25 19:06 ` Jan Engelhardt
  2007-11-25 19:39   ` Krzysztof Oledzki
  2007-11-26  7:24   ` Patrick McHardy
  2007-11-25 19:06 ` NF [PATCH 3/4] xt_TCPOPTSTRIP Jan Engelhardt
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 35+ messages in thread
From: Jan Engelhardt @ 2007-11-25 19:06 UTC (permalink / raw)
  To: kaber; +Cc: Netfilter Developer Mailing List, Sebastian Classen


Netfilter: Import xt_TEE


Originally from Sebastian Classen.
xt_TEE is the logical successor to ipt_ROUTE; routing based on packet
charactersitics is done using xt_MARK/iproute2/fwmark nowadays, so
what remains of ipt_ROUTE is the --tee option, which xt_TEE implements.

Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
Cc: Sebastian Classen <sebastian.classen@freenet.de>

---
 include/linux/netfilter/xt_TEE.h |   12 +
 net/netfilter/Kconfig            |   13 ++
 net/netfilter/Makefile           |    1 
 net/netfilter/xt_TEE.c           |  240 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 266 insertions(+)

Index: linux-2.6/include/linux/netfilter/xt_TEE.h
===================================================================
--- /dev/null
+++ linux-2.6/include/linux/netfilter/xt_TEE.h
@@ -0,0 +1,12 @@
+#ifndef _XT_TEE_TARGET_H
+#define _XT_TEE_TARGET_H
+
+struct xt_tee_target_info {
+	union {
+		/* Address of gateway */
+		u_int32_t gateway_v4;
+		u_int32_t gateway_v6[4];
+	};
+};
+
+#endif /* _XT_TEE_TARGET_H */
Index: linux-2.6/net/netfilter/Kconfig
===================================================================
--- linux-2.6.orig/net/netfilter/Kconfig
+++ linux-2.6/net/netfilter/Kconfig
@@ -411,6 +411,19 @@ config NETFILTER_XT_TARGET_TCPMSS
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
+config NETFILTER_XT_TARGET_TEE
+	tristate '"TEE" target support'
+	depends on NETFILTER_XTABLES && IP_NF_MANGLE
+	---help---
+	  This option adds a "TEE" target, which enables you to duplicate
+	  packets and route those duplicates to a different gateway.
+
+	  The target has to be used inside the mangle table.
+
+	  If you want to compile it as a module, say M here and read
+	  Documentation/modules.txt. The module will be called xt_TEE.ko.
+	  If unsure, say N.
+
 config NETFILTER_XT_MATCH_COMMENT
 	tristate  '"comment" match support'
 	depends on NETFILTER_XTABLES
Index: linux-2.6/net/netfilter/Makefile
===================================================================
--- linux-2.6.orig/net/netfilter/Makefile
+++ linux-2.6/net/netfilter/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE
 obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_TEE) += xt_TEE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
 
 # matches
Index: linux-2.6/net/netfilter/xt_TEE.c
===================================================================
--- /dev/null
+++ linux-2.6/net/netfilter/xt_TEE.c
@@ -0,0 +1,240 @@
+/*
+ * This implements the TEE target.
+ *
+ * Copyright (C) 2007 Sebastian Classen <sebastian.classen@freenet.de> and
+ * CC Computer Consultants GmbH, 2007
+ * (Contact: Jan Engelhardt <jengelh@computergmbh.de>)
+ *
+ * based on ipt_ROUTE.c from Cédric de Launois <delaunois@info.ucl.ac.be>
+ *
+ * This software is distributed under GNU GPL v2, 1991
+ */
+#include <linux/ip.h>
+#include <linux/module.h>
+#include <linux/route.h>
+#include <linux/skbuff.h>
+#include <net/checksum.h>
+#include <net/icmp.h>
+#include <net/ip.h>
+#include <net/route.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_TEE.h>
+
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+#	define WITH_CONNTRACK 1
+#	include <net/netfilter/nf_conntrack.h>
+static struct nf_conn tee_track;
+#endif
+
+/*
+ * Try to route the packet according to the routing keys specified in
+ * route_info. Keys are :
+ *  - ifindex :
+ *      0 if no oif preferred,
+ *      otherwise set to the index of the desired oif
+ *  - route_info->gateway :
+ *      0 if no gateway specified,
+ *      otherwise set to the next host to which the pkt must be routed
+ * If success, skb->dev is the output device to which the packet must
+ * be sent and skb->dst is not NULL
+ *
+ * RETURN: false - if an error occured
+ *         true  - if the packet was succesfully routed to the
+ *                 destination desired
+ */
+static bool tee_routing(struct sk_buff *skb,
+                        const struct xt_tee_target_info *info)
+{
+	int err;
+	struct rtable *rt;
+	struct iphdr *iph = ip_hdr(skb);
+	struct flowi fl = {
+		.nl_u = {
+			.ip4_u = {
+				.daddr = iph->daddr,
+				.tos   = RT_TOS(iph->tos),
+				.scope = RT_SCOPE_UNIVERSE,
+			}
+		}
+	};
+
+	/* The destination address may be overloaded by the target */
+	if (info->gateway_v4 != 0)
+		fl.fl4_dst = info->gateway_v4;
+
+	/* Trying to route the packet using the standard routing table. */
+	err = ip_route_output_key(&rt, &fl);
+	if (err != 0) {
+		if (net_ratelimit())
+			pr_debug(KBUILD_MODNAME
+			         ": could not route packet (%d)", err);
+		return false;
+	}
+
+	/* Drop old route. */
+	dst_release(skb->dst);
+	skb->dst = NULL;
+
+	/*
+	 * Success if no oif specified or if the oif correspond to the
+	 * one desired.
+	 * [SC]: always the case, because we have no oif.
+	 */
+	skb->dst      = &rt->u.dst;
+	skb->dev      = skb->dst->dev;
+	skb->protocol = htons(ETH_P_IP);
+	return true;
+}
+
+/*
+ * Stolen from ip_finish_output2
+ * PRE : skb->dev is set to the device we are leaving by
+ *       skb->dst is not NULL
+ * POST: the packet is sent with the link layer header pushed
+ *       the packet is destroyed
+ */
+static void tee_ip_direct_send(struct sk_buff *skb)
+{
+	const struct dst_entry *dst  = skb->dst;
+	const struct net_device *dev = dst->dev;
+	unsigned int hh_len = LL_RESERVED_SPACE(dev);
+
+	/* Be paranoid, rather than too clever. */
+	if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops != NULL)) {
+		struct sk_buff *skb2;
+
+		skb2 = skb_realloc_headroom(skb, LL_RESERVED_SPACE(dev));
+		if (skb2 == NULL) {
+			kfree_skb(skb);
+			return;
+		}
+		if (skb->sk != NULL)
+			skb_set_owner_w(skb2, skb->sk);
+		kfree_skb(skb);
+		skb = skb2;
+	}
+
+	if (dst->hh != NULL) {
+		neigh_hh_output(dst->hh, skb);
+	} else if (dst->neighbour != NULL) {
+		dst->neighbour->output(skb);
+	} else {
+		if (net_ratelimit())
+			pr_debug(KBUILD_MODNAME "no hdr & no neighbour cache!\n");
+		kfree_skb(skb);
+	}
+}
+
+/*
+ * To detect and deter routed packet loopback when using the --tee option, we
+ * take a page out of the raw.patch book: on the copied skb, we set up a fake
+ * ->nfct entry, pointing to the local &route_tee_track. We skip routing
+ * packets when we see they already have that ->nfct.
+ */
+static unsigned int
+tee_tg(struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, unsigned int hooknum,
+       const struct xt_target *target, const void *targinfo)
+{
+	const struct xt_tee_target_info *info = targinfo;
+
+#ifdef WITH_CONNTRACK
+	if (skb->nfct == &tee_track.ct_general) {
+		/*
+		 * Loopback - a packet we already routed, is to be
+		 * routed another time. Avoid that, now.
+		 */
+		if (net_ratelimit())
+			pr_debug(KBUILD_MODNAME "loopback - DROP!\n");
+		return NF_DROP;
+	}
+#endif
+
+	/*
+	 * If we are in INPUT, the checksum must be recalculated since
+	 * the length could have changed as a result of defragmentation.
+	 */
+	if (hooknum == NF_INET_LOCAL_IN) {
+		struct iphdr *iph = ip_hdr(skb);
+		iph->check = 0;
+		iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
+	}
+
+	/*
+	 * Copy the skb, and route the copy. Will later return %XT_CONTINUE for
+	 * the original skb, which should continue on its way as if nothing has
+	 * happened. The copy should be independantly delivered to the TEE --gw.
+	 */
+	skb = skb_copy(skb, GFP_ATOMIC);
+	if (skb == NULL) {
+		if (net_ratelimit())
+			pr_debug(KBUILD_MODNAME "copy failed!\n");
+		return XT_CONTINUE;
+	}
+
+#ifdef WITH_CONNTRACK
+	/*
+	 * Tell conntrack to forget this packet since it may get confused
+	 * when a packet is leaving with dst address == our address.
+	 * Good idea? Dunno. Need advice.
+	 *
+	 * NEW: mark the skb with our &tee_track, so we avoid looping
+	 * on any already routed packet.
+	 */
+	nf_conntrack_put(skb->nfct);
+	skb->nfct     = &tee_track.ct_general;
+	skb->nfctinfo = IP_CT_NEW;
+	nf_conntrack_get(skb->nfct);
+#endif
+
+	if (info->gateway_v4 != 0) {
+		if (tee_routing(skb, info))
+			tee_ip_direct_send(skb);
+	} else {
+		if (net_ratelimit())
+			pr_debug(KBUILD_MODNAME ": no parameter!\n");
+	}
+
+	return XT_CONTINUE;
+}
+
+static struct xt_target tee_tg_reg __read_mostly = {
+	.name       = "TEE",
+	.family     = AF_INET,
+	.table      = "mangle",
+	.target     = tee_tg,
+	.targetsize = sizeof(struct xt_tee_target_info),
+	.me         = THIS_MODULE,
+};
+
+static int __init tee_tg_init(void)
+{
+#ifdef WITH_CONNTRACK
+	/*
+	 * Set up fake conntrack (stolen from raw.patch):
+	 * - to never be deleted, not in any hashes
+	 */
+	atomic_set(&tee_track.ct_general.use, 1);
+
+	/* - and look it like as a confirmed connection */
+	set_bit(IPS_CONFIRMED_BIT, &tee_track.status);
+
+	/* Initialize fake conntrack so that NAT will skip it */
+	tee_track.status |= IPS_NAT_DONE_MASK;
+#endif
+
+	return xt_register_target(&tee_tg_reg);
+}
+
+static void __exit tee_tg_exit(void)
+{
+	xt_unregister_target(&tee_tg_reg);
+	/* [SC]: shoud not we cleanup tee_track here? */
+}
+
+module_init(tee_tg_init);
+module_exit(tee_tg_exit);
+MODULE_AUTHOR("Sebastian Classen <sebastian.classen@freenet.ag>, Jan Engelhardt <jengelh@computergmbh.de>");
+MODULE_DESCRIPTION("netfilter \"TEE\" target module");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_TEE");
-
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] 35+ messages in thread

* NF [PATCH 3/4] xt_TCPOPTSTRIP
  2007-11-25 19:05 NF [PATCH 1/4] xt_owner Jan Engelhardt
  2007-11-25 19:06 ` NF [PATCH 2/4] xt_TEE Jan Engelhardt
@ 2007-11-25 19:06 ` Jan Engelhardt
  2007-11-26  7:24   ` Patrick McHardy
  2007-11-25 19:07 ` NF [PATCH 4/4] xt_gateway Jan Engelhardt
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 35+ messages in thread
From: Jan Engelhardt @ 2007-11-25 19:06 UTC (permalink / raw)
  To: kaber; +Cc: Netfilter Developer Mailing List, Sven Schnelle


Netfilter: Import xt_TCPOPTSTRIP


Originally from Sven Schnelle.
xt_TCPOPTSTRIP can strip TCP options from TCP packets, for example,
to disable Selective ACK or Window scaling.

Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
Cc: Sven Schnelle <svens@bitebene.org>

---
 include/linux/netfilter/xt_TCPOPTSTRIP.h |   13 ++
 net/netfilter/Kconfig                    |    8 +
 net/netfilter/Makefile                   |    1 
 net/netfilter/xt_TCPOPTSTRIP.c           |  143 +++++++++++++++++++++++++++++++
 4 files changed, 165 insertions(+)

Index: linux-2.6/include/linux/netfilter/xt_TCPOPTSTRIP.h
===================================================================
--- /dev/null
+++ linux-2.6/include/linux/netfilter/xt_TCPOPTSTRIP.h
@@ -0,0 +1,13 @@
+#ifndef _XT_TCPOPTSTRIP_H
+#define _XT_TCPOPTSTRIP_H
+
+#define tcpoptstrip_set_bit(bmap, idx) \
+	(bmap[(idx) >> 5] |= 1UL << (idx & 31))
+#define tcpoptstrip_test_bit(bmap, idx) \
+	(((1UL << (idx & 31)) & bmap[(idx) >> 5]) != 0)
+
+struct xt_tcpoptstrip_target_info {
+	u_int32_t strip_bmap[8];
+};
+
+#endif /* _XT_TCPOPTSTRIP_H */
Index: linux-2.6/net/netfilter/Kconfig
===================================================================
--- linux-2.6.orig/net/netfilter/Kconfig
+++ linux-2.6/net/netfilter/Kconfig
@@ -424,6 +424,14 @@ config NETFILTER_XT_TARGET_TEE
 	  Documentation/modules.txt. The module will be called xt_TEE.ko.
 	  If unsure, say N.
 
+config NETFILTER_XT_TARGET_TCPOPTSTRIP
+	tristate '"TCPOPTSTRIP" target support'
+	depends on NETFILTER_XTABLES
+	depends on IP_NF_MANGLE || IP6_NF_MANGLE
+	---help---
+	This option adds a "TCPOPTSTRIP" target, which allows you to strip
+	TCP options from TCP packets.
+
 config NETFILTER_XT_MATCH_COMMENT
 	tristate  '"comment" match support'
 	depends on NETFILTER_XTABLES
Index: linux-2.6/net/netfilter/Makefile
===================================================================
--- linux-2.6.orig/net/netfilter/Makefile
+++ linux-2.6/net/netfilter/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE
 obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TEE) += xt_TEE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
 
Index: linux-2.6/net/netfilter/xt_TCPOPTSTRIP.c
===================================================================
--- /dev/null
+++ linux-2.6/net/netfilter/xt_TCPOPTSTRIP.c
@@ -0,0 +1,143 @@
+/*
+ * A module for stripping a specific TCP option from TCP packets.
+ *
+ * Copyright (C) 2007 Sven Schnelle <svens@bitebene.org>
+ * Copyright © CC Computer Consultants GmbH, 2007
+ * Contact: Jan Engelhardt <jengelh@computergmbh.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/tcp.h>
+#include <net/ipv6.h>
+#include <net/tcp.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_TCPOPTSTRIP.h>
+
+static inline unsigned int optlen(const u_int8_t *opt, unsigned int offset)
+{
+	/* Beware zero-length options: make finite progress */
+	if (opt[offset] <= TCPOPT_NOP || opt[offset+1] == 0)
+		return 1;
+	else
+		return opt[offset+1];
+}
+
+static unsigned int
+tcpoptstrip_mangle_packet(struct sk_buff *skb,
+                          const struct xt_tcpoptstrip_target_info *info,
+                          unsigned int tcphoff, unsigned int minlen)
+{
+	unsigned int optl, i, j;
+	struct tcphdr *tcph;
+	u_int16_t n, o;
+	u_int8_t *opt;
+
+	if (!skb_make_writable(skb, skb->len))
+		return NF_DROP;
+
+	tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
+	opt  = (u_int8_t *)tcph;
+
+	/*
+	 * Walk through all TCP options - if we find some option to remove,
+	 * set all octets to %TCPOPT_NOP and adjust checksum.
+	 */
+	for (i = sizeof(struct tcphdr); i < tcp_hdrlen(skb); i += optl) {
+		optl = optlen(opt, i);
+
+		if (i + optl > tcp_hdrlen(skb))
+			break;
+
+		if (!tcpoptstrip_test_bit(info->strip_bmap, opt[i]))
+			continue;
+
+		for (j = 0; j < optl; ++j) {
+			o = opt[i+j];
+			n = TCPOPT_NOP;
+			if ((i + j) % 2 == 0) {
+				o <<= 8;
+				n <<= 8;
+			}
+			nf_proto_csum_replace2(&tcph->check, skb, htons(o),
+			                       htons(n), 0);
+		}
+		memset(opt + i, TCPOPT_NOP, optl);
+	}
+
+	return XT_CONTINUE;
+}
+
+static unsigned int
+tcpoptstrip_tg4(struct sk_buff *skb, const struct net_device *in,
+                const struct net_device *out, unsigned int hooknum,
+                const struct xt_target *target, const void *targinfo)
+{
+	return tcpoptstrip_mangle_packet(skb, targinfo, ip_hdrlen(skb),
+	       sizeof(struct iphdr) + sizeof(struct tcphdr));
+}
+
+static unsigned int
+tcpoptstrip_tg6(struct sk_buff *skb, const struct net_device *in,
+                const struct net_device *out, unsigned int hooknum,
+                const struct xt_target *target, const void *targinfo)
+{
+	struct ipv6hdr *ipv6h = ipv6_hdr(skb);
+	unsigned int tcphoff;
+	u_int8_t nexthdr;
+
+	nexthdr = ipv6h->nexthdr;
+	tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr);
+	if (tcphoff < 0)
+		return NF_DROP;
+
+	return tcpoptstrip_mangle_packet(skb, targinfo, tcphoff,
+	       sizeof(*ipv6h) + sizeof(struct tcphdr));
+}
+
+static struct xt_target tcpoptstrip_tg_reg[] __read_mostly = {
+	{
+		.name       = "TCPOPTSTRIP",
+		.family     = AF_INET,
+		.table      = "mangle",
+		.proto      = IPPROTO_TCP,
+		.target     = tcpoptstrip_tg4,
+		.targetsize = sizeof(struct xt_tcpoptstrip_target_info),
+		.me         = THIS_MODULE,
+	},
+	{
+		.name       = "TCPOPTSTRIP",
+		.family     = AF_INET6,
+		.table      = "mangle",
+		.proto      = IPPROTO_TCP,
+		.target     = tcpoptstrip_tg6,
+		.targetsize = sizeof(struct xt_tcpoptstrip_target_info),
+		.me         = THIS_MODULE,
+	},
+};
+
+static int __init tcpoptstrip_tg_init(void)
+{
+	return xt_register_targets(tcpoptstrip_tg_reg,
+	       ARRAY_SIZE(tcpoptstrip_tg_reg));
+}
+
+static void __exit tcpoptstrip_tg_exit(void)
+{
+	xt_unregister_targets(tcpoptstrip_tg_reg,
+	                      ARRAY_SIZE(tcpoptstrip_tg_reg));
+}
+
+module_init(tcpoptstrip_tg_init);
+module_exit(tcpoptstrip_tg_exit);
+MODULE_AUTHOR("Sven Schnelle <svens@bitebene.org>, Jan Engelhardt <jengelh@computergmbh.de>");
+MODULE_DESCRIPTION("netfilter \"TCPOPTSTRIP\" target module");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_TCPOPTSTRIP");
+MODULE_ALIAS("ip6t_TCPOPTSTRIP");
-
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] 35+ messages in thread

* NF [PATCH 4/4] xt_gateway
  2007-11-25 19:05 NF [PATCH 1/4] xt_owner Jan Engelhardt
  2007-11-25 19:06 ` NF [PATCH 2/4] xt_TEE Jan Engelhardt
  2007-11-25 19:06 ` NF [PATCH 3/4] xt_TCPOPTSTRIP Jan Engelhardt
@ 2007-11-25 19:07 ` Jan Engelhardt
  2007-11-26  7:30   ` Patrick McHardy
  2007-11-25 19:07 ` IPT [PATCH 1/4] libxt_owner Jan Engelhardt
  2007-11-26  7:12 ` NF [PATCH 1/4] xt_owner Patrick McHardy
  4 siblings, 1 reply; 35+ messages in thread
From: Jan Engelhardt @ 2007-11-25 19:07 UTC (permalink / raw)
  To: kaber; +Cc: Netfilter Developer Mailing List, azez


Netfilter: Import xt_gateway


Originally from <azez@ufomechanic.net>,
http://lists.netfilter.org/pipermail/netfilter-devel/2007-June/027954.html

This adds a gateway match to iptables that lets you match against the
routed ipv4 gateway, it is very useful for SNAT if you want to avoid
replicating your routing in your SNAT table.

e.g.

	iptables -t nat -A POSTROUTING -m gateway --nexthop \
		172.16.1.1 -j SNAT --to-address 172.16.1.5
	iptables -t nat -A POSTROUTING -m gateway --nexthop \
		192.168.1.1 -j SNAT --to-address 192.168.1.25

to help you choose the right SNAT address.

It works by comparing the to-be-matched gateway IP address with the
key in the neighbor table of the next-hop (the key is the layer 3
address).

	--gateway 1.2.3.4

only matches if the packet is destined to 1.2.3.4 as a ROUTE, i.e.
1.2.3.4 is not also the target address.

	--nexthop 1.2.3.4

matches if the next hop is specified as 1.2.3.4 either as a gateway or
as a final destination.

It cannot do magic, and match on non-routed aliases of routers, it only
matches the targeted IP address from which the layer 2 address has been
(or will be) actually derived.


Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
Cc: <azez@ufomechanic.net>

---
 include/linux/netfilter/xt_gateway.h |   19 ++++++++
 net/netfilter/Kconfig                |    9 +++
 net/netfilter/Makefile               |    1 
 net/netfilter/xt_gateway.c           |   83 +++++++++++++++++++++++++++++++++++
 4 files changed, 112 insertions(+)

Index: linux-2.6/include/linux/netfilter/xt_gateway.h
===================================================================
--- /dev/null
+++ linux-2.6/include/linux/netfilter/xt_gateway.h
@@ -0,0 +1,19 @@
+#ifndef _XT_GATEWAY_H
+#define _XT_GATEWAY_H
+
+enum {
+	/* Negate the condition */
+	XT_GATEWAY_INVERT = 1 << 0,
+	/* and the gateway is not the final hop */
+	XT_GATEWAY_ROUTE  = 1 << 1,
+};
+
+struct xt_gateway_match_info {
+	union {
+		__be32 gateway_v4;
+		__be32 gateway_v6[4];
+	};
+	u_int8_t flags;
+};
+
+#endif /* _XT_GATEWAY_H */
Index: linux-2.6/net/netfilter/Kconfig
===================================================================
--- linux-2.6.orig/net/netfilter/Kconfig
+++ linux-2.6/net/netfilter/Kconfig
@@ -519,6 +519,15 @@ config NETFILTER_XT_MATCH_ESP
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
+config NETFILTER_XT_MATCH_GATEWAY
+	tristate '"gateway" match support'
+	depends on NETFILTER_XTABLES
+	---help---
+	This option makes possible to match the IP address of the
+	routed gateway for routed packets.
+
+	To compile it as a module, choose M here. If unsure, say N.
+
 config NETFILTER_XT_MATCH_HELPER
 	tristate '"helper" match support'
 	depends on NETFILTER_XTABLES
Index: linux-2.6/net/netfilter/Makefile
===================================================================
--- linux-2.6.orig/net/netfilter/Makefile
+++ linux-2.6/net/netfilter/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRAC
 obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_DSCP) += xt_dscp.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += xt_esp.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_GATEWAY) += xt_gateway.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o
Index: linux-2.6/net/netfilter/xt_gateway.c
===================================================================
--- /dev/null
+++ linux-2.6/net/netfilter/xt_gateway.c
@@ -0,0 +1,83 @@
+/*
+ * netfilter module to match nexthop router by IP address
+ *
+ * (C) 2007 UFO Mechanic <azez@ufomechanic.net>
+ * Copyright © CC Computer Consultants GmbH, 2007
+ * Contact: Jan Engelhardt <jengelh@computergmbh.de>
+ *
+ *   to save time and bugs, based on ip_range by
+ *   (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/ip.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/types.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_gateway.h>
+#include <net/dst.h>
+#include <net/neighbour.h>
+
+static bool gateway_match_it(const struct sk_buff *skb,
+                             const struct xt_gateway_match_info *info)
+{
+	const struct iphdr *iph;
+	const struct dst_entry *dst;
+	const struct neighbour *neigh;
+	const struct neigh_table *tbl;
+
+	dst = skb->dst;
+	if ((neigh = dst->neighbour) == NULL)
+		return false;
+	tbl = neigh->tbl;
+	if (memcmp(&info->gateway_v4, &neigh->primary_key, tbl->key_len) != 0)
+		return false;
+	if (!(info->flags & XT_GATEWAY_ROUTE))
+		return true;
+	iph = ip_hdr(skb);
+	if (iph->daddr != info->gateway_v4)
+		return true;
+
+	return false;
+}
+
+static bool gateway_mt(const struct sk_buff *skb, const struct net_device *in,
+                       const struct net_device *out,
+                       const struct xt_match *match, const void *matchinfo,
+                       int offset, unsigned int protoff, bool *hotdrop)
+{
+	const struct xt_gateway_match_info *info = matchinfo;
+
+	return !!(info->flags & XT_GATEWAY_INVERT) ^
+	       gateway_match_it(skb, info);
+}
+
+static struct xt_match gateway_mt_reg __read_mostly = {
+	.name      = "gateway",
+	.family    = AF_INET,
+	.hooks     = (1 << NF_INET_FORWARD) | (1 << NF_INET_LOCAL_OUT) |
+	             (1 << NF_INET_POST_ROUTING),
+	.match     = gateway_mt,
+	.matchsize = sizeof(struct xt_gateway_match_info),
+	.me        = THIS_MODULE,
+};
+
+static int __init gateway_mt_init(void)
+{
+	return xt_register_match(&gateway_mt_reg);
+}
+
+static void __exit gateway_mt_exit(void)
+{
+	xt_unregister_match(&gateway_mt_reg);
+}
+
+module_init(gateway_mt_init);
+module_exit(gateway_mt_exit);
+MODULE_AUTHOR("Sam Liddicott <azez@ufomechanic.net>");
+MODULE_DESCRIPTION("netfilter nexthop/gateway match module");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_gateway");
-
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] 35+ messages in thread

* IPT [PATCH 1/4] libxt_owner
  2007-11-25 19:05 NF [PATCH 1/4] xt_owner Jan Engelhardt
                   ` (2 preceding siblings ...)
  2007-11-25 19:07 ` NF [PATCH 4/4] xt_gateway Jan Engelhardt
@ 2007-11-25 19:07 ` Jan Engelhardt
  2007-11-25 19:08   ` IPT [PATCH 2/4] libxt_TEE Jan Engelhardt
                     ` (2 more replies)
  2007-11-26  7:12 ` NF [PATCH 1/4] xt_owner Patrick McHardy
  4 siblings, 3 replies; 35+ messages in thread
From: Jan Engelhardt @ 2007-11-25 19:07 UTC (permalink / raw)
  To: kaber; +Cc: Netfilter Developer Mailing List


Import libxt_owner into iptables


libxt_owner merges libipt_owner and libip6t_owner, and adds support
for the new xt_owner kernel module.

Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>

---
 Delete libipt_owner.c
 Delete libip6t_owner.c

 extensions/Makefile                |    6 
 extensions/libip6t_owner.c         |  240 --------------
 extensions/libipt_owner.c          |  241 ---------------
 extensions/libipt_owner.man        |   28 -
 extensions/libxt_owner.c           |  593 +++++++++++++++++++++++++++++++++++++
 extensions/libxt_owner.man         |   16 
 include/linux/netfilter/xt_owner.h |   16 
 7 files changed, 628 insertions(+), 512 deletions(-)

Index: iptables-modules/extensions/Makefile
===================================================================
--- iptables-modules.orig/extensions/Makefile
+++ iptables-modules/extensions/Makefile
@@ -5,9 +5,9 @@
 # header files are present in the include/linux directory of this iptables
 # package (HW)
 #
-PF_EXT_SLIB:=ah addrtype conntrack ecn icmp iprange owner policy realm recent tos ttl unclean CLUSTERIP DNAT ECN LOG MASQUERADE MIRROR NETMAP REDIRECT REJECT SAME SNAT TOS TTL ULOG
-PF6_EXT_SLIB:=ah dst eui64 frag hbh hl icmp6 ipv6header mh owner policy rt HL LOG REJECT
-PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TRACE
+PF_EXT_SLIB:=ah addrtype conntrack ecn icmp iprange policy realm recent tos ttl unclean CLUSTERIP DNAT ECN LOG MASQUERADE MIRROR NETMAP REDIRECT REJECT SAME SNAT TOS TTL ULOG
+PF6_EXT_SLIB:=ah dst eui64 frag hbh hl icmp6 ipv6header mh policy rt HL LOG REJECT
+PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport owner physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TRACE
 
 PF_EXT_SELINUX_SLIB:=
 PF6_EXT_SELINUX_SLIB:=
Index: iptables-modules/extensions/libip6t_owner.c
===================================================================
--- iptables-modules.orig/extensions/libip6t_owner.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/* Shared library add-on to iptables to add OWNER matching support. */
-#include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <pwd.h>
-#include <grp.h>
-
-#include <ip6tables.h>
-#include <linux/netfilter_ipv6/ip6t_owner.h>
-
-/* Function which prints out usage message. */
-static void owner_help(void)
-{
-#ifdef IP6T_OWNER_COMM
-	printf(
-"OWNER match v%s options:\n"
-"[!] --uid-owner userid     Match local uid\n"
-"[!] --gid-owner groupid    Match local gid\n"
-"[!] --pid-owner processid  Match local pid\n"
-"[!] --sid-owner sessionid  Match local sid\n"
-"[!] --cmd-owner name       Match local command name\n"
-"\n",
-IPTABLES_VERSION);
-#else
-	printf(
-"OWNER match v%s options:\n"
-"[!] --uid-owner userid     Match local uid\n"
-"[!] --gid-owner groupid    Match local gid\n"
-"[!] --pid-owner processid  Match local pid\n"
-"[!] --sid-owner sessionid  Match local sid\n"
-"\n",
-IPTABLES_VERSION);
-#endif /* IP6T_OWNER_COMM */
-}
-
-static const struct option owner_opts[] = {
-	{ "uid-owner", 1, NULL, '1' },
-	{ "gid-owner", 1, NULL, '2' },
-	{ "pid-owner", 1, NULL, '3' },
-	{ "sid-owner", 1, NULL, '4' },
-#ifdef IP6T_OWNER_COMM
-	{ "cmd-owner", 1, NULL, '5' },
-#endif
-	{ }
-};
-
-/* Function which parses command options; returns true if it
-   ate an option */
-static int owner_parse(int c, char **argv, int invert, unsigned int *flags,
-                       const void *entry, struct xt_entry_match **match)
-{
-	struct ip6t_owner_info *ownerinfo = (struct ip6t_owner_info *)(*match)->data;
-
-	switch (c) {
-		char *end;
-		struct passwd *pwd;
-		struct group *grp;
-	case '1':
-		check_inverse(optarg, &invert, &optind, 0);
-
-		if ((pwd = getpwnam(optarg)))
-			ownerinfo->uid = pwd->pw_uid;
-		else {
-			ownerinfo->uid = strtoul(optarg, &end, 0);
-			if (*end != '\0' || end == optarg)
-				exit_error(PARAMETER_PROBLEM, "Bad OWNER UID value `%s'", optarg);
-		}
-		if (invert)
-			ownerinfo->invert |= IP6T_OWNER_UID;
-		ownerinfo->match |= IP6T_OWNER_UID;
-		*flags = 1;
-		break;
-
-	case '2':
-		check_inverse(optarg, &invert, &optind, 0);
-		if ((grp = getgrnam(optarg)))
-			ownerinfo->gid = grp->gr_gid;
-		else {
-			ownerinfo->gid = strtoul(optarg, &end, 0);
-			if (*end != '\0' || end == optarg)
-				exit_error(PARAMETER_PROBLEM, "Bad OWNER GID value `%s'", optarg);
-		}
-		if (invert)
-			ownerinfo->invert |= IP6T_OWNER_GID;
-		ownerinfo->match |= IP6T_OWNER_GID;
-		*flags = 1;
-		break;
-
-	case '3':
-		check_inverse(optarg, &invert, &optind, 0);
-		ownerinfo->pid = strtoul(optarg, &end, 0);
-		if (*end != '\0' || end == optarg)
-			exit_error(PARAMETER_PROBLEM, "Bad OWNER PID value `%s'", optarg);
-		if (invert)
-			ownerinfo->invert |= IP6T_OWNER_PID;
-		ownerinfo->match |= IP6T_OWNER_PID;
-		*flags = 1;
-		break;
-
-	case '4':
-		check_inverse(optarg, &invert, &optind, 0);
-		ownerinfo->sid = strtoul(optarg, &end, 0);
-		if (*end != '\0' || end == optarg)
-			exit_error(PARAMETER_PROBLEM, "Bad OWNER SID value `%s'", optarg);
-		if (invert)
-			ownerinfo->invert |= IP6T_OWNER_SID;
-		ownerinfo->match |= IP6T_OWNER_SID;
-		*flags = 1;
-		break;
-
-#ifdef IP6T_OWNER_COMM
-	case '5':
-		check_inverse(optarg, &invert, &optind, 0);
-		if(strlen(optarg) > sizeof(ownerinfo->comm))
-			exit_error(PARAMETER_PROBLEM, "OWNER CMD `%s' too long, max %d characters", optarg, sizeof(ownerinfo->comm));
-		
-		strncpy(ownerinfo->comm, optarg, sizeof(ownerinfo->comm));
-		ownerinfo->comm[sizeof(ownerinfo->comm)-1] = '\0';
-
-		if (invert)
-			ownerinfo->invert |= IP6T_OWNER_COMM;
-		ownerinfo->match |= IP6T_OWNER_COMM;
-		*flags = 1;
-		break;
-#endif
-		
-	default:
-		return 0;
-	}
-	return 1;
-}
-
-static void
-print_item(struct ip6t_owner_info *info, u_int8_t flag, int numeric, char *label)
-{
-	if(info->match & flag) {
-
-		if (info->invert & flag)
-			printf("! ");
-
-		printf(label);
-
-		switch(info->match & flag) {
-		case IP6T_OWNER_UID:
-			if(!numeric) {
-				struct passwd *pwd = getpwuid(info->uid);
-
-				if(pwd && pwd->pw_name) {
-					printf("%s ", pwd->pw_name);
-					break;
-				}
-				/* FALLTHROUGH */
-			}
-			printf("%u ", info->uid);
-			break;
-		case IP6T_OWNER_GID:
-			if(!numeric) {
-				struct group *grp = getgrgid(info->gid);
-
-				if(grp && grp->gr_name) {
-					printf("%s ", grp->gr_name);
-					break;
-				}
-				/* FALLTHROUGH */
-			}
-			printf("%u ", info->gid);
-			break;
-		case IP6T_OWNER_PID:
-			printf("%u ", info->pid);
-			break;
-		case IP6T_OWNER_SID:
-			printf("%u ", info->sid);
-			break;
-#ifdef IP6T_OWNER_COMM
-		case IP6T_OWNER_COMM:
-			printf("%.*s ", (int)sizeof(info->comm), info->comm);
-			break;
-#endif
-		default:
-			break;
-		}
-	}
-}
-
-/* Final check; must have specified --own. */
-static void owner_check(unsigned int flags)
-{
-	if (!flags)
-		exit_error(PARAMETER_PROBLEM,
-			   "OWNER match: You must specify one or more options");
-}
-
-/* Prints out the matchinfo. */
-static void owner_print(const void *ip, const struct xt_entry_match *match,
-                        int numeric)
-{
-	struct ip6t_owner_info *info = (struct ip6t_owner_info *)match->data;
-
-	print_item(info, IP6T_OWNER_UID, numeric, "OWNER UID match ");
-	print_item(info, IP6T_OWNER_GID, numeric, "OWNER GID match ");
-	print_item(info, IP6T_OWNER_PID, numeric, "OWNER PID match ");
-	print_item(info, IP6T_OWNER_SID, numeric, "OWNER SID match ");
-#ifdef IP6T_OWNER_COMM
-	print_item(info, IP6T_OWNER_COMM, numeric, "OWNER CMD match ");
-#endif
-}
-
-/* Saves the union ip6t_matchinfo in parsable form to stdout. */
-static void owner_save(const void *ip, const struct xt_entry_match *match)
-{
-	struct ip6t_owner_info *info = (struct ip6t_owner_info *)match->data;
-
-	print_item(info, IP6T_OWNER_UID, 0, "--uid-owner ");
-	print_item(info, IP6T_OWNER_GID, 0, "--gid-owner ");
-	print_item(info, IP6T_OWNER_PID, 0, "--pid-owner ");
-	print_item(info, IP6T_OWNER_SID, 0, "--sid-owner ");
-#ifdef IP6T_OWNER_COMM
-	print_item(info, IP6T_OWNER_COMM, 0, "--cmd-owner ");
-#endif
-}
-
-static struct ip6tables_match owner_match6 = {
-	.name 		= "owner",
-	.version	= IPTABLES_VERSION,
-	.size		= IP6T_ALIGN(sizeof(struct ip6t_owner_info)),
-	.userspacesize	= IP6T_ALIGN(sizeof(struct ip6t_owner_info)),
-	.help		= owner_help,
-	.parse		= owner_parse,
-	.final_check	= owner_check,
-	.print		= owner_print,
-	.save		= owner_save,
-	.extra_opts	= owner_opts,
-};
-
-void _init(void)
-{
-	register_match6(&owner_match6);
-}
Index: iptables-modules/extensions/libipt_owner.c
===================================================================
--- iptables-modules.orig/extensions/libipt_owner.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/* Shared library add-on to iptables to add OWNER matching support. */
-#include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <pwd.h>
-#include <grp.h>
-
-#include <iptables.h>
-#include <linux/netfilter_ipv4/ipt_owner.h>
-
-/* Function which prints out usage message. */
-static void owner_help(void)
-{
-#ifdef IPT_OWNER_COMM
-	printf(
-"OWNER match v%s options:\n"
-"[!] --uid-owner userid     Match local uid\n"
-"[!] --gid-owner groupid    Match local gid\n"
-"[!] --pid-owner processid  Match local pid\n"
-"[!] --sid-owner sessionid  Match local sid\n"
-"[!] --cmd-owner name       Match local command name\n"
-"NOTE: pid, sid and command matching are broken on SMP\n"
-"\n",
-IPTABLES_VERSION);
-#else
-	printf(
-"OWNER match v%s options:\n"
-"[!] --uid-owner userid     Match local uid\n"
-"[!] --gid-owner groupid    Match local gid\n"
-"[!] --pid-owner processid  Match local pid\n"
-"[!] --sid-owner sessionid  Match local sid\n"
-"NOTE: pid and sid matching are broken on SMP\n"
-"\n",
-IPTABLES_VERSION);
-#endif /* IPT_OWNER_COMM */
-}
-
-static const struct option owner_opts[] = {
-	{ "uid-owner", 1, NULL, '1' },
-	{ "gid-owner", 1, NULL, '2' },
-	{ "pid-owner", 1, NULL, '3' },
-	{ "sid-owner", 1, NULL, '4' },
-#ifdef IPT_OWNER_COMM
-	{ "cmd-owner", 1, NULL, '5' },
-#endif
-	{ }
-};
-
-/* Function which parses command options; returns true if it
-   ate an option */
-static int owner_parse(int c, char **argv, int invert, unsigned int *flags,
-                       const void *entry, struct xt_entry_match **match)
-{
-	struct ipt_owner_info *ownerinfo = (struct ipt_owner_info *)(*match)->data;
-
-	switch (c) {
-		char *end;
-		struct passwd *pwd;
-		struct group *grp;
-	case '1':
-		check_inverse(optarg, &invert, &optind, 0);
-		if ((pwd = getpwnam(optarg)))
-			ownerinfo->uid = pwd->pw_uid;
-		else {
-			ownerinfo->uid = strtoul(optarg, &end, 0);
-			if (*end != '\0' || end == optarg)
-				exit_error(PARAMETER_PROBLEM, "Bad OWNER UID value `%s'", optarg);
-		}
-		if (invert)
-			ownerinfo->invert |= IPT_OWNER_UID;
-		ownerinfo->match |= IPT_OWNER_UID;
-		*flags = 1;
-		break;
-
-	case '2':
-		check_inverse(optarg, &invert, &optind, 0);
-		if ((grp = getgrnam(optarg)))
-			ownerinfo->gid = grp->gr_gid;
-		else {
-			ownerinfo->gid = strtoul(optarg, &end, 0);
-			if (*end != '\0' || end == optarg)
-				exit_error(PARAMETER_PROBLEM, "Bad OWNER GID value `%s'", optarg);
-		}
-		if (invert)
-			ownerinfo->invert |= IPT_OWNER_GID;
-		ownerinfo->match |= IPT_OWNER_GID;
-		*flags = 1;
-		break;
-
-	case '3':
-		check_inverse(optarg, &invert, &optind, 0);
-		ownerinfo->pid = strtoul(optarg, &end, 0);
-		if (*end != '\0' || end == optarg)
-			exit_error(PARAMETER_PROBLEM, "Bad OWNER PID value `%s'", optarg);
-		if (invert)
-			ownerinfo->invert |= IPT_OWNER_PID;
-		ownerinfo->match |= IPT_OWNER_PID;
-		*flags = 1;
-		break;
-
-	case '4':
-		check_inverse(optarg, &invert, &optind, 0);
-		ownerinfo->sid = strtoul(optarg, &end, 0);
-		if (*end != '\0' || end == optarg)
-			exit_error(PARAMETER_PROBLEM, "Bad OWNER SID value `%s'", optarg);
-		if (invert)
-			ownerinfo->invert |= IPT_OWNER_SID;
-		ownerinfo->match |= IPT_OWNER_SID;
-		*flags = 1;
-		break;
-
-#ifdef IPT_OWNER_COMM
-	case '5':
-		check_inverse(optarg, &invert, &optind, 0);
-		if(strlen(optarg) > sizeof(ownerinfo->comm))
-			exit_error(PARAMETER_PROBLEM, "OWNER CMD `%s' too long, max %u characters", optarg, (unsigned int)sizeof(ownerinfo->comm));
-
-		strncpy(ownerinfo->comm, optarg, sizeof(ownerinfo->comm));
-		ownerinfo->comm[sizeof(ownerinfo->comm)-1] = '\0';
-
-		if (invert)
-			ownerinfo->invert |= IPT_OWNER_COMM;
-		ownerinfo->match |= IPT_OWNER_COMM;
-		*flags = 1;
-		break;
-#endif
-
-	default:
-		return 0;
-	}
-	return 1;
-}
-
-static void
-print_item(struct ipt_owner_info *info, u_int8_t flag, int numeric, char *label)
-{
-	if(info->match & flag) {
-
-		if (info->invert & flag)
-			printf("! ");
-
-		printf(label);
-
-		switch(info->match & flag) {
-		case IPT_OWNER_UID:
-			if(!numeric) {
-				struct passwd *pwd = getpwuid(info->uid);
-
-				if(pwd && pwd->pw_name) {
-					printf("%s ", pwd->pw_name);
-					break;
-				}
-				/* FALLTHROUGH */
-			}
-			printf("%u ", info->uid);
-			break;
-		case IPT_OWNER_GID:
-			if(!numeric) {
-				struct group *grp = getgrgid(info->gid);
-
-				if(grp && grp->gr_name) {
-					printf("%s ", grp->gr_name);
-					break;
-				}
-				/* FALLTHROUGH */
-			}
-			printf("%u ", info->gid);
-			break;
-		case IPT_OWNER_PID:
-			printf("%u ", info->pid);
-			break;
-		case IPT_OWNER_SID:
-			printf("%u ", info->sid);
-			break;
-#ifdef IPT_OWNER_COMM
-		case IPT_OWNER_COMM:
-			printf("%.*s ", (int)sizeof(info->comm), info->comm);
-			break;
-#endif
-		default:
-			break;
-		}
-	}
-}
-
-/* Final check; must have specified --own. */
-static void owner_check(unsigned int flags)
-{
-	if (!flags)
-		exit_error(PARAMETER_PROBLEM,
-			   "OWNER match: You must specify one or more options");
-}
-
-/* Prints out the matchinfo. */
-static void owner_print(const void *ip, const struct xt_entry_match *match,
-                        int numeric)
-{
-	struct ipt_owner_info *info = (struct ipt_owner_info *)match->data;
-
-	print_item(info, IPT_OWNER_UID, numeric, "OWNER UID match ");
-	print_item(info, IPT_OWNER_GID, numeric, "OWNER GID match ");
-	print_item(info, IPT_OWNER_PID, numeric, "OWNER PID match ");
-	print_item(info, IPT_OWNER_SID, numeric, "OWNER SID match ");
-#ifdef IPT_OWNER_COMM
-	print_item(info, IPT_OWNER_COMM, numeric, "OWNER CMD match ");
-#endif
-}
-
-/* Saves the union ipt_matchinfo in parsable form to stdout. */
-static void owner_save(const void *ip, const struct xt_entry_match *match)
-{
-	struct ipt_owner_info *info = (struct ipt_owner_info *)match->data;
-
-	print_item(info, IPT_OWNER_UID, 0, "--uid-owner ");
-	print_item(info, IPT_OWNER_GID, 0, "--gid-owner ");
-	print_item(info, IPT_OWNER_PID, 0, "--pid-owner ");
-	print_item(info, IPT_OWNER_SID, 0, "--sid-owner ");
-#ifdef IPT_OWNER_COMM
-	print_item(info, IPT_OWNER_COMM, 0, "--cmd-owner ");
-#endif
-}
-
-static struct iptables_match owner_match = {
-	.name		= "owner",
-	.version	= IPTABLES_VERSION,
-	.size		= IPT_ALIGN(sizeof(struct ipt_owner_info)),
-	.userspacesize	= IPT_ALIGN(sizeof(struct ipt_owner_info)),
-	.help		= owner_help,
-	.parse		= owner_parse,
-	.final_check	= owner_check,
-	.print		= owner_print,
-	.save		= owner_save,
-	.extra_opts	= owner_opts,
-};
-
-void _init(void)
-{
-	register_match(&owner_match);
-}
Index: iptables-modules/extensions/libipt_owner.man
===================================================================
--- iptables-modules.orig/extensions/libipt_owner.man
+++ /dev/null
@@ -1,28 +0,0 @@
-This module attempts to match various characteristics of the packet
-creator, for locally-generated packets.  It is only valid in the
-.B OUTPUT
-chain, and even this some packets (such as ICMP ping responses) may
-have no owner, and hence never match.
-.TP
-.BI "--uid-owner " "userid"
-Matches if the packet was created by a process with the given
-effective user id.
-.TP
-.BI "--gid-owner " "groupid"
-Matches if the packet was created by a process with the given
-effective group id.
-.TP
-.BI "--pid-owner " "processid"
-Matches if the packet was created by a process with the given
-process id.
-.TP
-.BI "--sid-owner " "sessionid"
-Matches if the packet was created by a process in the given session
-group.
-.TP
-.BI "--cmd-owner " "name"
-Matches if the packet was created by a process with the given command name.
-(this option is present only if iptables was compiled under a kernel
-supporting this feature)
-.TP
-.B NOTE: pid, sid and command matching are broken on SMP
Index: iptables-modules/extensions/libxt_owner.c
===================================================================
--- /dev/null
+++ iptables-modules/extensions/libxt_owner.c
@@ -0,0 +1,593 @@
+/*
+ * Copyright © CC Computer Consultants GmbH, 2007
+ * Contact: Jan Engelhardt <jengelh@computergmbh.de>
+ */
+#include <getopt.h>
+#include <grp.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <xtables.h>
+#include <linux/netfilter/xt_owner.h>
+#include <linux/netfilter_ipv4/ipt_owner.h>
+#include <linux/netfilter_ipv6/ip6t_owner.h>
+
+enum {
+	FLAG_UID_OWNER     = 1 << 0,
+	FLAG_GID_OWNER     = 1 << 1,
+	FLAG_SOCKET_EXISTS = 1 << 2,
+	FLAG_PID_OWNER     = 1 << 3,
+	FLAG_SID_OWNER     = 1 << 4,
+	FLAG_COMM          = 1 << 5,
+};
+
+static void owner_mt_help_v0(void)
+{
+#ifdef IPT_OWNER_COMM
+	printf(
+"owner match v%s options:\n"
+"[!] --uid-owner userid       Match local UID\n"
+"[!] --gid-owner groupid      Match local GID\n"
+"[!] --pid-owner processid    Match local PID\n"
+"[!] --sid-owner sessionid    Match local SID\n"
+"[!] --cmd-owner name         Match local command name\n"
+"NOTE: PID, SID and command matching are broken on SMP\n"
+"\n",
+IPTABLES_VERSION);
+#else
+	printf(
+"owner match v%s options:\n"
+"[!] --uid-owner userid       Match local UID\n"
+"[!] --gid-owner groupid      Match local GID\n"
+"[!] --pid-owner processid    Match local PID\n"
+"[!] --sid-owner sessionid    Match local SID\n"
+"NOTE: PID and SID matching are broken on SMP\n"
+"\n",
+IPTABLES_VERSION);
+#endif /* IPT_OWNER_COMM */
+}
+
+static void owner_mt6_help_v0(void)
+{
+	printf(
+"owner match v%s options:\n"
+"[!] --uid-owner userid       Match local UID\n"
+"[!] --gid-owner groupid      Match local GID\n"
+"[!] --pid-owner processid    Match local PID\n"
+"[!] --sid-owner sessionid    Match local SID\n"
+"NOTE: PID and SID matching are broken on SMP\n"
+"\n",
+IPTABLES_VERSION);
+}
+
+static void owner_mt_help(void)
+{
+	printf(
+"owner match v%s options:\n"
+"[!] --uid-owner userid     Match local UID\n"
+"[!] --gid-owner groupid    Match local GID\n"
+"[!] --socket-exists        Match if socket exists\n"
+"\n",
+IPTABLES_VERSION);
+}
+
+static const struct option owner_mt_opts_v0[] = {
+	{.name = "uid-owner", .has_arg = true, .val = 'u'},
+	{.name = "gid-owner", .has_arg = true, .val = 'g'},
+	{.name = "pid-owner", .has_arg = true, .val = 'p'},
+	{.name = "sid-owner", .has_arg = true, .val = 's'},
+#ifdef IPT_OWNER_COMM
+	{.name = "cmd-owner", .has_arg = true, .val = 'c'},
+#endif
+	{},
+};
+
+static const struct option owner_mt6_opts_v0[] = {
+	{.name = "uid-owner", .has_arg = true, .val = 'u'},
+	{.name = "gid-owner", .has_arg = true, .val = 'g'},
+	{.name = "pid-owner", .has_arg = true, .val = 'p'},
+	{.name = "sid-owner", .has_arg = true, .val = 's'},
+	{},
+};
+
+static const struct option owner_mt_opts[] = {
+	{.name = "uid-owner",     .has_arg = true,  .val = 'u'},
+	{.name = "gid-owner",     .has_arg = true,  .val = 'g'},
+	{.name = "socket-exists", .has_arg = false, .val = 'k'},
+	{},
+};
+
+static int
+owner_mt_parse_v0(int c, char **argv, int invert, unsigned int *flags,
+                  const void *entry, struct xt_entry_match **match)
+{
+	struct ipt_owner_info *ownerinfo = (void *)(*match)->data;
+	struct passwd *pwd;
+	struct group *grp;
+	unsigned int id;
+
+	switch (c) {
+	case 'u':
+		check_inverse(optarg, &invert, &optind, 0);
+		if ((pwd = getpwnam(optarg)) != NULL)
+			ownerinfo->uid = pwd->pw_uid;
+		else if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "bad UID value \"%s\"", optarg);
+		if (invert)
+			ownerinfo->invert |= IPT_OWNER_UID;
+		ownerinfo->match |= IPT_OWNER_UID;
+		ownerinfo->uid    = id;
+		*flags |= FLAG_UID_OWNER;
+		return true;
+
+	case 'g':
+		check_inverse(optarg, &invert, &optind, 0);
+		if ((grp = getgrnam(optarg)) != NULL)
+			ownerinfo->gid = grp->gr_gid;
+		else if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "bad GID value \"%s\"", optarg);
+		if (invert)
+			ownerinfo->invert |= IPT_OWNER_GID;
+		ownerinfo->match |= IPT_OWNER_GID;
+		ownerinfo->gid    = id;
+		*flags |= FLAG_GID_OWNER;
+		return true;
+
+	case 'p':
+		check_inverse(optarg, &invert, &optind, 0);
+		if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "bad PID value \"%s\"", optarg);
+		if (invert)
+			ownerinfo->invert |= IPT_OWNER_PID;
+		ownerinfo->match |= IPT_OWNER_PID;
+		ownerinfo->pid    = id;
+		*flags |= FLAG_PID_OWNER;
+		return true;
+
+	case 's':
+		check_inverse(optarg, &invert, &optind, 0);
+		if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "bad SID value \"%s\"", optarg);
+		if (invert)
+			ownerinfo->invert |= IPT_OWNER_SID;
+		ownerinfo->match |= IPT_OWNER_SID;
+		ownerinfo->sid    = id;
+		*flags |= FLAG_SID_OWNER;
+		return true;
+
+#ifdef IPT_OWNER_COMM
+	case 'c':
+		check_inverse(optarg, &invert, &optind, 0);
+		if (strlen(optarg) > sizeof(ownerinfo->comm))
+			exit_error(PARAMETER_PROBLEM, "owner match: command "
+			           "\"%s\" too long, max. %u characters",
+			           optarg, (unsigned int)sizeof(ownerinfo->comm));
+
+		ownerinfo->comm[sizeof(ownerinfo->comm)-1] = '\0';
+		strncpy(ownerinfo->comm, optarg, sizeof(ownerinfo->comm));
+
+		if (invert)
+			ownerinfo->invert |= IPT_OWNER_COMM;
+		ownerinfo->match |= IPT_OWNER_COMM;
+		*flags |= FLAG_COMM;
+		return true;
+#endif
+	}
+	return false;
+}
+
+static int
+owner_mt6_parse_v0(int c, char **argv, int invert, unsigned int *flags,
+                   const void *entry, struct xt_entry_match **match)
+{
+	struct ip6t_owner_info *ownerinfo = (void *)(*match)->data;
+	struct passwd *pwd;
+	struct group *grp;
+	unsigned int id;
+
+	switch (c) {
+	case 'u':
+		check_inverse(optarg, &invert, &optind, 0);
+		if ((pwd = getpwnam(optarg)) != NULL)
+			ownerinfo->uid = pwd->pw_uid;
+		else if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "bad UID value \"%s\"", optarg);
+		if (invert)
+			ownerinfo->invert |= IP6T_OWNER_UID;
+		ownerinfo->match |= IP6T_OWNER_UID;
+		ownerinfo->uid    = id;
+		*flags |= FLAG_UID_OWNER;
+		return true;
+
+	case 'g':
+		check_inverse(optarg, &invert, &optind, 0);
+		if ((grp = getgrnam(optarg)) != NULL)
+			ownerinfo->gid = grp->gr_gid;
+		else if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "bad GID value \"%s\"", optarg);
+		if (invert)
+			ownerinfo->invert |= IP6T_OWNER_GID;
+		ownerinfo->match |= IP6T_OWNER_GID;
+		ownerinfo->gid    = id;
+		*flags |= FLAG_GID_OWNER;
+		return true;
+
+	case 'p':
+		check_inverse(optarg, &invert, &optind, 0);
+		if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "bad PID value \"%s\"", optarg);
+		if (invert)
+			ownerinfo->invert |= IP6T_OWNER_PID;
+		ownerinfo->match |= IP6T_OWNER_PID;
+		ownerinfo->pid    = id;
+		*flags |= FLAG_PID_OWNER;
+		return true;
+
+	case 's':
+		check_inverse(optarg, &invert, &optind, 0);
+		if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "bad SID value \"%s\"", optarg);
+		if (invert)
+			ownerinfo->invert |= IP6T_OWNER_SID;
+		ownerinfo->match |= IP6T_OWNER_SID;
+		ownerinfo->sid    = id;
+		*flags |= FLAG_SID_OWNER;
+		return true;
+	}
+	return false;
+}
+
+static int owner_mt_parse(int c, char **argv, int invert, unsigned int *flags,
+                          const void *entry, struct xt_entry_match **match)
+{
+	struct xt_owner_match_info *info = (void *)(*match)->data;
+	struct passwd *pwd;
+	struct group *grp;
+	unsigned int id;
+
+	switch (c) {
+	case 'u':
+		if (*flags & FLAG_UID_OWNER)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "--uid-owner may only be given once");
+		check_inverse(optarg, &invert, &optind, 0);
+		if ((pwd = getpwnam(optarg)) != NULL) {
+			info->uid = pwd->pw_uid;
+		} else {
+			if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+				exit_error(PARAMETER_PROBLEM, "owner match: "
+				           "Invalid value for --uid-owner "
+				           "parameter: %s", optarg);
+			info->uid = id;
+		}
+		if (invert)
+			info->invert |= XT_OWNER_UID;
+		info->match |= XT_OWNER_UID;
+		*flags |= FLAG_UID_OWNER;
+		return true;
+
+	case 'g':
+		if (*flags & FLAG_GID_OWNER)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "--gid-owner may only be given once");
+		check_inverse(optarg, &invert, &optind, 0);
+		if ((grp = getgrnam(optarg)) != NULL) {
+			info->gid = grp->gr_gid;
+		} else {
+			if (string_to_number(optarg, 0, UINT_MAX, &id) < 0)
+				exit_error(PARAMETER_PROBLEM, "owner match: "
+				           "Invalid value for --gid-owner "
+				           "parameter: %s", optarg);
+			info->gid = id;
+		}
+		if (invert)
+			info->invert |= XT_OWNER_GID;
+		info->match |= XT_OWNER_GID;
+		*flags |= FLAG_GID_OWNER;
+		return true;
+
+	case 'k':
+		if (*flags & FLAG_SOCKET_EXISTS)
+			exit_error(PARAMETER_PROBLEM, "owner match: "
+			           "--socket-exists may only be given once");
+		check_inverse(optarg, &invert, &optind, 0);
+		if (invert)
+			info->invert |= XT_OWNER_SOCKET;
+		info->match |= XT_OWNER_SOCKET;
+		*flags |= FLAG_SOCKET_EXISTS;
+		return true;
+
+	}
+	return false;
+}
+
+static void owner_mt_check(unsigned int flags)
+{
+	if (flags == 0)
+		exit_error(PARAMETER_PROBLEM,
+			   "owner match: One or more parameters are required");
+}
+
+static void
+owner_mt_print_item_v0(const struct ipt_owner_info *info, const char *label,
+                       u_int8_t flag, bool numeric)
+{
+	if (!(info->match & flag))
+		return;
+	if (info->invert & flag)
+		printf("! ");
+	printf(label);
+
+	switch (info->match & flag) {
+	case IPT_OWNER_UID:
+		if (!numeric) {
+			struct passwd *pwd = getpwuid(info->uid);
+
+			if (pwd != NULL && pwd->pw_name != NULL) {
+				printf("%s ", pwd->pw_name);
+				break;
+			}
+		}
+		printf("%u ", (unsigned int)info->uid);
+		break;
+
+	case IPT_OWNER_GID:
+		if (!numeric) {
+			struct group *grp = getgrgid(info->gid);
+
+			if (grp != NULL && grp->gr_name != NULL) {
+				printf("%s ", grp->gr_name);
+				break;
+			}
+		}
+		printf("%u ", (unsigned int)info->gid);
+		break;
+
+	case IPT_OWNER_PID:
+		printf("%u ", (unsigned int)info->pid);
+		break;
+
+	case IPT_OWNER_SID:
+		printf("%u ", (unsigned int)info->sid);
+		break;
+
+#ifdef IPT_OWNER_COMM
+	case IPT_OWNER_COMM:
+		printf("%.*s ", (int)sizeof(info->comm), info->comm);
+		break;
+#endif
+	}
+}
+
+static void
+owner_mt6_print_item_v0(const struct ip6t_owner_info *info, const char *label,
+                        u_int8_t flag, bool numeric)
+{
+	if (!(info->match & flag))
+		return;
+	if (info->invert & flag)
+		printf("! ");
+	printf(label);
+
+	switch (info->match & flag) {
+	case IP6T_OWNER_UID:
+		if (!numeric) {
+			struct passwd *pwd = getpwuid(info->uid);
+
+			if (pwd != NULL && pwd->pw_name != NULL) {
+				printf("%s ", pwd->pw_name);
+				break;
+			}
+		}
+		printf("%u ", (unsigned int)info->uid);
+		break;
+
+	case IP6T_OWNER_GID:
+		if (!numeric) {
+			struct group *grp = getgrgid(info->gid);
+
+			if (grp != NULL && grp->gr_name != NULL) {
+				printf("%s ", grp->gr_name);
+				break;
+			}
+		}
+		printf("%u ", (unsigned int)info->gid);
+		break;
+
+	case IP6T_OWNER_PID:
+		printf("%u ", (unsigned int)info->pid);
+		break;
+
+	case IP6T_OWNER_SID:
+		printf("%u ", (unsigned int)info->sid);
+		break;
+	}
+}
+
+static void
+owner_mt_print_item(const struct xt_owner_match_info *info, const char *label,
+                    u_int8_t flag, bool numeric)
+{
+	if (!(info->match & flag))
+		return;
+	if (info->invert & flag)
+		printf("! ");
+	printf(label);
+
+	switch (info->match & flag) {
+	case XT_OWNER_UID:
+		if (!numeric) {
+			const struct passwd *pwd = getpwuid(info->uid);
+
+			if (pwd != NULL && pwd->pw_name != NULL) {
+				printf("%s ", pwd->pw_name);
+				break;
+			}
+		}
+		printf("%u ", (unsigned int)info->uid);
+		break;
+
+	case XT_OWNER_GID:
+		if (!numeric) {
+			const struct group *grp = getgrgid(info->gid);
+
+			if (grp != NULL && grp->gr_name != NULL) {
+				printf("%s ", grp->gr_name);
+				break;
+			}
+		}
+		printf("%u ", (unsigned int)info->gid);
+		break;
+	}
+}
+
+static void
+owner_mt_print_v0(const void *ip, const struct xt_entry_match *match,
+                  int numeric)
+{
+	const struct ipt_owner_info *info = (void *)match->data;
+
+	owner_mt_print_item_v0(info, "owner UID match ", IPT_OWNER_UID, numeric);
+	owner_mt_print_item_v0(info, "owner GID match ", IPT_OWNER_GID, numeric);
+	owner_mt_print_item_v0(info, "owner PID match ", IPT_OWNER_PID, numeric);
+	owner_mt_print_item_v0(info, "owner SID match ", IPT_OWNER_SID, numeric);
+#ifdef IPT_OWNER_COMM
+	owner_mt_print_item_v0(info, "owner CMD match ", IPT_OWNER_COMM, numeric);
+#endif
+}
+
+static void
+owner_mt6_print_v0(const void *ip, const struct xt_entry_match *match,
+                   int numeric)
+{
+	const struct ip6t_owner_info *info = (void *)match->data;
+
+	owner_mt6_print_item_v0(info, "owner UID match ", IPT_OWNER_UID, numeric);
+	owner_mt6_print_item_v0(info, "owner GID match ", IPT_OWNER_GID, numeric);
+	owner_mt6_print_item_v0(info, "owner PID match ", IPT_OWNER_PID, numeric);
+	owner_mt6_print_item_v0(info, "owner SID match ", IPT_OWNER_SID, numeric);
+}
+
+static void owner_mt_print(const void *ip, const struct xt_entry_match *match,
+                           int numeric)
+{
+	const struct xt_owner_match_info *info = (void *)match->data;
+
+	owner_mt_print_item(info, "owner socket exists ", XT_OWNER_SOCKET, numeric);
+	owner_mt_print_item(info, "owner UID match ",     XT_OWNER_UID,    numeric);
+	owner_mt_print_item(info, "owner GID match ",     XT_OWNER_GID,    numeric);
+}
+
+static void
+owner_mt_save_v0(const void *ip, const struct xt_entry_match *match)
+{
+	const struct ipt_owner_info *info = (void *)match->data;
+
+	owner_mt_print_item_v0(info, "owner UID match ", IPT_OWNER_UID, true);
+	owner_mt_print_item_v0(info, "owner GID match ", IPT_OWNER_GID, true);
+	owner_mt_print_item_v0(info, "owner PID match ", IPT_OWNER_PID, true);
+	owner_mt_print_item_v0(info, "owner SID match ", IPT_OWNER_SID, true);
+#ifdef IPT_OWNER_COMM
+	owner_mt_print_item_v0(info, "owner CMD match ", IPT_OWNER_COMM, true);
+#endif
+}
+
+static void
+owner_mt6_save_v0(const void *ip, const struct xt_entry_match *match)
+{
+	const struct ip6t_owner_info *info = (void *)match->data;
+
+	owner_mt6_print_item_v0(info, "owner UID match ", IPT_OWNER_UID, true);
+	owner_mt6_print_item_v0(info, "owner GID match ", IPT_OWNER_GID, true);
+	owner_mt6_print_item_v0(info, "owner PID match ", IPT_OWNER_PID, true);
+	owner_mt6_print_item_v0(info, "owner SID match ", IPT_OWNER_SID, true);
+}
+
+static void owner_mt_save(const void *ip, const struct xt_entry_match *match)
+{
+	const struct xt_owner_match_info *info = (void *)match->data;
+
+	owner_mt_print_item(info, "--socket-exists ", XT_OWNER_SOCKET, false);
+	owner_mt_print_item(info, "--uid-owner",      XT_OWNER_UID,    false);
+	owner_mt_print_item(info, "--gid-owner",      XT_OWNER_GID,    false);
+}
+
+static struct xtables_match owner_mt_reg_v0 = {
+	.version       = IPTABLES_VERSION,
+	.name          = "owner",
+	.family        = AF_INET,
+	.revision      = 0,
+	.size          = XT_ALIGN(sizeof(struct ipt_owner_info)),
+	.userspacesize = XT_ALIGN(sizeof(struct ipt_owner_info)),
+	.help          = owner_mt_help_v0,
+	.parse         = owner_mt_parse_v0,
+	.final_check   = owner_mt_check,
+	.print         = owner_mt_print_v0,
+	.save          = owner_mt_save_v0,
+	.extra_opts    = owner_mt_opts_v0,
+};
+
+static struct xtables_match owner_mt6_reg_v0 = {
+	.version       = IPTABLES_VERSION,
+	.name          = "owner",
+	.family        = AF_INET6,
+	.revision      = 0,
+	.size          = XT_ALIGN(sizeof(struct ip6t_owner_info)),
+	.userspacesize = XT_ALIGN(sizeof(struct ip6t_owner_info)),
+	.help          = owner_mt6_help_v0,
+	.parse         = owner_mt6_parse_v0,
+	.final_check   = owner_mt_check,
+	.print         = owner_mt6_print_v0,
+	.save          = owner_mt6_save_v0,
+	.extra_opts    = owner_mt6_opts_v0,
+};
+
+static struct xtables_match owner_mt_reg = {
+	.version       = IPTABLES_VERSION,
+	.name          = "owner",
+	.family        = AF_INET,
+	.revision      = 1,
+	.size          = XT_ALIGN(sizeof(struct xt_owner_match_info)),
+	.userspacesize = XT_ALIGN(sizeof(struct xt_owner_match_info)),
+	.help          = owner_mt_help,
+	.parse         = owner_mt_parse,
+	.final_check   = owner_mt_check,
+	.print         = owner_mt_print,
+	.save          = owner_mt_save,
+	.extra_opts    = owner_mt_opts,
+};
+
+static struct xtables_match owner_mt6_reg = {
+	.version       = IPTABLES_VERSION,
+	.name          = "owner",
+	.family        = AF_INET6,
+	.revision      = 1,
+	.size          = XT_ALIGN(sizeof(struct xt_owner_match_info)),
+	.userspacesize = XT_ALIGN(sizeof(struct xt_owner_match_info)),
+	.help          = owner_mt_help,
+	.parse         = owner_mt_parse,
+	.final_check   = owner_mt_check,
+	.print         = owner_mt_print,
+	.save          = owner_mt_save,
+	.extra_opts    = owner_mt_opts,
+};
+
+void _init(void)
+{
+	xtables_register_match(&owner_mt_reg_v0);
+	xtables_register_match(&owner_mt6_reg_v0);
+	xtables_register_match(&owner_mt_reg);
+	xtables_register_match(&owner_mt6_reg);
+}
Index: iptables-modules/extensions/libxt_owner.man
===================================================================
--- /dev/null
+++ iptables-modules/extensions/libxt_owner.man
@@ -0,0 +1,16 @@
+This module attempts to match various characteristics of the packet creator,
+for locally generated packets. This match is only valid in the OUTPUT and
+POSTROUTING chains. Forwarded packets do not have any socket associated with
+them. Packets from kernel threads do have a socket, but usually no owner.
+.TP
+\fB--uid-owner\fR \fIuserid\fR
+Matches if the packet socket's file structure (if it has one) is owned by the
+given user ID. A user name may be specified in place of \fIuserid\fR, in which
+case iptables will try to look it up.
+.TP
+\fB--gid-owner\fR \fIgroupid\fR
+Matches if the packet socket's file structure is owned by the given group ID.
+A group name may be specified in place of \fIgroupid\fR.
+.TP
+\fB--socket-exists\fR
+Matches if the packet is associated with a socket.
Index: iptables-modules/include/linux/netfilter/xt_owner.h
===================================================================
--- /dev/null
+++ iptables-modules/include/linux/netfilter/xt_owner.h
@@ -0,0 +1,16 @@
+#ifndef _XT_OWNER_MATCH_H
+#define _XT_OWNER_MATCH_H
+
+enum {
+	XT_OWNER_UID    = 1 << 0,
+	XT_OWNER_GID    = 1 << 1,
+	XT_OWNER_SOCKET = 1 << 2,
+};
+
+struct xt_owner_match_info {
+	u_int32_t uid;
+	u_int32_t gid;
+	u_int8_t match, invert;
+};
+
+#endif /* _XT_OWNER_MATCH_H */
-
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] 35+ messages in thread

* IPT [PATCH 2/4] libxt_TEE
  2007-11-25 19:07 ` IPT [PATCH 1/4] libxt_owner Jan Engelhardt
@ 2007-11-25 19:08   ` Jan Engelhardt
  2007-11-25 19:08   ` IPT [PATCH 3/4] libxt_TCPOPTSTRIP Jan Engelhardt
  2007-11-25 19:08   ` IPT [PATCH 4/4] libxt_gateway Jan Engelhardt
  2 siblings, 0 replies; 35+ messages in thread
From: Jan Engelhardt @ 2007-11-25 19:08 UTC (permalink / raw)
  To: kaber; +Cc: Netfilter Developer Mailing List, Sebastian Classen


Import libxt_TEE into iptables

Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
Cc: Sebastian Classen <sebastian.classen@freenet.ag>

---
 extensions/Makefile              |    2 
 extensions/libxt_TEE.c           |  125 +++++++++++++++++++++++++++++++++++++++
 extensions/libxt_TEE.man         |    6 +
 include/linux/netfilter/xt_TEE.h |   12 +++
 4 files changed, 144 insertions(+), 1 deletion(-)

Index: iptables-modules/extensions/Makefile
===================================================================
--- iptables-modules.orig/extensions/Makefile
+++ iptables-modules/extensions/Makefile
@@ -7,7 +7,7 @@
 #
 PF_EXT_SLIB:=ah addrtype conntrack ecn icmp iprange policy realm recent tos ttl unclean CLUSTERIP DNAT ECN LOG MASQUERADE MIRROR NETMAP REDIRECT REJECT SAME SNAT TOS TTL ULOG
 PF6_EXT_SLIB:=ah dst eui64 frag hbh hl icmp6 ipv6header mh policy rt HL LOG REJECT
-PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport owner physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TRACE
+PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport owner physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TEE TRACE
 
 PF_EXT_SELINUX_SLIB:=
 PF6_EXT_SELINUX_SLIB:=
Index: iptables-modules/extensions/libxt_TEE.c
===================================================================
--- /dev/null
+++ iptables-modules/extensions/libxt_TEE.c
@@ -0,0 +1,125 @@
+/*
+ * Shared library add-on to iptables to add TEE target support.
+ *
+ * Copyright Sebastian Classen <sebastian.classen@freenet.ag>, 2007
+ *
+ * Copyright © CC Computer Consultants GmbH, 2007
+ * Contact: Jan Engelhardt <jengelh@computergmbh.de>
+ *
+ * Based on ROUTE target with was originaly from:
+ * Cedric de Launois, <delaunois@info.ucl.ac.be>
+ * v 1.0 2007-08-20
+ */
+#include <sys/socket.h>
+#include <getopt.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <netinet/in.h>
+
+#include <xtables.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_TEE.h>
+
+enum {
+	FLAG_GATEWAY = 1 << 0,
+};
+
+static const struct option tee_tg_opts[] = {
+	{.name = "gateway", .has_arg = true, .val = 'g'},
+	{},
+};
+
+static void tee_tg_help(void)
+{
+	printf(
+"TEE target v%s options:\n"
+"  --gateway IPADDR    Route packet via the gateway given by address\n"
+"\n",
+"1.11");
+}
+
+static void tee_tg_init(struct xt_entry_target *target)
+{
+	struct xt_tee_target_info *info = (void *)target->data;
+
+	memset(info, 0, sizeof(*info));
+}
+
+static int tee_tg_parse(int c, char **argv, int invert, unsigned int *flags,
+                        const void *entry, struct xt_entry_target **target)
+{
+	struct xt_tee_target_info *info = (void *)(*target)->data;
+
+	switch (c) {
+	case 'g':
+		if (*flags & FLAG_GATEWAY)
+			exit_error(PARAMETER_PROBLEM,
+			           "Cannot specify --gw more than once");
+
+		if (check_inverse(optarg, &invert, NULL, 0))
+			exit_error(PARAMETER_PROBLEM,
+			           "Unexpected \"!\" after --gateway");
+
+		if (!inet_aton(optarg, (void *)&info->gateway_v4))
+			exit_error(PARAMETER_PROBLEM,
+			           "Invalid IP address %s", optarg);
+
+		*flags |= FLAG_GATEWAY;
+		return true;
+	}
+
+	return false;
+}
+
+static void tee_tg_check(unsigned int flags)
+{
+	if (flags == 0)
+		exit_error(PARAMETER_PROBLEM, "TEE target: "
+		           "--gateway parameter required");
+}
+
+static void tee_tg_print(const void *ip, const struct xt_entry_target *target,
+                         int numeric)
+{
+	const struct xt_tee_target_info *info = (const void *)target->data;
+
+	printf("TEE ");
+	if (info->gateway_v4 != 0) {
+		struct in_addr ip = {info->gateway_v4};
+		printf("gw:%s ", inet_ntoa(ip));
+	}
+}
+
+static void tee_tg_save(const void *ip, const struct xt_entry_target *target)
+{
+	const struct xt_tee_target_info *info = (const void *)target->data;
+
+	if (info->gateway_v4 != 0) {
+		struct in_addr ip = {info->gateway_v4};
+		printf("--gateway %s ", inet_ntoa(ip));
+	}
+}
+
+static struct xtables_target tee_tg_reg = {
+	.name          = "TEE",
+	.version       = IPTABLES_VERSION,
+	.size          = XT_ALIGN(sizeof(struct xt_tee_target_info)),
+	.userspacesize = XT_ALIGN(sizeof(struct xt_tee_target_info)),
+	.help          = tee_tg_help,
+	.init          = tee_tg_init,
+	.parse         = tee_tg_parse,
+	.final_check   = tee_tg_check,
+	.print         = tee_tg_print,
+	.save          = tee_tg_save,
+	.extra_opts    = tee_tg_opts,
+};
+
+void _init(void)
+{
+	xtables_register_target(&tee_tg_reg);
+}
Index: iptables-modules/extensions/libxt_TEE.man
===================================================================
--- /dev/null
+++ iptables-modules/extensions/libxt_TEE.man
@@ -0,0 +1,6 @@
+This is used to explicitly override the core network stack's routing decision.
+.B mangle
+table.
+.TP
+.BI "--gw " "IP_address"
+Route the packet via this gateway
Index: iptables-modules/include/linux/netfilter/xt_TEE.h
===================================================================
--- /dev/null
+++ iptables-modules/include/linux/netfilter/xt_TEE.h
@@ -0,0 +1,12 @@
+#ifndef _XT_TEE_TARGET_H
+#define _XT_TEE_TARGET_H
+
+struct xt_tee_target_info {
+	union {
+		/* Address of gateway */
+		u_int32_t gateway_v4;
+		u_int32_t gateway_v6[4];
+	};
+};
+
+#endif /* _XT_TEE_TARGET_H */
-
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] 35+ messages in thread

* IPT [PATCH 3/4] libxt_TCPOPTSTRIP
  2007-11-25 19:07 ` IPT [PATCH 1/4] libxt_owner Jan Engelhardt
  2007-11-25 19:08   ` IPT [PATCH 2/4] libxt_TEE Jan Engelhardt
@ 2007-11-25 19:08   ` Jan Engelhardt
  2007-11-25 19:08   ` IPT [PATCH 4/4] libxt_gateway Jan Engelhardt
  2 siblings, 0 replies; 35+ messages in thread
From: Jan Engelhardt @ 2007-11-25 19:08 UTC (permalink / raw)
  To: kaber; +Cc: Netfilter Developer Mailing List, Sven Schnelle


Import libxt_TCPOPTSTRIP into iptables.

Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
Cc: Sven Schnelle <svens@bitebene.org>

---
 extensions/Makefile                      |    2 
 extensions/libxt_TCPOPTSTRIP.c           |  211 +++++++++++++++++++++++++++++++
 extensions/libxt_TCPOPTSTRIP.man         |    7 +
 include/linux/netfilter/xt_TCPOPTSTRIP.h |   13 +
 4 files changed, 232 insertions(+), 1 deletion(-)

Index: iptables-modules/extensions/Makefile
===================================================================
--- iptables-modules.orig/extensions/Makefile
+++ iptables-modules/extensions/Makefile
@@ -7,7 +7,7 @@
 #
 PF_EXT_SLIB:=ah addrtype conntrack ecn icmp iprange policy realm recent tos ttl unclean CLUSTERIP DNAT ECN LOG MASQUERADE MIRROR NETMAP REDIRECT REJECT SAME SNAT TOS TTL ULOG
 PF6_EXT_SLIB:=ah dst eui64 frag hbh hl icmp6 ipv6header mh policy rt HL LOG REJECT
-PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport owner physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TEE TRACE
+PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport owner physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TEE TCPOPTSTRIP TRACE
 
 PF_EXT_SELINUX_SLIB:=
 PF6_EXT_SELINUX_SLIB:=
Index: iptables-modules/extensions/libxt_TCPOPTSTRIP.c
===================================================================
--- /dev/null
+++ iptables-modules/extensions/libxt_TCPOPTSTRIP.c
@@ -0,0 +1,211 @@
+/*
+ * Shared library add-on to iptables to add TCPOPTSTRIP target support.
+ * Copyright (c) 2007 Sven Schnelle <svens@bitebene.org>
+ * Copyright © Jan Engelhardt <jengelh@computergmbh.de>
+ */
+#include <getopt.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <xtables.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_TCPOPTSTRIP.h>
+#ifndef TCPOPT_MD5SIG
+#	define TCPOPT_MD5SIG 19
+#endif
+
+enum {
+	FLAG_STRIP = 1 << 0,
+};
+
+struct tcp_optionmap {
+	const char *name, *desc;
+	const int option;
+};
+
+static const struct option tcpoptstrip_tg_opts[] = {
+	{.name = "strip-options", .has_arg = true, .val = 's'},
+	{},
+};
+
+static const struct tcp_optionmap tcp_optionmap[] = {
+	{"wscale",         "Window scale",         TCPOPT_WINDOW},
+	{"mss",            "Maximum Segment Size", TCPOPT_MAXSEG},
+	{"sack-permitted", "SACK permitted",       TCPOPT_SACK_PERMITTED},
+	{"sack",           "Selective ACK",        TCPOPT_SACK},
+	{"timestamp",      "Timestamp",            TCPOPT_TIMESTAMP},
+	{"md5",            "MD5 signature",        TCPOPT_MD5SIG},
+	{NULL},
+};
+
+static void tcpoptstrip_tg_help(void)
+{
+	const struct tcp_optionmap *w;
+
+	printf(
+"TCPOPTSTRIP target options:\n"
+"  --strip-options value     strip specified TCP options denoted by value\n"
+"                            (separated by comma) from TCP header\n"
+"  Instead of the numeric value, you can also use the following names:\n"
+	);
+
+	for (w = tcp_optionmap; w->name != NULL; ++w)
+		printf("    %-14s    strip \"%s\" option\n", w->name, w->desc);
+}
+
+static void tcpoptstrip_tg_init(struct xt_entry_target *t)
+{
+	struct xt_tcpoptstrip_target_info *info = (void *)t->data;
+
+	/* strictly necessary? play safe for now. */
+	memset(info->strip_bmap, 0, sizeof(info->strip_bmap));
+}
+
+static void parse_list(struct xt_tcpoptstrip_target_info *info, char *arg)
+{
+	unsigned int option;
+	char *p;
+	int i;
+
+	while (true) {
+		p = strchr(arg, ',');
+		if (p != NULL)
+			*p = '\0';
+
+		option = 0;
+		for (i = 0; tcp_optionmap[i].name != NULL; ++i)
+			if (strcmp(tcp_optionmap[i].name, arg) == 0) {
+				option = tcp_optionmap[i].option;
+				break;
+			}
+
+		if (option == 0 && string_to_number(arg, 0, 255, &option) == -1)
+			exit_error(PARAMETER_PROBLEM,
+			           "Bad TCP option value \"%s\"", arg);
+
+		if (option < 2)
+			exit_error(PARAMETER_PROBLEM,
+			           "Option value may not be 0 or 1");
+
+		if (tcpoptstrip_test_bit(info->strip_bmap, option))
+			exit_error(PARAMETER_PROBLEM,
+			           "Option \"%s\" already specified", arg);
+
+		tcpoptstrip_set_bit(info->strip_bmap, option);
+		if (p == NULL)
+			break;
+		arg = p + 1;
+	}
+}
+
+static int tcpoptstrip_tg_parse(int c, char **argv, int invert,
+                                unsigned int *flags, const void *entry,
+                                struct xt_entry_target **target)
+{
+	struct xt_tcpoptstrip_target_info *info = (void *)(*target)->data;
+
+	switch (c) {
+	case 's':
+		if (*flags & FLAG_STRIP)
+			exit_error(PARAMETER_PROBLEM,
+			           "You can specify --strip-options only once");
+		parse_list(info, optarg);
+		*flags |= FLAG_STRIP;
+		return true;
+	}
+
+	return false;
+}
+
+static void tcpoptstrip_tg_check(unsigned int flags)
+{
+	if (flags == 0)
+		exit_error(PARAMETER_PROBLEM,
+		           "TCPOPTSTRIP: --strip-options parameter required");
+}
+
+static void
+tcpoptstrip_print_list(const struct xt_tcpoptstrip_target_info *info,
+                       bool numeric)
+{
+	unsigned int i, j;
+	const char *name;
+	bool first = true;
+
+	for (i = 0; i < 256; ++i) {
+		if (!tcpoptstrip_test_bit(info->strip_bmap, i))
+			continue;
+		if (!first)
+			printf(",");
+
+		first = false;
+		name  = NULL;
+		if (!numeric)
+			for (j = 0; tcp_optionmap[j].name != NULL; ++j)
+				if (tcp_optionmap[j].option == i)
+					name = tcp_optionmap[j].name;
+
+		if (name != NULL)
+			printf("%s", name);
+		else
+			printf("%u", i);
+	}
+}
+
+static void
+tcpoptstrip_tg_print(const void *ip, const struct xt_entry_target *target,
+                     int numeric)
+{
+	const struct xt_tcpoptstrip_target_info *info =
+		(const void *)target->data;
+
+	printf("TCPOPTSTRIP options ");
+	tcpoptstrip_print_list(info, numeric);
+}
+
+static void
+tcpoptstrip_tg_save(const void *ip, const struct xt_entry_target *target)
+{
+	const struct xt_tcpoptstrip_target_info *info =
+		(const void *)target->data;
+
+	printf("--strip-options ");
+	tcpoptstrip_print_list(info, true);
+}
+
+static struct xtables_target tcpoptstrip_tg_reg = {
+	.name          = "TCPOPTSTRIP",
+	.family        = AF_INET,
+	.version       = IPTABLES_VERSION,
+	.size          = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
+	.userspacesize = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
+	.help          = tcpoptstrip_tg_help,
+	.init          = tcpoptstrip_tg_init,
+	.parse         = tcpoptstrip_tg_parse,
+	.final_check   = tcpoptstrip_tg_check,
+	.print         = tcpoptstrip_tg_print,
+	.save          = tcpoptstrip_tg_save,
+	.extra_opts    = tcpoptstrip_tg_opts,
+};
+
+static struct xtables_target tcpoptstrip_tg6_reg = {
+	.name          = "TCPOPTSTRIP",
+	.family        = AF_INET6,
+	.version       = IPTABLES_VERSION,
+	.size          = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
+	.userspacesize = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
+	.help          = tcpoptstrip_tg_help,
+	.init          = tcpoptstrip_tg_init,
+	.parse         = tcpoptstrip_tg_parse,
+	.final_check   = tcpoptstrip_tg_check,
+	.print         = tcpoptstrip_tg_print,
+	.save          = tcpoptstrip_tg_save,
+	.extra_opts    = tcpoptstrip_tg_opts,
+};
+
+void _init(void)
+{
+	xtables_register_target(&tcpoptstrip_tg_reg);
+	xtables_register_target(&tcpoptstrip_tg6_reg);
+}
Index: iptables-modules/extensions/libxt_TCPOPTSTRIP.man
===================================================================
--- /dev/null
+++ iptables-modules/extensions/libxt_TCPOPTSTRIP.man
@@ -0,0 +1,7 @@
+This target will strip TCP options off a TCP packet. (It will actually replace
+them by NO-OPs.) As such, you will need to add the \fB-p tcp\fR parameters.
+.TP
+\fB--strip-options\fR \fIoption\fR[\fB,\fR\fI...\fR]
+Strip the given option(s). The options may be specified by TCP option number or
+by symbolic name. The list of recognized options can be obtained by calling
+iptables with \fB-j TCPOPTSTRIP -h\fR.
Index: iptables-modules/include/linux/netfilter/xt_TCPOPTSTRIP.h
===================================================================
--- /dev/null
+++ iptables-modules/include/linux/netfilter/xt_TCPOPTSTRIP.h
@@ -0,0 +1,13 @@
+#ifndef _XT_TCPOPTSTRIP_H
+#define _XT_TCPOPTSTRIP_H
+
+#define tcpoptstrip_set_bit(bmap, idx) \
+	(bmap[(idx) >> 5] |= 1UL << (idx & 31))
+#define tcpoptstrip_test_bit(bmap, idx) \
+	(((1UL << (idx & 31)) & bmap[(idx) >> 5]) != 0)
+
+struct xt_tcpoptstrip_target_info {
+	u_int32_t strip_bmap[8];
+};
+
+#endif /* _XT_TCPOPTSTRIP_H */
-
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] 35+ messages in thread

* IPT [PATCH 4/4] libxt_gateway
  2007-11-25 19:07 ` IPT [PATCH 1/4] libxt_owner Jan Engelhardt
  2007-11-25 19:08   ` IPT [PATCH 2/4] libxt_TEE Jan Engelhardt
  2007-11-25 19:08   ` IPT [PATCH 3/4] libxt_TCPOPTSTRIP Jan Engelhardt
@ 2007-11-25 19:08   ` Jan Engelhardt
  2 siblings, 0 replies; 35+ messages in thread
From: Jan Engelhardt @ 2007-11-25 19:08 UTC (permalink / raw)
  To: kaber; +Cc: Netfilter Developer Mailing List, azez


Import libxt_gateway into iptables

Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
Cc: <azez@ufomechanic.net>

---
 extensions/Makefile                  |    2 
 extensions/libxt_gateway.c           |  161 +++++++++++++++++++++++++++++++++++
 extensions/libxt_gateway.man         |    9 +
 include/linux/netfilter/xt_gateway.h |   19 ++++
 4 files changed, 190 insertions(+), 1 deletion(-)

Index: iptables-modules/extensions/Makefile
===================================================================
--- iptables-modules.orig/extensions/Makefile
+++ iptables-modules/extensions/Makefile
@@ -7,7 +7,7 @@
 #
 PF_EXT_SLIB:=ah addrtype conntrack ecn icmp iprange policy realm recent tos ttl unclean CLUSTERIP DNAT ECN LOG MASQUERADE MIRROR NETMAP REDIRECT REJECT SAME SNAT TOS TTL ULOG
 PF6_EXT_SLIB:=ah dst eui64 frag hbh hl icmp6 ipv6header mh policy rt HL LOG REJECT
-PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport owner physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TEE TCPOPTSTRIP TRACE
+PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp gateway hashlimit helper length limit mac mark multiport owner physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TEE TCPOPTSTRIP TRACE
 
 PF_EXT_SELINUX_SLIB:=
 PF6_EXT_SELINUX_SLIB:=
Index: iptables-modules/extensions/libxt_gateway.c
===================================================================
--- /dev/null
+++ iptables-modules/extensions/libxt_gateway.c
@@ -0,0 +1,161 @@
+/*
+ * Shared library add-on to iptables to add gateway IP address matching support.
+ * Based on iprange.
+ * Copyright (C) UFO Mechanic <azez@ufomechanic.net>
+ * Copyright © CC Computer Consultants GmbH, 2007
+ * Contact: Jan Engelhardt <jengelh@computergmbh.de>
+ */
+#include <sys/types.h>
+#include <getopt.h>
+#include <netdb.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <xtables.h>
+#include <iptables.h>
+#include <linux/netfilter/xt_gateway.h>
+
+enum {
+	FLAG_GATEWAY = 1 << 0,
+	FLAG_NEXTHOP = 1 << 1,
+};
+
+static const struct option gateway_mt_opts[] = {
+	{.name = "gateway", .has_arg = true, .val = 'g'},
+	{.name = "nexthop", .has_arg = true, .val = 'n'},
+	{},
+};
+
+static void gateway_mt_help(void)
+{
+	printf(
+		"gateway match v%s options:\n"
+		"[!] --gateway ip        Match IP address of routed gateway\n"
+		"[!] --nexthop ip        Match IP address of next hop\n"
+		"\n",
+		IPTABLES_VERSION);
+}
+
+static int gateway_mt_parse(int c, char **argv, int invert,
+                            unsigned int *flags, const void *entry,
+                            struct xt_entry_match **match)
+{
+	struct xt_gateway_match_info *info = (void *)(*match)->data;
+	struct in_addr *ip;
+
+	switch (c) {
+	case 'g':
+		if (*flags & FLAG_GATEWAY)
+			exit_error(PARAMETER_PROBLEM, "gateway match: Cannot"
+			           "specify --gateway more than once");
+		if (*flags & FLAG_NEXTHOP)
+			exit_error(PARAMETER_PROBLEM, "gateway match: You "
+			           "cannot specify both --gateway and "
+			           "--nexthop");
+
+		check_inverse(optarg, &invert, &optind, 0);
+		if (invert)
+			info->flags |= XT_GATEWAY_INVERT;
+
+		ip = dotted_to_addr(optarg);
+		if (ip == NULL)
+			exit_error(PARAMETER_PROBLEM, "gateway match: Bad IP "
+			           "address \"%s\"\n", optarg);
+
+		info->gateway_v4 = ip->s_addr;
+		info->flags |= XT_GATEWAY_ROUTE;
+		*flags |= FLAG_GATEWAY;
+		return true;
+
+	case 'n':
+		if (*flags & FLAG_NEXTHOP)
+			exit_error(PARAMETER_PROBLEM, "gateway match: Cannot"
+			           "specify --nexthop more than once");
+		if (*flags & FLAG_GATEWAY)
+			exit_error(PARAMETER_PROBLEM, "gateway match: You "
+			           "cannot specify both --gateway and "
+			           "--nexthop");
+
+		check_inverse(optarg, &invert, &optind, 0);
+		if (invert)
+			info->flags |= XT_GATEWAY_INVERT;
+
+		ip = dotted_to_addr(optarg);
+		if (ip == NULL)
+			exit_error(PARAMETER_PROBLEM, "gateway match: Bad IP "
+			           "address \"%s|'\n", optarg);
+
+		info->gateway_v4 = ip->s_addr;
+		info->flags &= ~XT_GATEWAY_ROUTE;
+		*flags |= FLAG_NEXTHOP;
+		return true;
+	}
+
+	return false;
+}
+
+static void gateway_mt_check(unsigned int flags)
+{
+	if (flags == 0)
+		exit_error(PARAMETER_PROBLEM, "gateway match: --gateway or "
+		           "--nexthop parameter required");
+}
+
+static void
+gateway_mt_print(const void *ip, const struct xt_entry_match *match,
+                 int numeric)
+{
+	const struct xt_gateway_match_info *info = (const void *)match->data;
+	struct in_addr a;
+
+	a.s_addr = info->gateway_v4;
+
+	if (info->flags & XT_GATEWAY_ROUTE)
+		printf("gateway ");
+	else
+		printf("nexthop ");
+
+	if (info->flags & XT_GATEWAY_INVERT)
+		printf("! ");
+
+	printf("%s", addr_to_dotted(&a));
+}
+
+static void gateway_mt_save(const void *ip, const struct xt_entry_match *match)
+{
+	const struct xt_gateway_match_info *info = (const void *)match->data;
+	struct in_addr a;
+
+	a.s_addr = info->gateway_v4;
+
+	if (info->flags & XT_GATEWAY_INVERT)
+		printf("! ");
+
+	if (info->flags & XT_GATEWAY_ROUTE)
+		printf("--gateway ");
+	else
+		printf("--nexthop ");
+
+	printf("%s ", addr_to_dotted(&a));
+}
+
+static struct xtables_match gateway_mt_reg = {
+	.name		= "gateway",
+	.family         = AF_INET,
+	.version	= IPTABLES_VERSION,
+	.size		= XT_ALIGN(sizeof(struct xt_gateway_match_info)),
+	.userspacesize	= XT_ALIGN(sizeof(struct xt_gateway_match_info)),
+	.help		= gateway_mt_help,
+	.parse		= gateway_mt_parse,
+	.final_check	= gateway_mt_check,
+	.print		= gateway_mt_print,
+	.save		= gateway_mt_save,
+	.extra_opts	= gateway_mt_opts,
+};
+
+void _init(void)
+{
+	xtables_register_match(&gateway_mt_reg);
+}
Index: iptables-modules/extensions/libxt_gateway.man
===================================================================
--- /dev/null
+++ iptables-modules/extensions/libxt_gateway.man
@@ -0,0 +1,9 @@
+This matches the gateway by IP address on routed packets. It does not mach
+packets that are not routed, or which are directly addresses to the gateway.
+.TP
+[\fB!\fR] \fB--gateway\fR \fIaddress\fR
+Matches if the packet is routed to a gateway with the specified IP address.
+.TP
+[\fB!\fR] \fB--nexthop\fR \fIaddress\fR
+Matches if the packet is being directed to the specified IP address
+either directly or as a route.
Index: iptables-modules/include/linux/netfilter/xt_gateway.h
===================================================================
--- /dev/null
+++ iptables-modules/include/linux/netfilter/xt_gateway.h
@@ -0,0 +1,19 @@
+#ifndef _XT_GATEWAY_H
+#define _XT_GATEWAY_H
+
+enum {
+	/* Negate the condition */
+	XT_GATEWAY_INVERT = 1 << 0,
+	/* and the gateway is not the final hop */
+	XT_GATEWAY_ROUTE  = 1 << 1,
+};
+
+struct xt_gateway_match_info {
+	union {
+		__be32 gateway_v4;
+		__be32 gateway_v6[4];
+	};
+	u_int8_t flags;
+};
+
+#endif /* _XT_GATEWAY_H */
-
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] 35+ messages in thread

* Re: NF [PATCH 2/4] xt_TEE
  2007-11-25 19:06 ` NF [PATCH 2/4] xt_TEE Jan Engelhardt
@ 2007-11-25 19:39   ` Krzysztof Oledzki
  2007-11-25 19:55     ` Jan Engelhardt
  2007-11-26  7:24   ` Patrick McHardy
  1 sibling, 1 reply; 35+ messages in thread
From: Krzysztof Oledzki @ 2007-11-25 19:39 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: kaber, Netfilter Developer Mailing List, Sebastian Classen

[-- Attachment #1: Type: TEXT/PLAIN, Size: 633 bytes --]



On Sun, 25 Nov 2007, Jan Engelhardt wrote:

>
> Netfilter: Import xt_TEE
>
>
> Originally from Sebastian Classen.
> xt_TEE is the logical successor to ipt_ROUTE; routing based on packet
> charactersitics is done using xt_MARK/iproute2/fwmark nowadays, so
> what remains of ipt_ROUTE is the --tee option, which xt_TEE implements.

IMHO it is not successor as it does not provide all ipt_ROUTE 
functionality. As I appreciate your work and time spent on cleaning this 
code I think it would be better not to strip it as xt_MARK/iproute2/fwmark 
is not always a valid option.

Best regards,

 				Krzysztof Olędzki

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

* Re: NF [PATCH 2/4] xt_TEE
  2007-11-25 19:39   ` Krzysztof Oledzki
@ 2007-11-25 19:55     ` Jan Engelhardt
  2007-11-25 20:22       ` Krzysztof Oledzki
  0 siblings, 1 reply; 35+ messages in thread
From: Jan Engelhardt @ 2007-11-25 19:55 UTC (permalink / raw)
  To: Krzysztof Oledzki
  Cc: kaber, Netfilter Developer Mailing List, Sebastian Classen


On Nov 25 2007 20:39, Krzysztof Oledzki wrote:
> On Sun, 25 Nov 2007, Jan Engelhardt wrote:
>> Netfilter: Import xt_TEE
>>
>>
>> Originally from Sebastian Classen.
>> xt_TEE is the logical successor to ipt_ROUTE; routing based on packet
>> charactersitics is done using xt_MARK/iproute2/fwmark nowadays, so
>> what remains of ipt_ROUTE is the --tee option, which xt_TEE implements.
>
> IMHO it is not successor as it does not provide all ipt_ROUTE functionality. As
> I appreciate your work and time spent on cleaning this code I think it would be
> better not to strip it as xt_MARK/iproute2/fwmark is not always a valid option.

We've been there -
http://www.gossamer-threads.com/lists/engine?do=post_view_printable;post=68316;list=iptables

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

* Re: NF [PATCH 2/4] xt_TEE
  2007-11-25 19:55     ` Jan Engelhardt
@ 2007-11-25 20:22       ` Krzysztof Oledzki
  0 siblings, 0 replies; 35+ messages in thread
From: Krzysztof Oledzki @ 2007-11-25 20:22 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: kaber, Netfilter Developer Mailing List, Sebastian Classen

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1258 bytes --]



On Sun, 25 Nov 2007, Jan Engelhardt wrote:

>
> On Nov 25 2007 20:39, Krzysztof Oledzki wrote:
>> On Sun, 25 Nov 2007, Jan Engelhardt wrote:
>>> Netfilter: Import xt_TEE
>>>
>>>
>>> Originally from Sebastian Classen.
>>> xt_TEE is the logical successor to ipt_ROUTE; routing based on packet
>>> charactersitics is done using xt_MARK/iproute2/fwmark nowadays, so
>>> what remains of ipt_ROUTE is the --tee option, which xt_TEE implements.
>>
>> IMHO it is not successor as it does not provide all ipt_ROUTE functionality. As
>> I appreciate your work and time spent on cleaning this code I think it would be
>> better not to strip it as xt_MARK/iproute2/fwmark is not always a valid option.
>
> We've been there -
> http://www.gossamer-threads.com/lists/engine?do=post_view_printable;post=68316;list=iptables

Exactly. But still, it is not a successor but rather a substitute with a 
stripped functionality. I wish I haven't been so busy with other tasks 
lately to do it myself, but I really think that a cleaned xt_ROUTE 
extension is not going to bite. We can even add a config option to only 
allow --tee by default, so no one will use --gw if xt_MARK/iproute2/fwmark 
works for him.

Best regards,

 				Krzysztof Olędzki

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

* Re: NF [PATCH 1/4] xt_owner
  2007-11-25 19:05 NF [PATCH 1/4] xt_owner Jan Engelhardt
                   ` (3 preceding siblings ...)
  2007-11-25 19:07 ` IPT [PATCH 1/4] libxt_owner Jan Engelhardt
@ 2007-11-26  7:12 ` Patrick McHardy
  4 siblings, 0 replies; 35+ messages in thread
From: Patrick McHardy @ 2007-11-26  7:12 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List

Jan Engelhardt wrote:
> Netfilter: Import xt_owner
> 
> 
> xt_owner merges ipt_owner and ip6t_owner, and adds a flag to match
> on socket (non-)existence.


Applied, thanks Jan.

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

* Re: NF [PATCH 2/4] xt_TEE
  2007-11-25 19:06 ` NF [PATCH 2/4] xt_TEE Jan Engelhardt
  2007-11-25 19:39   ` Krzysztof Oledzki
@ 2007-11-26  7:24   ` Patrick McHardy
  2007-11-26 20:14     ` Jan Engelhardt
  1 sibling, 1 reply; 35+ messages in thread
From: Patrick McHardy @ 2007-11-26  7:24 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List, Sebastian Classen

Jan Engelhardt wrote:
> Netfilter: Import xt_TEE
> 
> 
> Originally from Sebastian Classen.
> xt_TEE is the logical successor to ipt_ROUTE; routing based on packet
> charactersitics is done using xt_MARK/iproute2/fwmark nowadays, so
> what remains of ipt_ROUTE is the --tee option, which xt_TEE implements.

This still has the same problems I've been mentioning
every time this or ROUTE has come up, which is missing
IPsec support, duplication of the IP output path and
lots of unnecessary cruft.

> Index: linux-2.6/include/linux/netfilter/xt_TEE.h
> ===================================================================
> --- /dev/null
> +++ linux-2.6/include/linux/netfilter/xt_TEE.h
> @@ -0,0 +1,12 @@
> +#ifndef _XT_TEE_TARGET_H
> +#define _XT_TEE_TARGET_H
> +
> +struct xt_tee_target_info {
> +	union {
> +		/* Address of gateway */
> +		u_int32_t gateway_v4;
> +		u_int32_t gateway_v6[4];

These should be __be32 or simply use in_addr/in6_addr.
At some point it would be good to have a nf_inet_addr
type (or something net/-wide) so we don't have to
introduce more and more of these.

> +static bool tee_routing(struct sk_buff *skb,
> +                        const struct xt_tee_target_info *info)
> +{
> +	int err;
> +	struct rtable *rt;
> +	struct iphdr *iph = ip_hdr(skb);
> +	struct flowi fl = {
> +		.nl_u = {
> +			.ip4_u = {
> +				.daddr = iph->daddr,
> +				.tos   = RT_TOS(iph->tos),
> +				.scope = RT_SCOPE_UNIVERSE,

Needs to initialize fl.proto for IPsec.

> +			}
> +		}
> +	};
> +
> +	/* The destination address may be overloaded by the target */
> +	if (info->gateway_v4 != 0)
> +		fl.fl4_dst = info->gateway_v4;
> +
> +	/* Trying to route the packet using the standard routing table. */
> +	err = ip_route_output_key(&rt, &fl);
> +	if (err != 0) {
> +		if (net_ratelimit())
> +			pr_debug(KBUILD_MODNAME
> +			         ": could not route packet (%d)", err);

No need to log this IMO. Not being able to route a packet
is a quite normal condition.

> +		return false;
> +	}
> +
> +	/* Drop old route. */
> +	dst_release(skb->dst);
> +	skb->dst = NULL;
> +
> +	/*
> +	 * Success if no oif specified or if the oif correspond to the
> +	 * one desired.
> +	 * [SC]: always the case, because we have no oif.
> +	 */
> +	skb->dst      = &rt->u.dst;
> +	skb->dev      = skb->dst->dev;
> +	skb->protocol = htons(ETH_P_IP);
> +	return true;
> +}
> +
> +/*
> + * Stolen from ip_finish_output2
> + * PRE : skb->dev is set to the device we are leaving by
> + *       skb->dst is not NULL
> + * POST: the packet is sent with the link layer header pushed
> + *       the packet is destroyed
> + */
> +static void tee_ip_direct_send(struct sk_buff *skb)
> +{

Why is this function needed? dst_output should do fine.

> +}
> +
> +/*
> + * To detect and deter routed packet loopback when using the --tee option, we
> + * take a page out of the raw.patch book: on the copied skb, we set up a fake
> + * ->nfct entry, pointing to the local &route_tee_track. We skip routing
> + * packets when we see they already have that ->nfct.
> + */
> +static unsigned int
> +tee_tg(struct sk_buff *skb, const struct net_device *in,
> +       const struct net_device *out, unsigned int hooknum,
> +       const struct xt_target *target, const void *targinfo)
> +{
> +	const struct xt_tee_target_info *info = targinfo;
> +
> +#ifdef WITH_CONNTRACK
> +	if (skb->nfct == &tee_track.ct_general) {
> +		/*
> +		 * Loopback - a packet we already routed, is to be
> +		 * routed another time. Avoid that, now.
> +		 */
> +		if (net_ratelimit())
> +			pr_debug(KBUILD_MODNAME "loopback - DROP!\n");
> +		return NF_DROP;
> +	}
> +#endif
> +
> +	/*
> +	 * If we are in INPUT, the checksum must be recalculated since
> +	 * the length could have changed as a result of defragmentation.
> +	 */
> +	if (hooknum == NF_INET_LOCAL_IN) {
> +		struct iphdr *iph = ip_hdr(skb);
> +		iph->check = 0;
> +		iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);

ip_send_check(). This is actually only needed without conntrack
since it already recalculates the checksum when defragmenting.

> +	}
> +
> +	/*
> +	 * Copy the skb, and route the copy. Will later return %XT_CONTINUE for
> +	 * the original skb, which should continue on its way as if nothing has
> +	 * happened. The copy should be independantly delivered to the TEE --gw.
> +	 */
> +	skb = skb_copy(skb, GFP_ATOMIC);
> +	if (skb == NULL) {
> +		if (net_ratelimit())
> +			pr_debug(KBUILD_MODNAME "copy failed!\n");
> +		return XT_CONTINUE;
> +	}

You have to do this before modifying the packets data. And no
logging for failed memory allocations please.

> +
> +#ifdef WITH_CONNTRACK
> +	/*
> +	 * Tell conntrack to forget this packet since it may get confused
> +	 * when a packet is leaving with dst address == our address.
> +	 * Good idea? Dunno. Need advice.
> +	 *
> +	 * NEW: mark the skb with our &tee_track, so we avoid looping
> +	 * on any already routed packet.
> +	 */
> +	nf_conntrack_put(skb->nfct);
> +	skb->nfct     = &tee_track.ct_general;
> +	skb->nfctinfo = IP_CT_NEW;
> +	nf_conntrack_get(skb->nfct);
> +#endif
> +
> +	if (info->gateway_v4 != 0) {
> +		if (tee_routing(skb, info))
> +			tee_ip_direct_send(skb);
> +	} else {
> +		if (net_ratelimit())
> +			pr_debug(KBUILD_MODNAME ": no parameter!\n");
> +	}

Seems to leak new packet in all but the successful case.

> +
> +	return XT_CONTINUE;
> +}
> +
> +static struct xt_target tee_tg_reg __read_mostly = {
> +	.name       = "TEE",
> +	.family     = AF_INET,
> +	.table      = "mangle",
> +	.target     = tee_tg,
> +	.targetsize = sizeof(struct xt_tee_target_info),
> +	.me         = THIS_MODULE,
> +};
> +
> +static int __init tee_tg_init(void)
> +{
> +#ifdef WITH_CONNTRACK
> +	/*
> +	 * Set up fake conntrack (stolen from raw.patch):
> +	 * - to never be deleted, not in any hashes
> +	 */
> +	atomic_set(&tee_track.ct_general.use, 1);
> +
> +	/* - and look it like as a confirmed connection */
> +	set_bit(IPS_CONFIRMED_BIT, &tee_track.status);
> +
> +	/* Initialize fake conntrack so that NAT will skip it */
> +	tee_track.status |= IPS_NAT_DONE_MASK;
> +#endif
> +
> +	return xt_register_target(&tee_tg_reg);
> +}
> +
> +static void __exit tee_tg_exit(void)
> +{
> +	xt_unregister_target(&tee_tg_reg);
> +	/* [SC]: shoud not we cleanup tee_track here? */

No, but you need to wait until all references to it
are gone.

> +}
> +
> +module_init(tee_tg_init);
> +module_exit(tee_tg_exit);
> +MODULE_AUTHOR("Sebastian Classen <sebastian.classen@freenet.ag>, Jan Engelhardt <jengelh@computergmbh.de>");
> +MODULE_DESCRIPTION("netfilter \"TEE\" target module");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("ipt_TEE");
> 


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

* Re: NF [PATCH 3/4] xt_TCPOPTSTRIP
  2007-11-25 19:06 ` NF [PATCH 3/4] xt_TCPOPTSTRIP Jan Engelhardt
@ 2007-11-26  7:24   ` Patrick McHardy
  2007-11-26 16:19     ` Jan Engelhardt
  0 siblings, 1 reply; 35+ messages in thread
From: Patrick McHardy @ 2007-11-26  7:24 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List, Sven Schnelle

Jan Engelhardt wrote:
> Netfilter: Import xt_TCPOPTSTRIP
> 
> 
> Originally from Sven Schnelle.
> xt_TCPOPTSTRIP can strip TCP options from TCP packets, for example,
> to disable Selective ACK or Window scaling.


I already have this queued. Will push upstream soon so you
can work against the current tree.

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

* Re: NF [PATCH 4/4] xt_gateway
  2007-11-25 19:07 ` NF [PATCH 4/4] xt_gateway Jan Engelhardt
@ 2007-11-26  7:30   ` Patrick McHardy
  2007-11-26  9:17     ` Amin Azez
  0 siblings, 1 reply; 35+ messages in thread
From: Patrick McHardy @ 2007-11-26  7:30 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List, azez

Jan Engelhardt wrote:
> Netfilter: Import xt_gateway
> 
> 
> Originally from <azez@ufomechanic.net>,
> http://lists.netfilter.org/pipermail/netfilter-devel/2007-June/027954.html
> 
> This adds a gateway match to iptables that lets you match against the
> routed ipv4 gateway, it is very useful for SNAT if you want to avoid
> replicating your routing in your SNAT table.
> 
> e.g.
> 
> 	iptables -t nat -A POSTROUTING -m gateway --nexthop \
> 		172.16.1.1 -j SNAT --to-address 172.16.1.5
> 	iptables -t nat -A POSTROUTING -m gateway --nexthop \
> 		192.168.1.1 -j SNAT --to-address 192.168.1.25
> 
> to help you choose the right SNAT address.


I think MASQUERADE with properly set source addresses for
the routes should do the same since we already use the
gateway for the lookup.

What advantages does this offer over using realms?

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

* Re: NF [PATCH 4/4] xt_gateway
  2007-11-26  7:30   ` Patrick McHardy
@ 2007-11-26  9:17     ` Amin Azez
  2007-11-26 15:35       ` Patrick McHardy
  0 siblings, 1 reply; 35+ messages in thread
From: Amin Azez @ 2007-11-26  9:17 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Jan Engelhardt, Netfilter Developer Mailing List

* Patrick McHardy wrote, On 26/11/07 07:30:
> Jan Engelhardt wrote:
>> Netfilter: Import xt_gateway
>>
>>
>> Originally from <azez@ufomechanic.net>,
>> http://lists.netfilter.org/pipermail/netfilter-devel/2007-June/027954.html
>>
>>
>> This adds a gateway match to iptables that lets you match against the
>> routed ipv4 gateway, it is very useful for SNAT if you want to avoid
>> replicating your routing in your SNAT table.
>>
>> e.g.
>>
>>     iptables -t nat -A POSTROUTING -m gateway --nexthop \
>>         172.16.1.1 -j SNAT --to-address 172.16.1.5
>>     iptables -t nat -A POSTROUTING -m gateway --nexthop \
>>         192.168.1.1 -j SNAT --to-address 192.168.1.25
>>
>> to help you choose the right SNAT address.
>
> I think MASQUERADE with properly set source addresses for
> the routes should do the same since we already use the
> gateway for the lookup.
>
> What advantages does this offer over using realms?
>From my point of view, the advantage is that you don't have to use realms.

Also, the match isn't REALLY strongly related to routing, which nexthop
suggests, it's really a dest-mac match but where the mac address is
resolved by IP each time from the neighbour table; so it's also useful
against layer 3 bridges as well, where the bridge hardware is out of
your control (may change) but it has the same IP address; e.g. some
hotspots. Realms can't do that AFAIK;

Sam

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

* Re: NF [PATCH 4/4] xt_gateway
  2007-11-26  9:17     ` Amin Azez
@ 2007-11-26 15:35       ` Patrick McHardy
  2007-11-26 16:34         ` Amin Azez
  0 siblings, 1 reply; 35+ messages in thread
From: Patrick McHardy @ 2007-11-26 15:35 UTC (permalink / raw)
  To: Amin Azez; +Cc: Jan Engelhardt, Netfilter Developer Mailing List

Amin Azez wrote:
> * Patrick McHardy wrote, On 26/11/07 07:30:
>
>> What advantages does this offer over using realms?
 >
>>From my point of view, the advantage is that you don't have to use realms.
> 
> Also, the match isn't REALLY strongly related to routing, which nexthop
> suggests, it's really a dest-mac match but where the mac address is
> resolved by IP each time from the neighbour table; so it's also useful
> against layer 3 bridges as well, where the bridge hardware is out of
> your control (may change) but it has the same IP address; e.g. some
> hotspots. Realms can't do that AFAIK;


Not sure I understand - if it has an IP, its not a bridge but a
router. If its visible to routing in any way, realms can be used.

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

* Re: NF [PATCH 3/4] xt_TCPOPTSTRIP
  2007-11-26  7:24   ` Patrick McHardy
@ 2007-11-26 16:19     ` Jan Engelhardt
  2007-11-26 16:19       ` Patrick McHardy
  0 siblings, 1 reply; 35+ messages in thread
From: Jan Engelhardt @ 2007-11-26 16:19 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Netfilter Developer Mailing List, Sven Schnelle


On Nov 26 2007 08:24, Patrick McHardy wrote:
> Jan Engelhardt wrote:
>> Netfilter: Import xt_TCPOPTSTRIP
>> 
>> Originally from Sven Schnelle.
>> xt_TCPOPTSTRIP can strip TCP options from TCP packets, for example,
>> to disable Selective ACK or Window scaling.
>
> I already have this queued. Will push upstream soon so you
> can work against the current tree.
>
If you quilt/stgit, just replace the patch.

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

* Re: NF [PATCH 3/4] xt_TCPOPTSTRIP
  2007-11-26 16:19     ` Jan Engelhardt
@ 2007-11-26 16:19       ` Patrick McHardy
  2007-11-26 16:25         ` Jan Engelhardt
  0 siblings, 1 reply; 35+ messages in thread
From: Patrick McHardy @ 2007-11-26 16:19 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List, Sven Schnelle

Jan Engelhardt wrote:
> On Nov 26 2007 08:24, Patrick McHardy wrote:
>> Jan Engelhardt wrote:
>>> Netfilter: Import xt_TCPOPTSTRIP
>>>
>>> Originally from Sven Schnelle.
>>> xt_TCPOPTSTRIP can strip TCP options from TCP packets, for example,
>>> to disable Selective ACK or Window scaling.
>> I already have this queued. Will push upstream soon so you
>> can work against the current tree.
>>
> If you quilt/stgit, just replace the patch.


What are the changes?


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

* Re: NF [PATCH 3/4] xt_TCPOPTSTRIP
  2007-11-26 16:19       ` Patrick McHardy
@ 2007-11-26 16:25         ` Jan Engelhardt
  2007-11-27 12:37           ` Patrick McHardy
  0 siblings, 1 reply; 35+ messages in thread
From: Jan Engelhardt @ 2007-11-26 16:25 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Netfilter Developer Mailing List, Sven Schnelle


On Nov 26 2007 17:19, Patrick McHardy wrote:
> Jan Engelhardt wrote:
>> On Nov 26 2007 08:24, Patrick McHardy wrote:
>> > Jan Engelhardt wrote:
>> > > Netfilter: Import xt_TCPOPTSTRIP
>> > >
>> > > Originally from Sven Schnelle.
>> > > xt_TCPOPTSTRIP can strip TCP options from TCP packets, for example,
>> > > to disable Selective ACK or Window scaling.
>> > I already have this queued. Will push upstream soon so you
>> > can work against the current tree.
>> >
>> If you quilt/stgit, just replace the patch.
>
> What are the changes?
>
The name unification thing is one thing for sure. A diff would tell.
As if I know what _you_ have in your tree ;-)

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

* Re: NF [PATCH 4/4] xt_gateway
  2007-11-26 15:35       ` Patrick McHardy
@ 2007-11-26 16:34         ` Amin Azez
  2007-11-27  0:19           ` Patrick McHardy
  0 siblings, 1 reply; 35+ messages in thread
From: Amin Azez @ 2007-11-26 16:34 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Jan Engelhardt, Netfilter Developer Mailing List

* Patrick McHardy wrote, On 26/11/07 15:35:
> Amin Azez wrote:
>> * Patrick McHardy wrote, On 26/11/07 07:30:
>>
>>> What advantages does this offer over using realms?
> >
>>> From my point of view, the advantage is that you don't have to use
>>> realms.
>>
>> Also, the match isn't REALLY strongly related to routing, which nexthop
>> suggests, it's really a dest-mac match but where the mac address is
>> resolved by IP each time from the neighbour table; so it's also useful
>> against layer 3 bridges as well, where the bridge hardware is out of
>> your control (may change) but it has the same IP address; e.g. some
>> hotspots. Realms can't do that AFAIK;
>
>
> Not sure I understand - if it has an IP, its not a bridge but a
> router. If its visible to routing in any way, realms can be used.
layer 3 bridges work by mac spoofing, so it's not routing or layer 2
bridging.
And so realms can't be used.

And the whole point of (ugh) layer 3 bridges is to join network segments
without the need to scatter routing changes everywhere.

The fact that xt_gatway can cope with this where realms can't is a nice
plus on top of the fact that you don't have to define a realm for each
gateway just to be able to match it's mac address.

Another advantage is that it can be used by linux users who haven't
manually defined any routing but still make use of
/etc/sysconfig/iptables to save and restore firewall rules.
(It's a matter of opinion whether or not it is desirable to give this
facility to users who haven't gone to the labour of defining a routing
table. Maybe we don't like those sort of people).

For myself, I have xml-based routing tables (yeah I posted my code to
lartc but no-one cared) but I still prefer xt_gateway over using realms
to indicate mere snat-ability, and to save realms for something more
realm-like. Lack of return routing seems incidental to the connotations
of realm in my mind, so use of realm seems like an abuse.

Sam

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

* Re: NF [PATCH 2/4] xt_TEE
  2007-11-26  7:24   ` Patrick McHardy
@ 2007-11-26 20:14     ` Jan Engelhardt
  2007-11-27  0:12       ` Patrick McHardy
  0 siblings, 1 reply; 35+ messages in thread
From: Jan Engelhardt @ 2007-11-26 20:14 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Netfilter Developer Mailing List, Sebastian Claßen


On Nov 26 2007 08:24, Patrick McHardy wrote:
>Jan Engelhardt wrote:
>> Netfilter: Import xt_TEE
>> 
>> Originally from Sebastian Classen.
>> xt_TEE is the logical successor to ipt_ROUTE; routing based on
>> packet charactersitics is done using xt_MARK/iproute2/fwmark
>> nowadays, so what remains of ipt_ROUTE is the --tee option, which
>> xt_TEE implements.
>
> This still has the same problems I've been mentioning every time
> this or ROUTE has come up, which is missing IPsec support,
> duplication of the IP output path and lots of unnecessary cruft.
>
>> +struct xt_tee_target_info {
>> +	union {
>> +		/* Address of gateway */
>> +		u_int32_t gateway_v4;
>> +		u_int32_t gateway_v6[4];
>
> These should be __be32 or simply use in_addr/in6_addr. At some
> point it would be good to have a nf_inet_addr type (or something
> net/-wide) so we don't have to introduce more and more of these.
>
In include/net/netfilter/nf_conntrack_tuple.h there is
nf_conntrack_address, which would be perfectly suited for the task.
But I am not sure if I can use that, since it would have to be
exported to userspacce (would probably need to move the union to
include/linux/netfilter/ too). Thoughts?


>> +	/* Trying to route the packet using the standard routing table. */
>> +	err = ip_route_output_key(&rt, &fl);
>> +	if (err != 0) {
>> +		if (net_ratelimit())
>> +			pr_debug(KBUILD_MODNAME
>> +			         ": could not route packet (%d)", err);
>
> No need to log this IMO. Not being able to route a packet is a
> quite normal condition.
>
It is a pr_debug(), which is compiled out by default. But I'll
happily rip it.


>> +/*
>> + * Stolen from ip_finish_output2
>> + * PRE : skb->dev is set to the device we are leaving by
>> + *       skb->dst is not NULL
>> + * POST: the packet is sent with the link layer header pushed
>> + *       the packet is destroyed
>> + */
>> +static void tee_ip_direct_send(struct sk_buff *skb)
>> +{
>
> Why is this function needed? dst_output should do fine.
>
Could IPsec xfrmation perhaps recurse? Thinking of something like

	(iptables -F OUTPUT)
	iptables -A OUTPUT -j TEE --gw overthere

Now, if overthere leads to an xfrm tunnel, the kernel will create an ESP
packet, and also send it through OUTPUT, would not it? Then there be a
recursion if using ipsec-aware dst_output.
How valid is this thought?


>> +static void __exit tee_tg_exit(void)
>> +{
>> +	xt_unregister_target(&tee_tg_reg);
>> +	/* [SC]: shoud not we cleanup tee_track here? */
>
> No, but you need to wait until all references to it
> are gone.
>
What's the _put() function I need for it?



thanks,
Jan

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

* Re: NF [PATCH 2/4] xt_TEE
  2007-11-26 20:14     ` Jan Engelhardt
@ 2007-11-27  0:12       ` Patrick McHardy
  2007-12-05 17:24         ` nf_inet_address (was: NF [PATCH 2/4] xt_TEE) Jan Engelhardt
  0 siblings, 1 reply; 35+ messages in thread
From: Patrick McHardy @ 2007-11-27  0:12 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List, Sebastian Claßen

Jan Engelhardt wrote:
> On Nov 26 2007 08:24, Patrick McHardy wrote:
>   
>> Jan Engelhardt wrote:
>>> +struct xt_tee_target_info {
>>> +	union {
>>> +		/* Address of gateway */
>>> +		u_int32_t gateway_v4;
>>> +		u_int32_t gateway_v6[4];
>>>       
>> These should be __be32 or simply use in_addr/in6_addr. At some
>> point it would be good to have a nf_inet_addr type (or something
>> net/-wide) so we don't have to introduce more and more of these.
>>
>>     
> In include/net/netfilter/nf_conntrack_tuple.h there is
> nf_conntrack_address, which would be perfectly suited for the task.
> But I am not sure if I can use that, since it would have to be
> exported to userspacce (would probably need to move the union to
> include/linux/netfilter/ too). Thoughts?
>   

And the name doesn't really match. I'd prefer to type for all of
netfilter and then have conntrack use that one.

>
>   
>>> +	/* Trying to route the packet using the standard routing table. */
>>> +	err = ip_route_output_key(&rt, &fl);
>>> +	if (err != 0) {
>>> +		if (net_ratelimit())
>>> +			pr_debug(KBUILD_MODNAME
>>> +			         ": could not route packet (%d)", err);
>>>       
>> No need to log this IMO. Not being able to route a packet is a
>> quite normal condition.
>>
>>     
> It is a pr_debug(), which is compiled out by default. But I'll
> happily rip it.
>   

Right, I missed that. Still seems like something that should go after
debugging.

>>> +/*
>>> + * Stolen from ip_finish_output2
>>> + * PRE : skb->dev is set to the device we are leaving by
>>> + *       skb->dst is not NULL
>>> + * POST: the packet is sent with the link layer header pushed
>>> + *       the packet is destroyed
>>> + */
>>> +static void tee_ip_direct_send(struct sk_buff *skb)
>>> +{
>>>       
>> Why is this function needed? dst_output should do fine.
>>
>>     
> Could IPsec xfrmation perhaps recurse? Thinking of something like
>
> 	(iptables -F OUTPUT)
> 	iptables -A OUTPUT -j TEE --gw overthere
>
> Now, if overthere leads to an xfrm tunnel, the kernel will create an ESP
> packet, and also send it through OUTPUT, would not it? Then there be a
> recursion if using ipsec-aware dst_output.
> How valid is this thought?
>   

Packets only go through IPsec once unless the IPSKB_XFRM_TRANSFORMED
flag is cleared. You need to clear it once of course to handle already
encapsulated packets, your tee_ct should prevent further recursion,
right?

>
>   
>>> +static void __exit tee_tg_exit(void)
>>> +{
>>> +	xt_unregister_target(&tee_tg_reg);
>>> +	/* [SC]: shoud not we cleanup tee_track here? */
>>>       
>> No, but you need to wait until all references to it
>> are gone.
>>
>>     
> What's the _put() function I need for it?

None, something like for the untracked conntrack:

        /* wait until all references to nf_conntrack_untracked are 
dropped */
        while (atomic_read(&nf_conntrack_untracked.ct_general.use) > 1)
                schedule();



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

* Re: NF [PATCH 4/4] xt_gateway
  2007-11-26 16:34         ` Amin Azez
@ 2007-11-27  0:19           ` Patrick McHardy
  2007-11-27  9:33             ` Amin Azez
  0 siblings, 1 reply; 35+ messages in thread
From: Patrick McHardy @ 2007-11-27  0:19 UTC (permalink / raw)
  To: Amin Azez; +Cc: Jan Engelhardt, Netfilter Developer Mailing List

Amin Azez wrote:
> * Patrick McHardy wrote, On 26/11/07 15:35:
>> Amin Azez wrote:
>>>
>>> Also, the match isn't REALLY strongly related to routing, which nexthop
>>> suggests, it's really a dest-mac match but where the mac address is
>>> resolved by IP each time from the neighbour table; so it's also useful
>>> against layer 3 bridges as well, where the bridge hardware is out of
>>> your control (may change) but it has the same IP address; e.g. some
>>> hotspots. Realms can't do that AFAIK;
>>>       
>> Not sure I understand - if it has an IP, its not a bridge but a
>> router. If its visible to routing in any way, realms can be used.
>>     
> layer 3 bridges work by mac spoofing, so it's not routing or layer 2
> bridging.
> And so realms can't be used.
>
> And the whole point of (ugh) layer 3 bridges is to join network segments
> without the need to scatter routing changes everywhere.
>
> The fact that xt_gatway can cope with this where realms can't is a nice
> plus on top of the fact that you don't have to define a realm for each
> gateway just to be able to match it's mac address.
>   

The version Jan posted doesn't match on mac but on IP address.
So I still don't see the point. You have a route with a gateway
address, which you can match on. The fact that some MAC spoofing
is done seems irrelevant. Since you have this route, you can also
use realms. What am I missing here?

> Another advantage is that it can be used by linux users who haven't
> manually defined any routing but still make use of
> /etc/sysconfig/iptables to save and restore firewall rules.
> (It's a matter of opinion whether or not it is desirable to give this
> facility to users who haven't gone to the labour of defining a routing
> table. Maybe we don't like those sort of people).
>
> For myself, I have xml-based routing tables (yeah I posted my code to
> lartc but no-one cared) but I still prefer xt_gateway over using realms
> to indicate mere snat-ability, and to save realms for something more
> realm-like. Lack of return routing seems incidental to the connotations
> of realm in my mind, so use of realm seems like an abuse

Since we already have a crapload of stuff in the kernel, I prefer to
only add things that extend the expressiveness of iptables to things
not possible otherwise. Mere simplifications can be done in userspace
IMO.



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

* Re: NF [PATCH 4/4] xt_gateway
  2007-11-27  0:19           ` Patrick McHardy
@ 2007-11-27  9:33             ` Amin Azez
  2007-11-27 13:03               ` Patrick McHardy
  0 siblings, 1 reply; 35+ messages in thread
From: Amin Azez @ 2007-11-27  9:33 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Jan Engelhardt, Netfilter Developer Mailing List

* Patrick McHardy wrote, On 27/11/07 00:19:
>
> The version Jan posted doesn't match on mac but on IP address.
It should be refusing to match mac if the ip's do match in the --gateway
match, because if the IP matches then the host is being addressed
directly and not as a gateway.
That's why it also checks IP.

+	if (memcmp(&info->gateway_v4, &neigh->primary_key, tbl->key_len) != 0)
+		return false;

It checks mac as the primary key of the neighbour table.
> So I still don't see the point. You have a route with a gateway
> address, which you can match on. The fact that some MAC spoofing
> is done seems irrelevant. 
Take the case of a numbered layer 2 bridge. The bridged packets are not
routed by the bridge, but you might still want to snat or dnat some
certain packets to a certain gateway. I know networks that do this.
(Maybe the nat helpers are better on the bridge than on the nat-ing
router or something). Hey - thats what brouters are for.

If there is mac spoofing where you are not routing, then it helps to
identify the box doing the spoofing; and it is best to do so by IP
address which in such cases usually identifies the role.
For example, if you have a win2K box doing internet connection sharing
on an ISDN dialup to another office on the same subnet, the box doing
the sharing (which may change) will generally have the same IP address.
There is no route to that box, but the xt_gateway match still has a use
here to recognize traffic that will be going over the ISDN link and may
want to be marked for shaping.

This setup is not so contrived, I write software that goes into hardware
which is re-sold as a drop-in solution in all kinds of scenarios.
Drop-in solutions get paid for where network re-organisations will not
be considered. How nice to be able to traffic-shape and prioritize (at
last) traffic over that lowly legacy ISDN link and not have to
reconfigure when we swap the hardware.
> Since you have this route, you can also
> use realms. What am I missing here?
There may be no route, as in layer 3 bridge
The routing may not be done on a layer 2 bridge as above.
Realms are sometimes ugly.

Consider the design principles of coupling and cohesion.
In the cases where there is a route, setting a routing realm and
checking in iptables introduces a higher degree of coupling or
inter-dependance.
Also, a lower degree of cohesion; because realms do not necessarily of
themselves signify snat-ability there is low natural cohesion between
realms and snat-ability.
Awareness of both these points must be communicated a any future use of
realms must consider whether or not in each case any of the realms is
being referred to for snat.

Whether or not realms actually are or are not suitable depends on the
actual network. In a formally defined networks where realms are used,
realms may well be the best answer.
In an informally defined network where a router and it's role are
identified only by it's IP address

>
>>
>> For myself, I have xml-based routing tables (yeah I posted my code to
>> lartc but no-one cared) but I still prefer xt_gateway over using realms
>> to indicate mere snat-ability, and to save realms for something more
>> realm-like. Lack of return routing seems incidental to the connotations
>> of realm in my mind, so use of realm seems like an abuse
>
> Since we already have a crapload of stuff in the kernel, I prefer to
> only add things that extend the expressiveness of iptables to things
> not possible otherwise. Mere simplifications can be done in userspace
> IMO.
>

This mere simplification is, in user-space, (as explained above)  a
complication, and doubly so because there are no generally available
routing table manipulation tools to match iptables-save/iptables-restore.

However, I think then by your criteria above you will accept xt_gateway
because it extends the expressiveness of iptables to do things not
possible by realm (detection of gateways on a box that did not route)
and to do other things which are possible, but in (as you say) a simpler
way (albeit not in userspace), and by my judgement, a more expressive way.

I think I met your criteria.... :-)

Sam

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

* Re: NF [PATCH 3/4] xt_TCPOPTSTRIP
  2007-11-26 16:25         ` Jan Engelhardt
@ 2007-11-27 12:37           ` Patrick McHardy
  2007-11-27 14:50             ` Jan Engelhardt
  0 siblings, 1 reply; 35+ messages in thread
From: Patrick McHardy @ 2007-11-27 12:37 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List, Sven Schnelle

[-- Attachment #1: Type: text/plain, Size: 402 bytes --]

Jan Engelhardt wrote:
> On Nov 26 2007 17:19, Patrick McHardy wrote:
>   
>> Jan Engelhardt wrote:
>>     
>>> If you quilt/stgit, just replace the patch.
>>>       
>> What are the changes?
>>
>>     
> The name unification thing is one thing for sure. A diff would tell.
> As if I know what _you_ have in your tree ;-)
>   

I merged the parts that make sense. This is the patch I have queued now.



[-- Attachment #2: x --]
[-- Type: text/plain, Size: 6634 bytes --]

commit 42e4a1405a2115a5956ca3842573d1afc58f97ce
Author: Sven Schnelle <svens@bitebene.org>
Date:   Mon Nov 26 08:03:57 2007 +0100

    [NETFILTER]: x_tables: add TCPOPTSTRIP target
    
    Signed-off-by: Sven Schnelle <svens@bitebene.org>
    Signed-off-by: Jan Engelhardt <jengelh@gmx.de>
    Signed-off-by: Patrick McHardy <kaber@trash.net>

diff --git a/include/linux/netfilter/xt_TCPOPTSTRIP.h b/include/linux/netfilter/xt_TCPOPTSTRIP.h
new file mode 100644
index 0000000..2db5432
--- /dev/null
+++ b/include/linux/netfilter/xt_TCPOPTSTRIP.h
@@ -0,0 +1,13 @@
+#ifndef _XT_TCPOPTSTRIP_H
+#define _XT_TCPOPTSTRIP_H
+
+#define tcpoptstrip_set_bit(bmap, idx) \
+	(bmap[(idx) >> 5] |= 1U << (idx & 31))
+#define tcpoptstrip_test_bit(bmap, idx) \
+	(((1U << (idx & 31)) & bmap[(idx) >> 5]) != 0)
+
+struct xt_tcpoptstrip_target_info {
+	u_int32_t strip_bmap[8];
+};
+
+#endif /* _XT_TCPOPTSTRIP_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 21a9fcc..693f861 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -411,6 +411,14 @@ config NETFILTER_XT_TARGET_TCPMSS
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
+config NETFILTER_XT_TARGET_TCPOPTSTRIP
+	tristate '"TCPOPTSTRIP" target support (EXPERIMENTAL)'
+	depends on EXPERIMENTAL && NETFILTER_XTABLES
+	depends on IP_NF_MANGLE || IP6_NF_MANGLE
+	help
+	  This option adds a "TCPOPTSTRIP" target, which allows you to strip
+	  TCP options from TCP packets.
+
 config NETFILTER_XT_MATCH_COMMENT
 	tristate  '"comment" match support'
 	depends on NETFILTER_XTABLES
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index ad0e36e..7763dea 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
 
 # matches
diff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c
new file mode 100644
index 0000000..6cc5cb0
--- /dev/null
+++ b/net/netfilter/xt_TCPOPTSTRIP.c
@@ -0,0 +1,147 @@
+/*
+ * A module for stripping a specific TCP option from TCP packets.
+ *
+ * Copyright (C) 2007 Sven Schnelle <svens@bitebene.org>
+ * Copyright © CC Computer Consultants GmbH, 2007
+ * Contact: Jan Engelhardt <jengelh@computergmbh.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/tcp.h>
+#include <net/ipv6.h>
+#include <net/tcp.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_TCPOPTSTRIP.h>
+
+static inline unsigned int optlen(const u_int8_t *opt, unsigned int offset)
+{
+	/* Beware zero-length options: make finite progress */
+	if (opt[offset] <= TCPOPT_NOP || opt[offset+1] == 0)
+		return 1;
+	else
+		return opt[offset+1];
+}
+
+static unsigned int
+tcpoptstrip_mangle_packet(struct sk_buff *skb,
+                          const struct xt_tcpoptstrip_target_info *info,
+                          unsigned int tcphoff, unsigned int minlen)
+{
+	unsigned int optl, i, j;
+	struct tcphdr *tcph;
+	u_int16_t n, o;
+	u_int8_t *opt;
+
+	if (!skb_make_writable(skb, skb->len))
+		return NF_DROP;
+
+	tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
+	opt  = (u_int8_t *)tcph;
+
+	/*
+	 * Walk through all TCP options - if we find some option to remove,
+	 * set all octets to %TCPOPT_NOP and adjust checksum.
+	 */
+	for (i = sizeof(struct tcphdr); i < tcp_hdrlen(skb); i += optl) {
+		optl = optlen(opt, i);
+
+		if (i + optl > tcp_hdrlen(skb))
+			break;
+
+		if (!tcpoptstrip_test_bit(info->strip_bmap, opt[i]))
+			continue;
+
+		for (j = 0; j < optl; ++j) {
+			o = opt[i+j];
+			n = TCPOPT_NOP;
+			if ((i + j) % 2 == 0) {
+				o <<= 8;
+				n <<= 8;
+			}
+			nf_proto_csum_replace2(&tcph->check, skb, htons(o),
+			                       htons(n), 0);
+		}
+		memset(opt + i, TCPOPT_NOP, optl);
+	}
+
+	return XT_CONTINUE;
+}
+
+static unsigned int
+tcpoptstrip_tg4(struct sk_buff *skb, const struct net_device *in,
+                const struct net_device *out, unsigned int hooknum,
+                const struct xt_target *target, const void *targinfo)
+{
+	return tcpoptstrip_mangle_packet(skb, targinfo, ip_hdrlen(skb),
+	       sizeof(struct iphdr) + sizeof(struct tcphdr));
+}
+
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
+static unsigned int
+tcpoptstrip_tg6(struct sk_buff *skb, const struct net_device *in,
+                const struct net_device *out, unsigned int hooknum,
+                const struct xt_target *target, const void *targinfo)
+{
+	struct ipv6hdr *ipv6h = ipv6_hdr(skb);
+	unsigned int tcphoff;
+	u_int8_t nexthdr;
+
+	nexthdr = ipv6h->nexthdr;
+	tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr);
+	if (tcphoff < 0)
+		return NF_DROP;
+
+	return tcpoptstrip_mangle_packet(skb, targinfo, tcphoff,
+	       sizeof(*ipv6h) + sizeof(struct tcphdr));
+}
+#endif
+
+static struct xt_target tcpoptstrip_tg_reg[] __read_mostly = {
+	{
+		.name       = "TCPOPTSTRIP",
+		.family     = AF_INET,
+		.table      = "mangle",
+		.proto      = IPPROTO_TCP,
+		.target     = tcpoptstrip_tg4,
+		.targetsize = sizeof(struct xt_tcpoptstrip_target_info),
+		.me         = THIS_MODULE,
+	},
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
+	{
+		.name       = "TCPOPTSTRIP",
+		.family     = AF_INET6,
+		.table      = "mangle",
+		.proto      = IPPROTO_TCP,
+		.target     = tcpoptstrip_tg6,
+		.targetsize = sizeof(struct xt_tcpoptstrip_target_info),
+		.me         = THIS_MODULE,
+	},
+#endif
+};
+
+static int __init tcpoptstrip_tg_init(void)
+{
+	return xt_register_targets(tcpoptstrip_tg_reg,
+	       ARRAY_SIZE(tcpoptstrip_tg_reg));
+}
+
+static void __exit tcpoptstrip_tg_exit(void)
+{
+	xt_unregister_targets(tcpoptstrip_tg_reg,
+	                      ARRAY_SIZE(tcpoptstrip_tg_reg));
+}
+
+module_init(tcpoptstrip_tg_init);
+module_exit(tcpoptstrip_tg_exit);
+MODULE_AUTHOR("Sven Schnelle <svens@bitebene.org>, Jan Engelhardt <jengelh@computergmbh.de>");
+MODULE_DESCRIPTION("netfilter \"TCPOPTSTRIP\" target module");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_TCPOPTSTRIP");
+MODULE_ALIAS("ip6t_TCPOPTSTRIP");

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

* Re: NF [PATCH 4/4] xt_gateway
  2007-11-27  9:33             ` Amin Azez
@ 2007-11-27 13:03               ` Patrick McHardy
  2007-11-27 13:33                 ` Amin Azez
  0 siblings, 1 reply; 35+ messages in thread
From: Patrick McHardy @ 2007-11-27 13:03 UTC (permalink / raw)
  To: Amin Azez; +Cc: Jan Engelhardt, Netfilter Developer Mailing List

Amin Azez wrote:
> * Patrick McHardy wrote, On 27/11/07 00:19:
>> The version Jan posted doesn't match on mac but on IP address.
> It should be refusing to match mac if the ip's do match in the --gateway
> match, because if the IP matches then the host is being addressed
> directly and not as a gateway.
> That's why it also checks IP.
> 
> +	if (memcmp(&info->gateway_v4, &neigh->primary_key, tbl->key_len) != 0)
> +		return false;
> 
> It checks mac as the primary key of the neighbour table.


The primary key is the IP address.

>> So I still don't see the point. You have a route with a gateway
>> address, which you can match on. The fact that some MAC spoofing
>> is done seems irrelevant. 
> Take the case of a numbered layer 2 bridge. The bridged packets are not
> routed by the bridge, but you might still want to snat or dnat some
> certain packets to a certain gateway. I know networks that do this.
> (Maybe the nat helpers are better on the bridge than on the nat-ing
> router or something). Hey - thats what brouters are for.
> 
> If there is mac spoofing where you are not routing, then it helps to
> identify the box doing the spoofing; and it is best to do so by IP
> address which in such cases usually identifies the role.
> For example, if you have a win2K box doing internet connection sharing
> on an ISDN dialup to another office on the same subnet, the box doing
> the sharing (which may change) will generally have the same IP address.
> There is no route to that box, but the xt_gateway match still has a use
> here to recognize traffic that will be going over the ISDN link and may
> want to be marked for shaping.


I don't even see how that would work, if the box is doing mac spoofing
then you have an arp entry for every IP behind the ISDN link. So you
have the choice of adding n "gateway" rules or n destination IP rules.
In case of destination IP rules it might at least be able to use masks.

If I'm still not getting you (which might be possible since my brain is
not really up to 100% because of sickness), just make an example using
the actual rules you'd use.

>> Since we already have a crapload of stuff in the kernel, I prefer to
>> only add things that extend the expressiveness of iptables to things
>> not possible otherwise. Mere simplifications can be done in userspace
>> IMO.
>>
> 
> This mere simplification is, in user-space, (as explained above)  a
> complication, and doubly so because there are no generally available
> routing table manipulation tools to match iptables-save/iptables-restore.
> 
> However, I think then by your criteria above you will accept xt_gateway
> because it extends the expressiveness of iptables to do things not
> possible by realm (detection of gateways on a box that did not route)
> and to do other things which are possible, but in (as you say) a simpler
> way (albeit not in userspace), and by my judgement, a more expressive way.
> 
> I think I met your criteria.... :-)


Possibly, but I didn't get it :) So please explain it using an example.

A completely different issue is that the neighbour entry is created
after a packet has traversed all netfilter hooks, so you might set up
incorrect NAT mappings (in your example). How do you deal with that?

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

* Re: NF [PATCH 4/4] xt_gateway
  2007-11-27 13:03               ` Patrick McHardy
@ 2007-11-27 13:33                 ` Amin Azez
  2007-12-03 14:19                   ` Jan Engelhardt
  0 siblings, 1 reply; 35+ messages in thread
From: Amin Azez @ 2007-11-27 13:33 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Jan Engelhardt, Netfilter Developer Mailing List

* Patrick McHardy wrote, On 27/11/07 13:03:
> Amin Azez wrote:
>> * Patrick McHardy wrote, On 27/11/07 00:19:
>>> The version Jan posted doesn't match on mac but on IP address.
>> It should be refusing to match mac if the ip's do match in the --gateway
>> match, because if the IP matches then the host is being addressed
>> directly and not as a gateway.
>> That's why it also checks IP.
>>
>> +    if (memcmp(&info->gateway_v4, &neigh->primary_key, tbl->key_len)
>> != 0)
>> +        return false;
>>
>> It checks mac as the primary key of the neighbour table.
>
> The primary key is the IP address.
thats true :-) Shame!
I can't even remember code I wrote 5 months back!

So....


>
>>> So I still don't see the point. You have a route with a gateway
>>> address, which you can match on. The fact that some MAC spoofing
>>> is done seems irrelevant. 
>> Take the case of a numbered layer 2 bridge. The bridged packets are not
>> routed by the bridge, but you might still want to snat or dnat some
>> certain packets to a certain gateway. I know networks that do this.
>> (Maybe the nat helpers are better on the bridge than on the nat-ing
>> router or something). Hey - thats what brouters are for.
>>
>> If there is mac spoofing where you are not routing, then it helps to
>> identify the box doing the spoofing; and it is best to do so by IP
>> address which in such cases usually identifies the role.
>> For example, if you have a win2K box doing internet connection sharing
>> on an ISDN dialup to another office on the same subnet, the box doing
>> the sharing (which may change) will generally have the same IP address.
>> There is no route to that box, but the xt_gateway match still has a use
>> here to recognize traffic that will be going over the ISDN link and may
>> want to be marked for shaping.
>
>
> I don't even see how that would work, if the box is doing mac spoofing
> then you have an arp entry for every IP behind the ISDN link. So you
> have the choice of adding n "gateway" rules or n destination IP rules.
Based on how the code works, you are right.  As you say, there is no mac
match.
> If I'm still not getting you (which might be possible since my brain is
> not really up to 100% because of sickness), just make an example using
> the actual rules you'd use.
I am not now certain the the example cases I proposed will work as I
said, your present understanding is well grounded.

>
> A completely different issue is that the neighbour entry is created
> after a packet has traversed all netfilter hooks, so you might set up
> incorrect NAT mappings (in your example). How do you deal with that?

For my examples you are correct. For real routing the neighbor table
entry is actually the routing entry; so you deftly show that the module
as it stands only has well defined behaviour in the case where there is
a routing entry or a static arp entry.

And so unless Jan has a strong case, I think you are right that this
adds nothing extra that routing realms have, and possible causes some
surprises in some non-routing conditions.

Although I still prefer it in routing cases, I admit there is no strong
case that you should prefer it.

Thanks for persisting nicely with me!

Sam

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

* Re: NF [PATCH 3/4] xt_TCPOPTSTRIP
  2007-11-27 12:37           ` Patrick McHardy
@ 2007-11-27 14:50             ` Jan Engelhardt
  2007-11-27 15:25               ` Patrick McHardy
  0 siblings, 1 reply; 35+ messages in thread
From: Jan Engelhardt @ 2007-11-27 14:50 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Netfilter Developer Mailing List, Sven Schnelle


On Nov 27 2007 13:37, Patrick McHardy wrote:
>> >     
>> > > If you quilt/stgit, just replace the patch.
>> > >       
>> > What are the changes?
>> >     
>> The name unification thing is one thing for sure. A diff would tell.
>
> I merged the parts that make sense. This is the patch I have queued now.
>
Looks fine, thanks.
BTW, what are the criteria that cause the tcpoptstrip_tg6 to be wrapped
into a #ifdef CONFIG_IP6_NF_TABLES?

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

* Re: NF [PATCH 3/4] xt_TCPOPTSTRIP
  2007-11-27 14:50             ` Jan Engelhardt
@ 2007-11-27 15:25               ` Patrick McHardy
  0 siblings, 0 replies; 35+ messages in thread
From: Patrick McHardy @ 2007-11-27 15:25 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List, Sven Schnelle

Jan Engelhardt wrote:
> On Nov 27 2007 13:37, Patrick McHardy wrote:
>>>>     
>>>>> If you quilt/stgit, just replace the patch.
>>>>>       
>>>> What are the changes?
>>>>     
>>> The name unification thing is one thing for sure. A diff would tell.
>> I merged the parts that make sense. This is the patch I have queued now.
>>
> Looks fine, thanks.
> BTW, what are the criteria that cause the tcpoptstrip_tg6 to be wrapped
> into a #ifdef CONFIG_IP6_NF_TABLES?


Dependency on IPv6 functions. CONFIG_IP6_NF_TABLES implies CONFIG_IPV6.


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

* Re: NF [PATCH 4/4] xt_gateway
  2007-11-27 13:33                 ` Amin Azez
@ 2007-12-03 14:19                   ` Jan Engelhardt
  2007-12-03 14:23                     ` Amin Azez
  0 siblings, 1 reply; 35+ messages in thread
From: Jan Engelhardt @ 2007-12-03 14:19 UTC (permalink / raw)
  To: Amin Azez; +Cc: Patrick McHardy, Netfilter Developer Mailing List


On Nov 27 2007 13:33, Amin Azez wrote:
>>>> The version Jan posted doesn't match on mac but on IP address.
>>>
>>> It should be refusing to match mac if the ip's do match in the --gateway
>>> match, because if the IP matches then the host is being addressed
>>> directly and not as a gateway.
>>> That's why it also checks IP.
>>>
>>> +    if (memcmp(&info->gateway_v4, &neigh->primary_key, tbl->key_len) != 0)
>>> +        return false;
>>>
>>> It checks mac as the primary key of the neighbour table.
>>
>> The primary key is the IP address.
>
>thats true :-) Shame!
>I can't even remember code I wrote 5 months back!
>
>So....
>
>And so unless Jan has a strong case, I think you are right that this
>adds nothing extra that routing realms have, and possible causes some
>surprises in some non-routing conditions.
>
>Although I still prefer it in routing cases, I admit there is no strong
>case that you should prefer it.

So, does this make xt_gateway "obsolete enough" for me to drop it from
my trees?

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

* Re: NF [PATCH 4/4] xt_gateway
  2007-12-03 14:19                   ` Jan Engelhardt
@ 2007-12-03 14:23                     ` Amin Azez
  0 siblings, 0 replies; 35+ messages in thread
From: Amin Azez @ 2007-12-03 14:23 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Patrick McHardy, Netfilter Developer Mailing List

Jan Engelhardt wrote:
> On Nov 27 2007 13:33, Amin Azez wrote:
>   
>>>>> The version Jan posted doesn't match on mac but on IP address.
>>>>>           
>>>> It should be refusing to match mac if the ip's do match in the --gateway
>>>> match, because if the IP matches then the host is being addressed
>>>> directly and not as a gateway.
>>>> That's why it also checks IP.
>>>>
>>>> +    if (memcmp(&info->gateway_v4, &neigh->primary_key, tbl->key_len) != 0)
>>>> +        return false;
>>>>
>>>> It checks mac as the primary key of the neighbour table.
>>>>         
>>> The primary key is the IP address.
>>>       
>> thats true :-) Shame!
>> I can't even remember code I wrote 5 months back!
>>
>> So....
>>
>> And so unless Jan has a strong case, I think you are right that this
>> adds nothing extra that routing realms have, and possible causes some
>> surprises in some non-routing conditions.
>>
>> Although I still prefer it in routing cases, I admit there is no strong
>> case that you should prefer it.
>>     
>
> So, does this make xt_gateway "obsolete enough" for me to drop it from
> my trees?
>   

I'll still be using it. I don't think we can make a strong case for
Patrick to accept it.
Anyone with routing setup scripts can easily add realm to that.

Sam

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

* Re: nf_inet_address (was: NF [PATCH 2/4] xt_TEE)
  2007-11-27  0:12       ` Patrick McHardy
@ 2007-12-05 17:24         ` Jan Engelhardt
  2007-12-05 17:35           ` Jan Engelhardt
  0 siblings, 1 reply; 35+ messages in thread
From: Jan Engelhardt @ 2007-12-05 17:24 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Netfilter Developer Mailing List


On Nov 27 2007 01:12, Patrick McHardy wrote:
>Jan Engelhardt wrote:
>>On Nov 26 2007 08:24, Patrick McHardy wrote:
>>   
>>>Jan Engelhardt wrote:
>>>>+struct xt_tee_target_info {
>>>>+	union {
>>>>+		/* Address of gateway */
>>>>+		u_int32_t gateway_v4;
>>>>+		u_int32_t gateway_v6[4];
>>>
>>> These should be __be32 or simply use in_addr/in6_addr. At some
>>> point it would be good to have a nf_inet_addr type (or something
>>> net/-wide) so we don't have to introduce more and more of these.
>>
>> In include/net/netfilter/nf_conntrack_tuple.h there is
>> nf_conntrack_address, which would be perfectly suited for the task.
>> But I am not sure if I can use that, since it would have to be
>> exported to userspacce (would probably need to move the union to
>> include/linux/netfilter/ too). Thoughts?
>
> And the name doesn't really match. I'd prefer to type for all of
> netfilter and then have conntrack use that one.
>
About nf_inet_addr; does any userspace program depend on 
nf_conntrack_address? If so, I would have to add some #defines to remain 
compat.

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

* Re: nf_inet_address (was: NF [PATCH 2/4] xt_TEE)
  2007-12-05 17:24         ` nf_inet_address (was: NF [PATCH 2/4] xt_TEE) Jan Engelhardt
@ 2007-12-05 17:35           ` Jan Engelhardt
  2007-12-06  9:54             ` nf_inet_address Patrick McHardy
  0 siblings, 1 reply; 35+ messages in thread
From: Jan Engelhardt @ 2007-12-05 17:35 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Netfilter Developer Mailing List


On Dec 5 2007 18:24, Jan Engelhardt wrote:
>> And the name doesn't really match. I'd prefer to type for all of
>> netfilter and then have conntrack use that one.
>>
>About nf_inet_addr; does any userspace program depend on 
>nf_conntrack_address? If so, I would have to add some #defines to remain 
>compat.

Oh and also, if we can actually do that. Because if xt_FOOBAR
starts using

	struct xt_foobar_target_info {
		union nf_inet_addr blubb;
	};

we may not change nf_inet_addr beyond its current size...
I hope that is ok for this century, given it is already 128 bits.

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

* Re: nf_inet_address
  2007-12-05 17:35           ` Jan Engelhardt
@ 2007-12-06  9:54             ` Patrick McHardy
  0 siblings, 0 replies; 35+ messages in thread
From: Patrick McHardy @ 2007-12-06  9:54 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List

Jan Engelhardt wrote:
> On Dec 5 2007 18:24, Jan Engelhardt wrote:
>>> And the name doesn't really match. I'd prefer to type for all of
>>> netfilter and then have conntrack use that one.
>>>
>> About nf_inet_addr; does any userspace program depend on 
>> nf_conntrack_address? If so, I would have to add some #defines to remain 
>> compat.
> 
> Oh and also, if we can actually do that. Because if xt_FOOBAR
> starts using
> 
> 	struct xt_foobar_target_info {
> 		union nf_inet_addr blubb;
> 	};
> 
> we may not change nf_inet_addr beyond its current size...
> I hope that is ok for this century, given it is already 128 bits.


Thats seems OK.

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

end of thread, other threads:[~2007-12-06  9:54 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-11-25 19:05 NF [PATCH 1/4] xt_owner Jan Engelhardt
2007-11-25 19:06 ` NF [PATCH 2/4] xt_TEE Jan Engelhardt
2007-11-25 19:39   ` Krzysztof Oledzki
2007-11-25 19:55     ` Jan Engelhardt
2007-11-25 20:22       ` Krzysztof Oledzki
2007-11-26  7:24   ` Patrick McHardy
2007-11-26 20:14     ` Jan Engelhardt
2007-11-27  0:12       ` Patrick McHardy
2007-12-05 17:24         ` nf_inet_address (was: NF [PATCH 2/4] xt_TEE) Jan Engelhardt
2007-12-05 17:35           ` Jan Engelhardt
2007-12-06  9:54             ` nf_inet_address Patrick McHardy
2007-11-25 19:06 ` NF [PATCH 3/4] xt_TCPOPTSTRIP Jan Engelhardt
2007-11-26  7:24   ` Patrick McHardy
2007-11-26 16:19     ` Jan Engelhardt
2007-11-26 16:19       ` Patrick McHardy
2007-11-26 16:25         ` Jan Engelhardt
2007-11-27 12:37           ` Patrick McHardy
2007-11-27 14:50             ` Jan Engelhardt
2007-11-27 15:25               ` Patrick McHardy
2007-11-25 19:07 ` NF [PATCH 4/4] xt_gateway Jan Engelhardt
2007-11-26  7:30   ` Patrick McHardy
2007-11-26  9:17     ` Amin Azez
2007-11-26 15:35       ` Patrick McHardy
2007-11-26 16:34         ` Amin Azez
2007-11-27  0:19           ` Patrick McHardy
2007-11-27  9:33             ` Amin Azez
2007-11-27 13:03               ` Patrick McHardy
2007-11-27 13:33                 ` Amin Azez
2007-12-03 14:19                   ` Jan Engelhardt
2007-12-03 14:23                     ` Amin Azez
2007-11-25 19:07 ` IPT [PATCH 1/4] libxt_owner Jan Engelhardt
2007-11-25 19:08   ` IPT [PATCH 2/4] libxt_TEE Jan Engelhardt
2007-11-25 19:08   ` IPT [PATCH 3/4] libxt_TCPOPTSTRIP Jan Engelhardt
2007-11-25 19:08   ` IPT [PATCH 4/4] libxt_gateway Jan Engelhardt
2007-11-26  7:12 ` NF [PATCH 1/4] xt_owner Patrick McHardy

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