All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/11] TProxy: kick out TIME_WAIT sockets in case a new connection comes in with the same tuple
  2009-08-26 14:03 [PATCH 00/11] TProxy for IPv6 Balazs Scheidler
@ 2009-08-15  8:00 ` Balazs Scheidler
  2009-08-15 12:01 ` [PATCH 02/11] TProxy: add lookup type checks for UDP in nf_tproxy_get_sock_v4() Balazs Scheidler
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Balazs Scheidler @ 2009-08-15  8:00 UTC (permalink / raw)
  To: netfilter-devel, tproxy; +Cc: Harry Mason

Without tproxy redirections an incoming SYN kicks out conflicting
TIME_WAIT sockets, in order to handle clients that reuse ports
within the TIME_WAIT period.

The same mechanism didn't work in case TProxy is involved in finding
the proper socket, as the time_wait processing code looked up the
listening socket assuming that the listener addr/port matches those
of the established connection.

This is not the case with TProxy as the listener addr/port is possibly
changed with the tproxy rule.

Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
---
 include/net/netfilter/nf_tproxy_core.h |    6 ++++-
 net/netfilter/nf_tproxy_core.c         |   29 +++++++++++++++++++-------
 net/netfilter/xt_TPROXY.c              |   35 ++++++++++++++++++++++++++++---
 net/netfilter/xt_socket.c              |    2 +-
 4 files changed, 58 insertions(+), 14 deletions(-)

diff --git a/include/net/netfilter/nf_tproxy_core.h b/include/net/netfilter/nf_tproxy_core.h
index 208b46f..b3a8942 100644
--- a/include/net/netfilter/nf_tproxy_core.h
+++ b/include/net/netfilter/nf_tproxy_core.h
@@ -8,12 +8,16 @@
 #include <net/inet_sock.h>
 #include <net/tcp.h>
 
+#define NFT_LOOKUP_ANY         0
+#define NFT_LOOKUP_LISTENER    1
+#define NFT_LOOKUP_ESTABLISHED 2
+
 /* look up and get a reference to a matching socket */
 extern struct sock *
 nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
 		      const __be32 saddr, const __be32 daddr,
 		      const __be16 sport, const __be16 dport,
-		      const struct net_device *in, bool listening);
+		      const struct net_device *in, int lookup_type);
 
 static inline void
 nf_tproxy_put_sock(struct sock *sk)
diff --git a/net/netfilter/nf_tproxy_core.c b/net/netfilter/nf_tproxy_core.c
index 5490fc3..8589e5e 100644
--- a/net/netfilter/nf_tproxy_core.c
+++ b/net/netfilter/nf_tproxy_core.c
@@ -22,21 +22,34 @@ struct sock *
 nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
 		      const __be32 saddr, const __be32 daddr,
 		      const __be16 sport, const __be16 dport,
-		      const struct net_device *in, bool listening_only)
+		      const struct net_device *in, int lookup_type)
 {
 	struct sock *sk;
 
 	/* look up socket */
 	switch (protocol) {
 	case IPPROTO_TCP:
-		if (listening_only)
-			sk = __inet_lookup_listener(net, &tcp_hashinfo,
-						    daddr, ntohs(dport),
-						    in->ifindex);
-		else
+		switch (lookup_type) {
+		case NFT_LOOKUP_ANY:
 			sk = __inet_lookup(net, &tcp_hashinfo,
 					   saddr, sport, daddr, dport,
 					   in->ifindex);
+			break;
+		case NFT_LOOKUP_LISTENER:
+			sk = inet_lookup_listener(net, &tcp_hashinfo,
+						    daddr, dport,
+						    in->ifindex);
+			break;
+		case NFT_LOOKUP_ESTABLISHED:
+			sk = inet_lookup_established(net, &tcp_hashinfo,
+						    saddr, sport, daddr, dport,
+						    in->ifindex);
+			break;
+		default:
+			WARN_ON(1);
+			sk = NULL;
+			break;
+		}
 		break;
 	case IPPROTO_UDP:
 		sk = udp4_lib_lookup(net, saddr, sport, daddr, dport,
@@ -47,8 +60,8 @@ nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
 		sk = NULL;
 	}
 
-	pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, listener only: %d, sock %p\n",
-		 protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), listening_only, sk);
+	pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, lookup type: %d, sock %p\n",
+		 protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), lookup_type, sk);
 
 	return sk;
 }
diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c
index 1340c2f..5592b72 100644
--- a/net/netfilter/xt_TPROXY.c
+++ b/net/netfilter/xt_TPROXY.c
@@ -29,7 +29,7 @@ tproxy_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 	const struct iphdr *iph = ip_hdr(skb);
 	const struct xt_tproxy_target_info *tgi = par->targinfo;
-	struct udphdr _hdr, *hp;
+	struct tcphdr _hdr, *hp;
 	struct sock *sk;
 
 	hp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_hdr), &_hdr);
@@ -37,10 +37,37 @@ tproxy_tg(struct sk_buff *skb, const struct xt_target_param *par)
 		return NF_DROP;
 
 	sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol,
-				   iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr,
-				   hp->source, tgi->lport ? tgi->lport : hp->dest,
-				   par->in, true);
-
+				   iph->saddr, iph->daddr,
+				   hp->source, hp->dest,
+				   par->in, NFT_LOOKUP_ESTABLISHED);
+
+	/* udp has no TCP_TIME_WAIT state, so we never enter here */
+	if (sk && sk->sk_state == TCP_TIME_WAIT &&
+	    hp->syn && !hp->rst && !hp->ack && !hp->fin) {
+		struct sock *sk2;
+
+		/* Hm.. we got a SYN to a TIME_WAIT socket, let's see if
+		 * there's a listener on the redirected port
+		 */
+		sk2 = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol,
+					   iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr,
+					   hp->source, tgi->lport ? tgi->lport : hp->dest,
+					   par->in, NFT_LOOKUP_LISTENER);
+		if (sk2) {
+
+			/* yeah, there's one, let's kill the TIME_WAIT
+			 * socket and redirect to the listener
+			 */
+			inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row);
+			inet_twsk_put(inet_twsk(sk));
+			sk = sk2;
+		}
+	} else if (!sk) {
+		sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol,
+					   iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr,
+					   hp->source, tgi->lport ? tgi->lport : hp->dest,
+					   par->in, NFT_LOOKUP_LISTENER);
+	}
 	/* NOTE: assign_sock consumes our sk reference */
 	if (sk && nf_tproxy_assign_sock(skb, sk)) {
 		/* This should be in a separate target, but we don't do multiple
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c
index ebf00ad..12a7140 100644
--- a/net/netfilter/xt_socket.c
+++ b/net/netfilter/xt_socket.c
@@ -142,7 +142,7 @@ socket_match(const struct sk_buff *skb, const struct xt_match_param *par,
 #endif
 
 	sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), protocol,
-				   saddr, daddr, sport, dport, par->in, false);
+				   saddr, daddr, sport, dport, par->in, NFT_LOOKUP_ANY);
 	if (sk != NULL) {
 		bool wildcard;
 		bool transparent = true;
-- 
1.6.0.4



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

* [PATCH 02/11] TProxy: add lookup type checks for UDP in nf_tproxy_get_sock_v4()
  2009-08-26 14:03 [PATCH 00/11] TProxy for IPv6 Balazs Scheidler
  2009-08-15  8:00 ` [PATCH 01/11] TProxy: kick out TIME_WAIT sockets in case a new connection comes in with the same tuple Balazs Scheidler
@ 2009-08-15 12:01 ` Balazs Scheidler
  2009-08-23  9:02 ` [PATCH 03/11] TProxy: reuse a 32bit hole in struct ipv6_pinfo Balazs Scheidler
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Balazs Scheidler @ 2009-08-15 12:01 UTC (permalink / raw)
  To: netfilter-devel, tproxy; +Cc: Harry Mason

Also, inline this function as the lookup_type is always a literal
and inlineing removes branches performed at runtime.

Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
---
 include/net/netfilter/nf_tproxy_core.h |  116 +++++++++++++++++++++++++++++++-
 net/netfilter/nf_tproxy_core.c         |   48 -------------
 2 files changed, 114 insertions(+), 50 deletions(-)

diff --git a/include/net/netfilter/nf_tproxy_core.h b/include/net/netfilter/nf_tproxy_core.h
index b3a8942..4064f35 100644
--- a/include/net/netfilter/nf_tproxy_core.h
+++ b/include/net/netfilter/nf_tproxy_core.h
@@ -13,11 +13,123 @@
 #define NFT_LOOKUP_ESTABLISHED 2
 
 /* look up and get a reference to a matching socket */
-extern struct sock *
+
+
+/* This function is used by the 'TPROXY' target and the 'socket'
+ * match. The following lookups are supported:
+ *
+ * Explicit TProxy target rule
+ * ===========================
+ *
+ * This is used when the user wants to intercept a connection matching
+ * an explicit iptables rule. In this case the sockets are assumed
+ * matching in preference order:
+ *
+ *   - match: if there's a fully established connection matching the
+ *     _packet_ tuple, it is returned, assuming the redirection
+ *     already took place and we process a packet belonging to an
+ *     established connection
+ *
+ *   - match: if there's a listening socket matching the redirection
+ *     (e.g. on-port & on-ip of the connection), it is returned,
+ *     regardless if it was bound to 0.0.0.0 or an explicit
+ *     address. The reasoning is that if there's an explicit rule, it
+ *     does not really matter if the listener is bound to an interface
+ *     or to 0. The user already stated that he wants redirection
+ *     (since he added the rule).
+ *
+ * "socket" match based redirection (no specific rule)
+ * ===================================================
+ * 
+ * There are connections with dynamic endpoints (e.g. FTP data
+ * connection) that the user is unable to add explicit rules
+ * for. These are taken care of by a generic "socket" rule. It is
+ * assumed that the proxy application is trusted to open such
+ * connections without explicit iptables rule (except of course the
+ * generic 'socket' rule). In this case the following sockets are
+ * matched in preference order:
+ *
+ *   - match: if there's a fully established connection matching the
+ *     _packet_ tuple
+ * 
+ *   - match: if there's a non-zero bound listener (possibly with a
+ *     non-local address) We don't accept zero-bound listeners, since
+ *     then local services could intercept traffic going through the
+ *     box.
+ *
+ * Please note that there's an overlap between what a TPROXY target
+ * and a socket match will match. Normally if you have both rules the
+ * "socket" match will be the first one, effectively all packets
+ * belonging to established connections going through that one.
+ */
+static inline struct sock *
 nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
 		      const __be32 saddr, const __be32 daddr,
 		      const __be16 sport, const __be16 dport,
-		      const struct net_device *in, int lookup_type);
+		      const struct net_device *in, int lookup_type)
+{
+	struct sock *sk;
+
+	/* look up socket */
+	switch (protocol) {
+	case IPPROTO_TCP:
+		switch (lookup_type) {
+		case NFT_LOOKUP_ANY:
+			sk = __inet_lookup(net, &tcp_hashinfo,
+					   saddr, sport, daddr, dport,
+					   in->ifindex);
+			break;
+		case NFT_LOOKUP_LISTENER:
+			sk = inet_lookup_listener(net, &tcp_hashinfo,
+						    daddr, dport,
+						    in->ifindex);
+
+                        /* NOTE: we return listeners even if bound to
+                         * 0.0.0.0, those are filtered out in
+                         * xt_socket, since xt_TPROXY needs 0 bound
+                         * listeners too */
+
+			break;
+		case NFT_LOOKUP_ESTABLISHED:
+			sk = inet_lookup_established(net, &tcp_hashinfo,
+						    saddr, sport, daddr, dport,
+						    in->ifindex);
+			break;
+		default:
+			WARN_ON(1);
+			sk = NULL;
+			break;
+		}
+		break;
+	case IPPROTO_UDP:
+		sk = udp4_lib_lookup(net, saddr, sport, daddr, dport,
+				     in->ifindex);
+                if (sk && lookup_type != NFT_LOOKUP_ANY) {
+                        int connected = (sk->sk_state == TCP_ESTABLISHED);
+                        int wildcard = (inet_sk(sk)->rcv_saddr == 0);
+                        
+                        /* NOTE: we return listeners even if bound to
+                         * 0.0.0.0, those are filtered out in
+                         * xt_socket, since xt_TPROXY needs 0 bound
+                         * listeners too */
+                        if ((lookup_type == NFT_LOOKUP_ESTABLISHED && (!connected || wildcard)) ||
+			    (lookup_type == NFT_LOOKUP_LISTENER && connected)) {
+				sock_put(sk);
+				sk = NULL;
+                        }
+		}
+		break;
+	default:
+		WARN_ON(1);
+		sk = NULL;
+	}
+
+	pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, lookup type: %d, sock %p\n",
+		 protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), lookup_type, sk);
+
+	return sk;
+}
+
 
 static inline void
 nf_tproxy_put_sock(struct sock *sk)
