* [PATCH 00/13] Transparent Proxying Patches, Take 3
@ 2007-09-30 20:51 KOVACS Krisztian
2007-09-30 20:51 ` [PATCH 01/13] Loosen source address check on IPv4 output KOVACS Krisztian
` (13 more replies)
0 siblings, 14 replies; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 20:51 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
Hi Patrick,
These patches are our (Balazs, Attila and me) third try at providing Linux
2.2-like transparent proxying support for Linux 2.6. During the 5th Netfilter
Workshop in Karlsruhe, Germany we tried to come up with an even more
lightweight approach not requiring the modification of the IPv4 routing code at
all.
The most important changes relative to the previous versions[1,2] are:
* the tproxy table is gone, TPROXY targets need to be added to the
mangle table instead
* the tproxy match is gone, a new "socket" match is introduced
* instead of using a separate routing trick to divert packets to the
local IP stack inside the TProxy target, we are now using stock routing
decisions, and need a bit in the packet MARK field, and perform diversion by
using an advanced routing rule (this hopefully makes it possible to
implement IPv6 support in the future
* instead of IP_FREEBIND we are using a setsockopt named IP_TRANSPARENT
which requires CAP_NET_ADMIN privilege
* in previous patches the output routing decision was commented out, it
is now correctly decided whether a packet belongs to a tproxied
connection or not.
Usage is a bit more complicated compared to the previous approach, but it's
certainly not rocket science:
# iptables rules necessary:
# create a chain named DIVERT
iptables -t mangle -N DIVERT
# everything that matches "-m socket" should go to the local stack
iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
# connections to be redirected should use the TPROXY target, which sets
# up redirection, and marks the packet according to its 'tproxy-mark'
# argument
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY \
--tproxy-mark 0x1/0x1 --on-port 50080
# DIVERT chain: mark packets and accept
iptables -t mangle -A DIVERT -j MARK --set-mark 1
iptables -t mangle -A DIVERT -j ACCEPT
# set up advanced routing rules to deliver our marked packets locally
ip rule add fwmark 1 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100
The proxy code needs to be modified as well, but these are really lightweight:
before binding, the IP_TRANSPARENT sockopt needs to be enabled on the socket.
This implies IP_FREEBIND, so after enabling this socket option non-local binds
will work and if you got your iptables/iproute setup right non-local traffic
will be delivered to/from the socket. A netcat patch demonstrating this is
available[4] as an example.
Some word about the patches:
* output path (patches 1-5): these modifications make it possible to
output IPv4 datagrams with non-local IP addresses by:
- introducing a new flowi flag (FLOWI_FLAG_ANYSRC) which disables the source
address check in ip_route_output_slow() [3]
- adding the IP_TRANSPARENT socket option (setting this requires CAP_NET_ADMIN)
- setting FLOWI_FLAG_ANYSRC if IP_TRANSPARENT is enabled for the originating
socket
- set FLOWI_FLAG_ANYSRC where appropriate for sending reply packets
generated by the kernel; this requires extending the ip_reply_arg
structure with a flags field and adding an IP_REPLY_ARG_NOSRCCHECK flag
* input patch (patches 6-13): these changes implement redirection support for
TCP plus the iptables socket match and TPROXY target -- these provide the
actual user interface:
- split IPv4 defragmentation into a separate module, as this is needed by
both our target and match
- add a 'socket' match which does a socket lookup based on the destination
tuple in the packet and matches is a socket has been found
- add a 'TPROXY' target which looks up a socket based on a modified IP/port
tuple and stores the socket reference in the skb
- modifying the TCP/UDP input paths to use the stored socket reference if
present
All kinds of comments welcome. Patrick, I'd like to ask you to review these
patches and if no issues are found by you or by anyone on the list, please
consider merging them.
I'll send the necessary iptables changes in a separate mail.
References:
[1] http://marc.info/?l=linux-netdev&m=117310979603009&w=2
[2] http://www.balabit.com/downloads/files/tproxy/
[3] http://marc.info/?l=linux-netdev&m=118065358510836&w=2
[4] http://people.netfilter.org/hidden/tproxy/netcat-ip_transparent-support.patch
--
KOVACS Krisztian
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH 01/13] Loosen source address check on IPv4 output
2007-09-30 20:51 [PATCH 00/13] Transparent Proxying Patches, Take 3 KOVACS Krisztian
@ 2007-09-30 20:51 ` KOVACS Krisztian
2007-09-30 22:12 ` Patrick McHardy
2007-09-30 20:52 ` [PATCH 02/13] Implement IP_TRANSPARENT socket option KOVACS Krisztian
` (12 subsequent siblings)
13 siblings, 1 reply; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 20:51 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
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@ssi.bg>
Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
---
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 af59fa5..c734d50 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -49,6 +49,7 @@ struct flowi {
__u8 proto;
__u8 flags;
#define FLOWI_FLAG_MULTIPATHOLDROUTE 0x01
+#define FLOWI_FLAG_ANYSRC 0x02
union {
struct {
__be16 sport;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index c7ca94b..26e9659 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2172,11 +2172,6 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
ZERONET(oldflp->fl4_src))
goto out;
- /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
- dev_out = ip_dev_find(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(saddr) can return wrong iface, if saddr is
@@ -2187,6 +2182,11 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
if (oldflp->oif == 0
&& (MULTICAST(oldflp->fl4_dst) || oldflp->fl4_dst == htonl(0xFFFFFFFF))) {
+ /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
+ dev_out = ip_dev_find(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.
@@ -2205,9 +2205,15 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
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(oldflp->fl4_src);
+ if (dev_out == NULL)
+ goto out;
dev_put(dev_out);
- dev_out = NULL;
+ dev_out = NULL;
+ }
}
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 02/13] Implement IP_TRANSPARENT socket option
2007-09-30 20:51 [PATCH 00/13] Transparent Proxying Patches, Take 3 KOVACS Krisztian
2007-09-30 20:51 ` [PATCH 01/13] Loosen source address check on IPv4 output KOVACS Krisztian
@ 2007-09-30 20:52 ` KOVACS Krisztian
2007-09-30 22:12 ` Patrick McHardy
2007-09-30 20:52 ` [PATCH 03/13] Allow binding to non-local addresses if IP_TRANSPARENT is set KOVACS Krisztian
` (11 subsequent siblings)
13 siblings, 1 reply; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 20:52 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
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@sch.bme.hu>
---
include/linux/in.h | 1 +
include/net/inet_sock.h | 3 ++-
include/net/inet_timewait_sock.h | 3 ++-
include/net/route.h | 1 +
net/ipv4/inet_timewait_sock.c | 1 +
net/ipv4/ip_sockglue.c | 12 +++++++++++-
6 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/include/linux/in.h b/include/linux/in.h
index 3975cbf..d8c55ab 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 62daf21..e86832d 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 47d52b2..23e2fba 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -126,7 +126,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;
int tw_timeout;
diff --git a/include/net/route.h b/include/net/route.h
index f7ce625..88fed3c 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -27,6 +27,7 @@
#include <net/dst.h>
#include <net/inetpeer.h>
#include <net/flow.h>
+#include <net/inet_sock.h>
#include <linux/in_route.h>
#include <linux/rtnetlink.h>
#include <linux/route.h>
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index 2586df0..cf057a3 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -107,6 +107,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;
atomic_set(&tw->tw_refcnt, 1);
inet_twsk_dead_node_init(tw);
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 6b420ae..282b187 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)) {
@@ -885,6 +885,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;
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 03/13] Allow binding to non-local addresses if IP_TRANSPARENT is set
2007-09-30 20:51 [PATCH 00/13] Transparent Proxying Patches, Take 3 KOVACS Krisztian
2007-09-30 20:51 ` [PATCH 01/13] Loosen source address check on IPv4 output KOVACS Krisztian
2007-09-30 20:52 ` [PATCH 02/13] Implement IP_TRANSPARENT socket option KOVACS Krisztian
@ 2007-09-30 20:52 ` KOVACS Krisztian
2007-09-30 22:12 ` Patrick McHardy
2007-09-30 20:52 ` [PATCH 04/13] Conditionally enable transparent flow flag when connecting KOVACS Krisztian
` (10 subsequent siblings)
13 siblings, 1 reply; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 20:52 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
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@balabit.hu>
---
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 e681034..90344db 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -448,7 +448,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 != INADDR_ANY &&
chk_addr_ret != RTN_LOCAL &&
chk_addr_ret != RTN_MULTICAST &&
-
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 04/13] Conditionally enable transparent flow flag when connecting
2007-09-30 20:51 [PATCH 00/13] Transparent Proxying Patches, Take 3 KOVACS Krisztian
` (2 preceding siblings ...)
2007-09-30 20:52 ` [PATCH 03/13] Allow binding to non-local addresses if IP_TRANSPARENT is set KOVACS Krisztian
@ 2007-09-30 20:52 ` KOVACS Krisztian
2007-09-30 20:52 ` [PATCH 05/13] Handle TCP SYN+ACK/ACK/RST transparency KOVACS Krisztian
` (9 subsequent siblings)
13 siblings, 0 replies; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 20:52 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
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@sch.bme.hu>
---
include/net/route.h | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/include/net/route.h b/include/net/route.h
index 88fed3c..9788cc2 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -158,6 +158,10 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst,
.dport = dport } } };
int err;
+
+ if (inet_sk(sk)->transparent)
+ fl.flags |= FLOWI_FLAG_ANYSRC;
+
if (!dst || !src) {
err = __ip_route_output_key(rp, &fl);
if (err)
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 05/13] Handle TCP SYN+ACK/ACK/RST transparency
2007-09-30 20:51 [PATCH 00/13] Transparent Proxying Patches, Take 3 KOVACS Krisztian
` (3 preceding siblings ...)
2007-09-30 20:52 ` [PATCH 04/13] Conditionally enable transparent flow flag when connecting KOVACS Krisztian
@ 2007-09-30 20:52 ` KOVACS Krisztian
2007-09-30 21:45 ` Jan Engelhardt
2007-09-30 22:23 ` Patrick McHardy
2007-09-30 20:52 ` [PATCH 06/13] Port redirection support for TCP KOVACS Krisztian
` (8 subsequent siblings)
13 siblings, 2 replies; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 20:52 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
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@sch.bme.hu>
---
include/net/ip.h | 3 +++
include/net/request_sock.h | 3 ++-
net/ipv4/inet_connection_sock.c | 2 ++
net/ipv4/ip_output.c | 6 +++++-
net/ipv4/syncookies.c | 2 ++
net/ipv4/tcp_ipv4.c | 17 ++++++++++-------
net/ipv4/tcp_minisocks.c | 3 ++-
net/ipv6/tcp_ipv6.c | 5 +++--
8 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/include/net/ip.h b/include/net/ip.h
index abf2820..0084001 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -138,8 +138,11 @@ static inline void ip_tr_mc_map(__be32 addr, char *buf)
buf[5]=0x00;
}
+#define IP_REPLY_ARG_NOSRCCHECK 1
+
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 */
diff --git a/include/net/request_sock.h b/include/net/request_sock.h
index 7aed02c..b9c8974 100644
--- a/include/net/request_sock.h
+++ b/include/net/request_sock.h
@@ -34,7 +34,8 @@ struct request_sock_ops {
struct request_sock *req,
struct dst_entry *dst);
void (*send_ack)(struct sk_buff *skb,
- struct request_sock *req);
+ struct request_sock *req,
+ int reply_flags);
void (*send_reset)(struct sock *sk,
struct sk_buff *skb);
void (*destructor)(struct request_sock *req);
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index fbe7714..26b9dbe 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -321,6 +321,8 @@ 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(sk)->transparent ?
+ FLOWI_FLAG_ANYSRC : 0,
.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 0f1d7be..40cafcd 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -322,6 +322,8 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
.saddr = inet->saddr,
.tos = RT_CONN_FLAGS(sk) } },
.proto = sk->sk_protocol,
+ .flags = inet->transparent ?
+ FLOWI_FLAG_ANYSRC : 0,
.uli_u = { .ports =
{ .sport = inet->sport,
.dport = inet->dport } } };
@@ -1364,7 +1366,9 @@ 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 = (arg->flags & IP_REPLY_ARG_NOSRCCHECK) ?
+ FLOWI_FLAG_ANYSRC : 0 };
security_skb_classify_flow(skb, &fl);
if (ip_route_output_key(&rt, &fl))
return;
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 2da1be0..f7fad59 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -260,6 +260,8 @@ 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(sk)->transparent ?
+ FLOWI_FLAG_ANYSRC : 0,
.uli_u = { .ports =
{ .sport = th->dest,
.dport = th->source } } };
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index e089a97..7ae47e6 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -612,6 +612,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(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len);
@@ -625,7 +626,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 {
@@ -701,36 +702,37 @@ 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);
arg.csumoffset = offsetof(struct tcphdr, check) / 2;
if (twsk)
arg.bound_dev_if = twsk->tw_sk.tw_bound_dev_if;
-
ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len);
TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
}
-static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
+static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb, int reply_flags)
{
struct inet_timewait_sock *tw = inet_twsk(sk);
struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
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, reply_flags);
inet_twsk_put(tw);
}
static void tcp_v4_reqsk_send_ack(struct sk_buff *skb,
- struct request_sock *req)
+ struct request_sock *req,
+ int reply_flags)
{
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, reply_flags);
}
/*
@@ -1742,7 +1744,8 @@ do_time_wait:
/* Fall through to ACK */
}
case TCP_TW_ACK:
- tcp_v4_timewait_ack(sk, skb);
+ tcp_v4_timewait_ack(sk, skb, inet_twsk(sk)->tw_transparent ?
+ IP_REPLY_ARG_NOSRCCHECK : 0);
break;
case TCP_TW_RST:
goto no_tcp_socket;
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index a12b08f..734d119 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -604,7 +604,8 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
tcp_rsk(req)->rcv_isn + 1, tcp_rsk(req)->rcv_isn + 1 + req->rcv_wnd)) {
/* Out of window: send ACK and drop. */
if (!(flg & TCP_FLAG_RST))
- req->rsk_ops->send_ack(skb, req);
+ req->rsk_ops->send_ack(skb, req, inet_sk(sk)->transparent ?
+ IP_REPLY_ARG_NOSRCCHECK : 0);
if (paws_reject)
NET_INC_STATS_BH(LINUX_MIB_PAWSESTABREJECTED);
return NULL;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 3e06799..b3f3c1d 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -72,7 +72,7 @@
static struct socket *tcp6_socket;
static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb);
-static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req);
+static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req, int reply_flags);
static void tcp_v6_send_check(struct sock *sk, int len,
struct sk_buff *skb);
@@ -1183,7 +1183,8 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
inet_twsk_put(tw);
}
-static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req)
+static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req,
+ int reply_flags)
{
tcp_v6_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent);
}
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 06/13] Port redirection support for TCP
2007-09-30 20:51 [PATCH 00/13] Transparent Proxying Patches, Take 3 KOVACS Krisztian
` (4 preceding siblings ...)
2007-09-30 20:52 ` [PATCH 05/13] Handle TCP SYN+ACK/ACK/RST transparency KOVACS Krisztian
@ 2007-09-30 20:52 ` KOVACS Krisztian
2007-09-30 22:26 ` Patrick McHardy
2007-09-30 20:52 ` [PATCH 07/13] Export UDP socket lookup function KOVACS Krisztian
` (7 subsequent siblings)
13 siblings, 1 reply; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 20:52 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
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
techniques obviously breaks this, so we have to store the original
destination port address.
This patch extends struct inet_request_sock and stores the incoming
destination port value there. It also modifies the handshake code to
use that value as the source port when sending reply packets.
Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
---
include/net/inet_sock.h | 3 +++
include/net/tcp.h | 3 +++
net/ipv4/inet_connection_sock.c | 4 ++++
net/ipv4/syncookies.c | 3 +++
net/ipv4/tcp_output.c | 4 ++++
5 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index e86832d..5339089 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -65,6 +65,9 @@ struct inet_request_sock {
#endif
__be32 loc_addr;
__be32 rmt_addr;
+#if defined(CONFIG_NETFILTER_TPROXY) || defined(CONFIG_NETFILTER_TPROXY_MODULE)
+ __be16 loc_port;
+#endif
__be16 rmt_port;
u16 snd_wscale : 4,
rcv_wscale : 4,
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 54053de..927d235 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -980,6 +980,9 @@ static inline void tcp_openreq_init(struct request_sock *req,
ireq->acked = 0;
ireq->ecn_ok = 0;
ireq->rmt_port = tcp_hdr(skb)->source;
+#if defined(CONFIG_NETFILTER_TPROXY) || defined(CONFIG_NETFILTER_TPROXY_MODULE)
+ ireq->loc_port = tcp_hdr(skb)->dest;
+#endif
}
extern void tcp_enter_memory_pressure(void);
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 26b9dbe..f47d966 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -502,6 +502,10 @@ struct sock *inet_csk_clone(struct sock *sk, const struct request_sock *req,
newicsk->icsk_bind_hash = NULL;
inet_sk(newsk)->dport = inet_rsk(req)->rmt_port;
+#if defined(CONFIG_IP_NF_TPROXY) || defined(CONFIG_IP_NF_TPROXY_MODULE)
+ inet_sk(newsk)->num = ntohs(inet_rsk(req)->loc_port);
+ inet_sk(newsk)->sport = inet_rsk(req)->loc_port;
+#endif
newsk->sk_write_space = sk_stream_write_space;
newicsk->icsk_retransmits = 0;
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index f7fad59..a55ccf1 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -223,6 +223,9 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
treq->rcv_isn = ntohl(th->seq) - 1;
treq->snt_isn = cookie;
req->mss = mss;
+#if defined(CONFIG_IP_NF_TPROXY) || defined(CONFIG_IP_NF_TPROXY_MODULE)
+ ireq->loc_port = th->dest;
+#endif
ireq->rmt_port = th->source;
ireq->loc_addr = ip_hdr(skb)->daddr;
ireq->rmt_addr = ip_hdr(skb)->saddr;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 666d8a5..69dd230 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2153,7 +2153,11 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
th->syn = 1;
th->ack = 1;
TCP_ECN_make_synack(req, th);
+#if defined(CONFIG_IP_NF_TPROXY) || defined(CONFIG_IP_NF_TPROXY_MODULE)
+ th->source = ireq->loc_port;
+#else
th->source = inet_sk(sk)->sport;
+#endif
th->dest = ireq->rmt_port;
TCP_SKB_CB(skb)->seq = tcp_rsk(req)->snt_isn;
TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1;
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 07/13] Export UDP socket lookup function
2007-09-30 20:51 [PATCH 00/13] Transparent Proxying Patches, Take 3 KOVACS Krisztian
` (5 preceding siblings ...)
2007-09-30 20:52 ` [PATCH 06/13] Port redirection support for TCP KOVACS Krisztian
@ 2007-09-30 20:52 ` KOVACS Krisztian
2007-09-30 20:53 ` [PATCH 08/13] Split Netfilter IPv4 defragmentation into a separate module KOVACS Krisztian
` (6 subsequent siblings)
13 siblings, 0 replies; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 20:52 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
The iptables tproxy code has to be able to do UDP socket hash lookups,
so we have to provide an exported lookup function for this purpose.
Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
---
include/net/udp.h | 4 ++++
net/ipv4/udp.c | 8 ++++++++
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/include/net/udp.h b/include/net/udp.h
index 98755eb..3efae7d 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -138,6 +138,10 @@ extern int udp_lib_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, int optlen,
int (*push_pending_frames)(struct sock *));
+extern struct sock *udp4_lib_lookup(__be32 saddr, __be16 sport,
+ __be32 daddr, __be16 dport,
+ int dif);
+
DECLARE_SNMP_STAT(struct udp_mib, udp_statistics);
/*
* SNMP statistics for UDP and UDP-Lite
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 69d4bd1..2fb3b7c 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -287,6 +287,14 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
return result;
}
+struct sock *udp4_lib_lookup(__be32 saddr, __be16 sport,
+ __be32 daddr, __be16 dport,
+ int dif)
+{
+ return __udp4_lib_lookup(saddr, sport, daddr, dport, dif, udp_hash);
+}
+EXPORT_SYMBOL_GPL(udp4_lib_lookup);
+
static inline struct sock *udp_v4_mcast_next(struct sock *sk,
__be16 loc_port, __be32 loc_addr,
__be16 rmt_port, __be32 rmt_addr,
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 08/13] Split Netfilter IPv4 defragmentation into a separate module
2007-09-30 20:51 [PATCH 00/13] Transparent Proxying Patches, Take 3 KOVACS Krisztian
` (6 preceding siblings ...)
2007-09-30 20:52 ` [PATCH 07/13] Export UDP socket lookup function KOVACS Krisztian
@ 2007-09-30 20:53 ` KOVACS Krisztian
2007-09-30 22:35 ` Patrick McHardy
2007-09-30 20:53 ` [PATCH 09/13] iptables tproxy core KOVACS Krisztian
` (5 subsequent siblings)
13 siblings, 1 reply; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 20:53 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
Netfilter connection tracking requires all IPv4 packets to be defragmented.
Both the socket match and the TPROXY target depend on this functionality, so
this patch separates the Netfilter IPv4 defrag hooks into a separate module.
Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
---
include/net/netfilter/ipv4/nf_defrag_ipv4.h | 6 ++
net/ipv4/netfilter/Kconfig | 5 +
net/ipv4/netfilter/Makefile | 3 +
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 55 +-------------
net/ipv4/netfilter/nf_defrag_ipv4.c | 94 ++++++++++++++++++++++++
5 files changed, 110 insertions(+), 53 deletions(-)
diff --git a/include/net/netfilter/ipv4/nf_defrag_ipv4.h b/include/net/netfilter/ipv4/nf_defrag_ipv4.h
new file mode 100644
index 0000000..6b00ea3
--- /dev/null
+++ b/include/net/netfilter/ipv4/nf_defrag_ipv4.h
@@ -0,0 +1,6 @@
+#ifndef _NF_DEFRAG_IPV4_H
+#define _NF_DEFRAG_IPV4_H
+
+extern void nf_defrag_ipv4_enable(void);
+
+#endif /* _NF_DEFRAG_IPV4_H */
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index fa97947..c9108de 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -5,9 +5,14 @@
menu "IP: Netfilter Configuration"
depends on INET && NETFILTER
+config NF_DEFRAG_IPV4
+ tristate
+ default n
+
config NF_CONNTRACK_IPV4
tristate "IPv4 connection tracking support (required for NAT)"
depends on NF_CONNTRACK
+ select NF_DEFRAG_IPV4
---help---
Connection tracking keeps a record of what packets have passed
through your machine, in order to figure out how they are related
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 409d273..6504de5 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -18,6 +18,9 @@ obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
obj-$(CONFIG_NF_NAT) += nf_nat.o
+# defrag
+obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o
+
# NAT helpers (nf_conntrack)
obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index f813e02..3bc2e0c 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -23,6 +23,7 @@
#include <net/netfilter/nf_conntrack_l3proto.h>
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
+#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
struct nf_conntrack_tuple *tuple)
@@ -62,22 +63,6 @@ static int ipv4_print_conntrack(struct seq_file *s,
return 0;
}
-/* Returns new sk_buff, or NULL */
-static struct sk_buff *
-nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
-{
- skb_orphan(skb);
-
- local_bh_disable();
- skb = ip_defrag(skb, user);
- local_bh_enable();
-
- if (skb)
- ip_send_check(ip_hdr(skb));
-
- return skb;
-}
-
static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
unsigned int *dataoff, u_int8_t *protonum)
{
@@ -135,29 +120,6 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum,
ct, ctinfo);
}
-static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
- struct sk_buff **pskb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff *))
-{
- /* Previously seen (loopback)? Ignore. Do this before
- fragment check. */
- if ((*pskb)->nfct)
- return NF_ACCEPT;
-
- /* Gather fragments. */
- if (ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)) {
- *pskb = nf_ct_ipv4_gather_frags(*pskb,
- hooknum == NF_IP_PRE_ROUTING ?
- IP_DEFRAG_CONNTRACK_IN :
- IP_DEFRAG_CONNTRACK_OUT);
- if (!*pskb)
- return NF_STOLEN;
- }
- return NF_ACCEPT;
-}
-
static unsigned int ipv4_conntrack_in(unsigned int hooknum,
struct sk_buff **pskb,
const struct net_device *in,
@@ -187,13 +149,6 @@ static unsigned int ipv4_conntrack_local(unsigned int hooknum,
make it the first hook. */
static struct nf_hook_ops ipv4_conntrack_ops[] = {
{
- .hook = ipv4_conntrack_defrag,
- .owner = THIS_MODULE,
- .pf = PF_INET,
- .hooknum = NF_IP_PRE_ROUTING,
- .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
- },
- {
.hook = ipv4_conntrack_in,
.owner = THIS_MODULE,
.pf = PF_INET,
@@ -201,13 +156,6 @@ static struct nf_hook_ops ipv4_conntrack_ops[] = {
.priority = NF_IP_PRI_CONNTRACK,
},
{
- .hook = ipv4_conntrack_defrag,
- .owner = THIS_MODULE,
- .pf = PF_INET,
- .hooknum = NF_IP_LOCAL_OUT,
- .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
- },
- {
.hook = ipv4_conntrack_local,
.owner = THIS_MODULE,
.pf = PF_INET,
@@ -430,6 +378,7 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
int ret = 0;
need_conntrack();
+ nf_defrag_ipv4_enable();
ret = nf_register_sockopt(&so_getorigdst);
if (ret < 0) {
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c
new file mode 100644
index 0000000..9872c47
--- /dev/null
+++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
@@ -0,0 +1,94 @@
+/* (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/ip.h>
+#include <linux/netfilter.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <net/route.h>
+#include <net/ip.h>
+
+#include <linux/netfilter_ipv4.h>
+#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
+
+/* Returns new sk_buff, or NULL */
+static struct sk_buff *
+ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
+{
+ skb_orphan(skb);
+
+ local_bh_disable();
+ skb = ip_defrag(skb, user);
+ local_bh_enable();
+
+ if (skb)
+ ip_send_check(ip_hdr(skb));
+
+ return skb;
+}
+
+static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ /* Previously seen (loopback)? Ignore. Do this before
+ fragment check. */
+ if ((*pskb)->nfct)
+ return NF_ACCEPT;
+
+ /* Gather fragments. */
+ if (ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)) {
+ *pskb = ipv4_gather_frags(*pskb,
+ hooknum == NF_IP_PRE_ROUTING ?
+ IP_DEFRAG_CONNTRACK_IN :
+ IP_DEFRAG_CONNTRACK_OUT);
+ if (!*pskb)
+ return NF_STOLEN;
+ }
+ return NF_ACCEPT;
+}
+
+static struct nf_hook_ops ipv4_defrag_ops[] = {
+ {
+ .hook = ipv4_conntrack_defrag,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_PRE_ROUTING,
+ .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
+ },
+ {
+ .hook = ipv4_conntrack_defrag,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_LOCAL_OUT,
+ .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
+ },
+};
+
+static int __init nf_defrag_init(void)
+{
+ return nf_register_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
+}
+
+static void __exit nf_defrag_fini(void)
+{
+ nf_unregister_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
+}
+
+void nf_defrag_ipv4_enable(void)
+{
+}
+EXPORT_SYMBOL(nf_defrag_ipv4_enable);
+
+module_init(nf_defrag_init);
+module_exit(nf_defrag_fini);
+
+MODULE_LICENSE("GPL");
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 09/13] iptables tproxy core
2007-09-30 20:51 [PATCH 00/13] Transparent Proxying Patches, Take 3 KOVACS Krisztian
` (7 preceding siblings ...)
2007-09-30 20:53 ` [PATCH 08/13] Split Netfilter IPv4 defragmentation into a separate module KOVACS Krisztian
@ 2007-09-30 20:53 ` KOVACS Krisztian
2007-09-30 22:37 ` Patrick McHardy
2007-09-30 20:53 ` [PATCH 10/13] iptables socket match KOVACS Krisztian
` (4 subsequent siblings)
13 siblings, 1 reply; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 20:53 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
The iptables tproxy core is a module that contains the common routines used by
various tproxy related modules (TPROXY target and socket match)
Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
---
include/net/netfilter/nf_tproxy_core.h | 32 +++++++++++
net/netfilter/Kconfig | 10 +++
net/netfilter/Makefile | 3 +
net/netfilter/nf_tproxy_core.c | 96 ++++++++++++++++++++++++++++++++
4 files changed, 141 insertions(+), 0 deletions(-)
diff --git a/include/net/netfilter/nf_tproxy_core.h b/include/net/netfilter/nf_tproxy_core.h
new file mode 100644
index 0000000..2fac3ad
--- /dev/null
+++ b/include/net/netfilter/nf_tproxy_core.h
@@ -0,0 +1,32 @@
+#ifndef _NF_TPROXY_CORE_H
+#define _NF_TPROXY_CORE_H
+
+#include <linux/types.h>
+#include <linux/in.h>
+#include <linux/skbuff.h>
+#include <net/sock.h>
+#include <net/inet_sock.h>
+#include <net/tcp.h>
+
+/* look up and get a reference to a matching socket */
+extern struct sock *
+nf_tproxy_get_sock_v4(const u8 protocol,
+ const __be32 saddr, const __be32 daddr,
+ const __be16 sport, const __be16 dport,
+ const struct net_device *in, bool listening);
+
+static inline void
+nf_tproxy_put_sock(struct sock *sk)
+{
+ /* TIME_WAIT inet sockets have to be handled differently */
+ if ((sk->sk_protocol == IPPROTO_TCP) && (sk->sk_state == TCP_TIME_WAIT))
+ inet_twsk_put(inet_twsk(sk));
+ else
+ sock_put(sk);
+}
+
+/* assign a socket to the skb -- consumes sk */
+int
+nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk);
+
+#endif
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 3599770..2187cca 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -257,6 +257,16 @@ config NF_CT_NETLINK
help
This option enables support for a netlink-based userspace interface
+# transparent proxy support
+config NETFILTER_TPROXY
+ tristate "Transparent proxying support"
+ depends on IP_NF_MANGLE
+ help
+ Transparent proxying. For more information see
+ http://www.balabit.com/downloads/tproxy.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
config NETFILTER_XTABLES
tristate "Netfilter Xtables support (required for ip_tables)"
help
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 0c054bf..76e16ea 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -34,6 +34,9 @@ obj-$(CONFIG_NF_CONNTRACK_SANE) += nf_conntrack_sane.o
obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o
obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o
+# transparent proxy support
+obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o
+
# generic X tables
obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
diff --git a/net/netfilter/nf_tproxy_core.c b/net/netfilter/nf_tproxy_core.c
new file mode 100644
index 0000000..0ed4a7f
--- /dev/null
+++ b/net/netfilter/nf_tproxy_core.c
@@ -0,0 +1,96 @@
+/*
+ * Transparent proxy support for Linux/iptables
+ *
+ * Copyright (c) 2006-2007 BalaBit IT Ltd.
+ * Author: Balazs Scheidler, Krisztian Kovacs
+ *
+ * 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/version.h>
+#include <linux/module.h>
+
+#include <linux/net.h>
+#include <linux/if.h>
+#include <linux/netdevice.h>
+#include <net/udp.h>
+#include <net/netfilter/nf_tproxy_core.h>
+
+struct sock *
+nf_tproxy_get_sock_v4(const u8 protocol,
+ const __be32 saddr, const __be32 daddr,
+ const __be16 sport, const __be16 dport,
+ const struct net_device *in, bool listening_only)
+{
+ struct sock *sk;
+
+ /* look up socket */
+ switch (protocol) {
+ case IPPROTO_TCP:
+ if (listening_only)
+ sk = __inet_lookup_listener(&tcp_hashinfo,
+ daddr, ntohs(dport),
+ in->ifindex);
+ else
+ sk = __inet_lookup(&tcp_hashinfo,
+ saddr, sport, daddr, dport,
+ in->ifindex);
+ break;
+ case IPPROTO_UDP:
+ sk = udp4_lib_lookup(saddr, sport, daddr, dport,
+ in->ifindex);
+ break;
+ default:
+ WARN_ON(1);
+ sk = NULL;
+ }
+
+ pr_debug("tproxy socket lookup: proto %d %08x:%d -> %08x:%d sock %p\n",
+ protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), sk);
+
+ return sk;
+}
+EXPORT_SYMBOL_GPL(nf_tproxy_get_sock_v4);
+
+static void
+nf_tproxy_destructor(struct sk_buff *skb)
+{
+ struct sock *sk = skb->sk;
+
+ skb->sk = NULL;
+ skb->destructor = NULL;
+
+ if (sk)
+ nf_tproxy_put_sock(sk);
+}
+
+/* consumes sk */
+int
+nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk)
+{
+ if (inet_sk(sk)->transparent) {
+ skb->sk = sk;
+ skb->destructor = nf_tproxy_destructor;
+ return 1;
+ } else
+ nf_tproxy_put_sock(sk);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(nf_tproxy_assign_sock);
+
+static int __init init(void)
+{
+ printk("NF_TPROXY: Transparent proxy support initialized, version 4.1.0\n"
+ "NF_TPROXY: Copyright (c) 2006-2007 BalaBit IT Ltd.\n");
+ return 0;
+}
+
+module_init(init);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Krisztian Kovacs");
+MODULE_DESCRIPTION("Transparent proxy core routines");
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 10/13] iptables socket match
2007-09-30 20:51 [PATCH 00/13] Transparent Proxying Patches, Take 3 KOVACS Krisztian
` (8 preceding siblings ...)
2007-09-30 20:53 ` [PATCH 09/13] iptables tproxy core KOVACS Krisztian
@ 2007-09-30 20:53 ` KOVACS Krisztian
2007-09-30 21:43 ` Jan Engelhardt
2007-09-30 22:15 ` [PATCH 10/13] xt_socket Jan Engelhardt
2007-09-30 20:53 ` [PATCH 11/13] iptables TPROXY target KOVACS Krisztian
` (3 subsequent siblings)
13 siblings, 2 replies; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 20:53 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
Add iptables 'socket' match, which matches packets for which a TCP/UDP
socket lookup succeeds.
Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
---
net/netfilter/Kconfig | 12 ++++++
net/netfilter/Makefile | 1 +
net/netfilter/xt_socket.c | 87 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 100 insertions(+), 0 deletions(-)
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 2187cca..899fdde 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -632,6 +632,18 @@ config NETFILTER_XT_MATCH_SCTP
If you want to compile it as a module, say M here and read
<file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
+config NETFILTER_XT_MATCH_SOCKET
+ tristate '"socket" match support'
+ depends on NETFILTER_TPROXY
+ depends on NETFILTER_XTABLES
+ select NF_DEFRAG_IPV4
+ help
+ This option adds a `socket' match, which can be used to match
+ packets for which a TCP or UDP socket lookup finds a valid socket.
+ It can only be used in the tproxy table.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
config NETFILTER_XT_MATCH_STATE
tristate '"state" match support'
depends on NETFILTER_XTABLES
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 76e16ea..7d7dbd6 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -73,6 +73,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o
obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o
obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c
new file mode 100644
index 0000000..b1b0103
--- /dev/null
+++ b/net/netfilter/xt_socket.c
@@ -0,0 +1,87 @@
+/*
+ * Transparent proxy support for Linux/iptables
+ *
+ * Copyright (c) 2007 BalaBit IT Ltd.
+ * Author: Krisztian Kovacs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/netfilter/x_tables.h>
+#include <net/netfilter/nf_tproxy_core.h>
+#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
+#include <net/tcp.h>
+#include <net/udp.h>
+#include <net/sock.h>
+#include <net/inet_sock.h>
+
+static bool
+match(const struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ const struct xt_match *match,
+ const void *matchinfo,
+ int offset,
+ unsigned int protoff,
+ bool *hotdrop)
+{
+ const struct iphdr *iph = ip_hdr(skb);
+ struct udphdr _hdr, *hp;
+ struct sock *sk;
+
+ /* TCP/UDP only */
+ if ((iph->protocol != IPPROTO_TCP) &&
+ (iph->protocol != IPPROTO_UDP))
+ return false;
+
+ hp = skb_header_pointer(skb, iph->ihl * 4, sizeof(_hdr), &_hdr);
+ if (hp == NULL)
+ return false;
+
+ sk = nf_tproxy_get_sock_v4(iph->protocol,
+ iph->saddr, iph->daddr,
+ hp->source, hp->dest, in, false);
+ if (sk != NULL)
+ nf_tproxy_put_sock(sk);
+
+ pr_debug("socket match: proto %d %08x:%d -> %08x:%d sock %p\n",
+ iph->protocol, ntohl(iph->saddr), ntohs(hp->source),
+ ntohl(iph->daddr), ntohs(hp->dest), sk);
+
+ return (sk != NULL);
+}
+
+static struct xt_match socket_matches[] = {
+ {
+ .name = "socket",
+ .family = AF_INET,
+ .match = match,
+ .matchsize = 0,
+ .hooks = (1 << NF_IP_PRE_ROUTING),
+ .me = THIS_MODULE,
+ },
+};
+
+static int __init ipt_socket_init(void)
+{
+ nf_defrag_ipv4_enable();
+ return xt_register_matches(socket_matches, ARRAY_SIZE(socket_matches));
+}
+
+static void __exit ipt_socket_fini(void)
+{
+ xt_unregister_matches(socket_matches, ARRAY_SIZE(socket_matches));
+}
+
+module_init(ipt_socket_init);
+module_exit(ipt_socket_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Krisztian Kovacs");
+MODULE_DESCRIPTION("x_tables socket match module");
+MODULE_ALIAS("ipt_socket");
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 11/13] iptables TPROXY target
2007-09-30 20:51 [PATCH 00/13] Transparent Proxying Patches, Take 3 KOVACS Krisztian
` (9 preceding siblings ...)
2007-09-30 20:53 ` [PATCH 10/13] iptables socket match KOVACS Krisztian
@ 2007-09-30 20:53 ` KOVACS Krisztian
2007-09-30 21:40 ` [PATCH 11/13] xtables " Jan Engelhardt
` (2 more replies)
2007-09-30 20:53 ` [PATCH 12/13] Don't lookup the socket if there's a socket attached to the skb KOVACS Krisztian
` (2 subsequent siblings)
13 siblings, 3 replies; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 20:53 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
The TPROXY target implements redirection of non-local TCP/UDP traffic to local
sockets. Additionally, it's possible to manipulate the packet mark if and only
if a socket has been found. (We need this because we cannot use multiple
targets in the same iptables rule.)
Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
---
include/linux/netfilter_ipv4/ipt_TPROXY.h | 14 +++
net/netfilter/Kconfig | 12 +++
net/netfilter/Makefile | 1
net/netfilter/xt_TPROXY.c | 139 +++++++++++++++++++++++++++++
4 files changed, 166 insertions(+), 0 deletions(-)
diff --git a/include/linux/netfilter_ipv4/ipt_TPROXY.h b/include/linux/netfilter_ipv4/ipt_TPROXY.h
new file mode 100644
index 0000000..4a2dfa1
--- /dev/null
+++ b/include/linux/netfilter_ipv4/ipt_TPROXY.h
@@ -0,0 +1,14 @@
+#ifndef _IPT_TPROXY_H_target
+#define _IPT_TPROXY_H_target
+
+/* 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 ipt_tproxy_target_info {
+ __be32 laddr;
+ __be16 lport;
+ unsigned long mark_mask;
+ unsigned long mark_value;
+};
+
+#endif
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 899fdde..21e39eb 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -363,6 +363,18 @@ config NETFILTER_XT_TARGET_NOTRACK
If you want to compile it as a module, say M here and read
<file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
+config NETFILTER_XT_TARGET_TPROXY
+ tristate "TPROXY target support"
+ depends on NETFILTER_TPROXY
+ depends on NETFILTER_XTABLES
+ help
+ This option adds a `TPROXY' target, which is somewhat similar to
+ REDIRECT. It can only be used in the tproxy table and is useful
+ to redirect traffic to a transparent proxy. It does _not_ depend
+ on Netfilter connection tracking.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
config NETFILTER_XT_TARGET_TRACE
tristate '"TRACE" target support'
depends on NETFILTER_XTABLES
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 7d7dbd6..0684e2b 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c
new file mode 100644
index 0000000..8603421
--- /dev/null
+++ b/net/netfilter/xt_TPROXY.c
@@ -0,0 +1,139 @@
+/*
+ * Transparent proxy support for Linux/iptables
+ *
+ * Copyright (c) 2006-2007 BalaBit IT Ltd.
+ * Author: Balazs Scheidler, Krisztian Kovacs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <net/checksum.h>
+#include <net/udp.h>
+#include <net/inet_sock.h>
+
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter_ipv4/ipt_TPROXY.h>
+
+#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
+#include <net/netfilter/nf_tproxy_core.h>
+
+static unsigned int
+target(struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ unsigned int hooknum,
+ const struct xt_target *target,
+ const void *targinfo)
+{
+ const struct iphdr *iph = ip_hdr(*pskb);
+ const struct ipt_tproxy_target_info *tgi =
+ (const struct ipt_tproxy_target_info *) targinfo;
+ struct sk_buff *skb = *pskb;
+ struct udphdr _hdr, *hp;
+ struct sock *sk;
+
+ /* TCP/UDP only */
+ if ((iph->protocol != IPPROTO_TCP) &&
+ (iph->protocol != IPPROTO_UDP))
+ return NF_ACCEPT;
+
+ hp = skb_header_pointer(*pskb, iph->ihl * 4, sizeof(_hdr), &_hdr);
+ if (hp == NULL)
+ return NF_DROP;
+
+ sk = nf_tproxy_get_sock_v4(iph->protocol,
+ iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr,
+ hp->source, tgi->lport ? tgi->lport : hp->dest,
+ in, true);
+
+ /* 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 & ~tgi->mark_mask) ^ tgi->mark_value;
+
+ pr_debug("redirecting: proto %d %08x:%d -> %08x:%d, mark: %x\n",
+ iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
+ ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark);
+ return NF_ACCEPT;
+ }
+ else {
+ pr_debug("no socket, dropping: proto %d %08x:%d -> %08x:%d, mark: %x\n",
+ iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
+ ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark);
+ return NF_DROP;
+ }
+}
+
+#ifdef CONFIG_COMPAT
+struct compat_ipt_tproxy_target_info {
+ __be32 laddr;
+ __be16 lport;
+ __be16 __pad1;
+ compat_ulong_t mark_mask;
+ compat_ulong_t mark_value;
+};
+
+static void compat_from_user(void *dst, void *src)
+{
+ const struct compat_ipt_tproxy_target_info *c = src;
+ struct ipt_tproxy_target_info m = {
+ .laddr = c->laddr,
+ .lport = c->lport,
+ .mark_mask = c->mark_mask,
+ .mark_value = c->mark_value,
+ };
+ memcpy(dst, &m, sizeof(m));
+}
+
+static void compat_to_user(void __user *dst, void *src)
+{
+ const struct ipt_tproxy_target_info *m = src;
+ struct compat_ipt_tproxy_target_info c = {
+ .laddr = m->laddr,
+ .lport = m->lport,
+ .mark_mask = m->mark_mask,
+ .mark_value = m->mark_value,
+ };
+ return copy_to_user(dst, &c, sizeof(c)) ? -EFAULT : 0;
+}
+#endif /* CONFIG_COMPAT */
+
+static struct xt_target xt_tproxy_reg = {
+ .name = "TPROXY",
+ .family = AF_INET,
+ .target = target,
+ .targetsize = sizeof(struct ipt_tproxy_target_info),
+#ifdef CONFIG_COMPAT
+ .compatsize = sizeof(struct compat_ipt_tproxy_target_info),
+ .compat_from_user = compat_from_user,
+ .compat_to_user = compat_to_user,
+#endif
+ .table = "mangle",
+ .hooks = (1 << NF_IP_PRE_ROUTING),
+ .me = THIS_MODULE,
+};
+
+static int __init init(void)
+{
+ nf_defrag_ipv4_enable();
+ return xt_register_target(&xt_tproxy_reg);
+}
+
+static void __exit fini(void)
+{
+ xt_unregister_target(&xt_tproxy_reg);
+}
+
+module_init(init);
+module_exit(fini);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Krisztian Kovacs");
+MODULE_DESCRIPTION("Netfilter transparent proxy (TPROXY) target module.");
+MODULE_ALIAS("ipt_TPROXY");
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 12/13] Don't lookup the socket if there's a socket attached to the skb
2007-09-30 20:51 [PATCH 00/13] Transparent Proxying Patches, Take 3 KOVACS Krisztian
` (10 preceding siblings ...)
2007-09-30 20:53 ` [PATCH 11/13] iptables TPROXY target KOVACS Krisztian
@ 2007-09-30 20:53 ` KOVACS Krisztian
2007-09-30 20:53 ` [PATCH 13/13] " KOVACS Krisztian
2007-09-30 22:01 ` [PATCH 00/13] Transparent Proxying Patches, Take 3 Patrick McHardy
13 siblings, 0 replies; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 20:53 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
Use the socket cached in the TPROXY target if it's present.
Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
---
net/ipv4/tcp_ipv4.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 7ae47e6..7ebf1c7 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1658,6 +1658,14 @@ int tcp_v4_rcv(struct sk_buff *skb)
TCP_SKB_CB(skb)->flags = iph->tos;
TCP_SKB_CB(skb)->sacked = 0;
+#if defined(CONFIG_IP_NF_TPROXY) || defined (CONFIG_IP_NF_TPROXY_MODULE)
+ if (unlikely(skb->sk)) {
+ /* steal reference */
+ sk = skb->sk;
+ skb->destructor = NULL;
+ skb->sk = NULL;
+ } else
+#endif
sk = __inet_lookup(&tcp_hashinfo, iph->saddr, th->source,
iph->daddr, th->dest, inet_iif(skb));
if (!sk)
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 13/13] Don't lookup the socket if there's a socket attached to the skb
2007-09-30 20:51 [PATCH 00/13] Transparent Proxying Patches, Take 3 KOVACS Krisztian
` (11 preceding siblings ...)
2007-09-30 20:53 ` [PATCH 12/13] Don't lookup the socket if there's a socket attached to the skb KOVACS Krisztian
@ 2007-09-30 20:53 ` KOVACS Krisztian
2007-09-30 22:01 ` [PATCH 00/13] Transparent Proxying Patches, Take 3 Patrick McHardy
13 siblings, 0 replies; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 20:53 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
Use the socket cached in the TPROXY target if it's present.
Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
---
net/ipv4/udp.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 2fb3b7c..2bdf034 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1151,6 +1151,14 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable);
+#if defined(CONFIG_IP_NF_TPROXY) || defined (CONFIG_IP_NF_TPROXY_MODULE)
+ if (unlikely(skb->sk)) {
+ /* steal reference */
+ sk = skb->sk;
+ skb->destructor = NULL;
+ skb->sk = NULL;
+ } else
+#endif
sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest,
skb->dev->ifindex, udptable );
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PATCH 11/13] xtables TPROXY target
2007-09-30 20:53 ` [PATCH 11/13] iptables TPROXY target KOVACS Krisztian
@ 2007-09-30 21:40 ` Jan Engelhardt
2007-09-30 22:07 ` KOVACS Krisztian
2007-09-30 22:20 ` [PATCH 11/13] xt_TPROXY Jan Engelhardt
2007-09-30 22:43 ` [PATCH 11/13] iptables TPROXY target Patrick McHardy
2 siblings, 1 reply; 45+ messages in thread
From: Jan Engelhardt @ 2007-09-30 21:40 UTC (permalink / raw)
To: KOVACS Krisztian
Cc: Patrick McHardy, Netfilter Developer Mailing List,
Balazs Scheidler, Toth Laszlo Attila
On Sep 30 2007 22:53, KOVACS Krisztian wrote:
>The TPROXY target implements redirection of non-local TCP/UDP traffic to local
>sockets. Additionally, it's possible to manipulate the packet mark if and only
>if a socket has been found. (We need this because we cannot use multiple
>targets in the same iptables rule.)
This provides xt_TPROXY.
===
iptables TPROXY target
From: KOVACS Krisztian <hidden@balabit.hu>
The TPROXY target implements redirection of non-local TCP/UDP traffic
to local sockets. It is simply a wrapper around functionality exported
from iptable_tproxy.
Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
---
include/linux/netfilter/xt_TPROXY.h | 9 ++++
net/ipv4/netfilter/Kconfig | 11 +++++
net/netfilter/Makefile | 1
net/netfilter/xt_TPROXY.c | 76 ++++++++++++++++++++++++++++++++++++
4 files changed, 97 insertions(+)
Index: linux-2.6.22.1/include/linux/netfilter/xt_TPROXY.h
===================================================================
--- /dev/null
+++ linux-2.6.22.1/include/linux/netfilter/xt_TPROXY.h
@@ -0,0 +1,9 @@
+#ifndef _XT_TPROXY_H
+#define _XT_TPROXY_H
+
+struct xt_tproxy_info {
+ u_int32_t laddr;
+ u_int16_t lport;
+};
+
+#endif /* _XT_TPROXY_H */
Index: linux-2.6.22.1/net/ipv4/netfilter/Kconfig
===================================================================
--- linux-2.6.22.1.orig/net/ipv4/netfilter/Kconfig
+++ linux-2.6.22.1/net/ipv4/netfilter/Kconfig
@@ -403,6 +403,17 @@ config IP_NF_TPROXY_TABLE
To compile it as a module, choose M here. If unsure, say `N'.
+config NETFILTER_XT_TARGET_TPROXY
+ tristate "TPROXY target support"
+ depends on IP_NF_TPROXY_TABLE
+ help
+ This option adds a `TPROXY' target, which is somewhat similar to
+ REDIRECT. It can only be used in the tproxy table and is useful
+ to redirect traffic to a transparent proxy. It does _not_ depend
+ on Netfilter connection tracking.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
# ARP tables
config IP_NF_ARPTABLES
tristate "ARP tables support"
Index: linux-2.6.22.1/net/netfilter/Makefile
===================================================================
--- linux-2.6.22.1.orig/net/netfilter/Makefile
+++ linux-2.6.22.1/net/netfilter/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE)
obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TARPIT) += xt_TARPIT.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o
obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
# matches
Index: linux-2.6.22.1/net/netfilter/xt_TPROXY.c
===================================================================
--- /dev/null
+++ linux-2.6.22.1/net/netfilter/xt_TPROXY.c
@@ -0,0 +1,76 @@
+/*
+ * Transparent proxy support for Linux/iptables
+ *
+ * Copyright (c) 2006-2007 BalaBit IT Ltd.
+ * Author: Balazs Scheidler, Krisztian Kovacs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/ip.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ip_tproxy.h>
+#include <linux/netfilter/xt_TPROXY.h>
+#include <net/checksum.h>
+#include <net/inet_sock.h>
+#include <net/udp.h>
+
+static unsigned int
+tproxy_target(struct sk_buff **pskb, const struct net_device *in,
+ const struct net_device *out, unsigned int hooknum,
+ const struct xt_target *target, const void *targinfo)
+{
+ const struct xt_tproxy_info *tgi = targinfo;
+ const struct iphdr *iph = ip_hdr(*pskb);
+ struct sk_buff *skb = *pskb;
+ struct udphdr _hdr, *hp;
+
+ /* TCP/UDP only */
+ if (iph->protocol != IPPROTO_TCP && iph->protocol != IPPROTO_UDP)
+ return NF_ACCEPT;
+
+ hp = skb_header_pointer(*pskb, iph->ihl * 4, sizeof(_hdr), &_hdr);
+ if (hp == NULL)
+ return NF_DROP;
+
+ skb->nf_tproxy.redirect_address = tgi->laddr ? : iph->daddr;
+ skb->nf_tproxy.redirect_port = tgi->lport ? : hp->dest;
+
+ pr_debug(KERN_DEBUG "redirecting: proto %d %08x:%d -> %08x:%d\n",
+ iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
+ ntohl(skb->nf_tproxy.redirect_address),
+ ntohs(skb->nf_tproxy.redirect_port));
+
+ return NF_ACCEPT;
+}
+
+static struct xt_target xt_tproxy_reg __read_mostly = {
+ .name = "TPROXY",
+ .family = AF_INET,
+ .table = "tproxy",
+ .target = tproxy_target,
+ .targetsize = sizeof(struct xt_tproxy_info),
+ .me = THIS_MODULE,
+};
+
+static int __init xt_tproxy_init(void)
+{
+ return xt_register_target(&xt_tproxy_reg);
+}
+
+static void __exit xt_tproxy_exit(void)
+{
+ xt_unregister_target(&xt_tproxy_reg);
+}
+
+module_init(xt_tproxy_init);
+module_exit(xt_tproxy_exit);
+MODULE_AUTHOR("Krisztian Kovacs <hidden@balabit.hu>");
+MODULE_DESCRIPTION("Netfilter transparent proxy TPROXY target module");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_TPROXY");
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 10/13] iptables socket match
2007-09-30 20:53 ` [PATCH 10/13] iptables socket match KOVACS Krisztian
@ 2007-09-30 21:43 ` Jan Engelhardt
2007-09-30 22:15 ` [PATCH 10/13] xt_socket Jan Engelhardt
1 sibling, 0 replies; 45+ messages in thread
From: Jan Engelhardt @ 2007-09-30 21:43 UTC (permalink / raw)
To: KOVACS Krisztian
Cc: Patrick McHardy, netfilter-devel, Balazs Scheidler,
Toth Laszlo Attila
On Sep 30 2007 22:53, KOVACS Krisztian wrote:
>
>Add iptables 'socket' match, which matches packets for which a TCP/UDP
>socket lookup succeeds.
>
>---
And here is the xt_socket that I had..
===
iptables socket match
From: KOVACS Krisztian <hidden@balabit.hu>
Add iptables 'socket' match, which matches packets for which a TCP/UDP
socket lookup succeeds.
Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
---
net/ipv4/netfilter/Kconfig | 10 +++++
net/netfilter/Makefile | 1
net/netfilter/xt_socket.c | 80 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 91 insertions(+)
Index: linux-2.6.22.1/net/ipv4/netfilter/Kconfig
===================================================================
--- linux-2.6.22.1.orig/net/ipv4/netfilter/Kconfig
+++ linux-2.6.22.1/net/ipv4/netfilter/Kconfig
@@ -414,6 +414,16 @@ config NETFILTER_XT_TARGET_TPROXY
To compile it as a module, choose M here. If unsure, say N.
+config NETFILTER_XT_MATCH_SOCKET
+ tristate "socket match support"
+ depends on IP_NF_TPROXY_TABLE
+ help
+ This option adds a `socket' match, which can be used to match
+ packets for which a TCP or UDP socket lookup finds a valid socket.
+ It can only be used in the tproxy table.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
# ARP tables
config IP_NF_ARPTABLES
tristate "ARP tables support"
Index: linux-2.6.22.1/net/netfilter/Makefile
===================================================================
--- linux-2.6.22.1.orig/net/netfilter/Makefile
+++ linux-2.6.22.1/net/netfilter/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE)
obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o
obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
Index: linux-2.6.22.1/net/netfilter/xt_socket.c
===================================================================
--- /dev/null
+++ linux-2.6.22.1/net/netfilter/xt_socket.c
@@ -0,0 +1,80 @@
+/*
+ * Transparent proxy support for Linux/iptables
+ *
+ * Copyright (c) 2007 BalaBit IT Ltd.
+ * Author: Krisztian Kovacs
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter_ipv4/ip_tproxy.h>
+#include <net/inet_sock.h>
+#include <net/sock.h>
+#include <net/tcp.h>
+#include <net/udp.h>
+
+static int
+socket_match(const struct sk_buff *skb, const struct net_device *in,
+ const struct net_device *out, const struct xt_match *match,
+ const void *matchinfo, int offset, unsigned int protoff,
+ int *hotdrop)
+{
+ const struct iphdr *iph = ip_hdr(skb);
+ struct udphdr _hdr, *hp;
+ struct sock *sk;
+
+ /* TCP/UDP only */
+ if (iph->protocol != IPPROTO_TCP && iph->protocol != IPPROTO_UDP)
+ return false;
+
+ hp = skb_header_pointer(skb, iph->ihl * 4, sizeof(_hdr), &_hdr);
+ if (hp == NULL)
+ return false;
+
+ sk = ip_tproxy_get_sock(iph->protocol, iph->saddr, iph->daddr,
+ hp->source, hp->dest, in);
+ if (sk != NULL) {
+ if (iph->protocol == IPPROTO_TCP &&
+ sk->sk_state == TCP_TIME_WAIT)
+ inet_twsk_put(inet_twsk(sk));
+ else
+ sock_put(sk);
+ }
+
+ pr_debug(KERN_DEBUG "socket match: proto %d %08x:%d -> %08x:%d sock %p\n",
+ iph->protocol, ntohl(iph->saddr), ntohs(hp->source),
+ ntohl(iph->daddr), ntohs(hp->dest), sk);
+
+ return sk != NULL;
+}
+
+static struct xt_match socket_reg __read_mostly = {
+ .name = "socket",
+ .family = AF_INET,
+ .table = "tproxy",
+ .match = socket_match,
+ .me = THIS_MODULE,
+};
+
+static int __init xt_socket_init(void)
+{
+ return xt_register_match(&socket_reg);
+}
+
+static void __exit xt_socket_fini(void)
+{
+ xt_unregister_match(&socket_reg);
+}
+
+module_init(xt_socket_init);
+module_exit(xt_socket_fini);
+MODULE_AUTHOR("Krisztian Kovacs <hidden@balabit.hu>");
+MODULE_DESCRIPTION("netfilter socket match module");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_socket");
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 05/13] Handle TCP SYN+ACK/ACK/RST transparency
2007-09-30 20:52 ` [PATCH 05/13] Handle TCP SYN+ACK/ACK/RST transparency KOVACS Krisztian
@ 2007-09-30 21:45 ` Jan Engelhardt
2007-09-30 21:46 ` Jan Engelhardt
2007-09-30 21:58 ` KOVACS Krisztian
2007-09-30 22:23 ` Patrick McHardy
1 sibling, 2 replies; 45+ messages in thread
From: Jan Engelhardt @ 2007-09-30 21:45 UTC (permalink / raw)
To: KOVACS Krisztian
Cc: Patrick McHardy, netfilter-devel, Balazs Scheidler,
Toth Laszlo Attila
On Sep 30 2007 22:52, KOVACS Krisztian wrote:
>
>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.
I needed to add extra patches to actually compile it cleanly....
> include/net/ip.h | 3 +++
> include/net/request_sock.h | 3 ++-
> net/ipv4/inet_connection_sock.c | 2 ++
> net/ipv4/ip_output.c | 6 +++++-
> net/ipv4/syncookies.c | 2 ++
> net/ipv4/tcp_ipv4.c | 17 ++++++++++-------
> net/ipv4/tcp_minisocks.c | 3 ++-
> net/ipv6/tcp_ipv6.c | 5 +++--
> 8 files changed, 29 insertions(+), 12 deletions(-)
>
Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
---
net/dccp/dccp.h | 3 ++-
net/dccp/minisocks.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
Index: linux-2.6.22.1/net/dccp/dccp.h
===================================================================
--- linux-2.6.22.1.orig/net/dccp/dccp.h
+++ linux-2.6.22.1/net/dccp/dccp.h
@@ -209,7 +209,8 @@ extern int dccp_retransmit_skb(struct s
extern void dccp_send_ack(struct sock *sk);
extern void dccp_send_delayed_ack(struct sock *sk);
-extern void dccp_reqsk_send_ack(struct sk_buff *sk, struct request_sock *rsk);
+extern void dccp_reqsk_send_ack(struct sk_buff *sk, struct request_sock *rsk,
+ int reply_flags);
extern void dccp_send_sync(struct sock *sk, const u64 seq,
const enum dccp_pkt_type pkt_type);
Index: linux-2.6.22.1/net/dccp/minisocks.c
===================================================================
--- linux-2.6.22.1.orig/net/dccp/minisocks.c
+++ linux-2.6.22.1/net/dccp/minisocks.c
@@ -285,7 +285,8 @@ int dccp_child_process(struct sock *pare
EXPORT_SYMBOL_GPL(dccp_child_process);
-void dccp_reqsk_send_ack(struct sk_buff *skb, struct request_sock *rsk)
+void dccp_reqsk_send_ack(struct sk_buff *skb, struct request_sock *rsk,
+ int reply_flags)
{
DCCP_BUG("DCCP-ACK packets are never sent in LISTEN/RESPOND state");
}
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 05/13] Handle TCP SYN+ACK/ACK/RST transparency
2007-09-30 21:45 ` Jan Engelhardt
@ 2007-09-30 21:46 ` Jan Engelhardt
2007-09-30 21:59 ` KOVACS Krisztian
2007-09-30 21:58 ` KOVACS Krisztian
1 sibling, 1 reply; 45+ messages in thread
From: Jan Engelhardt @ 2007-09-30 21:46 UTC (permalink / raw)
To: KOVACS Krisztian
Cc: Patrick McHardy, netfilter-devel, Balazs Scheidler,
Toth Laszlo Attila
>On Sep 30 2007 22:52, KOVACS Krisztian wrote:
>>
>>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.
>
>I needed to add extra patches to actually compile it cleanly....
>
>> include/net/ip.h | 3 +++
>> include/net/request_sock.h | 3 ++-
>> net/ipv4/inet_connection_sock.c | 2 ++
>> net/ipv4/ip_output.c | 6 +++++-
>> net/ipv4/syncookies.c | 2 ++
>> net/ipv4/tcp_ipv4.c | 17 ++++++++++-------
>> net/ipv4/tcp_minisocks.c | 3 ++-
>> net/ipv6/tcp_ipv6.c | 5 +++--
>> 8 files changed, 29 insertions(+), 12 deletions(-)
>>
part 2/2.
>
>Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
>
---
net/ipv6/tcp_ipv6.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Index: linux-2.6.22.3/net/ipv6/tcp_ipv6.c
===================================================================
--- linux-2.6.22.3.orig/net/ipv6/tcp_ipv6.c
+++ linux-2.6.22.3/net/ipv6/tcp_ipv6.c
@@ -73,7 +73,7 @@
static struct socket *tcp6_socket;
static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb);
-static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req);
+static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req, int);
static void tcp_v6_send_check(struct sock *sk, int len,
struct sk_buff *skb);
@@ -1195,7 +1195,7 @@ static void tcp_v6_timewait_ack(struct s
inet_twsk_put(tw);
}
-static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req)
+static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req, int reply_flags)
{
tcp_v6_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent);
}
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 05/13] Handle TCP SYN+ACK/ACK/RST transparency
2007-09-30 21:45 ` Jan Engelhardt
2007-09-30 21:46 ` Jan Engelhardt
@ 2007-09-30 21:58 ` KOVACS Krisztian
1 sibling, 0 replies; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 21:58 UTC (permalink / raw)
To: Jan Engelhardt
Cc: Patrick McHardy, netfilter-devel, Balazs Scheidler,
Toth Laszlo Attila
Hi Jan,
On Sunday 30 September 2007, Jan Engelhardt wrote:
> Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
>
> ---
> net/dccp/dccp.h | 3 ++-
> net/dccp/minisocks.c | 3 ++-
> 2 files changed, 4 insertions(+), 2 deletions(-)
>
> Index: linux-2.6.22.1/net/dccp/dccp.h
> ===================================================================
> --- linux-2.6.22.1.orig/net/dccp/dccp.h
> +++ linux-2.6.22.1/net/dccp/dccp.h
> @@ -209,7 +209,8 @@ extern int dccp_retransmit_skb(struct s
>
> extern void dccp_send_ack(struct sock *sk);
> extern void dccp_send_delayed_ack(struct sock *sk);
> -extern void dccp_reqsk_send_ack(struct sk_buff *sk, struct
> request_sock *rsk); +extern void dccp_reqsk_send_ack(struct sk_buff
> *sk, struct request_sock *rsk, + int reply_flags);
>
> extern void dccp_send_sync(struct sock *sk, const u64 seq,
> const enum dccp_pkt_type pkt_type);
> Index: linux-2.6.22.1/net/dccp/minisocks.c
> ===================================================================
> --- linux-2.6.22.1.orig/net/dccp/minisocks.c
> +++ linux-2.6.22.1/net/dccp/minisocks.c
> @@ -285,7 +285,8 @@ int dccp_child_process(struct sock *pare
>
> EXPORT_SYMBOL_GPL(dccp_child_process);
>
> -void dccp_reqsk_send_ack(struct sk_buff *skb, struct request_sock
> *rsk) +void dccp_reqsk_send_ack(struct sk_buff *skb, struct
> request_sock *rsk, + int reply_flags)
> {
> DCCP_BUG("DCCP-ACK packets are never sent in LISTEN/RESPOND state");
> }
Yes, this was missing. Thanks.
--
KOVACS Krisztian
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 05/13] Handle TCP SYN+ACK/ACK/RST transparency
2007-09-30 21:46 ` Jan Engelhardt
@ 2007-09-30 21:59 ` KOVACS Krisztian
2007-09-30 22:02 ` Jan Engelhardt
0 siblings, 1 reply; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 21:59 UTC (permalink / raw)
To: Jan Engelhardt
Cc: Patrick McHardy, netfilter-devel, Balazs Scheidler,
Toth Laszlo Attila
Hi Jan,
On Sunday 30 September 2007, Jan Engelhardt wrote:
> part 2/2.
>
> >Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
>
> ---
> net/ipv6/tcp_ipv6.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> Index: linux-2.6.22.3/net/ipv6/tcp_ipv6.c
> ===================================================================
> --- linux-2.6.22.3.orig/net/ipv6/tcp_ipv6.c
> +++ linux-2.6.22.3/net/ipv6/tcp_ipv6.c
> @@ -73,7 +73,7 @@
> static struct socket *tcp6_socket;
>
> static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb);
> -static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct
> request_sock *req); +static void tcp_v6_reqsk_send_ack(struct sk_buff
> *skb, struct request_sock *req, int); static
> void tcp_v6_send_check(struct sock *sk, int len,
> struct sk_buff *skb);
>
> @@ -1195,7 +1195,7 @@ static void tcp_v6_timewait_ack(struct s
> inet_twsk_put(tw);
> }
>
> -static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct
> request_sock *req) +static void tcp_v6_reqsk_send_ack(struct sk_buff
> *skb, struct request_sock *req, int reply_flags) {
> tcp_v6_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1,
> tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent); }
> -
> To unsubscribe from this list: send the line "unsubscribe
> netfilter-devel" in the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
This is already _in_ the patch I've sent.
--
KOVACS Krisztian
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 00/13] Transparent Proxying Patches, Take 3
2007-09-30 20:51 [PATCH 00/13] Transparent Proxying Patches, Take 3 KOVACS Krisztian
` (12 preceding siblings ...)
2007-09-30 20:53 ` [PATCH 13/13] " KOVACS Krisztian
@ 2007-09-30 22:01 ` Patrick McHardy
2007-09-30 22:13 ` KOVACS Krisztian
13 siblings, 1 reply; 45+ messages in thread
From: Patrick McHardy @ 2007-09-30 22:01 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
KOVACS Krisztian wrote:
> Hi Patrick,
>
> These patches are our (Balazs, Attila and me) third try at providing Linux
> 2.2-like transparent proxying support for Linux 2.6. During the 5th Netfilter
> Workshop in Karlsruhe, Germany we tried to come up with an even more
> lightweight approach not requiring the modification of the IPv4 routing code at
> all.
>
> The most important changes relative to the previous versions[1,2] are:
> * the tproxy table is gone, TPROXY targets need to be added to the
> mangle table instead
> * the tproxy match is gone, a new "socket" match is introduced
> * instead of using a separate routing trick to divert packets to the
> local IP stack inside the TProxy target, we are now using stock routing
> decisions, and need a bit in the packet MARK field, and perform diversion by
> using an advanced routing rule (this hopefully makes it possible to
> implement IPv6 support in the future
> * instead of IP_FREEBIND we are using a setsockopt named IP_TRANSPARENT
> which requires CAP_NET_ADMIN privilege
> * in previous patches the output routing decision was commented out, it
> is now correctly decided whether a packet belongs to a tproxied
> connection or not.
>
> Usage is a bit more complicated compared to the previous approach, but it's
> certainly not rocket science:
>
> # iptables rules necessary:
> # create a chain named DIVERT
> iptables -t mangle -N DIVERT
> # everything that matches "-m socket" should go to the local stack
> iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
> # connections to be redirected should use the TPROXY target, which sets
> # up redirection, and marks the packet according to its 'tproxy-mark'
> # argument
> iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY \
> --tproxy-mark 0x1/0x1 --on-port 50080
> # DIVERT chain: mark packets and accept
> iptables -t mangle -A DIVERT -j MARK --set-mark 1
> iptables -t mangle -A DIVERT -j ACCEPT
>
> # set up advanced routing rules to deliver our marked packets locally
> ip rule add fwmark 1 lookup 100
> ip route add local 0.0.0.0/0 dev lo table 100
>
> The proxy code needs to be modified as well, but these are really lightweight:
> before binding, the IP_TRANSPARENT sockopt needs to be enabled on the socket.
> This implies IP_FREEBIND, so after enabling this socket option non-local binds
> will work and if you got your iptables/iproute setup right non-local traffic
> will be delivered to/from the socket. A netcat patch demonstrating this is
> available[4] as an example.
>
> Some word about the patches:
>
> * output path (patches 1-5): these modifications make it possible to
> output IPv4 datagrams with non-local IP addresses by:
> - introducing a new flowi flag (FLOWI_FLAG_ANYSRC) which disables the source
> address check in ip_route_output_slow() [3]
> - adding the IP_TRANSPARENT socket option (setting this requires CAP_NET_ADMIN)
> - setting FLOWI_FLAG_ANYSRC if IP_TRANSPARENT is enabled for the originating
> socket
> - set FLOWI_FLAG_ANYSRC where appropriate for sending reply packets
> generated by the kernel; this requires extending the ip_reply_arg
> structure with a flags field and adding an IP_REPLY_ARG_NOSRCCHECK flag
>
> * input patch (patches 6-13): these changes implement redirection support for
> TCP plus the iptables socket match and TPROXY target -- these provide the
> actual user interface:
> - split IPv4 defragmentation into a separate module, as this is needed by
> both our target and match
> - add a 'socket' match which does a socket lookup based on the destination
> tuple in the packet and matches is a socket has been found
> - add a 'TPROXY' target which looks up a socket based on a modified IP/port
> tuple and stores the socket reference in the skb
> - modifying the TCP/UDP input paths to use the stored socket reference if
> present
>
> All kinds of comments welcome. Patrick, I'd like to ask you to review these
> patches and if no issues are found by you or by anyone on the list, please
> consider merging them.
>
Thanks for posting these patches. I'll gladly review them, but
the patches touching things outside of netfilter need to go
through netdev and Dave for merging.
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 05/13] Handle TCP SYN+ACK/ACK/RST transparency
2007-09-30 21:59 ` KOVACS Krisztian
@ 2007-09-30 22:02 ` Jan Engelhardt
0 siblings, 0 replies; 45+ messages in thread
From: Jan Engelhardt @ 2007-09-30 22:02 UTC (permalink / raw)
To: KOVACS Krisztian
Cc: Patrick McHardy, netfilter-devel, Balazs Scheidler,
Toth Laszlo Attila
On Sep 30 2007 23:59, KOVACS Krisztian wrote:
>> ---
>> net/ipv6/tcp_ipv6.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> Index: linux-2.6.22.3/net/ipv6/tcp_ipv6.c
>> ===================================================================
>> --- linux-2.6.22.3.orig/net/ipv6/tcp_ipv6.c
>> +++ linux-2.6.22.3/net/ipv6/tcp_ipv6.c
>> @@ -73,7 +73,7 @@
>> static struct socket *tcp6_socket;
>>
>> static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb);
>> -static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct
>> request_sock *req); +static void tcp_v6_reqsk_send_ack(struct sk_buff
>> *skb, struct request_sock *req, int); static
>> void tcp_v6_send_check(struct sock *sk, int len,
>> struct sk_buff *skb);
>
>This is already _in_ the patch I've sent.
Hm, my bad, did not look to far. (Also these were the 2.6.22 ones -
I should probably update)
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 11/13] xtables TPROXY target
2007-09-30 21:40 ` [PATCH 11/13] xtables " Jan Engelhardt
@ 2007-09-30 22:07 ` KOVACS Krisztian
0 siblings, 0 replies; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 22:07 UTC (permalink / raw)
To: Jan Engelhardt
Cc: Patrick McHardy, Netfilter Developer Mailing List,
Balazs Scheidler, Toth Laszlo Attila
Hi Jan,
On Sunday 30 September 2007, Jan Engelhardt wrote:
> +static unsigned int
> +tproxy_target(struct sk_buff **pskb, const struct net_device *in,
> + const struct net_device *out, unsigned int hooknum,
> + const struct xt_target *target, const void *targinfo)
> +{
> + const struct xt_tproxy_info *tgi = targinfo;
> + const struct iphdr *iph = ip_hdr(*pskb);
> + struct sk_buff *skb = *pskb;
> + struct udphdr _hdr, *hp;
> +
> + /* TCP/UDP only */
> + if (iph->protocol != IPPROTO_TCP && iph->protocol != IPPROTO_UDP)
> + return NF_ACCEPT;
> +
> + hp = skb_header_pointer(*pskb, iph->ihl * 4, sizeof(_hdr), &_hdr);
> + if (hp == NULL)
> + return NF_DROP;
> +
> + skb->nf_tproxy.redirect_address = tgi->laddr ? : iph->daddr;
> + skb->nf_tproxy.redirect_port = tgi->lport ? : hp->dest;
> +
> + pr_debug(KERN_DEBUG "redirecting: proto %d %08x:%d -> %08x:%d\n",
> + iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
> + ntohl(skb->nf_tproxy.redirect_address),
> + ntohs(skb->nf_tproxy.redirect_port));
> +
> + return NF_ACCEPT;
> +}
I guess this is also an old version, the current one does not look like
this. Are you sure this is really up-to-date?
--
KOVACS Krisztian
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 01/13] Loosen source address check on IPv4 output
2007-09-30 20:51 ` [PATCH 01/13] Loosen source address check on IPv4 output KOVACS Krisztian
@ 2007-09-30 22:12 ` Patrick McHardy
0 siblings, 0 replies; 45+ messages in thread
From: Patrick McHardy @ 2007-09-30 22:12 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
KOVACS Krisztian wrote:
> 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@ssi.bg>
> Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
Acked-by: Patrick McHardy <kaber@trash.net>
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 02/13] Implement IP_TRANSPARENT socket option
2007-09-30 20:52 ` [PATCH 02/13] Implement IP_TRANSPARENT socket option KOVACS Krisztian
@ 2007-09-30 22:12 ` Patrick McHardy
0 siblings, 0 replies; 45+ messages in thread
From: Patrick McHardy @ 2007-09-30 22:12 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
KOVACS Krisztian wrote:
> 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@sch.bme.hu>
Acked-by: Patrick McHardy <kaber@trash.net>
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 03/13] Allow binding to non-local addresses if IP_TRANSPARENT is set
2007-09-30 20:52 ` [PATCH 03/13] Allow binding to non-local addresses if IP_TRANSPARENT is set KOVACS Krisztian
@ 2007-09-30 22:12 ` Patrick McHardy
0 siblings, 0 replies; 45+ messages in thread
From: Patrick McHardy @ 2007-09-30 22:12 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
KOVACS Krisztian wrote:
> 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@balabit.hu>
>
Acked-by: Patrick McHardy <kaber@trash.net>
-
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 00/13] Transparent Proxying Patches, Take 3
2007-09-30 22:01 ` [PATCH 00/13] Transparent Proxying Patches, Take 3 Patrick McHardy
@ 2007-09-30 22:13 ` KOVACS Krisztian
0 siblings, 0 replies; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 22:13 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
Hi Patrick,
On Monday 01 October 2007, Patrick McHardy wrote:
> Thanks for posting these patches. I'll gladly review them, but
> the patches touching things outside of netfilter need to go
> through netdev and Dave for merging.
Thanks a lot. I guess getting feedback from you and the list is very
important -- we absolutely would like to hammer out as many problems as
possible before posting to netdev/Dave. Not to mention the Netfilter
specific parts... :)
--
KOVACS Krisztian
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 10/13] xt_socket
2007-09-30 20:53 ` [PATCH 10/13] iptables socket match KOVACS Krisztian
2007-09-30 21:43 ` Jan Engelhardt
@ 2007-09-30 22:15 ` Jan Engelhardt
1 sibling, 0 replies; 45+ messages in thread
From: Jan Engelhardt @ 2007-09-30 22:15 UTC (permalink / raw)
To: KOVACS Krisztian
Cc: Patrick McHardy, netfilter-devel, Balazs Scheidler,
Toth Laszlo Attila
On Sep 30 2007 22:53, KOVACS Krisztian wrote:
>+
>+ hp = skb_header_pointer(skb, iph->ihl * 4, sizeof(_hdr), &_hdr);
>+ if (hp == NULL)
>+ return false;
ip_hdrlen(skb) for 2nd arg.
>+ pr_debug("socket match: proto %d %08x:%d -> %08x:%d sock %p\n",
>+ iph->protocol, ntohl(iph->saddr), ntohs(hp->source),
>+ ntohl(iph->daddr), ntohs(hp->dest), sk);
Should be %u.
>+static struct xt_match socket_matches[] = {
A single struct suffices.
>+ .name = "socket",
>+ .family = AF_INET,
>+ .match = match,
This goes against debugging. If everyone names their match function
"match" (and it's done too often in netfilter and iptables-userspace
already), it is hard to find out which is meant (e.g. in an oops). It
also makes debugging quite impossible because setting a breakpoint will
be ambiguous.
Find below a patch that makes me happy, and compiles. :)
===
Add the xt_socket match, which matches packets for which a TCP/UDP
socket lookup succeeds.
(originally from: KOVACS Krisztian <hidden@sch.bme.hu>)
A few cleanups.
Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
---
net/netfilter/Kconfig | 12 +++++++
net/netfilter/Makefile | 1
net/netfilter/xt_socket.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 89 insertions(+)
Index: linux-2.6.23/net/netfilter/Kconfig
===================================================================
--- linux-2.6.23.orig/net/netfilter/Kconfig
+++ linux-2.6.23/net/netfilter/Kconfig
@@ -632,6 +632,18 @@ config NETFILTER_XT_MATCH_SCTP
If you want to compile it as a module, say M here and read
<file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
+config NETFILTER_XT_MATCH_SOCKET
+ tristate '"socket" match support'
+ depends on NETFILTER_TPROXY
+ depends on NETFILTER_XTABLES
+ select NF_DEFRAG_IPV4
+ help
+ This option adds a "socket" match, which can be used to match
+ packets for which a TCP or UDP socket lookup finds a valid socket.
+ It can only be used in the tproxy table.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
config NETFILTER_XT_MATCH_STATE
tristate '"state" match support'
depends on NETFILTER_XTABLES
Index: linux-2.6.23/net/netfilter/Makefile
===================================================================
--- linux-2.6.23.orig/net/netfilter/Makefile
+++ linux-2.6.23/net/netfilter/Makefile
@@ -73,6 +73,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE)
obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o
obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
Index: linux-2.6.23/net/netfilter/xt_socket.c
===================================================================
--- /dev/null
+++ linux-2.6.23/net/netfilter/xt_socket.c
@@ -0,0 +1,76 @@
+/*
+ * Transparent proxy support for Linux/iptables
+ *
+ * Copyright (c) 2007 BalaBit IT Ltd.
+ * Author: Krisztian Kovacs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/netfilter/x_tables.h>
+#include <net/inet_sock.h>
+#include <net/sock.h>
+#include <net/tcp.h>
+#include <net/udp.h>
+#include <net/netfilter/nf_tproxy_core.h>
+#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
+
+static bool
+socket_match(const struct sk_buff *skb, const struct net_device *in,
+ const struct net_device *out, const struct xt_match *match,
+ const void *matchinfo, int offset, unsigned int protoff,
+ bool *hotdrop)
+{
+ const struct iphdr *iph = ip_hdr(skb);
+ struct udphdr _hdr, *hp;
+ struct sock *sk;
+
+ /* TCP/UDP only */
+ if (iph->protocol != IPPROTO_TCP && iph->protocol != IPPROTO_UDP)
+ return false;
+
+ hp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_hdr), &_hdr);
+ if (hp == NULL)
+ return false;
+
+ sk = nf_tproxy_get_sock_v4(iph->protocol, iph->saddr, iph->daddr,
+ hp->source, hp->dest, in, false);
+ if (sk != NULL)
+ nf_tproxy_put_sock(sk);
+
+ pr_debug("socket match: proto %u %08x:%u -> %08x:%u sock %p\n",
+ iph->protocol, ntohl(iph->saddr), ntohs(hp->source),
+ ntohl(iph->daddr), ntohs(hp->dest), sk);
+ return sk != NULL;
+}
+
+static struct xt_match socket_reg __read_mostly = {
+ .name = "socket",
+ .family = AF_INET,
+ .hooks = 1 << NF_IP_PRE_ROUTING,
+ .match = socket_match,
+ .me = THIS_MODULE,
+};
+
+static int __init xt_socket_init(void)
+{
+ nf_defrag_ipv4_enable();
+ return xt_register_match(&socket_reg);
+}
+
+static void __exit xt_socket_exit(void)
+{
+ xt_unregister_match(&socket_reg);
+}
+
+module_init(xt_socket_init);
+module_exit(xt_socket_exit);
+MODULE_AUTHOR("Krisztian Kovacs");
+MODULE_DESCRIPTION("netfilter socket match module");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_socket");
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 11/13] xt_TPROXY
2007-09-30 20:53 ` [PATCH 11/13] iptables TPROXY target KOVACS Krisztian
2007-09-30 21:40 ` [PATCH 11/13] xtables " Jan Engelhardt
@ 2007-09-30 22:20 ` Jan Engelhardt
2007-09-30 23:04 ` KOVACS Krisztian
2007-09-30 22:43 ` [PATCH 11/13] iptables TPROXY target Patrick McHardy
2 siblings, 1 reply; 45+ messages in thread
From: Jan Engelhardt @ 2007-09-30 22:20 UTC (permalink / raw)
To: KOVACS Krisztian
Cc: Patrick McHardy, netfilter-devel, Balazs Scheidler,
Toth Laszlo Attila
On Sep 30 2007 22:53, KOVACS Krisztian wrote:
>+struct ipt_tproxy_target_info {
>+ __be32 laddr;
>+ __be16 lport;
>+ unsigned long mark_mask;
>+ unsigned long mark_value;
>+};
Cannot use unsigned long, as its size is not fixed.
(other nitpicks that were already in xt_socket)
>+ /* 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 & ~tgi->mark_mask) ^ tgi->mark_value;
I guess you mean | instead of ^ here.
>+#ifdef CONFIG_COMPAT
>+struct compat_ipt_tproxy_target_info {
>+ __be32 laddr;
>+ __be16 lport;
>+ __be16 __pad1;
>+ compat_ulong_t mark_mask;
>+ compat_ulong_t mark_value;
>+};
Uhm, that's a bit cumbersome. By reordering, we can get all the
alignment done without any premature compat code.
Find below a patch that makes me happy, and compiles. :)
[ xtification comes at no cost, even if it's ipv4-only.
Although it is just a guess, I suppose xt_ is going to replace
ipt_ and ip6t_ even if some matches/targets are not all-protocol ]
===
The TPROXY target implements redirection of non-local TCP/UDP traffic to local
sockets. Additionally, it's possible to manipulate the packet mark if and only
if a socket has been found. (We need this because we cannot use multiple
targets in the same iptables rule.)
(originally from: KOVACS Krisztian <hidden@sch.bme.hu>)
A few cleanups and fixes.
Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
---
include/linux/netfilter/xt_TPROXY.h | 16 ++++++
net/netfilter/Kconfig | 12 ++++
net/netfilter/Makefile | 1
net/netfilter/xt_TPROXY.c | 92 ++++++++++++++++++++++++++++++++++++
4 files changed, 121 insertions(+)
Index: linux-2.6.23/include/linux/netfilter/xt_TPROXY.h
===================================================================
--- /dev/null
+++ linux-2.6.23/include/linux/netfilter/xt_TPROXY.h
@@ -0,0 +1,16 @@
+#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_info {
+ u_int32_t mark_mask;
+ u_int32_t mark_value;
+ __be32 laddr;
+ __be16 lport;
+};
+
+#endif /* _XT_TPROXY_H */
Index: linux-2.6.23/net/netfilter/Kconfig
===================================================================
--- linux-2.6.23.orig/net/netfilter/Kconfig
+++ linux-2.6.23/net/netfilter/Kconfig
@@ -363,6 +363,18 @@ config NETFILTER_XT_TARGET_NOTRACK
If you want to compile it as a module, say M here and read
<file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
+config NETFILTER_XT_TARGET_TPROXY
+ tristate '"TPROXY" target support'
+ depends on NETFILTER_TPROXY
+ depends on NETFILTER_XTABLES
+ help
+ This option adds a "TPROXY" target, which is somewhat similar to
+ REDIRECT. It can only be used in the tproxy table and is useful
+ to redirect traffic to a transparent proxy. It does _not_ depend
+ on Netfilter connection tracking.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
config NETFILTER_XT_TARGET_TRACE
tristate '"TRACE" target support'
depends on NETFILTER_XTABLES
Index: linux-2.6.23/net/netfilter/Makefile
===================================================================
--- linux-2.6.23.orig/net/netfilter/Makefile
+++ linux-2.6.23/net/netfilter/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG)
obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
Index: linux-2.6.23/net/netfilter/xt_TPROXY.c
===================================================================
--- /dev/null
+++ linux-2.6.23/net/netfilter/xt_TPROXY.c
@@ -0,0 +1,92 @@
+/*
+ * Transparent proxy support for Linux/iptables
+ *
+ * Copyright (c) 2006-2007 BalaBit IT Ltd.
+ * Author: Balazs Scheidler, Krisztian Kovacs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <net/checksum.h>
+#include <net/inet_sock.h>
+#include <net/udp.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_TPROXY.h>
+#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
+#include <net/netfilter/nf_tproxy_core.h>
+
+static unsigned int
+tproxy_target(struct sk_buff **pskb, const struct net_device *in,
+ const struct net_device *out, unsigned int hooknum,
+ const struct xt_target *target, const void *targinfo)
+{
+ const struct xt_tproxy_info *tgi = targinfo;
+ const struct iphdr *iph = ip_hdr(*pskb);
+ struct sk_buff *skb = *pskb;
+ struct udphdr _hdr, *hp;
+ struct sock *sk;
+
+ /* TCP/UDP only */
+ if (iph->protocol != IPPROTO_TCP && iph->protocol != IPPROTO_UDP)
+ return NF_ACCEPT;
+
+ hp = skb_header_pointer(*pskb, ip_hdrlen(skb), sizeof(_hdr), &_hdr);
+ if (hp == NULL)
+ return NF_DROP;
+
+ sk = nf_tproxy_get_sock_v4(iph->protocol, iph->saddr,
+ tgi->laddr ? tgi->laddr : iph->daddr, hp->source,
+ tgi->lport ? tgi->lport : hp->dest, in, true);
+
+ /* NOTE: assign_sock consumes our sk reference */
+ if (sk != NULL && nf_tproxy_assign_sock(skb, sk) != 0) {
+ /*
+ * This should be in a separate target, but we do not do
+ * multiple 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);
+ 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);
+ return NF_DROP;
+}
+
+static struct xt_target xt_tproxy_reg = {
+ .name = "TPROXY",
+ .family = AF_INET,
+ .table = "mangle",
+ .target = tproxy_target,
+ .targetsize = sizeof(struct xt_tproxy_info),
+ .hooks = 1 << NF_IP_PRE_ROUTING,
+ .me = THIS_MODULE,
+};
+
+static int __init xt_tproxy_init(void)
+{
+ nf_defrag_ipv4_enable();
+ return xt_register_target(&xt_tproxy_reg);
+}
+
+static void __exit xt_tproxy_exit(void)
+{
+ xt_unregister_target(&xt_tproxy_reg);
+}
+
+module_init(xt_tproxy_init);
+module_exit(xt_tproxy_exit);
+MODULE_AUTHOR("Krisztian Kovacs");
+MODULE_DESCRIPTION("Netfilter transparent proxy (TPROXY) target module");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_TPROXY");
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 05/13] Handle TCP SYN+ACK/ACK/RST transparency
2007-09-30 20:52 ` [PATCH 05/13] Handle TCP SYN+ACK/ACK/RST transparency KOVACS Krisztian
2007-09-30 21:45 ` Jan Engelhardt
@ 2007-09-30 22:23 ` Patrick McHardy
2007-10-01 19:27 ` KOVACS Krisztian
1 sibling, 1 reply; 45+ messages in thread
From: Patrick McHardy @ 2007-09-30 22:23 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
KOVACS Krisztian wrote:
> 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@sch.bme.hu>
> ---
>
> diff --git a/include/net/request_sock.h b/include/net/request_sock.h
> index 7aed02c..b9c8974 100644
> --- a/include/net/request_sock.h
> +++ b/include/net/request_sock.h
> @@ -34,7 +34,8 @@ struct request_sock_ops {
> struct request_sock *req,
> struct dst_entry *dst);
> void (*send_ack)(struct sk_buff *skb,
> - struct request_sock *req);
> + struct request_sock *req,
> + int reply_flags);
>
How about putting the flags in the request_sock?
> diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
> index fbe7714..26b9dbe 100644
> --- a/net/ipv4/inet_connection_sock.c
> +++ b/net/ipv4/inet_connection_sock.c
> @@ -321,6 +321,8 @@ 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(sk)->transparent ?
> + FLOWI_FLAG_ANYSRC : 0,
>
Introducing a function (sk_flowi_flags(sk) or something) might make
it a bit nicer to look at.
> diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
> index e089a97..7ae47e6 100644
> --- a/net/ipv4/tcp_ipv4.c
> +++ b/net/ipv4/tcp_ipv4.c
> @@ -625,7 +626,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 {
> @@ -701,36 +702,37 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
> arg.iov[0].iov_len);
> }
> #endif
> + arg.flags = reply_flags;
>
Shouldn't this use twsk->transparent?
> arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,
> ip_hdr(skb)->saddr, /* XXX */
> arg.iov[0].iov_len, IPPROTO_TCP, 0);
> arg.csumoffset = offsetof(struct tcphdr, check) / 2;
> if (twsk)
> arg.bound_dev_if = twsk->tw_sk.tw_bound_dev_if;
> -
> ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len);
Unrelated whitespace change
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 06/13] Port redirection support for TCP
2007-09-30 20:52 ` [PATCH 06/13] Port redirection support for TCP KOVACS Krisztian
@ 2007-09-30 22:26 ` Patrick McHardy
2007-09-30 22:49 ` KOVACS Krisztian
0 siblings, 1 reply; 45+ messages in thread
From: Patrick McHardy @ 2007-09-30 22:26 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
KOVACS Krisztian wrote:
> 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
> techniques obviously breaks this, so we have to store the original
> destination port address.
>
> This patch extends struct inet_request_sock and stores the incoming
> destination port value there. It also modifies the handshake code to
> use that value as the source port when sending reply packets.
>
> Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
> ---
>
> diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
> index e86832d..5339089 100644
> --- a/include/net/inet_sock.h
> +++ b/include/net/inet_sock.h
> @@ -65,6 +65,9 @@ struct inet_request_sock {
> #endif
> __be32 loc_addr;
> __be32 rmt_addr;
> +#if defined(CONFIG_NETFILTER_TPROXY) || defined(CONFIG_NETFILTER_TPROXY_MODULE)
> + __be16 loc_port;
> +#endif
> __be16 rmt_port;
> u16 snd_wscale : 4,
> rcv_wscale : 4,
> diff --git a/include/net/tcp.h b/include/net/tcp.h
> index 54053de..927d235 100644
> --- a/include/net/tcp.h
> +++ b/include/net/tcp.h
> @@ -980,6 +980,9 @@ static inline void tcp_openreq_init(struct request_sock *req,
> ireq->acked = 0;
> ireq->ecn_ok = 0;
> ireq->rmt_port = tcp_hdr(skb)->source;
> +#if defined(CONFIG_NETFILTER_TPROXY) || defined(CONFIG_NETFILTER_TPROXY_MODULE)
> + ireq->loc_port = tcp_hdr(skb)->dest;
> +#endif
> }
>
> extern void tcp_enter_memory_pressure(void);
> diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
> index 26b9dbe..f47d966 100644
> --- a/net/ipv4/inet_connection_sock.c
> +++ b/net/ipv4/inet_connection_sock.c
> @@ -502,6 +502,10 @@ struct sock *inet_csk_clone(struct sock *sk, const struct request_sock *req,
> newicsk->icsk_bind_hash = NULL;
>
> inet_sk(newsk)->dport = inet_rsk(req)->rmt_port;
> +#if defined(CONFIG_IP_NF_TPROXY) || defined(CONFIG_IP_NF_TPROXY_MODULE)
> + inet_sk(newsk)->num = ntohs(inet_rsk(req)->loc_port);
>
> + inet_sk(newsk)->sport = inet_rsk(req)->loc_port;
>
Why do you store the port twice here?
> ipv4/tcp_output.c
> index 666d8a5..69dd230 100644
> --- a/net/ipv4/tcp_output.c
> +++ b/net/ipv4/tcp_output.c
> @@ -2153,7 +2153,11 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
> th->syn = 1;
> th->ack = 1;
> TCP_ECN_make_synack(req, th);
> +#if defined(CONFIG_IP_NF_TPROXY) || defined(CONFIG_IP_NF_TPROXY_MODULE)
> + th->source = ireq->loc_port;
> +#else
> th->source = inet_sk(sk)->sport;
> +#endif
>
I think this should simply use loc_port unconditionally.
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 08/13] Split Netfilter IPv4 defragmentation into a separate module
2007-09-30 20:53 ` [PATCH 08/13] Split Netfilter IPv4 defragmentation into a separate module KOVACS Krisztian
@ 2007-09-30 22:35 ` Patrick McHardy
0 siblings, 0 replies; 45+ messages in thread
From: Patrick McHardy @ 2007-09-30 22:35 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
KOVACS Krisztian wrote:
> Netfilter connection tracking requires all IPv4 packets to be defragmented.
> Both the socket match and the TPROXY target depend on this functionality, so
> this patch separates the Netfilter IPv4 defrag hooks into a separate module.
>
> Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
>
Mhh .. I don't like this too much, but I don't see a much
better way myself, especially for the socket match since
it can't do defragmentation itself.
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 09/13] iptables tproxy core
2007-09-30 20:53 ` [PATCH 09/13] iptables tproxy core KOVACS Krisztian
@ 2007-09-30 22:37 ` Patrick McHardy
0 siblings, 0 replies; 45+ messages in thread
From: Patrick McHardy @ 2007-09-30 22:37 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
KOVACS Krisztian wrote:
> The iptables tproxy core is a module that contains the common routines used by
> various tproxy related modules (TPROXY target and socket match)
>
> Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
Looks fine.
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 11/13] iptables TPROXY target
2007-09-30 20:53 ` [PATCH 11/13] iptables TPROXY target KOVACS Krisztian
2007-09-30 21:40 ` [PATCH 11/13] xtables " Jan Engelhardt
2007-09-30 22:20 ` [PATCH 11/13] xt_TPROXY Jan Engelhardt
@ 2007-09-30 22:43 ` Patrick McHardy
2007-09-30 22:50 ` Jan Engelhardt
2007-09-30 22:51 ` KOVACS Krisztian
2 siblings, 2 replies; 45+ messages in thread
From: Patrick McHardy @ 2007-09-30 22:43 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
KOVACS Krisztian wrote:
> The TPROXY target implements redirection of non-local TCP/UDP traffic to local
> sockets. Additionally, it's possible to manipulate the packet mark if and only
> if a socket has been found. (We need this because we cannot use multiple
> targets in the same iptables rule.)
>
> Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
> ---
> +++ b/include/linux/netfilter_ipv4/ipt_TPROXY.h
> @@ -0,0 +1,14 @@
> +#ifndef _IPT_TPROXY_H_target
> +#define _IPT_TPROXY_H_target
> +
> +/* 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 ipt_tproxy_target_info {
> + __be32 laddr;
> + __be16 lport;
> + unsigned long mark_mask;
> + unsigned long mark_value;
>
This should use fixed size types.
> diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c
> new file mode 100644
> index 0000000..8603421
> --- /dev/null
> +++ b/net/netfilter/xt_TPROXY.c
> @@ -0,0 +1,139 @@
> +/*
> + * Transparent proxy support for Linux/iptables
> + *
> + * Copyright (c) 2006-2007 BalaBit IT Ltd.
> + * Author: Balazs Scheidler, Krisztian Kovacs
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/skbuff.h>
> +#include <linux/ip.h>
> +#include <net/checksum.h>
> +#include <net/udp.h>
> +#include <net/inet_sock.h>
> +
> +#include <linux/netfilter/x_tables.h>
> +#include <linux/netfilter_ipv4/ipt_TPROXY.h>
> +
> +#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
> +#include <net/netfilter/nf_tproxy_core.h>
> +
> +static unsigned int
> +target(struct sk_buff **pskb,
> + const struct net_device *in,
> + const struct net_device *out,
> + unsigned int hooknum,
> + const struct xt_target *target,
> + const void *targinfo)
> +{
> + const struct iphdr *iph = ip_hdr(*pskb);
> + const struct ipt_tproxy_target_info *tgi =
> + (const struct ipt_tproxy_target_info *) targinfo;
> + struct sk_buff *skb = *pskb;
> + struct udphdr _hdr, *hp;
> + struct sock *sk;
> +
> + /* TCP/UDP only */
> + if ((iph->protocol != IPPROTO_TCP) &&
> + (iph->protocol != IPPROTO_UDP))
> + return NF_ACCEPT;
> +
> + hp = skb_header_pointer(*pskb, iph->ihl * 4, sizeof(_hdr), &_hdr);
> + if (hp == NULL)
> + return NF_DROP;
> +
> + sk = nf_tproxy_get_sock_v4(iph->protocol,
> + iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr,
> + hp->source, tgi->lport ? tgi->lport : hp->dest,
> + in, true);
>
> +
> + /* 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 & ~tgi->mark_mask) ^ tgi->mark_value;
> +
> + pr_debug("redirecting: proto %d %08x:%d -> %08x:%d, mark: %x\n",
> + iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
> + ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark);
> + return NF_ACCEPT;
> + }
> + else {
> + pr_debug("no socket, dropping: proto %d %08x:%d -> %08x:%d, mark: %x\n",
> + iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
> + ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark);
> + return NF_DROP;
> + }
> +}
> +
> +#ifdef CONFIG_COMPAT
All this compat stuff becomes unnecessary with fixed size types.
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 06/13] Port redirection support for TCP
2007-09-30 22:26 ` Patrick McHardy
@ 2007-09-30 22:49 ` KOVACS Krisztian
2007-10-01 14:09 ` Patrick McHardy
0 siblings, 1 reply; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 22:49 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
Hi Patrick,
On Monday 01 October 2007, Patrick McHardy wrote:
> KOVACS Krisztian wrote:
> > 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
> > techniques obviously breaks this, so we have to store the original
> > destination port address.
> >
> > This patch extends struct inet_request_sock and stores the incoming
> > destination port value there. It also modifies the handshake code to
> > use that value as the source port when sending reply packets.
> >
> > Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
> > ---
> >
> > diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
> > index e86832d..5339089 100644
> > --- a/include/net/inet_sock.h
> > +++ b/include/net/inet_sock.h
> > @@ -65,6 +65,9 @@ struct inet_request_sock {
> > #endif
> > __be32 loc_addr;
> > __be32 rmt_addr;
> > +#if defined(CONFIG_NETFILTER_TPROXY) ||
> > defined(CONFIG_NETFILTER_TPROXY_MODULE) + __be16 loc_port;
> > +#endif
> > __be16 rmt_port;
> > u16 snd_wscale : 4,
> > rcv_wscale : 4,
> > diff --git a/include/net/tcp.h b/include/net/tcp.h
> > index 54053de..927d235 100644
> > --- a/include/net/tcp.h
> > +++ b/include/net/tcp.h
> > @@ -980,6 +980,9 @@ static inline void tcp_openreq_init(struct
> > request_sock *req, ireq->acked = 0;
> > ireq->ecn_ok = 0;
> > ireq->rmt_port = tcp_hdr(skb)->source;
> > +#if defined(CONFIG_NETFILTER_TPROXY) ||
> > defined(CONFIG_NETFILTER_TPROXY_MODULE) + ireq->loc_port =
> > tcp_hdr(skb)->dest;
> > +#endif
> > }
> >
> > extern void tcp_enter_memory_pressure(void);
> > diff --git a/net/ipv4/inet_connection_sock.c
> > b/net/ipv4/inet_connection_sock.c index 26b9dbe..f47d966 100644
> > --- a/net/ipv4/inet_connection_sock.c
> > +++ b/net/ipv4/inet_connection_sock.c
> > @@ -502,6 +502,10 @@ struct sock *inet_csk_clone(struct sock *sk,
> > const struct request_sock *req, newicsk->icsk_bind_hash = NULL;
> >
> > inet_sk(newsk)->dport = inet_rsk(req)->rmt_port;
> > +#if defined(CONFIG_IP_NF_TPROXY) ||
> > defined(CONFIG_IP_NF_TPROXY_MODULE) + inet_sk(newsk)->num =
> > ntohs(inet_rsk(req)->loc_port);
> >
> > + inet_sk(newsk)->sport = inet_rsk(req)->loc_port;
>
> Why do you store the port twice here?
Because ->num is in host byte order while sport is host byte order.
> > ipv4/tcp_output.c
> > index 666d8a5..69dd230 100644
> > --- a/net/ipv4/tcp_output.c
> > +++ b/net/ipv4/tcp_output.c
> > @@ -2153,7 +2153,11 @@ struct sk_buff * tcp_make_synack(struct sock
> > *sk, struct dst_entry *dst, th->syn = 1;
> > th->ack = 1;
> > TCP_ECN_make_synack(req, th);
> > +#if defined(CONFIG_IP_NF_TPROXY) ||
> > defined(CONFIG_IP_NF_TPROXY_MODULE) + th->source = ireq->loc_port;
> > +#else
> > th->source = inet_sk(sk)->sport;
> > +#endif
>
> I think this should simply use loc_port unconditionally.
Unfortunately ireq->loc_port does not exist unless tproxy is enabled in
the config. (We could remove all these #ifdefs but that would mean
extending inet_request_sock with 2 bytes even if tproxy is not enabled.)
--
KOVACS Krisztian
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 11/13] iptables TPROXY target
2007-09-30 22:43 ` [PATCH 11/13] iptables TPROXY target Patrick McHardy
@ 2007-09-30 22:50 ` Jan Engelhardt
2007-09-30 22:51 ` KOVACS Krisztian
1 sibling, 0 replies; 45+ messages in thread
From: Jan Engelhardt @ 2007-09-30 22:50 UTC (permalink / raw)
To: Patrick McHardy
Cc: KOVACS Krisztian, netfilter-devel, Balazs Scheidler,
Toth Laszlo Attila
On Oct 1 2007 00:43, Patrick McHardy wrote:
>
> All this compat stuff becomes unnecessary with fixed size types.
Fixed size types alone won't do it. Think 64-bit. You would have
{32, 16, 32, 32}, and I would be pretty sure they pad it up to
{32, 16, [16], 32, 32}. Well, see my version, which avoids that :)
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 11/13] iptables TPROXY target
2007-09-30 22:43 ` [PATCH 11/13] iptables TPROXY target Patrick McHardy
2007-09-30 22:50 ` Jan Engelhardt
@ 2007-09-30 22:51 ` KOVACS Krisztian
2007-09-30 22:56 ` Patrick McHardy
2007-09-30 22:57 ` Jan Engelhardt
1 sibling, 2 replies; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 22:51 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
Hi Patrick,
On Monday 01 October 2007, Patrick McHardy wrote:
> KOVACS Krisztian wrote:
> > The TPROXY target implements redirection of non-local TCP/UDP traffic
> > to local sockets. Additionally, it's possible to manipulate the
> > packet mark if and only if a socket has been found. (We need this
> > because we cannot use multiple targets in the same iptables rule.)
> >
> > Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
> > ---
> > +++ b/include/linux/netfilter_ipv4/ipt_TPROXY.h
> > @@ -0,0 +1,14 @@
> > +#ifndef _IPT_TPROXY_H_target
> > +#define _IPT_TPROXY_H_target
> > +
> > +/* 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 ipt_tproxy_target_info {
> > + __be32 laddr;
> > + __be16 lport;
> > + unsigned long mark_mask;
> > + unsigned long mark_value;
>
> This should use fixed size types.
Yes, but marks are unsigned longs, aren't they? So if we restrict this to
say 32bit then we lose the ability to use the upper half of the mark...
> > diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c
> > new file mode 100644
> > index 0000000..8603421
> > --- /dev/null
> > +++ b/net/netfilter/xt_TPROXY.c
> > @@ -0,0 +1,139 @@
> > +/*
> > + * Transparent proxy support for Linux/iptables
> > + *
> > + * Copyright (c) 2006-2007 BalaBit IT Ltd.
> > + * Author: Balazs Scheidler, Krisztian Kovacs
> > + *
> > + * This program is free software; you can redistribute it and/or
> > modify + * it under the terms of the GNU General Public License
> > version 2 as + * published by the Free Software Foundation.
> > + *
> > + */
> > +
> > +#include <linux/module.h>
> > +#include <linux/skbuff.h>
> > +#include <linux/ip.h>
> > +#include <net/checksum.h>
> > +#include <net/udp.h>
> > +#include <net/inet_sock.h>
> > +
> > +#include <linux/netfilter/x_tables.h>
> > +#include <linux/netfilter_ipv4/ipt_TPROXY.h>
> > +
> > +#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
> > +#include <net/netfilter/nf_tproxy_core.h>
> > +
> > +static unsigned int
> > +target(struct sk_buff **pskb,
> > + const struct net_device *in,
> > + const struct net_device *out,
> > + unsigned int hooknum,
> > + const struct xt_target *target,
> > + const void *targinfo)
> > +{
> > + const struct iphdr *iph = ip_hdr(*pskb);
> > + const struct ipt_tproxy_target_info *tgi =
> > + (const struct ipt_tproxy_target_info *) targinfo;
> > + struct sk_buff *skb = *pskb;
> > + struct udphdr _hdr, *hp;
> > + struct sock *sk;
> > +
> > + /* TCP/UDP only */
> > + if ((iph->protocol != IPPROTO_TCP) &&
> > + (iph->protocol != IPPROTO_UDP))
> > + return NF_ACCEPT;
> > +
> > + hp = skb_header_pointer(*pskb, iph->ihl * 4, sizeof(_hdr), &_hdr);
> > + if (hp == NULL)
> > + return NF_DROP;
> > +
> > + sk = nf_tproxy_get_sock_v4(iph->protocol,
> > + iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr,
> > + hp->source, tgi->lport ? tgi->lport : hp->dest,
> > + in, true);
> >
> > +
> > + /* 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 & ~tgi->mark_mask) ^ tgi->mark_value;
> > +
> > + pr_debug("redirecting: proto %d %08x:%d -> %08x:%d, mark: %x\n",
> > + iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
> > + ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark);
> > + return NF_ACCEPT;
> > + }
> > + else {
> > + pr_debug("no socket, dropping: proto %d %08x:%d -> %08x:%d, mark:
> > %x\n", + iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
> > + ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark);
> > + return NF_DROP;
> > + }
> > +}
> > +
> > +#ifdef CONFIG_COMPAT
>
> All this compat stuff becomes unnecessary with fixed size types.
--
KOVACS Krisztian
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 11/13] iptables TPROXY target
2007-09-30 22:51 ` KOVACS Krisztian
@ 2007-09-30 22:56 ` Patrick McHardy
2007-09-30 23:06 ` KOVACS Krisztian
2007-09-30 22:57 ` Jan Engelhardt
1 sibling, 1 reply; 45+ messages in thread
From: Patrick McHardy @ 2007-09-30 22:56 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
KOVACS Krisztian wrote:
> Hi Patrick,
>
> On Monday 01 October 2007, Patrick McHardy wrote:
>
>> KOVACS Krisztian wrote:
>>
>>> The TPROXY target implements redirection of non-local TCP/UDP traffic
>>> to local sockets. Additionally, it's possible to manipulate the
>>> packet mark if and only if a socket has been found. (We need this
>>> because we cannot use multiple targets in the same iptables rule.)
>>>
>>> Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
>>> ---
>>> +++ b/include/linux/netfilter_ipv4/ipt_TPROXY.h
>>> @@ -0,0 +1,14 @@
>>> +#ifndef _IPT_TPROXY_H_target
>>> +#define _IPT_TPROXY_H_target
>>> +
>>> +/* 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 ipt_tproxy_target_info {
>>> + __be32 laddr;
>>> + __be16 lport;
>>> + unsigned long mark_mask;
>>> + unsigned long mark_value;
>>>
>> This should use fixed size types.
>>
>
> Yes, but marks are unsigned longs, aren't they? So if we restrict this to
> say 32bit then we lose the ability to use the upper half of the mark...
>
No, marks are 32 bit for a long time now. The unsigned longs in
the mark target and matches are just there for compatiblity.
(BTW, going to sleep now, will continue tommorrow)
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 11/13] iptables TPROXY target
2007-09-30 22:51 ` KOVACS Krisztian
2007-09-30 22:56 ` Patrick McHardy
@ 2007-09-30 22:57 ` Jan Engelhardt
2007-10-01 14:11 ` Patrick McHardy
1 sibling, 1 reply; 45+ messages in thread
From: Jan Engelhardt @ 2007-09-30 22:57 UTC (permalink / raw)
To: KOVACS Krisztian
Cc: Patrick McHardy, netfilter-devel, Balazs Scheidler,
Toth Laszlo Attila
On Oct 1 2007 00:51, KOVACS Krisztian wrote:
>> > +/* 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 ipt_tproxy_target_info {
>> > + __be32 laddr;
>> > + __be16 lport;
>> > + unsigned long mark_mask;
>> > + unsigned long mark_value;
>>
>> This should use fixed size types.
>
>Yes, but marks are unsigned longs, aren't they? So if we restrict this to say
>32bit then we lose the ability to use the upper half of the mark...
longs are 32 and 64 bits, resp. A 64-bit kernel with a 32-bit userland,
well it speaks for itself.
The more I am puzzled as to why xt_MARK.h, xt_mark.h, xt_CONNMARK.h,
xt_connmark.h use longs, and not uint32_t! Only xt_SECMARK.h does it right...
Patrick, is this a longstanding 'bug'?
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 11/13] xt_TPROXY
2007-09-30 22:20 ` [PATCH 11/13] xt_TPROXY Jan Engelhardt
@ 2007-09-30 23:04 ` KOVACS Krisztian
0 siblings, 0 replies; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 23:04 UTC (permalink / raw)
To: Jan Engelhardt
Cc: Patrick McHardy, netfilter-devel, Balazs Scheidler,
Toth Laszlo Attila
On Monday 01 October 2007, Jan Engelhardt wrote:
> On Sep 30 2007 22:53, KOVACS Krisztian wrote:
> >+struct ipt_tproxy_target_info {
> >+ __be32 laddr;
> >+ __be16 lport;
> >+ unsigned long mark_mask;
> >+ unsigned long mark_value;
> >+};
>
> Cannot use unsigned long, as its size is not fixed.
>
>
> (other nitpicks that were already in xt_socket)
>
> >+ /* 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 & ~tgi->mark_mask) ^ tgi->mark_value;
>
> I guess you mean | instead of ^ here.
No, ^ is intentional. The idea is that in addition to being able to _set_
the masked part of the mark to a given value, you can also flip other
bits of the mark with the unmasked parts of the value. So it has slightly
more expressive power, and does the right thing if you use it in
a 'conventional' way.
>
> >+#ifdef CONFIG_COMPAT
> >+struct compat_ipt_tproxy_target_info {
> >+ __be32 laddr;
> >+ __be16 lport;
> >+ __be16 __pad1;
> >+ compat_ulong_t mark_mask;
> >+ compat_ulong_t mark_value;
> >+};
>
> Uhm, that's a bit cumbersome. By reordering, we can get all the
> alignment done without any premature compat code.
Yes, given that we can go back to using 32 bit marks.
>
> Find below a patch that makes me happy, and compiles. :)
>
> [ xtification comes at no cost, even if it's ipv4-only.
> Although it is just a guess, I suppose xt_ is going to replace
> ipt_ and ip6t_ even if some matches/targets are not all-protocol ]
>
> ===
>
> The TPROXY target implements redirection of non-local TCP/UDP traffic
> to local sockets. Additionally, it's possible to manipulate the packet
> mark if and only if a socket has been found. (We need this because we
> cannot use multiple targets in the same iptables rule.)
>
> (originally from: KOVACS Krisztian <hidden@sch.bme.hu>)
>
> A few cleanups and fixes.
>
> Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
>
> ---
>
> include/linux/netfilter/xt_TPROXY.h | 16 ++++++
> net/netfilter/Kconfig | 12 ++++
> net/netfilter/Makefile | 1
> net/netfilter/xt_TPROXY.c | 92
> ++++++++++++++++++++++++++++++++++++ 4 files changed, 121 insertions(+)
>
> Index: linux-2.6.23/include/linux/netfilter/xt_TPROXY.h
> ===================================================================
> --- /dev/null
> +++ linux-2.6.23/include/linux/netfilter/xt_TPROXY.h
> @@ -0,0 +1,16 @@
> +#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_info {
> + u_int32_t mark_mask;
> + u_int32_t mark_value;
> + __be32 laddr;
> + __be16 lport;
> +};
> +
> +#endif /* _XT_TPROXY_H */
> Index: linux-2.6.23/net/netfilter/Kconfig
> ===================================================================
> --- linux-2.6.23.orig/net/netfilter/Kconfig
> +++ linux-2.6.23/net/netfilter/Kconfig
> @@ -363,6 +363,18 @@ config NETFILTER_XT_TARGET_NOTRACK
> If you want to compile it as a module, say M here and read
> <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
>
> +config NETFILTER_XT_TARGET_TPROXY
> + tristate '"TPROXY" target support'
> + depends on NETFILTER_TPROXY
> + depends on NETFILTER_XTABLES
> + help
> + This option adds a "TPROXY" target, which is somewhat similar to
> + REDIRECT. It can only be used in the tproxy table and is useful
> + to redirect traffic to a transparent proxy. It does _not_ depend
> + on Netfilter connection tracking.
> +
> + To compile it as a module, choose M here. If unsure, say N.
> +
> config NETFILTER_XT_TARGET_TRACE
> tristate '"TRACE" target support'
> depends on NETFILTER_XTABLES
> Index: linux-2.6.23/net/netfilter/Makefile
> ===================================================================
> --- linux-2.6.23.orig/net/netfilter/Makefile
> +++ linux-2.6.23/net/netfilter/Makefile
> @@ -50,6 +50,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG)
> obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
> obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
> obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
> +obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o
> obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
> obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
>
> Index: linux-2.6.23/net/netfilter/xt_TPROXY.c
> ===================================================================
> --- /dev/null
> +++ linux-2.6.23/net/netfilter/xt_TPROXY.c
> @@ -0,0 +1,92 @@
> +/*
> + * Transparent proxy support for Linux/iptables
> + *
> + * Copyright (c) 2006-2007 BalaBit IT Ltd.
> + * Author: Balazs Scheidler, Krisztian Kovacs
> + *
> + * This program is free software; you can redistribute it and/or
> modify + * it under the terms of the GNU General Public License version
> 2 as + * published by the Free Software Foundation.
> + *
> + */
> +#include <linux/module.h>
> +#include <linux/skbuff.h>
> +#include <linux/ip.h>
> +#include <net/checksum.h>
> +#include <net/inet_sock.h>
> +#include <net/udp.h>
> +#include <linux/netfilter/x_tables.h>
> +#include <linux/netfilter/xt_TPROXY.h>
> +#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
> +#include <net/netfilter/nf_tproxy_core.h>
> +
> +static unsigned int
> +tproxy_target(struct sk_buff **pskb, const struct net_device *in,
> + const struct net_device *out, unsigned int hooknum,
> + const struct xt_target *target, const void *targinfo)
> +{
> + const struct xt_tproxy_info *tgi = targinfo;
> + const struct iphdr *iph = ip_hdr(*pskb);
> + struct sk_buff *skb = *pskb;
> + struct udphdr _hdr, *hp;
> + struct sock *sk;
> +
> + /* TCP/UDP only */
> + if (iph->protocol != IPPROTO_TCP && iph->protocol != IPPROTO_UDP)
> + return NF_ACCEPT;
> +
> + hp = skb_header_pointer(*pskb, ip_hdrlen(skb), sizeof(_hdr), &_hdr);
> + if (hp == NULL)
> + return NF_DROP;
> +
> + sk = nf_tproxy_get_sock_v4(iph->protocol, iph->saddr,
> + tgi->laddr ? tgi->laddr : iph->daddr, hp->source,
> + tgi->lport ? tgi->lport : hp->dest, in, true);
> +
> + /* NOTE: assign_sock consumes our sk reference */
> + if (sk != NULL && nf_tproxy_assign_sock(skb, sk) != 0) {
> + /*
> + * This should be in a separate target, but we do not do
> + * multiple 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);
> + 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);
> + return NF_DROP;
> +}
> +
> +static struct xt_target xt_tproxy_reg = {
> + .name = "TPROXY",
> + .family = AF_INET,
> + .table = "mangle",
> + .target = tproxy_target,
> + .targetsize = sizeof(struct xt_tproxy_info),
> + .hooks = 1 << NF_IP_PRE_ROUTING,
> + .me = THIS_MODULE,
> +};
> +
> +static int __init xt_tproxy_init(void)
> +{
> + nf_defrag_ipv4_enable();
> + return xt_register_target(&xt_tproxy_reg);
> +}
> +
> +static void __exit xt_tproxy_exit(void)
> +{
> + xt_unregister_target(&xt_tproxy_reg);
> +}
> +
> +module_init(xt_tproxy_init);
> +module_exit(xt_tproxy_exit);
> +MODULE_AUTHOR("Krisztian Kovacs");
> +MODULE_DESCRIPTION("Netfilter transparent proxy (TPROXY) target
> module"); +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("ipt_TPROXY");
> -
> To unsubscribe from this list: send the line "unsubscribe
> netfilter-devel" in the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
KOVACS Krisztian
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 11/13] iptables TPROXY target
2007-09-30 22:56 ` Patrick McHardy
@ 2007-09-30 23:06 ` KOVACS Krisztian
0 siblings, 0 replies; 45+ messages in thread
From: KOVACS Krisztian @ 2007-09-30 23:06 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
Hi Patrick,
On Monday 01 October 2007, Patrick McHardy wrote:
> KOVACS Krisztian wrote:
> > Hi Patrick,
> >
> > On Monday 01 October 2007, Patrick McHardy wrote:
> >> KOVACS Krisztian wrote:
> >>> The TPROXY target implements redirection of non-local TCP/UDP
> >>> traffic to local sockets. Additionally, it's possible to manipulate
> >>> the packet mark if and only if a socket has been found. (We need
> >>> this because we cannot use multiple targets in the same iptables
> >>> rule.)
> >>>
> >>> Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
> >>> ---
> >>> +++ b/include/linux/netfilter_ipv4/ipt_TPROXY.h
> >>> @@ -0,0 +1,14 @@
> >>> +#ifndef _IPT_TPROXY_H_target
> >>> +#define _IPT_TPROXY_H_target
> >>> +
> >>> +/* 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 ipt_tproxy_target_info {
> >>> + __be32 laddr;
> >>> + __be16 lport;
> >>> + unsigned long mark_mask;
> >>> + unsigned long mark_value;
> >>
> >> This should use fixed size types.
> >
> > Yes, but marks are unsigned longs, aren't they? So if we restrict
> > this to say 32bit then we lose the ability to use the upper half of
> > the mark...
>
> No, marks are 32 bit for a long time now. The unsigned longs in
> the mark target and matches are just there for compatiblity.
Indeed, I must have missed this. Obviously if this is the case then we
don't need all this cruft and can simply use 32 bit mark fields (and the
reordered info structure Jan suggested.)
> (BTW, going to sleep now, will continue tommorrow)
OK, me too. :)
--
KOVACS Krisztian
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 06/13] Port redirection support for TCP
2007-09-30 22:49 ` KOVACS Krisztian
@ 2007-10-01 14:09 ` Patrick McHardy
2007-10-01 14:24 ` KOVACS Krisztian
0 siblings, 1 reply; 45+ messages in thread
From: Patrick McHardy @ 2007-10-01 14:09 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
KOVACS Krisztian wrote:
>>>ipv4/tcp_output.c
>>>index 666d8a5..69dd230 100644
>>>--- a/net/ipv4/tcp_output.c
>>>+++ b/net/ipv4/tcp_output.c
>>>@@ -2153,7 +2153,11 @@ struct sk_buff * tcp_make_synack(struct sock
>>>*sk, struct dst_entry *dst, th->syn = 1;
>>> th->ack = 1;
>>> TCP_ECN_make_synack(req, th);
>>>+#if defined(CONFIG_IP_NF_TPROXY) ||
>>>defined(CONFIG_IP_NF_TPROXY_MODULE) + th->source = ireq->loc_port;
>>>+#else
>>> th->source = inet_sk(sk)->sport;
>>>+#endif
>>
>>I think this should simply use loc_port unconditionally.
>
>
> Unfortunately ireq->loc_port does not exist unless tproxy is enabled in
> the config. (We could remove all these #ifdefs but that would mean
> extending inet_request_sock with 2 bytes even if tproxy is not enabled.)
There's a 2 byte hole with IPv6 where you could put this in.
I think even without IPv6 the small waste is not worth the
increased testing complexity.
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 11/13] iptables TPROXY target
2007-09-30 22:57 ` Jan Engelhardt
@ 2007-10-01 14:11 ` Patrick McHardy
0 siblings, 0 replies; 45+ messages in thread
From: Patrick McHardy @ 2007-10-01 14:11 UTC (permalink / raw)
To: Jan Engelhardt
Cc: KOVACS Krisztian, netfilter-devel, Balazs Scheidler,
Toth Laszlo Attila
Jan Engelhardt wrote:
> On Oct 1 2007 00:51, KOVACS Krisztian wrote:
>
>>>>+/* 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 ipt_tproxy_target_info {
>>>>+ __be32 laddr;
>>>>+ __be16 lport;
>>>>+ unsigned long mark_mask;
>>>>+ unsigned long mark_value;
>>>
>>>This should use fixed size types.
>>
>>Yes, but marks are unsigned longs, aren't they? So if we restrict this to say
>>32bit then we lose the ability to use the upper half of the mark...
>
>
> longs are 32 and 64 bits, resp. A 64-bit kernel with a 32-bit userland,
> well it speaks for itself.
>
> The more I am puzzled as to why xt_MARK.h, xt_mark.h, xt_CONNMARK.h,
> xt_connmark.h use longs, and not uint32_t! Only xt_SECMARK.h does it right...
>
> Patrick, is this a longstanding 'bug'?
Not a bug, compatiblity crap. skb->nfmark used to be unsigned long,
but since a) it sucks to have userspace-visible stuff like this
depend on the architecture and b) routing, classifiers etc. all
only supported 32 bits, we've changed it.
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 06/13] Port redirection support for TCP
2007-10-01 14:09 ` Patrick McHardy
@ 2007-10-01 14:24 ` KOVACS Krisztian
0 siblings, 0 replies; 45+ messages in thread
From: KOVACS Krisztian @ 2007-10-01 14:24 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
Hi Patrick,
On h, okt 01, 2007 at 04:09:21 +0200, Patrick McHardy wrote:
> KOVACS Krisztian wrote:
> >>>ipv4/tcp_output.c
> >>>index 666d8a5..69dd230 100644
> >>>--- a/net/ipv4/tcp_output.c
> >>>+++ b/net/ipv4/tcp_output.c
> >>>@@ -2153,7 +2153,11 @@ struct sk_buff * tcp_make_synack(struct sock
> >>>*sk, struct dst_entry *dst, th->syn = 1;
> >>> th->ack = 1;
> >>> TCP_ECN_make_synack(req, th);
> >>>+#if defined(CONFIG_IP_NF_TPROXY) ||
> >>>defined(CONFIG_IP_NF_TPROXY_MODULE) + th->source = ireq->loc_port;
> >>>+#else
> >>> th->source = inet_sk(sk)->sport;
> >>>+#endif
> >>
> >>I think this should simply use loc_port unconditionally.
> >
> >
> > Unfortunately ireq->loc_port does not exist unless tproxy is enabled in
> > the config. (We could remove all these #ifdefs but that would mean
> > extending inet_request_sock with 2 bytes even if tproxy is not enabled.)
>
>
> There's a 2 byte hole with IPv6 where you could put this in.
> I think even without IPv6 the small waste is not worth the
> increased testing complexity.
Ok, I'll remove the ifdefs then and add loc_port in that hole. Thanks for
your feedback.
--
KOVACS Krisztian
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 05/13] Handle TCP SYN+ACK/ACK/RST transparency
2007-09-30 22:23 ` Patrick McHardy
@ 2007-10-01 19:27 ` KOVACS Krisztian
0 siblings, 0 replies; 45+ messages in thread
From: KOVACS Krisztian @ 2007-10-01 19:27 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Balazs Scheidler, Toth Laszlo Attila
Hi Patrick,
On Monday 01 October 2007, Patrick McHardy wrote:
> KOVACS Krisztian wrote:
> > 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@sch.bme.hu>
> > ---
> >
> > diff --git a/include/net/request_sock.h b/include/net/request_sock.h
> > index 7aed02c..b9c8974 100644
> > --- a/include/net/request_sock.h
> > +++ b/include/net/request_sock.h
> > @@ -34,7 +34,8 @@ struct request_sock_ops {
> > struct request_sock *req,
> > struct dst_entry *dst);
> > void (*send_ack)(struct sk_buff *skb,
> > - struct request_sock *req);
> > + struct request_sock *req,
> > + int reply_flags);
>
> How about putting the flags in the request_sock?
Nice idea, I'll give it a try.
> > diff --git a/net/ipv4/inet_connection_sock.c
> > b/net/ipv4/inet_connection_sock.c index fbe7714..26b9dbe 100644
> > --- a/net/ipv4/inet_connection_sock.c
> > +++ b/net/ipv4/inet_connection_sock.c
> > @@ -321,6 +321,8 @@ 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(sk)->transparent ?
> > + FLOWI_FLAG_ANYSRC : 0,
>
> Introducing a function (sk_flowi_flags(sk) or something) might make
> it a bit nicer to look at.
Ok, done for the next round of patches.
> > diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
> > index e089a97..7ae47e6 100644
> > --- a/net/ipv4/tcp_ipv4.c
> > +++ b/net/ipv4/tcp_ipv4.c
> > @@ -625,7 +626,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 {
> > @@ -701,36 +702,37 @@ static void tcp_v4_send_ack(struct
> > tcp_timewait_sock *twsk, arg.iov[0].iov_len);
> > }
> > #endif
> > + arg.flags = reply_flags;
>
> Shouldn't this use twsk->transparent?
We can't, as tcp_v4_send_ack() is called with twsk == NULL from
tcp_v4_reqsk_send_ack().
--
KOVACS Krisztian
^ permalink raw reply [flat|nested] 45+ messages in thread
end of thread, other threads:[~2007-10-01 19:27 UTC | newest]
Thread overview: 45+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-09-30 20:51 [PATCH 00/13] Transparent Proxying Patches, Take 3 KOVACS Krisztian
2007-09-30 20:51 ` [PATCH 01/13] Loosen source address check on IPv4 output KOVACS Krisztian
2007-09-30 22:12 ` Patrick McHardy
2007-09-30 20:52 ` [PATCH 02/13] Implement IP_TRANSPARENT socket option KOVACS Krisztian
2007-09-30 22:12 ` Patrick McHardy
2007-09-30 20:52 ` [PATCH 03/13] Allow binding to non-local addresses if IP_TRANSPARENT is set KOVACS Krisztian
2007-09-30 22:12 ` Patrick McHardy
2007-09-30 20:52 ` [PATCH 04/13] Conditionally enable transparent flow flag when connecting KOVACS Krisztian
2007-09-30 20:52 ` [PATCH 05/13] Handle TCP SYN+ACK/ACK/RST transparency KOVACS Krisztian
2007-09-30 21:45 ` Jan Engelhardt
2007-09-30 21:46 ` Jan Engelhardt
2007-09-30 21:59 ` KOVACS Krisztian
2007-09-30 22:02 ` Jan Engelhardt
2007-09-30 21:58 ` KOVACS Krisztian
2007-09-30 22:23 ` Patrick McHardy
2007-10-01 19:27 ` KOVACS Krisztian
2007-09-30 20:52 ` [PATCH 06/13] Port redirection support for TCP KOVACS Krisztian
2007-09-30 22:26 ` Patrick McHardy
2007-09-30 22:49 ` KOVACS Krisztian
2007-10-01 14:09 ` Patrick McHardy
2007-10-01 14:24 ` KOVACS Krisztian
2007-09-30 20:52 ` [PATCH 07/13] Export UDP socket lookup function KOVACS Krisztian
2007-09-30 20:53 ` [PATCH 08/13] Split Netfilter IPv4 defragmentation into a separate module KOVACS Krisztian
2007-09-30 22:35 ` Patrick McHardy
2007-09-30 20:53 ` [PATCH 09/13] iptables tproxy core KOVACS Krisztian
2007-09-30 22:37 ` Patrick McHardy
2007-09-30 20:53 ` [PATCH 10/13] iptables socket match KOVACS Krisztian
2007-09-30 21:43 ` Jan Engelhardt
2007-09-30 22:15 ` [PATCH 10/13] xt_socket Jan Engelhardt
2007-09-30 20:53 ` [PATCH 11/13] iptables TPROXY target KOVACS Krisztian
2007-09-30 21:40 ` [PATCH 11/13] xtables " Jan Engelhardt
2007-09-30 22:07 ` KOVACS Krisztian
2007-09-30 22:20 ` [PATCH 11/13] xt_TPROXY Jan Engelhardt
2007-09-30 23:04 ` KOVACS Krisztian
2007-09-30 22:43 ` [PATCH 11/13] iptables TPROXY target Patrick McHardy
2007-09-30 22:50 ` Jan Engelhardt
2007-09-30 22:51 ` KOVACS Krisztian
2007-09-30 22:56 ` Patrick McHardy
2007-09-30 23:06 ` KOVACS Krisztian
2007-09-30 22:57 ` Jan Engelhardt
2007-10-01 14:11 ` Patrick McHardy
2007-09-30 20:53 ` [PATCH 12/13] Don't lookup the socket if there's a socket attached to the skb KOVACS Krisztian
2007-09-30 20:53 ` [PATCH 13/13] " KOVACS Krisztian
2007-09-30 22:01 ` [PATCH 00/13] Transparent Proxying Patches, Take 3 Patrick McHardy
2007-09-30 22:13 ` KOVACS Krisztian
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).