SOURCES: kernel-tproxy.patch (NEW) - concatenated files from http://www.bal...

zbyniu zbyniu at pld-linux.org
Wed May 14 19:27:11 CEST 2008


Author: zbyniu                       Date: Wed May 14 17:27:11 2008 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- concatenated files from http://www.balabit.com/downloads/files/tproxy/tproxy-kernel-2.6.25-20080509-164605-1210344365.tar.bz2

---- Files affected:
SOURCES:
   kernel-tproxy.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/kernel-tproxy.patch
diff -u /dev/null SOURCES/kernel-tproxy.patch:1.1
--- /dev/null	Wed May 14 19:27:11 2008
+++ SOURCES/kernel-tproxy.patch	Wed May 14 19:27:05 2008
@@ -0,0 +1,1761 @@
+From f01a1b1a0cb61eaadebd9d910286c5f382a4928c Mon Sep 17 00:00:00 2001
+From: KOVACS Krisztian <hidden at sch.bme.hu>
+Date: Mon, 28 Apr 2008 14:46:46 +0200
+Subject: [PATCH] Loosen source address check on IPv4 output
+
+ip_route_output() contains a check to make sure that no flows with
+non-local source IP addresses are routed. This obviously makes using
+such addresses impossible.
+
+This patch introduces a flowi flag which makes omitting this check
+possible. The new flag provides a way of handling transparent and
+non-transparent connections differently.
+
+Signed-off-by: Julian Anastasov <ja at ssi.bg>
+Signed-off-by: KOVACS Krisztian <hidden at sch.bme.hu>
+Acked-by: Patrick McHardy <kaber at trash.net>
+---
+ include/net/flow.h |    1 +
+ net/ipv4/route.c   |   20 +++++++++++++-------
+ 2 files changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/include/net/flow.h b/include/net/flow.h
+index ad16e00..b45a5e4 100644
+--- a/include/net/flow.h
++++ b/include/net/flow.h
+@@ -48,6 +48,7 @@ struct flowi {
+ 
+ 	__u8	proto;
+ 	__u8	flags;
++#define FLOWI_FLAG_ANYSRC 0x01
+ 	union {
+ 		struct {
+ 			__be16	sport;
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index ce25a13..c0ed024 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2307,11 +2307,6 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
+ 		    ipv4_is_zeronet(oldflp->fl4_src))
+ 			goto out;
+ 
+-		/* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
+-		dev_out = ip_dev_find(net, oldflp->fl4_src);
+-		if (dev_out == NULL)
+-			goto out;
+-
+ 		/* I removed check for oif == dev_out->oif here.
+ 		   It was wrong for two reasons:
+ 		   1. ip_dev_find(net, saddr) can return wrong iface, if saddr
+@@ -2323,6 +2318,11 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
+ 		if (oldflp->oif == 0
+ 		    && (ipv4_is_multicast(oldflp->fl4_dst) ||
+ 			oldflp->fl4_dst == htonl(0xFFFFFFFF))) {
++			/* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
++			dev_out = ip_dev_find(net, oldflp->fl4_src);
++			if (dev_out == NULL)
++				goto out;
++
+ 			/* Special hack: user can direct multicasts
+ 			   and limited broadcast via necessary interface
+ 			   without fiddling with IP_MULTICAST_IF or IP_PKTINFO.
+@@ -2341,9 +2341,15 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
+ 			fl.oif = dev_out->ifindex;
+ 			goto make_route;
+ 		}
+-		if (dev_out)
++
++		if (!(oldflp->flags & FLOWI_FLAG_ANYSRC)) {
++			/* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
++			dev_out = ip_dev_find(net, oldflp->fl4_src);
++			if (dev_out == NULL)
++				goto out;
+ 			dev_put(dev_out);
+-		dev_out = NULL;
++			dev_out = NULL;
++		}
+ 	}
+ 
+ 
+-- 
+1.5.2.5
+
+From cc2f0afbffaad66b7794e4b4e5d50609f3571fbd Mon Sep 17 00:00:00 2001
+From: KOVACS Krisztian <hidden at sch.bme.hu>
+Date: Mon, 28 Apr 2008 14:46:48 +0200
+Subject: [PATCH] Implement IP_TRANSPARENT socket option
+
+This patch introduces the IP_TRANSPARENT socket option: enabling that will make
+the IPv4 routing omit the non-local source address check on output. Setting
+IP_TRANSPARENT requires NET_ADMIN capability.
+
+Signed-off-by: KOVACS Krisztian <hidden at sch.bme.hu>
+Acked-by: Patrick McHardy <kaber at trash.net>
+---
+ include/linux/in.h               |    1 +
+ include/net/inet_sock.h          |    3 ++-
+ include/net/inet_timewait_sock.h |    3 ++-
+ net/ipv4/inet_timewait_sock.c    |    1 +
+ net/ipv4/ip_sockglue.c           |   12 +++++++++++-
+ 5 files changed, 17 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/in.h b/include/linux/in.h
+index 4065313..db458be 100644
+--- a/include/linux/in.h
++++ b/include/linux/in.h
+@@ -75,6 +75,7 @@ struct in_addr {
+ #define IP_IPSEC_POLICY	16
+ #define IP_XFRM_POLICY	17
+ #define IP_PASSSEC	18
++#define IP_TRANSPARENT	19
+ 
+ /* BSD compatibility */
+ #define IP_RECVRETOPTS	IP_RETOPTS
+diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
+index a42cd63..2fafaab 100644
+--- a/include/net/inet_sock.h
++++ b/include/net/inet_sock.h
+@@ -128,7 +128,8 @@ struct inet_sock {
+ 				is_icsk:1,
+ 				freebind:1,
+ 				hdrincl:1,
+-				mc_loop:1;
++				mc_loop:1,
++				transparent:1;
+ 	int			mc_index;
+ 	__be32			mc_addr;
+ 	struct ip_mc_socklist	*mc_list;
+diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
+index 95c660c..8d983a2 100644
+--- a/include/net/inet_timewait_sock.h
++++ b/include/net/inet_timewait_sock.h
+@@ -128,7 +128,8 @@ struct inet_timewait_sock {
+ 	__be16			tw_dport;
+ 	__u16			tw_num;
+ 	/* And these are ours. */
+-	__u8			tw_ipv6only:1;
++	__u8			tw_ipv6only:1,
++				tw_transparent:1;
+ 	/* 15 bits hole, try to pack */
+ 	__u16			tw_ipv6_offset;
+ 	unsigned long		tw_ttd;
+diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
+index ce16e9a..af16fd4 100644
+--- a/net/ipv4/inet_timewait_sock.c
++++ b/net/ipv4/inet_timewait_sock.c
+@@ -124,6 +124,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat
+ 		tw->tw_reuse	    = sk->sk_reuse;
+ 		tw->tw_hash	    = sk->sk_hash;
+ 		tw->tw_ipv6only	    = 0;
++		tw->tw_transparent  = inet->transparent;
+ 		tw->tw_prot	    = sk->sk_prot_creator;
+ 		twsk_net_set(tw, hold_net(sock_net(sk)));
+ 		atomic_set(&tw->tw_refcnt, 1);
+diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
+index d8adfd4..a05bec6 100644
+--- a/net/ipv4/ip_sockglue.c
++++ b/net/ipv4/ip_sockglue.c
+@@ -420,7 +420,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
+ 			     (1<<IP_TTL) | (1<<IP_HDRINCL) |
+ 			     (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
+ 			     (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
+-			     (1<<IP_PASSSEC))) ||
++			     (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT))) ||
+ 	    optname == IP_MULTICAST_TTL ||
+ 	    optname == IP_MULTICAST_LOOP) {
+ 		if (optlen >= sizeof(int)) {
+@@ -879,6 +879,16 @@ static int do_ip_setsockopt(struct sock *sk, int level,
+ 		err = xfrm_user_policy(sk, optname, optval, optlen);
+ 		break;
+ 
++	case IP_TRANSPARENT:
++		if (!capable(CAP_NET_ADMIN)) {
++			err = -EPERM;
++			break;
++		}
++		if (optlen < 1)
++			goto e_inval;
++		inet->transparent = !!val;
++		break;
++
+ 	default:
+ 		err = -ENOPROTOOPT;
+ 		break;
+-- 
+1.5.2.5
+
+From b0f9031d33741ccd7745112d425d465035444859 Mon Sep 17 00:00:00 2001
+From: KOVACS Krisztian <hidden at sch.bme.hu>
+Date: Mon, 28 Apr 2008 14:46:48 +0200
+Subject: [PATCH] Allow binding to non-local addresses if IP_TRANSPARENT is set
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 8bit
+
+Setting IP_TRANSPARENT is not really useful without allowing non-local
+binds for the socket. To make user-space code simpler we allow these binds
+even if IP_TRANSPARENT is set but IP_FREEBIND is not.
+
+Signed-off-by: Tóth László Attila <panther at balabit.hu>
+Acked-by: Patrick McHardy <kaber at trash.net>
+---
+ net/ipv4/af_inet.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
+index f2b5270..d2d1001 100644
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -475,7 +475,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
+ 	 */
+ 	err = -EADDRNOTAVAIL;
+ 	if (!sysctl_ip_nonlocal_bind &&
+-	    !inet->freebind &&
++	    !(inet->freebind || inet->transparent) &&
+ 	    addr->sin_addr.s_addr != htonl(INADDR_ANY) &&
+ 	    chk_addr_ret != RTN_LOCAL &&
+ 	    chk_addr_ret != RTN_MULTICAST &&
+-- 
+1.5.2.5
+
+From 2b3cf4f3e3aa34ff42d17b202b945db2c5c563b2 Mon Sep 17 00:00:00 2001
+From: KOVACS Krisztian <hidden at sch.bme.hu>
+Date: Mon, 28 Apr 2008 14:46:49 +0200
+Subject: [PATCH] Make inet_sock.h independent of route.h
+
+inet_iif() in inet_sock.h requires route.h. Since users of inet_iif()
+usually require other route.h functionality anyway this patch moves
+inet_iif() to route.h.
+
+Signed-off-by: KOVACS Krisztian <hidden at sch.bme.hu>
+---
+ include/net/inet_sock.h            |    7 -------
+ include/net/route.h                |    5 +++++
+ net/ipv4/netfilter/nf_nat_helper.c |    1 +
+ net/ipv4/syncookies.c              |    1 +
+ net/ipv6/af_inet6.c                |    1 +
+ 5 files changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
+index 2fafaab..5ca683e 100644
+--- a/include/net/inet_sock.h
++++ b/include/net/inet_sock.h
+@@ -24,7 +24,6 @@
+ #include <net/flow.h>
+ #include <net/sock.h>
+ #include <net/request_sock.h>
+-#include <net/route.h>
+ 
+ /** struct ip_options - IP Options
+  *
+@@ -192,10 +191,4 @@ static inline int inet_sk_ehashfn(const struct sock *sk)
+ 	return inet_ehashfn(laddr, lport, faddr, fport);
+ }
+ 
+-
+-static inline int inet_iif(const struct sk_buff *skb)
+-{
+-	return skb->rtable->rt_iif;
+-}
+-
+ #endif	/* _INET_SOCK_H */
+diff --git a/include/net/route.h b/include/net/route.h
+index c633880..13e464f 100644
+--- a/include/net/route.h
++++ b/include/net/route.h
+@@ -204,6 +204,11 @@ static inline struct inet_peer *rt_get_peer(struct rtable *rt)
+ 	return rt->peer;
+ }
+ 
++static inline int inet_iif(const struct sk_buff *skb)
++{
++	return skb->rtable->rt_iif;
++}
++
+ extern ctl_table ipv4_route_table[];
+ 
+ #endif	/* _ROUTE_H */
+diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
+index 11976ea..112dcfa 100644
+--- a/net/ipv4/netfilter/nf_nat_helper.c
++++ b/net/ipv4/netfilter/nf_nat_helper.c
+@@ -16,6 +16,7 @@
+ #include <linux/udp.h>
+ #include <net/checksum.h>
+ #include <net/tcp.h>
++#include <net/route.h>
+ 
+ #include <linux/netfilter_ipv4.h>
+ #include <net/netfilter/nf_conntrack.h>
+diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
+index 73ba989..19a1037 100644
+--- a/net/ipv4/syncookies.c
++++ b/net/ipv4/syncookies.c
+@@ -18,6 +18,7 @@
+ #include <linux/cryptohash.h>
+ #include <linux/kernel.h>
+ #include <net/tcp.h>
++#include <net/route.h>
+ 
+ /* Timestamps: lowest 9 bits store TCP options */
+ #define TSBITS 9
+diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
+index 3c6aafb..f6645d2 100644
+--- a/net/ipv6/af_inet6.c
++++ b/net/ipv6/af_inet6.c
+@@ -52,6 +52,7 @@
+ #include <net/ipip.h>
+ #include <net/protocol.h>
+ #include <net/inet_common.h>
++#include <net/route.h>
+ #include <net/transp_v6.h>
+ #include <net/ip6_route.h>
+ #include <net/addrconf.h>
+-- 
+1.5.2.5
+
+From 03bf9d04e8a6d0dc994363c8133ff494226701ef Mon Sep 17 00:00:00 2001
+From: KOVACS Krisztian <hidden at sch.bme.hu>
+Date: Mon, 28 Apr 2008 14:46:50 +0200
+Subject: [PATCH] Conditionally enable transparent flow flag when connecting
+
+Set FLOWI_FLAG_ANYSRC in flowi->flags if the socket has the
+transparent socket option set. This way we selectively enable certain
+connections with non-local source addresses to be routed.
+
+Signed-off-by: KOVACS Krisztian <hidden at sch.bme.hu>
+---
+ include/net/route.h |    6 +++++-
+ 1 files changed, 5 insertions(+), 1 deletions(-)
+
+diff --git a/include/net/route.h b/include/net/route.h
+index 13e464f..2928618 100644
+--- a/include/net/route.h
++++ b/include/net/route.h
+@@ -27,7 +27,7 @@
+ #include <net/dst.h>
+ #include <net/inetpeer.h>
+ #include <net/flow.h>
+-#include <net/sock.h>
++#include <net/inet_sock.h>
+ #include <linux/in_route.h>
+ #include <linux/rtnetlink.h>
+ #include <linux/route.h>
+@@ -161,6 +161,10 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst,
+ 
+ 	int err;
+ 	struct net *net = sock_net(sk);
++
++	if (inet_sk(sk)->transparent)
++		fl.flags |= FLOWI_FLAG_ANYSRC;
++
+ 	if (!dst || !src) {
+ 		err = __ip_route_output_key(net, rp, &fl);
+ 		if (err)
+-- 
+1.5.2.5
+
+From 181680c6c0df4335bd8eeeafe06ea12e6918c3b7 Mon Sep 17 00:00:00 2001
+From: KOVACS Krisztian <hidden at sch.bme.hu>
+Date: Mon, 28 Apr 2008 14:46:50 +0200
+Subject: [PATCH] Handle TCP SYN+ACK/ACK/RST transparency
+
+The TCP stack sends out SYN+ACK/ACK/RST reply packets in response to
+incoming packets. The non-local source address check on output bites
+us again, as replies for transparently redirected traffic won't have a
+chance to leave the node.
+
+This patch selectively sets the FLOWI_FLAG_ANYSRC flag when doing
+the route lookup for those replies. Transparent replies are enabled if
+the listening socket has the transparent socket flag set.
+
+Signed-off-by: KOVACS Krisztian <hidden at sch.bme.hu>
+---
+ include/net/inet_sock.h         |    8 +++++++-
+ include/net/ip.h                |    9 +++++++++
+ net/ipv4/inet_connection_sock.c |    1 +
+ net/ipv4/ip_output.c            |    4 +++-
+ net/ipv4/syncookies.c           |    1 +
+ net/ipv4/tcp_ipv4.c             |   11 ++++++++---
+ 6 files changed, 29 insertions(+), 5 deletions(-)
+
+diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
+index 5ca683e..013e41d 100644
+--- a/include/net/inet_sock.h
++++ b/include/net/inet_sock.h
+@@ -71,7 +71,8 @@ struct inet_request_sock {
+ 				sack_ok	   : 1,
+ 				wscale_ok  : 1,
+ 				ecn_ok	   : 1,
+-				acked	   : 1;
++				acked	   : 1,
++				no_srccheck: 1;
+ 	struct ip_options	*opt;
+ };
+ 
+@@ -191,4 +192,9 @@ static inline int inet_sk_ehashfn(const struct sock *sk)
+ 	return inet_ehashfn(laddr, lport, faddr, fport);
+ }
+ 
++static inline __u8 inet_sk_flowi_flags(const struct sock *sk)
++{
++	return inet_sk(sk)->transparent ? FLOWI_FLAG_ANYSRC : 0;
++}
++
+ #endif	/* _INET_SOCK_H */
+diff --git a/include/net/ip.h b/include/net/ip.h
+index 6d7bcd5..c611608 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -29,6 +29,7 @@
+ 
+ #include <net/inet_sock.h>
+ #include <net/snmp.h>
++#include <net/flow.h>
+ 
+ struct sock;
+ 
+@@ -140,12 +141,20 @@ static inline void ip_tr_mc_map(__be32 addr, char *buf)
+ 
+ struct ip_reply_arg {
+ 	struct kvec iov[1];   
++	int	    flags;
+ 	__wsum 	    csum;
+ 	int	    csumoffset; /* u16 offset of csum in iov[0].iov_base */
+ 				/* -1 if not needed */ 
+ 	int	    bound_dev_if;
+ }; 
+ 
++#define IP_REPLY_ARG_NOSRCCHECK 1
++
++static inline __u8 ip_reply_arg_flowi_flags(const struct ip_reply_arg *arg)
++{
++	return (arg->flags & IP_REPLY_ARG_NOSRCCHECK) ? FLOWI_FLAG_ANYSRC : 0;
++}
++
+ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg,
+ 		   unsigned int len); 
+ 
+diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
+index 828ea21..6d70d51 100644
+--- a/net/ipv4/inet_connection_sock.c
++++ b/net/ipv4/inet_connection_sock.c
+@@ -333,6 +333,7 @@ struct dst_entry* inet_csk_route_req(struct sock *sk,
+ 					.saddr = ireq->loc_addr,
+ 					.tos = RT_CONN_FLAGS(sk) } },
+ 			    .proto = sk->sk_protocol,
++			    .flags = inet_sk_flowi_flags(sk),
+ 			    .uli_u = { .ports =
+ 				       { .sport = inet_sk(sk)->sport,
+ 					 .dport = ireq->rmt_port } } };
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index 0834926..9ac5270 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -342,6 +342,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
+ 							.saddr = inet->saddr,
+ 							.tos = RT_CONN_FLAGS(sk) } },
+ 					    .proto = sk->sk_protocol,
++					    .flags = inet_sk_flowi_flags(sk),
+ 					    .uli_u = { .ports =
+ 						       { .sport = inet->sport,
+ 							 .dport = inet->dport } } };
+@@ -1380,7 +1381,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
+ 				    .uli_u = { .ports =
+ 					       { .sport = tcp_hdr(skb)->dest,
+ 						 .dport = tcp_hdr(skb)->source } },
+-				    .proto = sk->sk_protocol };
++				    .proto = sk->sk_protocol,
++				    .flags = ip_reply_arg_flowi_flags(arg) };
+ 		security_skb_classify_flow(skb, &fl);
+ 		if (ip_route_output_key(sock_net(sk), &rt, &fl))
+ 			return;
+diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
+index 19a1037..d5fa8c7 100644
+--- a/net/ipv4/syncookies.c
++++ b/net/ipv4/syncookies.c
+@@ -340,6 +340,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
+ 						.saddr = ireq->loc_addr,
+ 						.tos = RT_CONN_FLAGS(sk) } },
+ 				    .proto = IPPROTO_TCP,
++				    .flags = inet_sk_flowi_flags(sk),
+ 				    .uli_u = { .ports =
+ 					       { .sport = th->dest,
+ 						 .dport = th->source } } };
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index 0e9bc12..58873ad 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -594,6 +594,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
+ 				      ip_hdr(skb)->saddr, /* XXX */
+ 				      sizeof(struct tcphdr), IPPROTO_TCP, 0);
+ 	arg.csumoffset = offsetof(struct tcphdr, check) / 2;
++	arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0;
+ 
+ 	ip_send_reply(dev_net(skb->dst->dev)->ipv4.tcp_sock, skb,
+ 		      &arg, arg.iov[0].iov_len);
+@@ -608,7 +609,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
+ 
+ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
+ 			    struct sk_buff *skb, u32 seq, u32 ack,
+-			    u32 win, u32 ts)
++			    u32 win, u32 ts, int reply_flags)
+ {
+ 	struct tcphdr *th = tcp_hdr(skb);
+ 	struct {
+@@ -684,6 +685,7 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
+ 					arg.iov[0].iov_len);
+ 	}
+ #endif
++	arg.flags = reply_flags;
+ 	arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,
+ 				      ip_hdr(skb)->saddr, /* XXX */
+ 				      arg.iov[0].iov_len, IPPROTO_TCP, 0);
+@@ -704,7 +706,8 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
+ 
+ 	tcp_v4_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
+ 			tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
+-			tcptw->tw_ts_recent);
++			tcptw->tw_ts_recent,
++			tw->tw_transparent ? IP_REPLY_ARG_NOSRCCHECK : 0);
+ 
+ 	inet_twsk_put(tw);
+ }
+@@ -714,7 +717,8 @@ static void tcp_v4_reqsk_send_ack(struct sk_buff *skb,
+ {
+ 	tcp_v4_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1,
+ 			tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd,
+-			req->ts_recent);
++			req->ts_recent,
++			inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0);
+ }
+ 
+ /*
+@@ -1321,6 +1325,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
+ 	ireq = inet_rsk(req);
+ 	ireq->loc_addr = daddr;
+ 	ireq->rmt_addr = saddr;
++	ireq->no_srccheck = inet_sk(sk)->transparent;
+ 	ireq->opt = tcp_v4_save_options(sk, skb);
+ 	if (!want_cookie)
+ 		TCP_ECN_create_request(req, tcp_hdr(skb));
+-- 
+1.5.2.5
+
+From f8be7a55d2a449d188f033d7914d2af007054fbc Mon Sep 17 00:00:00 2001
+From: KOVACS Krisztian <hidden at sch.bme.hu>
+Date: Mon, 28 Apr 2008 14:46:50 +0200
+Subject: [PATCH] Make Netfilter's ip_route_me_harder() non-local address compatible
+
+Netfilter's ip_route_me_harder() tries to re-route packets either generated or
+re-routed by Netfilter. This patch changes ip_route_me_harder() to handle
+packets from non-locally-bound sockets with IP_TRANSPARENT set as local and to
+set the appropriate flowi flags when re-doing the routing lookup.
+
+Signed-off-by: KOVACS Krisztian <hidden at sch.bme.hu>
+---
+ net/ipv4/netfilter.c |    3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
+index f8edacd..01671ad 100644
+--- a/net/ipv4/netfilter.c
++++ b/net/ipv4/netfilter.c
+@@ -20,6 +20,8 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
+ 	unsigned int type;
+ 
+ 	type = inet_addr_type(&init_net, iph->saddr);
++	if (skb->sk && inet_sk(skb->sk)->transparent)
++		type = RTN_LOCAL;
+ 	if (addr_type == RTN_UNSPEC)
+ 		addr_type = type;
+ 
+@@ -33,6 +35,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
+ 		fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
+ 		fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
+ 		fl.mark = skb->mark;
++		fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
+ 		if (ip_route_output_key(&init_net, &rt, &fl) != 0)
+ 			return -1;
+ 
+-- 
+1.5.2.5
+
+From 7797a39b59dae015e06bd4860affbdb250c312b7 Mon Sep 17 00:00:00 2001
+From: KOVACS Krisztian <hidden at sch.bme.hu>
+Date: Mon, 28 Apr 2008 14:46:50 +0200
+Subject: [PATCH] Port redirection support for TCP
+
+Current TCP code relies on the local port of the listening socket
+being the same as the destination address of the incoming
+connection. Port redirection used by many transparent proxying
<<Diff was trimmed, longer than 597 lines>>


More information about the pld-cvs-commit mailing list