diff --git a/net/netfilter/nf_tproxy_core.c b/net/netfilter/nf_tproxy_core.c
index 8589e5e..db65563 100644
--- a/net/netfilter/nf_tproxy_core.c
+++ b/net/netfilter/nf_tproxy_core.c
@@ -18,54 +18,6 @@
 #include <net/udp.h>
 #include <net/netfilter/nf_tproxy_core.h>
 
-struct sock *
-nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
-		      const __be32 saddr, const __be32 daddr,
-		      const __be16 sport, const __be16 dport,
-		      const struct net_device *in, int lookup_type)
-{
-	struct sock *sk;
-
-	/* look up socket */
-	switch (protocol) {
-	case IPPROTO_TCP:
-		switch (lookup_type) {
-		case NFT_LOOKUP_ANY:
-			sk = __inet_lookup(net, &tcp_hashinfo,
-					   saddr, sport, daddr, dport,
-					   in->ifindex);
-			break;
-		case NFT_LOOKUP_LISTENER:
-			sk = inet_lookup_listener(net, &tcp_hashinfo,
-						    daddr, dport,
-						    in->ifindex);
-			break;
-		case NFT_LOOKUP_ESTABLISHED:
-			sk = inet_lookup_established(net, &tcp_hashinfo,
-						    saddr, sport, daddr, dport,
-						    in->ifindex);
-			break;
-		default:
-			WARN_ON(1);
-			sk = NULL;
-			break;
-		}
-		break;
-	case IPPROTO_UDP:
-		sk = udp4_lib_lookup(net, saddr, sport, daddr, dport,
-				     in->ifindex);
-		break;
-	default:
-		WARN_ON(1);
-		sk = NULL;
-	}
-
-	pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, lookup type: %d, sock %p\n",
-		 protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), lookup_type, sk);
-
-	return sk;
-}
-EXPORT_SYMBOL_GPL(nf_tproxy_get_sock_v4);
 
 static void
 nf_tproxy_destructor(struct sk_buff *skb)
-- 
1.6.0.4



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

* [PATCH 03/11] TProxy: reuse a 32bit hole in struct ipv6_pinfo
  2009-08-26 14:03 [PATCH 00/11] TProxy for IPv6 Balazs Scheidler
  2009-08-15  8:00 ` [PATCH 01/11] TProxy: kick out TIME_WAIT sockets in case a new connection comes in with the same tuple Balazs Scheidler
  2009-08-15 12:01 ` [PATCH 02/11] TProxy: add lookup type checks for UDP in nf_tproxy_get_sock_v4() Balazs Scheidler
@ 2009-08-23  9:02 ` Balazs Scheidler
  2009-08-29 16:46   ` Jan Engelhardt
  2009-08-23  9:11 ` [PATCH 04/11] TProxy: split off ipv6 defragmentation to a separate module Balazs Scheidler
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 24+ messages in thread
From: Balazs Scheidler @ 2009-08-23  9:02 UTC (permalink / raw)
  To: netfilter-devel, tproxy; +Cc: Harry Mason

While looking for a place to add a new bitfield in ipv6_pinfo,
I've found a 32 bit hole (in 64 bit mode) at the beginning of the struct.
Since dst_cookie is used in the output fastpath, I've moved this field to
fill the hole, thus decreasing the struct size on 64 bit platforms by
4 bytes.

On 32 bit platforms the struct size doesn't change.

Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
---
 include/linux/ipv6.h |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index c662efa..52dcbf7 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -285,6 +285,7 @@ struct ipv6_pinfo {
 	struct in6_addr 	saddr;
 	struct in6_addr 	rcv_saddr;
 	struct in6_addr		daddr;
+	__u32			dst_cookie;
 	struct in6_pktinfo	sticky_pktinfo;
 	struct in6_addr		*daddr_cache;
 #ifdef CONFIG_IPV6_SUBTREES
@@ -348,8 +349,6 @@ struct ipv6_pinfo {
 						 */
 	__u8			tclass;
 
-	__u32			dst_cookie;
-
 	struct ipv6_mc_socklist	*ipv6_mc_list;
 	struct ipv6_ac_socklist	*ipv6_ac_list;
 	struct ipv6_fl_socklist *ipv6_fl_list;
-- 
1.6.0.4



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

* [PATCH 04/11] TProxy: split off ipv6 defragmentation to a separate module
  2009-08-26 14:03 [PATCH 00/11] TProxy for IPv6 Balazs Scheidler
                   ` (2 preceding siblings ...)
  2009-08-23  9:02 ` [PATCH 03/11] TProxy: reuse a 32bit hole in struct ipv6_pinfo Balazs Scheidler
@ 2009-08-23  9:11 ` Balazs Scheidler
  2009-08-23  9:16 ` [PATCH 05/11] TProxy: added const specifiers to udp lookup functions Balazs Scheidler
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Balazs Scheidler @ 2009-08-23  9:11 UTC (permalink / raw)
  To: netfilter-devel, tproxy; +Cc: Harry Mason

Like with IPv4, TProxy needs IP defragmentation but does not
require connection tracking. Since defragmentation was coupled
with conntrack, I split off the two, creating an nf_defrag_ipv6 module,
similar to the already existing nf_defrag_ipv4.

Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
---
 include/net/netfilter/ipv6/nf_defrag_ipv6.h    |    6 ++
 net/ipv6/netfilter/Makefile                    |    5 +-
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |   58 +------------
 net/ipv6/netfilter/nf_conntrack_reasm.c        |   12 ++-
 net/ipv6/netfilter/nf_defrag_ipv6_hooks.c      |  109 ++++++++++++++++++++++++
 5 files changed, 131 insertions(+), 59 deletions(-)
 create mode 100644 include/net/netfilter/ipv6/nf_defrag_ipv6.h
 create mode 100644 net/ipv6/netfilter/nf_defrag_ipv6_hooks.c

diff --git a/include/net/netfilter/ipv6/nf_defrag_ipv6.h b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
new file mode 100644
index 0000000..94dd54d
--- /dev/null
+++ b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
@@ -0,0 +1,6 @@
+#ifndef _NF_DEFRAG_IPV6_H
+#define _NF_DEFRAG_IPV6_H
+
+extern void nf_defrag_ipv6_enable(void);
+
+#endif /* _NF_DEFRAG_IPV6_H */
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index aafbba3..a78ee59 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -11,10 +11,11 @@ obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
 obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o
 
 # objects for l3 independent conntrack
-nf_conntrack_ipv6-objs  :=  nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o
+nf_conntrack_ipv6-objs  :=  nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o 
+nf_defrag_ipv6-objs := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o
 
 # l3 independent conntrack
-obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o
+obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o nf_defrag_ipv6.o
 
 # matches
 obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 2a15c2d..158d14c 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -27,6 +27,7 @@
 #include <net/netfilter/nf_conntrack_l3proto.h>
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
+#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
 
 static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
 			      struct nf_conntrack_tuple *tuple)
@@ -183,34 +184,6 @@ out:
 	return nf_conntrack_confirm(skb);
 }
 
-static unsigned int ipv6_defrag(unsigned int hooknum,
-				struct sk_buff *skb,
-				const struct net_device *in,
-				const struct net_device *out,
-				int (*okfn)(struct sk_buff *))
-{
-	struct sk_buff *reasm;
-
-	/* Previously seen (loopback)?  */
-	if (skb->nfct)
-		return NF_ACCEPT;
-
-	reasm = nf_ct_frag6_gather(skb);
-
-	/* queued */
-	if (reasm == NULL)
-		return NF_STOLEN;
-
-	/* error occured or not fragmented */
-	if (reasm == skb)
-		return NF_ACCEPT;
-
-	nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in,
-			   (struct net_device *)out, okfn);
-
-	return NF_STOLEN;
-}
-
 static unsigned int __ipv6_conntrack_in(struct net *net,
 					unsigned int hooknum,
 					struct sk_buff *skb,
@@ -263,13 +236,6 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum,
 
 static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
 	{
-		.hook		= ipv6_defrag,
-		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
-		.hooknum	= NF_INET_PRE_ROUTING,
-		.priority	= NF_IP6_PRI_CONNTRACK_DEFRAG,
-	},
-	{
 		.hook		= ipv6_conntrack_in,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
@@ -284,13 +250,6 @@ static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
 		.priority	= NF_IP6_PRI_CONNTRACK,
 	},
 	{
-		.hook		= ipv6_defrag,
-		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
-		.hooknum	= NF_INET_LOCAL_OUT,
-		.priority	= NF_IP6_PRI_CONNTRACK_DEFRAG,
-	},
-	{
 		.hook		= ipv6_confirm,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
@@ -362,10 +321,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = {
 	.nlattr_to_tuple	= ipv6_nlattr_to_tuple,
 	.nla_policy		= ipv6_nla_policy,
 #endif
-#ifdef CONFIG_SYSCTL
-	.ctl_table_path		= nf_net_netfilter_sysctl_path,
-	.ctl_table		= nf_ct_ipv6_sysctl_table,
-#endif
 	.me			= THIS_MODULE,
 };
 
@@ -378,16 +333,12 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
 	int ret = 0;
 
 	need_conntrack();
+	nf_defrag_ipv6_enable();
 
-	ret = nf_ct_frag6_init();
-	if (ret < 0) {
-		printk("nf_conntrack_ipv6: can't initialize frag6.\n");
-		return ret;
-	}
 	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp6);
 	if (ret < 0) {
 		printk("nf_conntrack_ipv6: can't register tcp.\n");
-		goto cleanup_frag6;
+                return ret;
 	}
 
 	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp6);
@@ -425,8 +376,6 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
 	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
  cleanup_tcp:
 	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
- cleanup_frag6:
-	nf_ct_frag6_cleanup();
 	return ret;
 }
 
@@ -438,7 +387,6 @@ static void __exit nf_conntrack_l3proto_ipv6_fini(void)
 	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
 	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
 	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
-	nf_ct_frag6_cleanup();
 }
 
 module_init(nf_conntrack_l3proto_ipv6_init);
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index f3aba25..b7b08fe 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -73,8 +73,8 @@ struct nf_ct_frag6_queue
 static struct inet_frags nf_frags;
 static struct netns_frags nf_init_frags;
 
-#ifdef CONFIG_SYSCTL
-struct ctl_table nf_ct_ipv6_sysctl_table[] = {
+#if defined(CONFIG_SYSCTL)
+struct ctl_table nf_ct_frag6_sysctl_table[] = {
 	{
 		.procname	= "nf_conntrack_frag6_timeout",
 		.data		= &nf_init_frags.timeout,
@@ -100,6 +100,8 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = {
 	},
 	{ .ctl_name = 0 }
 };
+
+static struct ctl_table_header *nf_ct_frag6_sysctl_header = NULL;
 #endif
 
 static unsigned int nf_hashfn(struct inet_frag_queue *q)
@@ -675,11 +677,17 @@ int nf_ct_frag6_init(void)
 	inet_frags_init_net(&nf_init_frags);
 	inet_frags_init(&nf_frags);
 
+        if (!(nf_ct_frag6_sysctl_header = register_sysctl_paths(nf_net_netfilter_sysctl_path, nf_ct_frag6_sysctl_table))) {
+		return -ENOMEM;
+	}
 	return 0;
 }
 
 void nf_ct_frag6_cleanup(void)
 {
+	unregister_sysctl_table(nf_ct_frag6_sysctl_header);
+	nf_ct_frag6_sysctl_header = NULL;
+
 	inet_frags_fini(&nf_frags);
 
 	nf_init_frags.low_thresh = 0;
diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
new file mode 100644
index 0000000..6f07971
--- /dev/null
+++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
@@ -0,0 +1,109 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * 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/types.h>
+#include <linux/ipv6.h>
+#include <linux/in6.h>
+#include <linux/netfilter.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/icmp.h>
+#include <linux/sysctl.h>
+#include <net/ipv6.h>
+#include <net/inet_frag.h>
+
+#include <linux/netfilter_ipv6.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_helper.h>
+#include <net/netfilter/nf_conntrack_l4proto.h>
+#include <net/netfilter/nf_conntrack_l3proto.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
+#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
+
+static unsigned int ipv6_defrag(unsigned int hooknum,
+				struct sk_buff *skb,
+				const struct net_device *in,
+				const struct net_device *out,
+				int (*okfn)(struct sk_buff *))
+{
+	struct sk_buff *reasm;
+
+	/* Previously seen (loopback)?  */
+	if (skb->nfct)
+		return NF_ACCEPT;
+
+	reasm = nf_ct_frag6_gather(skb);
+
+	/* queued */
+	if (reasm == NULL)
+		return NF_STOLEN;
+
+	/* error occured or not fragmented */
+	if (reasm == skb)
+		return NF_ACCEPT;
+
+	nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in,
+			   (struct net_device *)out, okfn);
+
+	return NF_STOLEN;
+}
+
+static struct nf_hook_ops ipv6_defrag_ops[] = {
+	{
+		.hook		= ipv6_defrag,
+		.owner		= THIS_MODULE,
+		.pf		= PF_INET6,
+		.hooknum	= NF_INET_PRE_ROUTING,
+		.priority	= NF_IP6_PRI_CONNTRACK_DEFRAG,
+	},
+	{
+		.hook		= ipv6_defrag,
+		.owner		= THIS_MODULE,
+		.pf		= PF_INET6,
+		.hooknum	= NF_INET_LOCAL_OUT,
+		.priority	= NF_IP6_PRI_CONNTRACK_DEFRAG,
+	},
+};
+
+static int __init nf_defrag_init(void)
+{
+        int ret = 0;
+
+	ret = nf_ct_frag6_init();
+	if (ret < 0) {
+		printk("nf_conntrack_ipv6: can't initialize frag6.\n");
+		return ret;
+	}
+	ret = nf_register_hooks(ipv6_defrag_ops, ARRAY_SIZE(ipv6_defrag_ops));
+	if (ret < 0) {
+	        printk("nf_defrag_ipv6: can't register hooks\n");
+	        goto cleanup_frag6;
+	}
+	return ret;
+ cleanup_frag6:
+	nf_ct_frag6_cleanup();
+	return ret;
+ 
+}
+
+static void __exit nf_defrag_fini(void)
+{
+	nf_unregister_hooks(ipv6_defrag_ops, ARRAY_SIZE(ipv6_defrag_ops));
+	nf_ct_frag6_cleanup();
+}
+
+void nf_defrag_ipv6_enable(void)
+{
+}
+EXPORT_SYMBOL_GPL(nf_defrag_ipv6_enable);
+
+module_init(nf_defrag_init);
+module_exit(nf_defrag_fini);
+
+MODULE_LICENSE("GPL");
-- 
1.6.0.4



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

* [PATCH 05/11] TProxy: added const specifiers to udp lookup functions
  2009-08-26 14:03 [PATCH 00/11] TProxy for IPv6 Balazs Scheidler
                   ` (3 preceding siblings ...)
  2009-08-23  9:11 ` [PATCH 04/11] TProxy: split off ipv6 defragmentation to a separate module Balazs Scheidler
@ 2009-08-23  9:16 ` Balazs Scheidler
  2009-08-23  9:19 ` [PATCH 06/11] TProxy: added udp6_lib_lookup function Balazs Scheidler
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Balazs Scheidler @ 2009-08-23  9:16 UTC (permalink / raw)
  To: netfilter-devel, tproxy; +Cc: Harry Mason

The parameters for various UDP lookup functions were non-const, even though
they could be const. TProxy has some const references and instead of
downcasting it, I added const specifiers along the path.

Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
---
 net/ipv6/udp.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 33b59bd..9c9b24b 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -88,8 +88,8 @@ int udp_v6_get_port(struct sock *sk, unsigned short snum)
 
 static inline int compute_score(struct sock *sk, struct net *net,
 				unsigned short hnum,
-				struct in6_addr *saddr, __be16 sport,
-				struct in6_addr *daddr, __be16 dport,
+				const struct in6_addr *saddr, __be16 sport,
+				const struct in6_addr *daddr, __be16 dport,
 				int dif)
 {
 	int score = -1;
@@ -125,8 +125,8 @@ static inline int compute_score(struct sock *sk, struct net *net,
 }
 
 static struct sock *__udp6_lib_lookup(struct net *net,
-				      struct in6_addr *saddr, __be16 sport,
-				      struct in6_addr *daddr, __be16 dport,
+				      const struct in6_addr *saddr, __be16 sport,
+				      const struct in6_addr *daddr, __be16 dport,
 				      int dif, struct udp_table *udptable)
 {
 	struct sock *sk, *result;
-- 
1.6.0.4



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

* [PATCH 06/11] TProxy: added udp6_lib_lookup function
  2009-08-26 14:03 [PATCH 00/11] TProxy for IPv6 Balazs Scheidler
                   ` (4 preceding siblings ...)
  2009-08-23  9:16 ` [PATCH 05/11] TProxy: added const specifiers to udp lookup functions Balazs Scheidler
@ 2009-08-23  9:19 ` Balazs Scheidler
  2009-08-24 12:47 ` [PATCH 07/11] TProxy: implement IPv6 "local" routing type Balazs Scheidler
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Balazs Scheidler @ 2009-08-23  9:19 UTC (permalink / raw)
  To: netfilter-devel, tproxy; +Cc: Harry Mason

Just like with IPv4, we need access to the UDP hash table to look up local
sockets, but instead of exporting the global udp_table, export a lookup
function.

Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
---
 include/net/udp.h |    3 +++
 net/ipv6/udp.c    |    8 ++++++++
 2 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/include/net/udp.h b/include/net/udp.h
index 90e6ce5..5b45f5b 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -150,6 +150,9 @@ extern int 	udp_lib_setsockopt(struct sock *sk, int level, int optname,
 extern struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
 				    __be32 daddr, __be16 dport,
 				    int dif);
+extern struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be16 sport,
+				    const struct in6_addr *daddr, __be16 dport,
+				    int dif);
 
 /*
  * 	SNMP statistics for UDP and UDP-Lite
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 9c9b24b..eee936c 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -182,6 +182,14 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb,
 				 udptable);
 }
 
+struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be16 sport,
+                             const struct in6_addr *daddr, __be16 dport, int dif)
+{
+        return __udp6_lib_lookup(net, saddr, sport, daddr, dport, dif, &udp_table);
+}
+EXPORT_SYMBOL_GPL(udp6_lib_lookup);
+
+
 /*
  * 	This should be easy, if there is something there we
  * 	return it, otherwise we block.
-- 
1.6.0.4



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

* [PATCH 07/11] TProxy: implement IPv6 "local" routing type
  2009-08-26 14:03 [PATCH 00/11] TProxy for IPv6 Balazs Scheidler
                   ` (5 preceding siblings ...)
  2009-08-23  9:19 ` [PATCH 06/11] TProxy: added udp6_lib_lookup function Balazs Scheidler
@ 2009-08-24 12:47 ` Balazs Scheidler
  2009-08-24 12:48 ` [PATCH 08/11] TProxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is enabled Balazs Scheidler
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Balazs Scheidler @ 2009-08-24 12:47 UTC (permalink / raw)
  To: netfilter-devel, tproxy; +Cc: Harry Mason

IPv4 policy routing (and the ip command) allows to add a routing rule
with 'local' type, however this did not work with IPv6. This
patch implements the 'local' routing type by redirecting all such packets
to the local IP stack.

Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
---
 net/ipv6/route.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 1473ee0..9491579 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1174,6 +1174,8 @@ int ip6_route_add(struct fib6_config *cfg)
 
 	if (addr_type & IPV6_ADDR_MULTICAST)
 		rt->u.dst.input = ip6_mc_input;
+	else if (cfg->fc_flags & RTF_LOCAL)
+		rt->u.dst.input = ip6_input;
 	else
 		rt->u.dst.input = ip6_forward;
 
@@ -1195,7 +1197,7 @@ int ip6_route_add(struct fib6_config *cfg)
 	   they would result in kernel looping; promote them to reject routes
 	 */
 	if ((cfg->fc_flags & RTF_REJECT) ||
-	    (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) {
+	    (((cfg->fc_flags & RTF_LOCAL) == 0) && (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK)))) {
 		/* hold loopback dev/idev if we haven't done so. */
 		if (dev != net->loopback_dev) {
 			if (dev) {
@@ -2086,6 +2088,8 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
 
 	if (rtm->rtm_type == RTN_UNREACHABLE)
 		cfg->fc_flags |= RTF_REJECT;
+        else if (rtm->rtm_type == RTN_LOCAL)
+		cfg->fc_flags |= RTF_LOCAL;
 
 	cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
 	cfg->fc_nlinfo.nlh = nlh;
-- 
1.6.0.4



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

* [PATCH 08/11] TProxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is enabled
  2009-08-26 14:03 [PATCH 00/11] TProxy for IPv6 Balazs Scheidler
                   ` (6 preceding siblings ...)
  2009-08-24 12:47 ` [PATCH 07/11] TProxy: implement IPv6 "local" routing type Balazs Scheidler
@ 2009-08-24 12:48 ` Balazs Scheidler
  2009-08-24 12:51 ` [PATCH 09/11] TProxy: added IPv6 socket lookup function to nf_tproxy_core Balazs Scheidler
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Balazs Scheidler @ 2009-08-24 12:48 UTC (permalink / raw)
  To: netfilter-devel, tproxy; +Cc: Harry Mason

Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
---
 net/ipv6/af_inet6.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index caa0278..5fa0f44 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -338,7 +338,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 			 */
 			v4addr = LOOPBACK4_IPV6;
 			if (!(addr_type & IPV6_ADDR_MULTICAST))	{
-				if (!ipv6_chk_addr(net, &addr->sin6_addr,
+				if (!inet->transparent && !ipv6_chk_addr(net, &addr->sin6_addr,
 						   dev, 0)) {
 					if (dev)
 						dev_put(dev);
-- 
1.6.0.4



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

* [PATCH 09/11] TProxy: added IPv6 socket lookup function to nf_tproxy_core
  2009-08-26 14:03 [PATCH 00/11] TProxy for IPv6 Balazs Scheidler
                   ` (7 preceding siblings ...)
  2009-08-24 12:48 ` [PATCH 08/11] TProxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is enabled Balazs Scheidler
@ 2009-08-24 12:51 ` Balazs Scheidler
  2009-08-24 12:51 ` [PATCH 10/11] TProxy: added IPv6 support to the TPROXY target Balazs Scheidler
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Balazs Scheidler @ 2009-08-24 12:51 UTC (permalink / raw)
  To: netfilter-devel, tproxy; +Cc: Harry Mason

Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
---
 include/net/netfilter/nf_tproxy_core.h |   72 +++++++++++++++++++++++++++++++-
 1 files changed, 71 insertions(+), 1 deletions(-)

diff --git a/include/net/netfilter/nf_tproxy_core.h b/include/net/netfilter/nf_tproxy_core.h
index 4064f35..101cc34 100644
--- a/include/net/netfilter/nf_tproxy_core.h
+++ b/include/net/netfilter/nf_tproxy_core.h
@@ -5,7 +5,8 @@
 #include <linux/in.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
-#include <net/inet_sock.h>
+#include <net/inet_hashtables.h>
+#include <net/inet6_hashtables.h>
 #include <net/tcp.h>
 
 #define NFT_LOOKUP_ANY         0
@@ -130,6 +131,75 @@ nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
 	return sk;
 }
 
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+static inline struct sock *
+nf_tproxy_get_sock_v6(struct net *net, const u8 protocol,
+		      const struct in6_addr *saddr, const struct in6_addr *daddr,
+		      const __be16 sport, const __be16 dport,
+		      const struct net_device *in, int lookup_type)
+{
+	struct sock *sk;
+
+	/* look up socket */
+	switch (protocol) {
+	case IPPROTO_TCP:
+		switch (lookup_type) {
+		case NFT_LOOKUP_ANY:
+			sk = inet6_lookup(net, &tcp_hashinfo,
+                                          saddr, sport, daddr, dport,
+                                          in->ifindex);
+			break;
+		case NFT_LOOKUP_LISTENER:
+			sk = inet6_lookup_listener(net, &tcp_hashinfo,
+                                                   daddr, ntohs(dport),
+                                                   in->ifindex);
+
+                        /* NOTE: we return listeners even if bound to
+                         * 0.0.0.0, those are filtered out in
+                         * xt_socket, since xt_TPROXY needs 0 bound
+                         * listeners too */
+
+			break;
+		case NFT_LOOKUP_ESTABLISHED:
+			sk = __inet6_lookup_established(net, &tcp_hashinfo,
+                                                        saddr, sport, daddr, ntohs(dport),
+                                                        in->ifindex);
+			break;
+		default:
+			WARN_ON(1);
+			sk = NULL;
+			break;
+		}
+		break;
+	case IPPROTO_UDP:
+		sk = udp6_lib_lookup(net, saddr, sport, daddr, dport,
+				     in->ifindex);
+                if (sk && lookup_type != NFT_LOOKUP_ANY) {
+                        int connected = (sk->sk_state == TCP_ESTABLISHED);
+                        int wildcard = ipv6_addr_any(&inet6_sk(sk)->rcv_saddr);
+                        
+                        /* NOTE: we return listeners even if bound to
+                         * 0.0.0.0, those are filtered out in
+                         * xt_socket, since xt_TPROXY needs 0 bound
+                         * listeners too */
+                        if ((lookup_type == NFT_LOOKUP_ESTABLISHED && (!connected || wildcard)) ||
+			    (lookup_type == NFT_LOOKUP_LISTENER && connected)) {
+				sock_put(sk);
+				sk = NULL;
+                        }
+		}
+		break;
+	default:
+		WARN_ON(1);
+		sk = NULL;
+	}
+
+	pr_debug("tproxy socket lookup: proto %u %pI6:%u -> %pI6:%u, lookup type: %d, sock %p\n",
+		 protocol, saddr, ntohs(sport), daddr, ntohs(dport), lookup_type, sk);
+
+	return sk;
+}
+#endif
 
 static inline void
 nf_tproxy_put_sock(struct sock *sk)
-- 
1.6.0.4



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

* [PATCH 10/11] TProxy: added IPv6 support to the TPROXY target
  2009-08-26 14:03 [PATCH 00/11] TProxy for IPv6 Balazs Scheidler
                   ` (8 preceding siblings ...)
  2009-08-24 12:51 ` [PATCH 09/11] TProxy: added IPv6 socket lookup function to nf_tproxy_core Balazs Scheidler
@ 2009-08-24 12:51 ` Balazs Scheidler
  2009-08-24 12:52 ` [PATCH 11/11] TProxy: added IPv6 support to the socket match Balazs Scheidler
  2009-09-04  6:07 ` [PATCH 00/11] TProxy for IPv6 Amos Jeffries
  11 siblings, 0 replies; 24+ messages in thread
From: Balazs Scheidler @ 2009-08-24 12:51 UTC (permalink / raw)
  To: netfilter-devel, tproxy; +Cc: Harry Mason

This requires a new revision as the old target structure was
IPv4 specific.

Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
---
 include/linux/netfilter/xt_TPROXY.h |   15 ++-
 net/netfilter/xt_TPROXY.c           |  248 +++++++++++++++++++++++++++++------
 2 files changed, 218 insertions(+), 45 deletions(-)

diff --git a/include/linux/netfilter/xt_TPROXY.h b/include/linux/netfilter/xt_TPROXY.h
index 152e8f9..7b4e06d 100644
--- a/include/linux/netfilter/xt_TPROXY.h
+++ b/include/linux/netfilter/xt_TPROXY.h
@@ -1,14 +1,21 @@
-#ifndef _XT_TPROXY_H_target
-#define _XT_TPROXY_H_target
+#ifndef _XT_TPROXY_H
+#define _XT_TPROXY_H
 
 /* TPROXY target is capable of marking the packet to perform
  * redirection. We can get rid of that whenever we get support for
  * mutliple targets in the same rule. */
-struct xt_tproxy_target_info {
+struct xt_tproxy_target_info_v0 {
 	u_int32_t mark_mask;
 	u_int32_t mark_value;
 	__be32 laddr;
 	__be16 lport;
 };
 
-#endif /* _XT_TPROXY_H_target */
+struct xt_tproxy_target_info_v1 {
+	u_int32_t mark_mask;
+	u_int32_t mark_value;
+	union nf_inet_addr laddr;
+	__be16 lport;
+};
+
+#endif /* _XT_TPROXY_H */
diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c
index 5592b72..9e00f4d 100644
--- a/net/netfilter/xt_TPROXY.c
+++ b/net/netfilter/xt_TPROXY.c
@@ -10,6 +10,8 @@
  *
  */
 
+#define DEBUG 1
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
@@ -19,52 +21,173 @@
 
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
 #include <linux/netfilter/xt_TPROXY.h>
 
 #include <net/netfilter/ipv4/nf_defrag_ipv4.h>
+#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
 #include <net/netfilter/nf_tproxy_core.h>
 
 static unsigned int
-tproxy_tg(struct sk_buff *skb, const struct xt_target_param *par)
+tproxy_tg4(struct sk_buff *skb, __be32 laddr, __be16 lport, u_int32_t mark_mask, u_int32_t mark_value)
 {
 	const struct iphdr *iph = ip_hdr(skb);
-	const struct xt_tproxy_target_info *tgi = par->targinfo;
-	struct tcphdr _hdr, *hp;
+	struct udphdr _hdr, *hp;
 	struct sock *sk;
 
 	hp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_hdr), &_hdr);
-	if (hp == NULL)
+	if (hp == NULL) {
+		pr_debug("TPROXY: packet is too short to contain a transport header, dropping\n");
 		return NF_DROP;
+	}
 
+        /* check if there's an ongoing connection on the packet
+	 * addresses, this happens if the redirect already happened
+	 * and the current packet belongs to an already established
+	 * connection */
 	sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol,
 				   iph->saddr, iph->daddr,
 				   hp->source, hp->dest,
-				   par->in, NFT_LOOKUP_ESTABLISHED);
+				   skb->dev, NFT_LOOKUP_ESTABLISHED);
 
 	/* udp has no TCP_TIME_WAIT state, so we never enter here */
-	if (sk && sk->sk_state == TCP_TIME_WAIT &&
-	    hp->syn && !hp->rst && !hp->ack && !hp->fin) {
-		struct sock *sk2;
-
-		/* Hm.. we got a SYN to a TIME_WAIT socket, let's see if
-		 * there's a listener on the redirected port
-		 */
-		sk2 = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol,
-					   iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr,
-					   hp->source, tgi->lport ? tgi->lport : hp->dest,
-					   par->in, NFT_LOOKUP_LISTENER);
-		if (sk2) {
+	if (sk && sk->sk_state == TCP_TIME_WAIT) {
+		struct tcphdr _hdr, *hp;
 
-			/* yeah, there's one, let's kill the TIME_WAIT
-			 * socket and redirect to the listener
+		hp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_hdr), &_hdr);
+		if (hp == NULL)
+			return NF_DROP;
+		
+		if (hp->syn && !hp->rst && !hp->ack && !hp->fin) {
+			struct sock *sk2;
+			
+			/* Hm.. we got a SYN to a TIME_WAIT socket, let's see if
+			 * there's a listener on the redirected port
 			 */
-			inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row);
-			inet_twsk_put(inet_twsk(sk));
-			sk = sk2;
+			sk2 = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol,
+						    iph->saddr, laddr ? laddr : iph->daddr,
+						    hp->source, lport ? lport : hp->dest,
+						    skb->dev, NFT_LOOKUP_LISTENER);
+			if (sk2) {
+				
+				/* yeah, there's one, let's kill the TIME_WAIT
+				 * socket and redirect to the listener
+				 */
+				inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row);
+				inet_twsk_put(inet_twsk(sk));
+				sk = sk2;
+			}
 		}
 	} else if (!sk) {
+		/* no there's no established connection, check if
+		 * there's a listener on the redirected addr/port */
 		sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol,
-					   iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr,
+					   iph->saddr, laddr ? laddr : iph->daddr,
+					   hp->source, lport ? lport : hp->dest,
+					   skb->dev, NFT_LOOKUP_LISTENER);
+	}
+	/* NOTE: assign_sock consumes our sk reference */
+	if (sk && nf_tproxy_assign_sock(skb, sk)) {
+		/* This should be in a separate target, but we don't do multiple
+		   targets on the same rule yet */
+		skb->mark = (skb->mark & ~mark_mask) ^ mark_value;
+
+		pr_debug("TPROXY: redirecting: proto %u %08x:%u -> %08x:%u, mark: %x\n",
+			 iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
+			 ntohl(laddr), ntohs(lport), skb->mark);
+		return NF_ACCEPT;
+	}
+
+	pr_debug("TPROXY: no socket, dropping: proto %u %08x:%u -> %08x:%u, mark: %x\n",
+		 iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
+		 ntohl(laddr), ntohs(lport), skb->mark);
+	return NF_DROP;
+}
+
+static unsigned int
+tproxy_tg4_v0(struct sk_buff *skb, const struct xt_target_param *par)
+{
+	const struct xt_tproxy_target_info_v0 *tgi = par->targinfo;
+
+	return tproxy_tg4(skb, tgi->laddr, tgi->lport, tgi->mark_mask, tgi->mark_value);
+}
+
+static unsigned int
+tproxy_tg4_v1(struct sk_buff *skb, const struct xt_target_param *par)
+{
+	const struct xt_tproxy_target_info_v1 *tgi = par->targinfo;
+
+	return tproxy_tg4(skb, tgi->laddr.ip, tgi->lport, tgi->mark_mask, tgi->mark_value);
+}
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+static unsigned int
+tproxy_tg6_v1(struct sk_buff *skb, const struct xt_target_param *par)
+{
+	const struct ipv6hdr *iph = ipv6_hdr(skb);
+	const struct xt_tproxy_target_info_v1 *tgi = par->targinfo;
+	struct udphdr _hdr, *hp;
+	struct sock *sk;
+        int thoff;
+        int tproto;
+
+        tproto = ipv6_find_hdr(skb, &thoff, -1, NULL);
+        if (tproto < 0) {
+		pr_debug("TPROXY: Unable to find transport header in IPv6 packet, dropping\n");
+		return NF_DROP;
+        }
+
+	hp = skb_header_pointer(skb, thoff, sizeof(_hdr), &_hdr);
+	if (hp == NULL) {
+		pr_debug("TPROXY: Unable to grab transport header contents in IPv6 packet, dropping\n");
+		return NF_DROP;
+	}
+
+        /* check if there's an ongoing connection on the packet
+	 * addresses, this happens if the redirect already happened
+	 * and the current packet belongs to an already established
+	 * connection */
+	sk = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto,
+				   &iph->saddr, &iph->daddr,
+				   hp->source, hp->dest,
+				   par->in, NFT_LOOKUP_ESTABLISHED);
+
+	/* udp has no TCP_TIME_WAIT state, so we never enter here */
+	if (sk && sk->sk_state == TCP_TIME_WAIT) {
+		struct tcphdr _hdr, *hp;
+
+		hp = skb_header_pointer(skb, thoff, sizeof(_hdr), &_hdr);
+		if (hp == NULL) {
+			pr_debug("TPROXY: Unable to grab TCP transport header contents in IPv6 packet, dropping\n");
+			return NF_DROP;
+		}
+
+		if (hp->syn && !hp->rst && !hp->ack && !hp->fin) {
+			struct sock *sk2;
+			
+
+			/* Hm.. we got a SYN to a TIME_WAIT socket, let's see if
+			 * there's a listener on the redirected port
+			 */
+			sk2 = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto,
+						    &iph->saddr, !ipv6_addr_any(&tgi->laddr.in6) ? &tgi->laddr.in6 : &iph->daddr,
+						    hp->source, tgi->lport ? tgi->lport : hp->dest,
+						    par->in, NFT_LOOKUP_LISTENER);
+			if (sk2) {
+				
+				/* yeah, there's one, let's kill the TIME_WAIT
+				 * socket and redirect to the listener
+				 */
+				inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row);
+				inet_twsk_put(inet_twsk(sk));
+				sk = sk2;
+			}
+		}
+	} else if (!sk) {
+		/* no there's no established connection, check if
+		 * there's a listener on the redirected addr/port */
+		sk = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto,
+					   &iph->saddr, !ipv6_addr_any(&tgi->laddr.in6) ? &tgi->laddr.in6 : &iph->daddr,
 					   hp->source, tgi->lport ? tgi->lport : hp->dest,
 					   par->in, NFT_LOOKUP_LISTENER);
 	}
@@ -74,51 +197,93 @@ tproxy_tg(struct sk_buff *skb, const struct xt_target_param *par)
 		   targets on the same rule yet */
 		skb->mark = (skb->mark & ~tgi->mark_mask) ^ tgi->mark_value;
 
-		pr_debug("redirecting: proto %u %08x:%u -> %08x:%u, mark: %x\n",
-			 iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
-			 ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark);
+		pr_debug("TPROXY: redirecting: proto %u %pI6:%u -> %pI6:%u, mark: %x\n",
+			 tproto, &iph->saddr, ntohs(hp->dest),
+			 &tgi->laddr.in6, ntohs(tgi->lport), skb->mark);
 		return NF_ACCEPT;
 	}
 
-	pr_debug("no socket, dropping: proto %u %08x:%u -> %08x:%u, mark: %x\n",
-		 iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
-		 ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark);
+	pr_debug("TPROXY: no socket, dropping: proto %u %pI6:%u -> %pI6:%u, mark: %x\n",
+		 tproto, &iph->saddr, ntohs(hp->dest),
+		 &tgi->laddr.in6, ntohs(tgi->lport), skb->mark);
 	return NF_DROP;
 }
+#endif
+
 
-static bool tproxy_tg_check(const struct xt_tgchk_param *par)
+static bool tproxy_tg4_check(const struct xt_tgchk_param *par)
 {
 	const struct ipt_ip *i = par->entryinfo;
 
 	if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP)
 	    && !(i->invflags & IPT_INV_PROTO))
 		return true;
+	pr_info("xt_TPROXY: Can be used only in combination with "
+		"either -p tcp or -p udp\n");
+	return false;
+}
+
+static bool tproxy_tg6_check(const struct xt_tgchk_param *par)
+{
+	const struct ip6t_ip6 *i = par->entryinfo;
 
+	if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP)
+	    && !(i->flags & IP6T_INV_PROTO))
+		return true;
 	pr_info("xt_TPROXY: Can be used only in combination with "
 		"either -p tcp or -p udp\n");
 	return false;
 }
 
-static struct xt_target tproxy_tg_reg __read_mostly = {
-	.name		= "TPROXY",
-	.family		= AF_INET,
-	.table		= "mangle",
-	.target		= tproxy_tg,
-	.targetsize	= sizeof(struct xt_tproxy_target_info),
-	.checkentry	= tproxy_tg_check,
-	.hooks		= 1 << NF_INET_PRE_ROUTING,
-	.me		= THIS_MODULE,
+static struct xt_target tproxy_tg_reg[] __read_mostly = {
+	{
+		.name		= "TPROXY",
+		.family		= NFPROTO_IPV4,
+		.table		= "mangle",
+		.target		= tproxy_tg4_v0,
+		.revision       = 0,
+		.targetsize	= sizeof(struct xt_tproxy_target_info_v0),
+		.checkentry	= tproxy_tg4_check,
+		.hooks		= 1 << NF_INET_PRE_ROUTING,
+		.me		= THIS_MODULE,
+	},
+	{
+		.name		= "TPROXY",
+		.family		= NFPROTO_IPV4,
+		.table		= "mangle",
+		.target		= tproxy_tg4_v1,
+		.revision       = 1,
+		.targetsize	= sizeof(struct xt_tproxy_target_info_v1),
+		.checkentry	= tproxy_tg4_check,
+		.hooks		= 1 << NF_INET_PRE_ROUTING,
+		.me		= THIS_MODULE,
+	},
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	{
+		.name		= "TPROXY",
+		.family		= NFPROTO_IPV6,
+		.table		= "mangle",
+		.target		= tproxy_tg6_v1,
+		.revision       = 1,
+		.targetsize	= sizeof(struct xt_tproxy_target_info_v1),
+		.checkentry	= tproxy_tg6_check,
+		.hooks		= 1 << NF_INET_PRE_ROUTING,
+		.me		= THIS_MODULE,
+	},
+#endif
+
 };
 
 static int __init tproxy_tg_init(void)
 {
 	nf_defrag_ipv4_enable();
-	return xt_register_target(&tproxy_tg_reg);
+	nf_defrag_ipv6_enable();
+	return xt_register_targets(tproxy_tg_reg, ARRAY_SIZE(tproxy_tg_reg));
 }
 
 static void __exit tproxy_tg_exit(void)
 {
-	xt_unregister_target(&tproxy_tg_reg);
+	xt_unregister_targets(tproxy_tg_reg, ARRAY_SIZE(tproxy_tg_reg));
 }
 
 module_init(tproxy_tg_init);
@@ -127,3 +292,4 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Krisztian Kovacs");
 MODULE_DESCRIPTION("Netfilter transparent proxy (TPROXY) target module.");
 MODULE_ALIAS("ipt_TPROXY");
+MODULE_ALIAS("ip6t_TPROXY");
-- 
1.6.0.4



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

* [PATCH 11/11] TProxy: added IPv6 support to the socket match
  2009-08-26 14:03 [PATCH 00/11] TProxy for IPv6 Balazs Scheidler
                   ` (9 preceding siblings ...)
  2009-08-24 12:51 ` [PATCH 10/11] TProxy: added IPv6 support to the TPROXY target Balazs Scheidler
@ 2009-08-24 12:52 ` Balazs Scheidler
  2009-09-04  6:07 ` [PATCH 00/11] TProxy for IPv6 Amos Jeffries
  11 siblings, 0 replies; 24+ messages in thread
From: Balazs Scheidler @ 2009-08-24 12:52 UTC (permalink / raw)
  To: netfilter-devel, tproxy; +Cc: Harry Mason

Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
---
 net/netfilter/xt_socket.c |  111 ++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 105 insertions(+), 6 deletions(-)

diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c
index 12a7140..41a8383 100644
--- a/net/netfilter/xt_socket.c
+++ b/net/netfilter/xt_socket.c
@@ -14,6 +14,7 @@
 #include <linux/skbuff.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
 #include <net/tcp.h>
 #include <net/udp.h>
 #include <net/icmp.h>
@@ -21,6 +22,7 @@
 #include <net/inet_sock.h>
 #include <net/netfilter/nf_tproxy_core.h>
 #include <net/netfilter/ipv4/nf_defrag_ipv4.h>
+#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
 
 #include <linux/netfilter/xt_socket.h>
 
@@ -30,7 +32,7 @@
 #endif
 
 static int
-extract_icmp_fields(const struct sk_buff *skb,
+extract_icmp4_fields(const struct sk_buff *skb,
 		    u8 *protocol,
 		    __be32 *raddr,
 		    __be32 *laddr,
@@ -115,7 +117,7 @@ socket_match(const struct sk_buff *skb, const struct xt_match_param *par,
 		dport = hp->dest;
 
 	} else if (iph->protocol == IPPROTO_ICMP) {
-		if (extract_icmp_fields(skb, &protocol, &saddr, &daddr,
+		if (extract_icmp4_fields(skb, &protocol, &saddr, &daddr,
 					&sport, &dport))
 			return false;
 	} else {
@@ -175,23 +177,107 @@ socket_match(const struct sk_buff *skb, const struct xt_match_param *par,
 }
 
 static bool
-socket_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
+socket_mt4_v0(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 	return socket_match(skb, par, NULL);
 }
 
 static bool
-socket_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
+socket_mt4_v1(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 	return socket_match(skb, par, par->matchinfo);
 }
 
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+
+static int
+extract_icmp6_fields(const struct sk_buff *skb,
+		     u8 *protocol,
+		     struct in6_addr **raddr,
+		     struct in6_addr **laddr,
+		     __be16 *rport,
+		     __be16 *lport)
+{
+	return 1;
+}
+
+static bool
+socket_mt6_v1(const struct sk_buff *skb, const struct xt_match_param *par)
+{
+	struct ipv6hdr *iph = ipv6_hdr(skb);
+	struct udphdr _hdr, *hp = NULL;
+	struct sock *sk;
+	struct in6_addr *daddr, *saddr;
+	__be16 dport, sport;
+        int thoff;
+	u8 tproto;
+        const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo;
+        
+        tproto = ipv6_find_hdr(skb, &thoff, -1, NULL);
+        if (tproto < 0) {
+		pr_debug("socket match: Unable to find transport header in IPv6 packet, dropping\n");
+		return NF_DROP;
+        }
+
+	if (tproto == IPPROTO_UDP || tproto == IPPROTO_TCP) {
+		hp = skb_header_pointer(skb, thoff,
+					sizeof(_hdr), &_hdr);
+		if (hp == NULL)
+			return false;
+
+		saddr = &iph->saddr;
+		sport = hp->source;
+		daddr = &iph->daddr;
+		dport = hp->dest;
+
+	} else if (tproto == IPPROTO_ICMP) {
+		if (extract_icmp6_fields(skb, &tproto, &saddr, &daddr,
+					&sport, &dport))
+			return false;
+	} else {
+		return false;
+	}
+
+	sk = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto,
+				   saddr, daddr, sport, dport, par->in, NFT_LOOKUP_ANY);
+	if (sk != NULL) {
+		bool wildcard;
+		bool transparent = true;
+
+		/* Ignore sockets listening on INADDR_ANY */
+		wildcard = (sk->sk_state != TCP_TIME_WAIT &&
+			    ipv6_addr_any(&inet6_sk(sk)->rcv_saddr));
+
+		/* Ignore non-transparent sockets,
+		   if XT_SOCKET_TRANSPARENT is used */
+		if (info && info->flags & XT_SOCKET_TRANSPARENT)
+			transparent = ((sk->sk_state != TCP_TIME_WAIT &&
+					inet_sk(sk)->transparent) ||
+				       (sk->sk_state == TCP_TIME_WAIT &&
+					inet_twsk(sk)->tw_transparent));
+
+		nf_tproxy_put_sock(sk);
+
+		if (wildcard || !transparent)
+			sk = NULL;
+	}
+
+	pr_debug("socket match: proto %u %pI6:%u -> %pI6:%u "
+		 "(orig %pI6:%u) sock %p\n",
+		 tproto, saddr, ntohs(sport),
+		 daddr, ntohs(dport),
+		 &iph->daddr, hp ? ntohs(hp->dest) : 0, sk);
+
+	return (sk != NULL);
+}
+#endif
+
 static struct xt_match socket_mt_reg[] __read_mostly = {
 	{
 		.name		= "socket",
 		.revision	= 0,
 		.family		= NFPROTO_IPV4,
-		.match		= socket_mt_v0,
+		.match		= socket_mt4_v0,
 		.hooks		= 1 << NF_INET_PRE_ROUTING,
 		.me		= THIS_MODULE,
 	},
@@ -199,16 +285,28 @@ static struct xt_match socket_mt_reg[] __read_mostly = {
 		.name		= "socket",
 		.revision	= 1,
 		.family		= NFPROTO_IPV4,
-		.match		= socket_mt_v1,
+		.match		= socket_mt4_v1,
+		.matchsize	= sizeof(struct xt_socket_mtinfo1),
+		.hooks		= 1 << NF_INET_PRE_ROUTING,
+		.me		= THIS_MODULE,
+	},
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	{
+		.name		= "socket",
+		.revision	= 1,
+		.family		= NFPROTO_IPV6,
+		.match		= socket_mt6_v1,
 		.matchsize	= sizeof(struct xt_socket_mtinfo1),
 		.hooks		= 1 << NF_INET_PRE_ROUTING,
 		.me		= THIS_MODULE,
 	},
+#endif
 };
 
 static int __init socket_mt_init(void)
 {
 	nf_defrag_ipv4_enable();
+	nf_defrag_ipv6_enable();
 	return xt_register_matches(socket_mt_reg, ARRAY_SIZE(socket_mt_reg));
 }
 
@@ -224,3 +322,4 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Krisztian Kovacs, Balazs Scheidler");
 MODULE_DESCRIPTION("x_tables socket match module");
 MODULE_ALIAS("ipt_socket");
+MODULE_ALIAS("ip6t_socket");
-- 
1.6.0.4



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

* [PATCH 00/11] TProxy for IPv6
@ 2009-08-26 14:03 Balazs Scheidler
  2009-08-15  8:00 ` [PATCH 01/11] TProxy: kick out TIME_WAIT sockets in case a new connection comes in with the same tuple Balazs Scheidler
                   ` (11 more replies)
  0 siblings, 12 replies; 24+ messages in thread
From: Balazs Scheidler @ 2009-08-26 14:03 UTC (permalink / raw)
  To: netfilter-devel, tproxy; +Cc: Harry Mason

[ Sorry if this reaches you twice, I sent to the wrong address the first time ]

I've just pushed a set of patches that implement TProxy for IPv6 to

http://git.balabit.hu/bazsi/tproxy-2.6.git

The patches are also posted in reply to this mail.

Although some work is still needed, basic testing shows that it works all
right.  

The accompanying iptables patches are available at

http://git.balabit.hu/bazsi/iptables-tproxy.git

There are some things left to do:

  * the recognition of related ICMPv6 packets missing (from xt_socket.c)

  * I should probably split xt_TPROXY/xt_socket to IPv4 and IPv6 modules, as
    right now those depend on both stacks at the same time.

I'm on a holiday right now, thus I might not respond to comments in a timely
manner, however I'm interested in any comments/feedback nevertheless.

Harry, I didn't remember that you actually wanted to work on TProxy for
IPv6, I just vaguely remembered that there was someone asking for IPv6
support, thus I implemented this without being in the know.  If you started
hacking, I hope that we didn't completely duplicate effort.  I'd appreciate
help in the missing bits and/or testing whichever fits you best.

Also, I have written a Python test script to test TProxy functionality
automatically both for IPv4 and IPv6, I can post that as well if anyone is
interested.


Balazs Scheidler (11):
  TProxy: kick out TIME_WAIT sockets in case a new connection comes in
    with the same tuple
  TProxy: add lookup type checks for UDP in nf_tproxy_get_sock_v4()
  TProxy: reuse a 32bit hole in struct ipv6_pinfo
  TProxy: split off ipv6 defragmentation to a separate module
  TProxy: added const specifiers to udp lookup functions
  TProxy: added udp6_lib_lookup function
  TProxy: implement IPv6 "local" routing type
  TProxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is
    enabled
  TProxy: added IPv6 socket lookup function to nf_tproxy_core
  TProxy: added IPv6 support to the TPROXY target
  TProxy: added IPv6 support to the socket match

 include/linux/ipv6.h                           |    3 +-
 include/linux/netfilter/xt_TPROXY.h            |   15 +-
 include/net/netfilter/ipv6/nf_defrag_ipv6.h    |    6 +
 include/net/netfilter/nf_tproxy_core.h         |  192 +++++++++++++++++++-
 include/net/udp.h                              |    3 +
 net/ipv6/af_inet6.c                            |    2 +-
 net/ipv6/netfilter/Makefile                    |    5 +-
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |   58 +------
 net/ipv6/netfilter/nf_conntrack_reasm.c        |   12 +-
 net/ipv6/netfilter/nf_defrag_ipv6_hooks.c      |  109 +++++++++++
 net/ipv6/route.c                               |    6 +-
 net/ipv6/udp.c                                 |   16 ++-
 net/netfilter/nf_tproxy_core.c                 |   35 ----
 net/netfilter/xt_TPROXY.c                      |  239 +++++++++++++++++++++---
 net/netfilter/xt_socket.c                      |  113 +++++++++++-
 15 files changed, 675 insertions(+), 139 deletions(-)
 create mode 100644 include/net/netfilter/ipv6/nf_defrag_ipv6.h
 create mode 100644 net/ipv6/netfilter/nf_defrag_ipv6_hooks.c



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

* Re: [PATCH 03/11] TProxy: reuse a 32bit hole in struct ipv6_pinfo
  2009-08-23  9:02 ` [PATCH 03/11] TProxy: reuse a 32bit hole in struct ipv6_pinfo Balazs Scheidler
@ 2009-08-29 16:46   ` Jan Engelhardt
  2009-08-30  6:56     ` Balazs Scheidler
  0 siblings, 1 reply; 24+ messages in thread
From: Jan Engelhardt @ 2009-08-29 16:46 UTC (permalink / raw)
  To: Balazs Scheidler; +Cc: netfilter-devel, tproxy, Harry Mason


On Sunday 2009-08-23 11:02, Balazs Scheidler wrote:

>While looking for a place to add a new bitfield in ipv6_pinfo,
>I've found a 32 bit hole (in 64 bit mode) at the beginning of the struct.
>Since dst_cookie is used in the output fastpath, I've moved this field to
>fill the hole, thus decreasing the struct size on 64 bit platforms by
>4 bytes.

Hm? I do not see a size reduction. pahole(1) tells me [for a base of 
v2.6.31-rc1-103-g644fc2c] the size is the same before and after.


--- p.1	2009-08-29 18:45:37.996787299 +0200
+++ p.2	2009-08-29 18:43:08.152753849 +0200
@@ -21824,10 +21824,8 @@ struct ipv6_pinfo {
 	struct in6_addr            saddr;                /*     0    16 */
 	struct in6_addr            rcv_saddr;            /*    16    16 */
 	struct in6_addr            daddr;                /*    32    16 */
-	struct in6_pktinfo         sticky_pktinfo;       /*    48    20 */
-
-	/* XXX 4 bytes hole, try to pack */
-
+	__u32                      dst_cookie;           /*    48     4 */
+	struct in6_pktinfo         sticky_pktinfo;       /*    52    20 */
 	/* --- cacheline 1 boundary (64 bytes) was 8 bytes ago --- */
 	struct in6_addr *          daddr_cache;          /*    72     8 */
 	struct in6_addr *          saddr_cache;          /*    80     8 */
@@ -21862,7 +21860,9 @@ struct ipv6_pinfo {
 	__u8                       ipv6only:1;           /*   106: 3  1 */
 	__u8                       srcprefs:3;           /*   106: 0  1 */
 	__u8                       tclass;               /*   107     1 */
-	__u32                      dst_cookie;           /*   108     4 */
+
+	/* XXX 4 bytes hole, try to pack */
+
 	struct ipv6_mc_socklist *  ipv6_mc_list;         /*   112     8 */
 	struct ipv6_ac_socklist *  ipv6_ac_list;         /*   120     8 */
 	/* --- cacheline 2 boundary (128 bytes) --- */

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

* Re: [PATCH 03/11] TProxy: reuse a 32bit hole in struct ipv6_pinfo
  2009-08-29 16:46   ` Jan Engelhardt
@ 2009-08-30  6:56     ` Balazs Scheidler
  2009-08-30 10:49       ` Jan Engelhardt
  2009-08-31 12:27       ` Patrick McHardy
  0 siblings, 2 replies; 24+ messages in thread
From: Balazs Scheidler @ 2009-08-30  6:56 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netfilter-devel, tproxy, Harry Mason

On Sat, 2009-08-29 at 18:46 +0200, Jan Engelhardt wrote:
> On Sunday 2009-08-23 11:02, Balazs Scheidler wrote:
> 
> >While looking for a place to add a new bitfield in ipv6_pinfo,
> >I've found a 32 bit hole (in 64 bit mode) at the beginning of the struct.
> >Since dst_cookie is used in the output fastpath, I've moved this field to
> >fill the hole, thus decreasing the struct size on 64 bit platforms by
> >4 bytes.
> 
> Hm? I do not see a size reduction. pahole(1) tells me [for a base of 
> v2.6.31-rc1-103-g644fc2c] the size is the same before and after.

you are right. I was inserting another bitfield and with that the size
didn't grow. at the end the bitfield wasn't needed, but I still felt
that dst_cookie should be moved to the first cacheline. it is used in
the output fastpath.

However since that's not necessarily worth in itself I can completely
drop this patch.

An updated version follows. 

By the way, what should be the proper procedure for posting patches that
are tproxy specific but touch the core networking code? Should those go
through Patrick, or should I just post them to netdev? Or just
cross-post the patch series to both lists?

commit 5ddc846b926be02c6cab93406d6e8adb1e3c9124
Author: Balazs Scheidler <bazsi@balabit.hu>
Date:   Sun Aug 30 08:52:01 2009 +0200

    TProxy: move dst_cookie to the first cacheline in ipv6_pinfo
    
    While looking for a place to add a new bitfield in ipv6_pinfo,
    I've found a 32 bit hole (in 64 bit mode) at the beginning of the struct.
    Since dst_cookie is used in the output fastpath, I've moved this field to
    fill the hole. The original place of dst_cookie is now empty, but
    can become a place to add further fields to the struct.
    
    Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>

diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index c662efa..be4c9c6 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -285,6 +285,7 @@ struct ipv6_pinfo {
 	struct in6_addr 	saddr;
 	struct in6_addr 	rcv_saddr;
 	struct in6_addr		daddr;
+	__u32			dst_cookie;
 	struct in6_pktinfo	sticky_pktinfo;
 	struct in6_addr		*daddr_cache;
 #ifdef CONFIG_IPV6_SUBTREES
@@ -348,7 +349,7 @@ struct ipv6_pinfo {
 						 */
 	__u8			tclass;
 
-	__u32			dst_cookie;
+	/* 32 bits hole on 64 bit platforms */
 
 	struct ipv6_mc_socklist	*ipv6_mc_list;
 	struct ipv6_ac_socklist	*ipv6_ac_list;


> 
> 
> --- p.1	2009-08-29 18:45:37.996787299 +0200
> +++ p.2	2009-08-29 18:43:08.152753849 +0200
> @@ -21824,10 +21824,8 @@ struct ipv6_pinfo {
>  	struct in6_addr            saddr;                /*     0    16 */
>  	struct in6_addr            rcv_saddr;            /*    16    16 */
>  	struct in6_addr            daddr;                /*    32    16 */
> -	struct in6_pktinfo         sticky_pktinfo;       /*    48    20 */
> -
> -	/* XXX 4 bytes hole, try to pack */
> -
> +	__u32                      dst_cookie;           /*    48     4 */
> +	struct in6_pktinfo         sticky_pktinfo;       /*    52    20 */
>  	/* --- cacheline 1 boundary (64 bytes) was 8 bytes ago --- */
>  	struct in6_addr *          daddr_cache;          /*    72     8 */
>  	struct in6_addr *          saddr_cache;          /*    80     8 */
> @@ -21862,7 +21860,9 @@ struct ipv6_pinfo {
>  	__u8                       ipv6only:1;           /*   106: 3  1 */
>  	__u8                       srcprefs:3;           /*   106: 0  1 */
>  	__u8                       tclass;               /*   107     1 */
> -	__u32                      dst_cookie;           /*   108     4 */
> +
> +	/* XXX 4 bytes hole, try to pack */
> +
>  	struct ipv6_mc_socklist *  ipv6_mc_list;         /*   112     8 */
>  	struct ipv6_ac_socklist *  ipv6_ac_list;         /*   120     8 */
>  	/* --- cacheline 2 boundary (128 bytes) --- */
> 
-- 
Bazsi



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

* Re: [PATCH 03/11] TProxy: reuse a 32bit hole in struct ipv6_pinfo
  2009-08-30  6:56     ` Balazs Scheidler
@ 2009-08-30 10:49       ` Jan Engelhardt
  2009-08-31 12:27       ` Patrick McHardy
  1 sibling, 0 replies; 24+ messages in thread
From: Jan Engelhardt @ 2009-08-30 10:49 UTC (permalink / raw)
  To: Balazs Scheidler; +Cc: netfilter-devel, tproxy, Harry Mason


On Sunday 2009-08-30 08:56, Balazs Scheidler wrote:
>
>By the way, what should be the proper procedure for posting patches that
>are tproxy specific but touch the core networking code? Should those go
>through Patrick, or should I just post them to netdev? Or just
>cross-post the patch series to both lists?

Depends on whether you are trying to get attention on a patch or
whether you go for sneaky inclusion ;-)


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

* Re: [PATCH 03/11] TProxy: reuse a 32bit hole in struct ipv6_pinfo
  2009-08-30  6:56     ` Balazs Scheidler
  2009-08-30 10:49       ` Jan Engelhardt
@ 2009-08-31 12:27       ` Patrick McHardy
  1 sibling, 0 replies; 24+ messages in thread
From: Patrick McHardy @ 2009-08-31 12:27 UTC (permalink / raw)
  To: Balazs Scheidler; +Cc: Jan Engelhardt, netfilter-devel, tproxy, Harry Mason

Balazs Scheidler wrote:
> By the way, what should be the proper procedure for posting patches that
> are tproxy specific but touch the core networking code? Should those go
> through Patrick, or should I just post them to netdev? Or just
> cross-post the patch series to both lists?

When further netfilter patches depend on those changes, they should
probably go through me, but you should CC netdev and the maintainers
of the code in question.

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

* Re: [PATCH 00/11] TProxy for IPv6
  2009-08-26 14:03 [PATCH 00/11] TProxy for IPv6 Balazs Scheidler
                   ` (10 preceding siblings ...)
  2009-08-24 12:52 ` [PATCH 11/11] TProxy: added IPv6 support to the socket match Balazs Scheidler
@ 2009-09-04  6:07 ` Amos Jeffries
  2009-09-04  9:28   ` Jan Engelhardt
                     ` (2 more replies)
  11 siblings, 3 replies; 24+ messages in thread
From: Amos Jeffries @ 2009-09-04  6:07 UTC (permalink / raw)
  To: Balazs Scheidler; +Cc: netfilter-devel, tproxy, Harry Mason

Balazs Scheidler wrote:
> [ Sorry if this reaches you twice, I sent to the wrong address the first time ]
> 
> I've just pushed a set of patches that implement TProxy for IPv6 to
> 
> http://git.balabit.hu/bazsi/tproxy-2.6.git
> 
> The patches are also posted in reply to this mail.
> 
> Although some work is still needed, basic testing shows that it works all
> right.  
> 
> The accompanying iptables patches are available at
> 
> http://git.balabit.hu/bazsi/iptables-tproxy.git
> 
> There are some things left to do:
> 
>   * the recognition of related ICMPv6 packets missing (from xt_socket.c)
> 
>   * I should probably split xt_TPROXY/xt_socket to IPv4 and IPv6 modules, as
>     right now those depend on both stacks at the same time.
> 
> I'm on a holiday right now, thus I might not respond to comments in a timely
> manner, however I'm interested in any comments/feedback nevertheless.
> 
> Harry, I didn't remember that you actually wanted to work on TProxy for
> IPv6, I just vaguely remembered that there was someone asking for IPv6
> support, thus I implemented this without being in the know.  If you started
> hacking, I hope that we didn't completely duplicate effort.  I'd appreciate
> help in the missing bits and/or testing whichever fits you best.
> 
> Also, I have written a Python test script to test TProxy functionality
> automatically both for IPv4 and IPv6, I can post that as well if anyone is
> interested.

I'm interested :)

Now that you have done this I'm going to have to find a robust userland 
run-time test to see if the underlying TPROXY is v4-only or v6-enabled. 
If anyone has suggestions they would be welcome.

Thank you very much by the way.


Amos Jeffries
Squid Proxy Project


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

* Re: [PATCH 00/11] TProxy for IPv6
  2009-09-04  6:07 ` [PATCH 00/11] TProxy for IPv6 Amos Jeffries
@ 2009-09-04  9:28   ` Jan Engelhardt
  2009-09-14 12:20     ` Amos Jeffries
  2009-09-08 18:42   ` Balazs Scheidler
       [not found]   ` <1252059564.7452.17.camel@nyarlathotep>
  2 siblings, 1 reply; 24+ messages in thread
From: Jan Engelhardt @ 2009-09-04  9:28 UTC (permalink / raw)
  To: Amos Jeffries; +Cc: Balazs Scheidler, netfilter-devel, tproxy, Harry Mason


On Friday 2009-09-04 08:07, Amos Jeffries wrote:
>>
>> Also, I have written a Python test script to test TProxy functionality
>> automatically both for IPv4 and IPv6, I can post that as well if anyone is
>> interested.
>
> I'm interested :)
>
> Now that you have done this I'm going to have to find a robust userland
> run-time test to see if the underlying TPROXY is v4-only or v6-enabled. If
> anyone has suggestions they would be welcome.

Would this perhaps suffice?

assert(socket(PF_INET6, ...) >= 0);
assert(setsockopt(fd, SOL_IP, IP_TRANSPARENT, ...) == 0);
assert(bind(fd, {::2}) == 0);

At least something like that I remember to have used to determine
tproxy-2.x ipv4 availability in the days. (I.e. seeing if setsockopt
failed.)

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

* Re: [PATCH 00/11] TProxy for IPv6
  2009-09-04  6:07 ` [PATCH 00/11] TProxy for IPv6 Amos Jeffries
  2009-09-04  9:28   ` Jan Engelhardt
@ 2009-09-08 18:42   ` Balazs Scheidler
  2009-09-11 12:12     ` Amos Jeffries
       [not found]   ` <1252059564.7452.17.camel@nyarlathotep>
  2 siblings, 1 reply; 24+ messages in thread
From: Balazs Scheidler @ 2009-09-08 18:42 UTC (permalink / raw)
  To: Amos Jeffries; +Cc: netfilter-devel, tproxy, Harry Mason

On Fri, 2009-09-04 at 18:07 +1200, Amos Jeffries wrote:
> Balazs Scheidler wrote:
> > [ Sorry if this reaches you twice, I sent to the wrong address the first time ]
> > 
> > I've just pushed a set of patches that implement TProxy for IPv6 to
> > 
> > http://git.balabit.hu/bazsi/tproxy-2.6.git
> > 
> > The patches are also posted in reply to this mail.
> > 
> > Although some work is still needed, basic testing shows that it works all
> > right.  
> > 
> > The accompanying iptables patches are available at
> > 
> > http://git.balabit.hu/bazsi/iptables-tproxy.git
> > 
> > There are some things left to do:
> > 
> >   * the recognition of related ICMPv6 packets missing (from xt_socket.c)
> > 
> >   * I should probably split xt_TPROXY/xt_socket to IPv4 and IPv6 modules, as
> >     right now those depend on both stacks at the same time.
> > 
> > I'm on a holiday right now, thus I might not respond to comments in a timely
> > manner, however I'm interested in any comments/feedback nevertheless.
> > 
> > Harry, I didn't remember that you actually wanted to work on TProxy for
> > IPv6, I just vaguely remembered that there was someone asking for IPv6
> > support, thus I implemented this without being in the know.  If you started
> > hacking, I hope that we didn't completely duplicate effort.  I'd appreciate
> > help in the missing bits and/or testing whichever fits you best.
> > 
> > Also, I have written a Python test script to test TProxy functionality
> > automatically both for IPv4 and IPv6, I can post that as well if anyone is
> > interested.
> 
> I'm interested :)
> 
> Now that you have done this I'm going to have to find a robust userland 
> run-time test to see if the underlying TPROXY is v4-only or v6-enabled. 
> If anyone has suggestions they would be welcome.
> 
> Thank you very much by the way.

The script I wrote is not a runtime test, it is a functional test that
tests various TPROXY scenarios for proper functionality.

It basically assumes that:
  1) you run it on the 'client' host, and it has ssh connectivity to the
'tproxy' host
  2) it assumes that IP/route configuration is already prepared
  3) it uses hardwired IP addresses, but generates iptables/ip6tables
rules automatically

I used a virtual machine running on my development computer to do the
testing.

IPV6 topology:

dead:1::1/64 is the client
dead:1::2/64 is the proxy box
dead:2::1/64 is the server behind the proxy box

The script basically copies an agent script to the other box
(test-agent.py) and uses that to change iptables config/start listeners
as needed. Then initiates tcp/udp connections to the target host and
checks if the proper listener received the new connection or a bogus
one.

I'm not that responsive these days, but I'm glad to help.

Last but not least, here's the gitweb interface:

http://git.balabit.hu/?p=bazsi/tproxy-test.git;a=summary

and the git URL

git://git.balabit.hu/bazsi/tproxy-test.git


-- 
Bazsi



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

* Re: [PATCH 00/11] TProxy for IPv6
  2009-09-08 18:42   ` Balazs Scheidler
@ 2009-09-11 12:12     ` Amos Jeffries
  0 siblings, 0 replies; 24+ messages in thread
From: Amos Jeffries @ 2009-09-11 12:12 UTC (permalink / raw)
  To: Balazs Scheidler; +Cc: netfilter-devel, tproxy, Harry Mason

Balazs Scheidler wrote:
> On Fri, 2009-09-04 at 18:07 +1200, Amos Jeffries wrote:
>> Balazs Scheidler wrote:
>>> [ Sorry if this reaches you twice, I sent to the wrong address the first time ]
>>>
>>> I've just pushed a set of patches that implement TProxy for IPv6 to
>>>
>>> http://git.balabit.hu/bazsi/tproxy-2.6.git
>>>
>>> The patches are also posted in reply to this mail.
>>>
>>> Although some work is still needed, basic testing shows that it works all
>>> right.  
>>>
>>> The accompanying iptables patches are available at
>>>
>>> http://git.balabit.hu/bazsi/iptables-tproxy.git
>>>
>>> There are some things left to do:
>>>
>>>   * the recognition of related ICMPv6 packets missing (from xt_socket.c)
>>>
>>>   * I should probably split xt_TPROXY/xt_socket to IPv4 and IPv6 modules, as
>>>     right now those depend on both stacks at the same time.
>>>
>>> I'm on a holiday right now, thus I might not respond to comments in a timely
>>> manner, however I'm interested in any comments/feedback nevertheless.
>>>
>>> Harry, I didn't remember that you actually wanted to work on TProxy for
>>> IPv6, I just vaguely remembered that there was someone asking for IPv6
>>> support, thus I implemented this without being in the know.  If you started
>>> hacking, I hope that we didn't completely duplicate effort.  I'd appreciate
>>> help in the missing bits and/or testing whichever fits you best.
>>>
>>> Also, I have written a Python test script to test TProxy functionality
>>> automatically both for IPv4 and IPv6, I can post that as well if anyone is
>>> interested.
>> I'm interested :)
>>
>> Now that you have done this I'm going to have to find a robust userland 
>> run-time test to see if the underlying TPROXY is v4-only or v6-enabled. 
>> If anyone has suggestions they would be welcome.
>>
>> Thank you very much by the way.
> 
> The script I wrote is not a runtime test, it is a functional test that
> tests various TPROXY scenarios for proper functionality.
> 
> It basically assumes that:
>   1) you run it on the 'client' host, and it has ssh connectivity to the
> 'tproxy' host
>   2) it assumes that IP/route configuration is already prepared
>   3) it uses hardwired IP addresses, but generates iptables/ip6tables
> rules automatically
> 
> I used a virtual machine running on my development computer to do the
> testing.
> 
> IPV6 topology:
> 
> dead:1::1/64 is the client
> dead:1::2/64 is the proxy box
> dead:2::1/64 is the server behind the proxy box
> 
> The script basically copies an agent script to the other box
> (test-agent.py) and uses that to change iptables config/start listeners
> as needed. Then initiates tcp/udp connections to the target host and
> checks if the proper listener received the new connection or a bogus
> one.
> 
> I'm not that responsive these days, but I'm glad to help.
> 
> Last but not least, here's the gitweb interface:
> 
> http://git.balabit.hu/?p=bazsi/tproxy-test.git;a=summary
> 
> and the git URL
> 
> git://git.balabit.hu/bazsi/tproxy-test.git
> 

I thought is was something like that. Thanks.
This is going to be helpful testing the various distro packages to see 
whats they have turned on/off. The newest FAQ for our users.

AYJ

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

* Re: [PATCH 00/11] TProxy for IPv6
       [not found]     ` <1252435673.32029.45.camel@bzorp.balabit>
@ 2009-09-14  7:41       ` Balazs Scheidler
  0 siblings, 0 replies; 24+ messages in thread
From: Balazs Scheidler @ 2009-09-14  7:41 UTC (permalink / raw)
  To: Harry Mason; +Cc: Amos Jeffries, netfilter-devel

Hi,

This is just a short note that I've updated the git repository and added
your patches to the tree (the UDP and ICMP related bits), although I
haven't had time to write proper changelogs and integrate related
patches to one, I figured it's better to say I did so instead of waiting
for code to rot in the git repo.

I hope I get another shot to do a formal release in the coming days.

On Tue, 2009-09-08 at 20:47 +0200, Balazs Scheidler wrote:
> On Fri, 2009-09-04 at 11:19 +0100, Harry Mason wrote:
> > On Fri, 2009-09-04 at 18:07 +1200, Amos Jeffries wrote:
> > > Balazs Scheidler wrote:
> > > 
> > > > I've just pushed a set of patches that implement TProxy for IPv6 to
> > > > 
> > > > http://git.balabit.hu/bazsi/tproxy-2.6.git
> > > 
> > > I'm interested :)
> > > 
> > > Amos Jeffries
> > > Squid Proxy Project
> > 
> > In TProxy for IPv4 there's support for the SO_ORIGINAL_DST sockopt, which returns
> > the original destination of the request. I needed this option in my prototype to
> > do TRT but I assume Squid will need it too for transparent proxying.
> > 
> > I've ported this feature to Balazs's implementation; Git bundle attached.
> > 
> > Balazs, does this look OK to be merged with your patches?
> > Amos, this might help you test Squid with IPv6; hopefully the API I chose won't
> > need to change but I'm very new to kernel development.
> 
> I'll check what I could pick from this and your previous bundle (which
> as I see was only sent in private) and push another round of patches.
> 
-- 
Bazsi


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

* Re: [PATCH 00/11] TProxy for IPv6
  2009-09-04  9:28   ` Jan Engelhardt
@ 2009-09-14 12:20     ` Amos Jeffries
  2009-09-14 12:29       ` Jan Engelhardt
  0 siblings, 1 reply; 24+ messages in thread
From: Amos Jeffries @ 2009-09-14 12:20 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Balazs Scheidler, netfilter-devel, tproxy, Harry Mason

Jan Engelhardt wrote:
> On Friday 2009-09-04 08:07, Amos Jeffries wrote:
>>> Also, I have written a Python test script to test TProxy functionality
>>> automatically both for IPv4 and IPv6, I can post that as well if anyone is
>>> interested.
>> I'm interested :)
>>
>> Now that you have done this I'm going to have to find a robust userland
>> run-time test to see if the underlying TPROXY is v4-only or v6-enabled. If
>> anyone has suggestions they would be welcome.
> 
> Would this perhaps suffice?
> 
> assert(socket(PF_INET6, ...) >= 0);
> assert(setsockopt(fd, SOL_IP, IP_TRANSPARENT, ...) == 0);
> assert(bind(fd, {::2}) == 0);
> 
> At least something like that I remember to have used to determine
> tproxy-2.x ipv4 availability in the days. (I.e. seeing if setsockopt
> failed.)

Thanks Jan. I gave a variant that a try. It does seem to detect the 
feature support nicely.

However, trying to bind the real IP:port soon after results in "(98) 
Address already in use" even with a shutdown(tmp_sock,...) added to 
clean up after the test.

AYJ

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

* Re: [PATCH 00/11] TProxy for IPv6
  2009-09-14 12:20     ` Amos Jeffries
@ 2009-09-14 12:29       ` Jan Engelhardt
  2009-09-15 11:58         ` Amos Jeffries
  0 siblings, 1 reply; 24+ messages in thread
From: Jan Engelhardt @ 2009-09-14 12:29 UTC (permalink / raw)
  To: Amos Jeffries; +Cc: Balazs Scheidler, netfilter-devel, tproxy, Harry Mason


On Monday 2009-09-14 14:20, Amos Jeffries wrote:
>> assert(socket(PF_INET6, ...) >= 0);
>> assert(setsockopt(fd, SOL_IP, IP_TRANSPARENT, ...) == 0);
>> assert(bind(fd, {::2}) == 0);
>>
>> At least something like that I remember to have used to determine
>> tproxy-2.x ipv4 availability in the days. (I.e. seeing if setsockopt
>> failed.)
>
> Thanks Jan. I gave a variant that a try. It does seem to detect the feature
> support nicely.
>
> However, trying to bind the real IP:port soon after results in "(98) Address
> already in use" even with a shutdown(tmp_sock,...) added to clean up after the
> test.

Odd, since binding to port 0 should give you a random one,
and there are plenty.
Does SO_REUSEADDR help it a bit?

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

* Re: [PATCH 00/11] TProxy for IPv6
  2009-09-14 12:29       ` Jan Engelhardt
@ 2009-09-15 11:58         ` Amos Jeffries
  0 siblings, 0 replies; 24+ messages in thread
From: Amos Jeffries @ 2009-09-15 11:58 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Balazs Scheidler, netfilter-devel, tproxy, Harry Mason

Jan Engelhardt wrote:
> On Monday 2009-09-14 14:20, Amos Jeffries wrote:
>>> assert(socket(PF_INET6, ...) >= 0);
>>> assert(setsockopt(fd, SOL_IP, IP_TRANSPARENT, ...) == 0);
>>> assert(bind(fd, {::2}) == 0);
>>>
>>> At least something like that I remember to have used to determine
>>> tproxy-2.x ipv4 availability in the days. (I.e. seeing if setsockopt
>>> failed.)
>> Thanks Jan. I gave a variant that a try. It does seem to detect the feature
>> support nicely.
>>
>> However, trying to bind the real IP:port soon after results in "(98) Address
>> already in use" even with a shutdown(tmp_sock,...) added to clean up after the
>> test.
> 
> Odd, since binding to port 0 should give you a random one,
> and there are plenty.
> Does SO_REUSEADDR help it a bit?

um... thanks for the hint.
I was re-using a handy address object without un-setting the port.
It works fully now.

AYJ

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

end of thread, other threads:[~2009-09-15 11:58 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-26 14:03 [PATCH 00/11] TProxy for IPv6 Balazs Scheidler
2009-08-15  8:00 ` [PATCH 01/11] TProxy: kick out TIME_WAIT sockets in case a new connection comes in with the same tuple Balazs Scheidler
2009-08-15 12:01 ` [PATCH 02/11] TProxy: add lookup type checks for UDP in nf_tproxy_get_sock_v4() Balazs Scheidler
2009-08-23  9:02 ` [PATCH 03/11] TProxy: reuse a 32bit hole in struct ipv6_pinfo Balazs Scheidler
2009-08-29 16:46   ` Jan Engelhardt
2009-08-30  6:56     ` Balazs Scheidler
2009-08-30 10:49       ` Jan Engelhardt
2009-08-31 12:27       ` Patrick McHardy
2009-08-23  9:11 ` [PATCH 04/11] TProxy: split off ipv6 defragmentation to a separate module Balazs Scheidler
2009-08-23  9:16 ` [PATCH 05/11] TProxy: added const specifiers to udp lookup functions Balazs Scheidler
2009-08-23  9:19 ` [PATCH 06/11] TProxy: added udp6_lib_lookup function Balazs Scheidler
2009-08-24 12:47 ` [PATCH 07/11] TProxy: implement IPv6 "local" routing type Balazs Scheidler
2009-08-24 12:48 ` [PATCH 08/11] TProxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is enabled Balazs Scheidler
2009-08-24 12:51 ` [PATCH 09/11] TProxy: added IPv6 socket lookup function to nf_tproxy_core Balazs Scheidler
2009-08-24 12:51 ` [PATCH 10/11] TProxy: added IPv6 support to the TPROXY target Balazs Scheidler
2009-08-24 12:52 ` [PATCH 11/11] TProxy: added IPv6 support to the socket match Balazs Scheidler
2009-09-04  6:07 ` [PATCH 00/11] TProxy for IPv6 Amos Jeffries
2009-09-04  9:28   ` Jan Engelhardt
2009-09-14 12:20     ` Amos Jeffries
2009-09-14 12:29       ` Jan Engelhardt
2009-09-15 11:58         ` Amos Jeffries
2009-09-08 18:42   ` Balazs Scheidler
2009-09-11 12:12     ` Amos Jeffries
     [not found]   ` <1252059564.7452.17.camel@nyarlathotep>
     [not found]     ` <1252435673.32029.45.camel@bzorp.balabit>
2009-09-14  7:41       ` Balazs Scheidler

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