]> git.pld-linux.org Git - packages/kernel.git/blob - kernel-tproxy.patch
- updated to 2.6.29.2 (builds and works --without apparmor --without grsecurity)
[packages/kernel.git] / kernel-tproxy.patch
1 From f01a1b1a0cb61eaadebd9d910286c5f382a4928c Mon Sep 17 00:00:00 2001
2 From: KOVACS Krisztian <hidden@sch.bme.hu>
3 Date: Mon, 28 Apr 2008 14:46:46 +0200
4 Subject: [PATCH] Loosen source address check on IPv4 output
5
6 ip_route_output() contains a check to make sure that no flows with
7 non-local source IP addresses are routed. This obviously makes using
8 such addresses impossible.
9
10 This patch introduces a flowi flag which makes omitting this check
11 possible. The new flag provides a way of handling transparent and
12 non-transparent connections differently.
13
14 Signed-off-by: Julian Anastasov <ja@ssi.bg>
15 Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
16 Acked-by: Patrick McHardy <kaber@trash.net>
17 ---
18  include/net/flow.h |    1 +
19  net/ipv4/route.c   |   20 +++++++++++++-------
20  2 files changed, 14 insertions(+), 7 deletions(-)
21
22 diff --git a/include/net/flow.h b/include/net/flow.h
23 index ad16e00..b45a5e4 100644
24 --- a/include/net/flow.h
25 +++ b/include/net/flow.h
26 @@ -48,6 +48,7 @@ struct flowi {
27  
28         __u8    proto;
29         __u8    flags;
30 +#define FLOWI_FLAG_ANYSRC 0x01
31         union {
32                 struct {
33                         __be16  sport;
34 diff --git a/net/ipv4/route.c b/net/ipv4/route.c
35 index ce25a13..c0ed024 100644
36 --- a/net/ipv4/route.c
37 +++ b/net/ipv4/route.c
38 @@ -2307,11 +2307,6 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
39                     ipv4_is_zeronet(oldflp->fl4_src))
40                         goto out;
41  
42 -               /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
43 -               dev_out = ip_dev_find(net, oldflp->fl4_src);
44 -               if (dev_out == NULL)
45 -                       goto out;
46 -
47                 /* I removed check for oif == dev_out->oif here.
48                    It was wrong for two reasons:
49                    1. ip_dev_find(net, saddr) can return wrong iface, if saddr
50 @@ -2323,6 +2318,11 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
51                 if (oldflp->oif == 0
52                     && (ipv4_is_multicast(oldflp->fl4_dst) ||
53                         oldflp->fl4_dst == htonl(0xFFFFFFFF))) {
54 +                       /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
55 +                       dev_out = ip_dev_find(net, oldflp->fl4_src);
56 +                       if (dev_out == NULL)
57 +                               goto out;
58 +
59                         /* Special hack: user can direct multicasts
60                            and limited broadcast via necessary interface
61                            without fiddling with IP_MULTICAST_IF or IP_PKTINFO.
62 @@ -2341,9 +2341,15 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
63                         fl.oif = dev_out->ifindex;
64                         goto make_route;
65                 }
66 -               if (dev_out)
67 +
68 +               if (!(oldflp->flags & FLOWI_FLAG_ANYSRC)) {
69 +                       /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
70 +                       dev_out = ip_dev_find(net, oldflp->fl4_src);
71 +                       if (dev_out == NULL)
72 +                               goto out;
73                         dev_put(dev_out);
74 -               dev_out = NULL;
75 +                       dev_out = NULL;
76 +               }
77         }
78  
79  
80 -- 
81 1.5.2.5
82
83 From cc2f0afbffaad66b7794e4b4e5d50609f3571fbd Mon Sep 17 00:00:00 2001
84 From: KOVACS Krisztian <hidden@sch.bme.hu>
85 Date: Mon, 28 Apr 2008 14:46:48 +0200
86 Subject: [PATCH] Implement IP_TRANSPARENT socket option
87
88 This patch introduces the IP_TRANSPARENT socket option: enabling that will make
89 the IPv4 routing omit the non-local source address check on output. Setting
90 IP_TRANSPARENT requires NET_ADMIN capability.
91
92 Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
93 Acked-by: Patrick McHardy <kaber@trash.net>
94 ---
95  include/linux/in.h               |    1 +
96  include/net/inet_sock.h          |    3 ++-
97  include/net/inet_timewait_sock.h |    3 ++-
98  net/ipv4/inet_timewait_sock.c    |    1 +
99  net/ipv4/ip_sockglue.c           |   12 +++++++++++-
100  5 files changed, 17 insertions(+), 3 deletions(-)
101
102 diff --git a/include/linux/in.h b/include/linux/in.h
103 index 4065313..db458be 100644
104 --- a/include/linux/in.h
105 +++ b/include/linux/in.h
106 @@ -75,6 +75,7 @@ struct in_addr {
107  #define IP_IPSEC_POLICY        16
108  #define IP_XFRM_POLICY 17
109  #define IP_PASSSEC     18
110 +#define IP_TRANSPARENT 19
111  
112  /* BSD compatibility */
113  #define IP_RECVRETOPTS IP_RETOPTS
114 diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
115 index a42cd63..2fafaab 100644
116 --- a/include/net/inet_sock.h
117 +++ b/include/net/inet_sock.h
118 @@ -128,7 +128,8 @@ struct inet_sock {
119                                 is_icsk:1,
120                                 freebind:1,
121                                 hdrincl:1,
122 -                               mc_loop:1;
123 +                               mc_loop:1,
124 +                               transparent:1;
125         int                     mc_index;
126         __be32                  mc_addr;
127         struct ip_mc_socklist   *mc_list;
128 diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
129 index 95c660c..8d983a2 100644
130 --- a/include/net/inet_timewait_sock.h
131 +++ b/include/net/inet_timewait_sock.h
132 @@ -128,7 +128,8 @@ struct inet_timewait_sock {
133         __be16                  tw_dport;
134         __u16                   tw_num;
135         /* And these are ours. */
136 -       __u8                    tw_ipv6only:1;
137 +       __u8                    tw_ipv6only:1,
138 +                               tw_transparent:1;
139         /* 15 bits hole, try to pack */
140         __u16                   tw_ipv6_offset;
141         unsigned long           tw_ttd;
142 diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
143 index ce16e9a..af16fd4 100644
144 --- a/net/ipv4/inet_timewait_sock.c
145 +++ b/net/ipv4/inet_timewait_sock.c
146 @@ -124,6 +124,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat
147                 tw->tw_reuse        = sk->sk_reuse;
148                 tw->tw_hash         = sk->sk_hash;
149                 tw->tw_ipv6only     = 0;
150 +               tw->tw_transparent  = inet->transparent;
151                 tw->tw_prot         = sk->sk_prot_creator;
152                 twsk_net_set(tw, hold_net(sock_net(sk)));
153                 atomic_set(&tw->tw_refcnt, 1);
154 diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
155 index d8adfd4..a05bec6 100644
156 --- a/net/ipv4/ip_sockglue.c
157 +++ b/net/ipv4/ip_sockglue.c
158 @@ -420,7 +420,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
159                              (1<<IP_TTL) | (1<<IP_HDRINCL) |
160                              (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
161                              (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
162 -                            (1<<IP_PASSSEC))) ||
163 +                            (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT))) ||
164             optname == IP_MULTICAST_TTL ||
165             optname == IP_MULTICAST_LOOP) {
166                 if (optlen >= sizeof(int)) {
167 @@ -879,6 +879,16 @@ static int do_ip_setsockopt(struct sock *sk, int level,
168                 err = xfrm_user_policy(sk, optname, optval, optlen);
169                 break;
170  
171 +       case IP_TRANSPARENT:
172 +               if (!capable(CAP_NET_ADMIN)) {
173 +                       err = -EPERM;
174 +                       break;
175 +               }
176 +               if (optlen < 1)
177 +                       goto e_inval;
178 +               inet->transparent = !!val;
179 +               break;
180 +
181         default:
182                 err = -ENOPROTOOPT;
183                 break;
184 -- 
185 1.5.2.5
186
187 From b0f9031d33741ccd7745112d425d465035444859 Mon Sep 17 00:00:00 2001
188 From: KOVACS Krisztian <hidden@sch.bme.hu>
189 Date: Mon, 28 Apr 2008 14:46:48 +0200
190 Subject: [PATCH] Allow binding to non-local addresses if IP_TRANSPARENT is set
191 MIME-Version: 1.0
192 Content-Type: text/plain; charset=utf-8
193 Content-Transfer-Encoding: 8bit
194
195 Setting IP_TRANSPARENT is not really useful without allowing non-local
196 binds for the socket. To make user-space code simpler we allow these binds
197 even if IP_TRANSPARENT is set but IP_FREEBIND is not.
198
199 Signed-off-by: Tóth László Attila <panther@balabit.hu>
200 Acked-by: Patrick McHardy <kaber@trash.net>
201 ---
202  net/ipv4/af_inet.c |    2 +-
203  1 files changed, 1 insertions(+), 1 deletions(-)
204
205 diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
206 index f2b5270..d2d1001 100644
207 --- a/net/ipv4/af_inet.c
208 +++ b/net/ipv4/af_inet.c
209 @@ -475,7 +475,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
210          */
211         err = -EADDRNOTAVAIL;
212         if (!sysctl_ip_nonlocal_bind &&
213 -           !inet->freebind &&
214 +           !(inet->freebind || inet->transparent) &&
215             addr->sin_addr.s_addr != htonl(INADDR_ANY) &&
216             chk_addr_ret != RTN_LOCAL &&
217             chk_addr_ret != RTN_MULTICAST &&
218 -- 
219 1.5.2.5
220
221 From 2b3cf4f3e3aa34ff42d17b202b945db2c5c563b2 Mon Sep 17 00:00:00 2001
222 From: KOVACS Krisztian <hidden@sch.bme.hu>
223 Date: Mon, 28 Apr 2008 14:46:49 +0200
224 Subject: [PATCH] Make inet_sock.h independent of route.h
225
226 inet_iif() in inet_sock.h requires route.h. Since users of inet_iif()
227 usually require other route.h functionality anyway this patch moves
228 inet_iif() to route.h.
229
230 Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
231 ---
232  include/net/inet_sock.h            |    7 -------
233  include/net/route.h                |    5 +++++
234  net/ipv4/netfilter/nf_nat_helper.c |    1 +
235  net/ipv4/syncookies.c              |    1 +
236  net/ipv6/af_inet6.c                |    1 +
237  5 files changed, 8 insertions(+), 7 deletions(-)
238
239 diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
240 index 2fafaab..5ca683e 100644
241 --- a/include/net/inet_sock.h
242 +++ b/include/net/inet_sock.h
243 @@ -24,7 +24,6 @@
244  #include <net/flow.h>
245  #include <net/sock.h>
246  #include <net/request_sock.h>
247 -#include <net/route.h>
248  
249  /** struct ip_options - IP Options
250   *
251 @@ -192,10 +191,4 @@ static inline int inet_sk_ehashfn(const struct sock *sk)
252         return inet_ehashfn(laddr, lport, faddr, fport);
253  }
254  
255 -
256 -static inline int inet_iif(const struct sk_buff *skb)
257 -{
258 -       return skb->rtable->rt_iif;
259 -}
260 -
261  #endif /* _INET_SOCK_H */
262 diff --git a/include/net/route.h b/include/net/route.h
263 index c633880..13e464f 100644
264 --- a/include/net/route.h
265 +++ b/include/net/route.h
266 @@ -204,6 +204,11 @@ static inline struct inet_peer *rt_get_peer(struct rtable *rt)
267         return rt->peer;
268  }
269  
270 +static inline int inet_iif(const struct sk_buff *skb)
271 +{
272 +       return skb->rtable->rt_iif;
273 +}
274 +
275  extern ctl_table ipv4_route_table[];
276  
277  #endif /* _ROUTE_H */
278 diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
279 index 11976ea..112dcfa 100644
280 --- a/net/ipv4/netfilter/nf_nat_helper.c
281 +++ b/net/ipv4/netfilter/nf_nat_helper.c
282 @@ -16,6 +16,7 @@
283  #include <linux/udp.h>
284  #include <net/checksum.h>
285  #include <net/tcp.h>
286 +#include <net/route.h>
287  
288  #include <linux/netfilter_ipv4.h>
289  #include <net/netfilter/nf_conntrack.h>
290 diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
291 index 73ba989..19a1037 100644
292 --- a/net/ipv4/syncookies.c
293 +++ b/net/ipv4/syncookies.c
294 @@ -18,6 +18,7 @@
295  #include <linux/cryptohash.h>
296  #include <linux/kernel.h>
297  #include <net/tcp.h>
298 +#include <net/route.h>
299  
300  /* Timestamps: lowest 9 bits store TCP options */
301  #define TSBITS 9
302 diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
303 index 3c6aafb..f6645d2 100644
304 --- a/net/ipv6/af_inet6.c
305 +++ b/net/ipv6/af_inet6.c
306 @@ -52,6 +52,7 @@
307  #include <net/ipip.h>
308  #include <net/protocol.h>
309  #include <net/inet_common.h>
310 +#include <net/route.h>
311  #include <net/transp_v6.h>
312  #include <net/ip6_route.h>
313  #include <net/addrconf.h>
314 -- 
315 1.5.2.5
316
317 From 03bf9d04e8a6d0dc994363c8133ff494226701ef Mon Sep 17 00:00:00 2001
318 From: KOVACS Krisztian <hidden@sch.bme.hu>
319 Date: Mon, 28 Apr 2008 14:46:50 +0200
320 Subject: [PATCH] Conditionally enable transparent flow flag when connecting
321
322 Set FLOWI_FLAG_ANYSRC in flowi->flags if the socket has the
323 transparent socket option set. This way we selectively enable certain
324 connections with non-local source addresses to be routed.
325
326 Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
327 ---
328  include/net/route.h |    6 +++++-
329  1 files changed, 5 insertions(+), 1 deletions(-)
330
331 diff --git a/include/net/route.h b/include/net/route.h
332 index 13e464f..2928618 100644
333 --- a/include/net/route.h
334 +++ b/include/net/route.h
335 @@ -27,7 +27,7 @@
336  #include <net/dst.h>
337  #include <net/inetpeer.h>
338  #include <net/flow.h>
339 -#include <net/sock.h>
340 +#include <net/inet_sock.h>
341  #include <linux/in_route.h>
342  #include <linux/rtnetlink.h>
343  #include <linux/route.h>
344 @@ -161,6 +161,10 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst,
345  
346         int err;
347         struct net *net = sock_net(sk);
348 +
349 +       if (inet_sk(sk)->transparent)
350 +               fl.flags |= FLOWI_FLAG_ANYSRC;
351 +
352         if (!dst || !src) {
353                 err = __ip_route_output_key(net, rp, &fl);
354                 if (err)
355 -- 
356 1.5.2.5
357
358 From 181680c6c0df4335bd8eeeafe06ea12e6918c3b7 Mon Sep 17 00:00:00 2001
359 From: KOVACS Krisztian <hidden@sch.bme.hu>
360 Date: Mon, 28 Apr 2008 14:46:50 +0200
361 Subject: [PATCH] Handle TCP SYN+ACK/ACK/RST transparency
362
363 The TCP stack sends out SYN+ACK/ACK/RST reply packets in response to
364 incoming packets. The non-local source address check on output bites
365 us again, as replies for transparently redirected traffic won't have a
366 chance to leave the node.
367
368 This patch selectively sets the FLOWI_FLAG_ANYSRC flag when doing
369 the route lookup for those replies. Transparent replies are enabled if
370 the listening socket has the transparent socket flag set.
371
372 Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
373 ---
374  include/net/inet_sock.h         |    8 +++++++-
375  include/net/ip.h                |    9 +++++++++
376  net/ipv4/inet_connection_sock.c |    1 +
377  net/ipv4/ip_output.c            |    4 +++-
378  net/ipv4/syncookies.c           |    1 +
379  net/ipv4/tcp_ipv4.c             |   11 ++++++++---
380  6 files changed, 29 insertions(+), 5 deletions(-)
381
382 diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
383 index 5ca683e..013e41d 100644
384 --- a/include/net/inet_sock.h
385 +++ b/include/net/inet_sock.h
386 @@ -71,7 +71,8 @@ struct inet_request_sock {
387                                 sack_ok    : 1,
388                                 wscale_ok  : 1,
389                                 ecn_ok     : 1,
390 -                               acked      : 1;
391 +                               acked      : 1,
392 +                               no_srccheck: 1;
393         struct ip_options       *opt;
394  };
395  
396 @@ -191,4 +192,9 @@ static inline int inet_sk_ehashfn(const struct sock *sk)
397         return inet_ehashfn(laddr, lport, faddr, fport);
398  }
399  
400 +static inline __u8 inet_sk_flowi_flags(const struct sock *sk)
401 +{
402 +       return inet_sk(sk)->transparent ? FLOWI_FLAG_ANYSRC : 0;
403 +}
404 +
405  #endif /* _INET_SOCK_H */
406 diff --git a/include/net/ip.h b/include/net/ip.h
407 index 6d7bcd5..c611608 100644
408 --- a/include/net/ip.h
409 +++ b/include/net/ip.h
410 @@ -29,6 +29,7 @@
411  
412  #include <net/inet_sock.h>
413  #include <net/snmp.h>
414 +#include <net/flow.h>
415  
416  struct sock;
417  
418 @@ -140,12 +141,20 @@ static inline void ip_tr_mc_map(__be32 addr, char *buf)
419  
420  struct ip_reply_arg {
421         struct kvec iov[1];   
422 +       int         flags;
423         __wsum      csum;
424         int         csumoffset; /* u16 offset of csum in iov[0].iov_base */
425                                 /* -1 if not needed */ 
426         int         bound_dev_if;
427  }; 
428  
429 +#define IP_REPLY_ARG_NOSRCCHECK 1
430 +
431 +static inline __u8 ip_reply_arg_flowi_flags(const struct ip_reply_arg *arg)
432 +{
433 +       return (arg->flags & IP_REPLY_ARG_NOSRCCHECK) ? FLOWI_FLAG_ANYSRC : 0;
434 +}
435 +
436  void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg,
437                    unsigned int len); 
438  
439 diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
440 index 828ea21..6d70d51 100644
441 --- a/net/ipv4/inet_connection_sock.c
442 +++ b/net/ipv4/inet_connection_sock.c
443 @@ -333,6 +333,7 @@ struct dst_entry* inet_csk_route_req(struct sock *sk,
444                                         .saddr = ireq->loc_addr,
445                                         .tos = RT_CONN_FLAGS(sk) } },
446                             .proto = sk->sk_protocol,
447 +                           .flags = inet_sk_flowi_flags(sk),
448                             .uli_u = { .ports =
449                                        { .sport = inet_sk(sk)->sport,
450                                          .dport = ireq->rmt_port } } };
451 diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
452 index 0834926..9ac5270 100644
453 --- a/net/ipv4/ip_output.c
454 +++ b/net/ipv4/ip_output.c
455 @@ -342,6 +342,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
456                                                         .saddr = inet->saddr,
457                                                         .tos = RT_CONN_FLAGS(sk) } },
458                                             .proto = sk->sk_protocol,
459 +                                           .flags = inet_sk_flowi_flags(sk),
460                                             .uli_u = { .ports =
461                                                        { .sport = inet->sport,
462                                                          .dport = inet->dport } } };
463 @@ -1380,7 +1381,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
464                                     .uli_u = { .ports =
465                                                { .sport = tcp_hdr(skb)->dest,
466                                                  .dport = tcp_hdr(skb)->source } },
467 -                                   .proto = sk->sk_protocol };
468 +                                   .proto = sk->sk_protocol,
469 +                                   .flags = ip_reply_arg_flowi_flags(arg) };
470                 security_skb_classify_flow(skb, &fl);
471                 if (ip_route_output_key(sock_net(sk), &rt, &fl))
472                         return;
473 diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
474 index 19a1037..d5fa8c7 100644
475 --- a/net/ipv4/syncookies.c
476 +++ b/net/ipv4/syncookies.c
477 @@ -340,6 +340,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
478                                                 .saddr = ireq->loc_addr,
479                                                 .tos = RT_CONN_FLAGS(sk) } },
480                                     .proto = IPPROTO_TCP,
481 +                                   .flags = inet_sk_flowi_flags(sk),
482                                     .uli_u = { .ports =
483                                                { .sport = th->dest,
484                                                  .dport = th->source } } };
485 diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
486 index 0e9bc12..58873ad 100644
487 --- a/net/ipv4/tcp_ipv4.c
488 +++ b/net/ipv4/tcp_ipv4.c
489 @@ -594,6 +594,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
490                                       ip_hdr(skb)->saddr, /* XXX */
491                                       sizeof(struct tcphdr), IPPROTO_TCP, 0);
492         arg.csumoffset = offsetof(struct tcphdr, check) / 2;
493 +       arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0;
494  
495         ip_send_reply(dev_net(skb->dst->dev)->ipv4.tcp_sock, skb,
496                       &arg, arg.iov[0].iov_len);
497 @@ -608,7 +609,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
498  
499  static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
500                             struct sk_buff *skb, u32 seq, u32 ack,
501 -                           u32 win, u32 ts)
502 +                           u32 win, u32 ts, int reply_flags)
503  {
504         struct tcphdr *th = tcp_hdr(skb);
505         struct {
506 @@ -684,6 +685,7 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
507                                         arg.iov[0].iov_len);
508         }
509  #endif
510 +       arg.flags = reply_flags;
511         arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,
512                                       ip_hdr(skb)->saddr, /* XXX */
513                                       arg.iov[0].iov_len, IPPROTO_TCP, 0);
514 @@ -704,7 +706,8 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
515  
516         tcp_v4_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
517                         tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
518 -                       tcptw->tw_ts_recent);
519 +                       tcptw->tw_ts_recent,
520 +                       tw->tw_transparent ? IP_REPLY_ARG_NOSRCCHECK : 0);
521  
522         inet_twsk_put(tw);
523  }
524 @@ -714,7 +717,8 @@ static void tcp_v4_reqsk_send_ack(struct sk_buff *skb,
525  {
526         tcp_v4_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1,
527                         tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd,
528 -                       req->ts_recent);
529 +                       req->ts_recent,
530 +                       inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0);
531  }
532  
533  /*
534 @@ -1321,6 +1325,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
535         ireq = inet_rsk(req);
536         ireq->loc_addr = daddr;
537         ireq->rmt_addr = saddr;
538 +       ireq->no_srccheck = inet_sk(sk)->transparent;
539         ireq->opt = tcp_v4_save_options(sk, skb);
540         if (!want_cookie)
541                 TCP_ECN_create_request(req, tcp_hdr(skb));
542 -- 
543 1.5.2.5
544
545 From f8be7a55d2a449d188f033d7914d2af007054fbc Mon Sep 17 00:00:00 2001
546 From: KOVACS Krisztian <hidden@sch.bme.hu>
547 Date: Mon, 28 Apr 2008 14:46:50 +0200
548 Subject: [PATCH] Make Netfilter's ip_route_me_harder() non-local address compatible
549
550 Netfilter's ip_route_me_harder() tries to re-route packets either generated or
551 re-routed by Netfilter. This patch changes ip_route_me_harder() to handle
552 packets from non-locally-bound sockets with IP_TRANSPARENT set as local and to
553 set the appropriate flowi flags when re-doing the routing lookup.
554
555 Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
556 ---
557  net/ipv4/netfilter.c |    3 +++
558  1 files changed, 3 insertions(+), 0 deletions(-)
559
560 diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
561 index f8edacd..01671ad 100644
562 --- a/net/ipv4/netfilter.c
563 +++ b/net/ipv4/netfilter.c
564 @@ -20,6 +20,8 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
565         unsigned int type;
566  
567         type = inet_addr_type(&init_net, iph->saddr);
568 +       if (skb->sk && inet_sk(skb->sk)->transparent)
569 +               type = RTN_LOCAL;
570         if (addr_type == RTN_UNSPEC)
571                 addr_type = type;
572  
573 @@ -33,6 +35,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
574                 fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
575                 fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
576                 fl.mark = skb->mark;
577 +               fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
578                 if (ip_route_output_key(&init_net, &rt, &fl) != 0)
579                         return -1;
580  
581 -- 
582 1.5.2.5
583
584 From 7797a39b59dae015e06bd4860affbdb250c312b7 Mon Sep 17 00:00:00 2001
585 From: KOVACS Krisztian <hidden@sch.bme.hu>
586 Date: Mon, 28 Apr 2008 14:46:50 +0200
587 Subject: [PATCH] Port redirection support for TCP
588
589 Current TCP code relies on the local port of the listening socket
590 being the same as the destination address of the incoming
591 connection. Port redirection used by many transparent proxying
592 techniques obviously breaks this, so we have to store the original
593 destination port address.
594
595 This patch extends struct inet_request_sock and stores the incoming
596 destination port value there. It also modifies the handshake code to
597 use that value as the source port when sending reply packets.
598
599 Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
600 ---
601  include/net/inet_sock.h         |    2 +-
602  include/net/tcp.h               |    1 +
603  net/ipv4/inet_connection_sock.c |    2 ++
604  net/ipv4/syncookies.c           |    1 +
605  net/ipv4/tcp_output.c           |    2 +-
606  5 files changed, 6 insertions(+), 2 deletions(-)
607
608 diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
609 index 013e41d..42b5d36 100644
610 --- a/include/net/inet_sock.h
611 +++ b/include/net/inet_sock.h
612 @@ -60,8 +60,8 @@ struct inet_request_sock {
613         struct request_sock     req;
614  #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
615         u16                     inet6_rsk_offset;
616 -       /* 2 bytes hole, try to pack */
617  #endif
618 +       __be16                  loc_port;
619         __be32                  loc_addr;
620         __be32                  rmt_addr;
621         __be16                  rmt_port;
622 diff --git a/include/net/tcp.h b/include/net/tcp.h
623 index 633147c..3c6a549 100644
624 --- a/include/net/tcp.h
625 +++ b/include/net/tcp.h
626 @@ -975,6 +975,7 @@ static inline void tcp_openreq_init(struct request_sock *req,
627         ireq->acked = 0;
628         ireq->ecn_ok = 0;
629         ireq->rmt_port = tcp_hdr(skb)->source;
630 +       ireq->loc_port = tcp_hdr(skb)->dest;
631  }
632  
633  extern void tcp_enter_memory_pressure(void);
634 diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
635 index 6d70d51..33dc826 100644
636 --- a/net/ipv4/inet_connection_sock.c
637 +++ b/net/ipv4/inet_connection_sock.c
638 @@ -508,6 +508,8 @@ struct sock *inet_csk_clone(struct sock *sk, const struct request_sock *req,
639                 newicsk->icsk_bind_hash = NULL;
640  
641                 inet_sk(newsk)->dport = inet_rsk(req)->rmt_port;
642 +               inet_sk(newsk)->num = ntohs(inet_rsk(req)->loc_port);
643 +               inet_sk(newsk)->sport = inet_rsk(req)->loc_port;
644                 newsk->sk_write_space = sk_stream_write_space;
645  
646                 newicsk->icsk_retransmits = 0;
647 diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
648 index d5fa8c7..676c550 100644
649 --- a/net/ipv4/syncookies.c
650 +++ b/net/ipv4/syncookies.c
651 @@ -299,6 +299,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
652         treq->rcv_isn           = ntohl(th->seq) - 1;
653         treq->snt_isn           = cookie;
654         req->mss                = mss;
655 +       ireq->loc_port          = th->dest;
656         ireq->rmt_port          = th->source;
657         ireq->loc_addr          = ip_hdr(skb)->daddr;
658         ireq->rmt_addr          = ip_hdr(skb)->saddr;
659 diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
660 index debf235..2b1d34d 100644
661 --- a/net/ipv4/tcp_output.c
662 +++ b/net/ipv4/tcp_output.c
663 @@ -2211,7 +2211,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
664         th->syn = 1;
665         th->ack = 1;
666         TCP_ECN_make_synack(req, th);
667 -       th->source = inet_sk(sk)->sport;
668 +       th->source = ireq->loc_port;
669         th->dest = ireq->rmt_port;
670         /* Setting of flags are superfluous here for callers (and ECE is
671          * not even correctly set)
672 -- 
673 1.5.2.5
674
675 From 4feb1a188b6bd0ff8cab5c8d817fbfc7d7788802 Mon Sep 17 00:00:00 2001
676 From: KOVACS Krisztian <hidden@sch.bme.hu>
677 Date: Mon, 28 Apr 2008 14:46:51 +0200
678 Subject: [PATCH] Export UDP socket lookup function
679
680 The iptables tproxy code has to be able to do UDP socket hash lookups,
681 so we have to provide an exported lookup function for this purpose.
682
683 Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
684 ---
685  include/net/udp.h |    4 ++++
686  net/ipv4/udp.c    |    7 +++++++
687  2 files changed, 11 insertions(+), 0 deletions(-)
688
689 diff --git a/include/net/udp.h b/include/net/udp.h
690 index 3e55a99..b88a196 100644
691 --- a/include/net/udp.h
692 +++ b/include/net/udp.h
693 @@ -147,6 +147,10 @@ extern int         udp_lib_setsockopt(struct sock *sk, int level, int optname,
694                                    char __user *optval, int optlen,
695                                    int (*push_pending_frames)(struct sock *));
696  
697 +extern struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
698 +                                   __be32 daddr, __be16 dport,
699 +                                   int dif);
700 +
701  DECLARE_SNMP_STAT(struct udp_mib, udp_statistics);
702  DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6);
703  
704 diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
705 index 1f535e3..672d0d4 100644
706 --- a/net/ipv4/udp.c
707 +++ b/net/ipv4/udp.c
708 @@ -307,6 +307,13 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
709         return result;
710  }
711  
712 +struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
713 +                            __be32 daddr, __be16 dport, int dif)
714 +{
715 +       return __udp4_lib_lookup(net, saddr, sport, daddr, dport, dif, udp_hash);
716 +}
717 +EXPORT_SYMBOL_GPL(udp4_lib_lookup);
718 +
719  static inline struct sock *udp_v4_mcast_next(struct sock *sk,
720                                              __be16 loc_port, __be32 loc_addr,
721                                              __be16 rmt_port, __be32 rmt_addr,
722 -- 
723 1.5.2.5
724
725 From d49cee38069417f3cb83ca67baa65a2034d2d2ce Mon Sep 17 00:00:00 2001
726 From: KOVACS Krisztian <hidden@sch.bme.hu>
727 Date: Mon, 28 Apr 2008 14:46:51 +0200
728 Subject: [PATCH] Split Netfilter IPv4 defragmentation into a separate module
729
730 Netfilter connection tracking requires all IPv4 packets to be defragmented.
731 Both the socket match and the TPROXY target depend on this functionality, so
732 this patch separates the Netfilter IPv4 defrag hooks into a separate module.
733
734 Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
735 ---
736  include/net/netfilter/ipv4/nf_defrag_ipv4.h    |    6 ++
737  net/ipv4/netfilter/Kconfig                     |    5 +
738  net/ipv4/netfilter/Makefile                    |    3 +
739  net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c |   56 +-------------
740  net/ipv4/netfilter/nf_defrag_ipv4.c            |   96 ++++++++++++++++++++++++
741  5 files changed, 113 insertions(+), 53 deletions(-)
742
743 diff --git a/include/net/netfilter/ipv4/nf_defrag_ipv4.h b/include/net/netfilter/ipv4/nf_defrag_ipv4.h
744 new file mode 100644
745 index 0000000..6b00ea3
746 --- /dev/null
747 +++ b/include/net/netfilter/ipv4/nf_defrag_ipv4.h
748 @@ -0,0 +1,6 @@
749 +#ifndef _NF_DEFRAG_IPV4_H
750 +#define _NF_DEFRAG_IPV4_H
751 +
752 +extern void nf_defrag_ipv4_enable(void);
753 +
754 +#endif /* _NF_DEFRAG_IPV4_H */
755 diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
756 index 2767841..3520c01 100644
757 --- a/net/ipv4/netfilter/Kconfig
758 +++ b/net/ipv4/netfilter/Kconfig
759 @@ -5,10 +5,15 @@
760  menu "IP: Netfilter Configuration"
761         depends on INET && NETFILTER
762  
763 +config NF_DEFRAG_IPV4
764 +       tristate
765 +       default n
766 +
767  config NF_CONNTRACK_IPV4
768         tristate "IPv4 connection tracking support (required for NAT)"
769         depends on NF_CONNTRACK
770         default m if NETFILTER_ADVANCED=n
771 +       select NF_DEFRAG_IPV4
772         ---help---
773           Connection tracking keeps a record of what packets have passed
774           through your machine, in order to figure out how they are related
775 diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
776 index d9b92fb..782b1e7 100644
777 --- a/net/ipv4/netfilter/Makefile
778 +++ b/net/ipv4/netfilter/Makefile
779 @@ -18,6 +18,9 @@ obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
780  
781  obj-$(CONFIG_NF_NAT) += nf_nat.o
782  
783 +# defrag
784 +obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o
785 +
786  # NAT helpers (nf_conntrack)
787  obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
788  obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
789 diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
790 index cacb9cb..9da59f3 100644
791 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
792 +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
793 @@ -1,3 +1,4 @@
794 +
795  /* (C) 1999-2001 Paul `Rusty' Russell
796   * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
797   *
798 @@ -24,6 +25,7 @@
799  #include <net/netfilter/nf_conntrack_core.h>
800  #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
801  #include <net/netfilter/nf_nat_helper.h>
802 +#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
803  
804  int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,
805                               struct nf_conn *ct,
806 @@ -63,23 +65,6 @@ static int ipv4_print_tuple(struct seq_file *s,
807                           NIPQUAD(tuple->dst.u3.ip));
808  }
809  
810 -/* Returns new sk_buff, or NULL */
811 -static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
812 -{
813 -       int err;
814 -
815 -       skb_orphan(skb);
816 -
817 -       local_bh_disable();
818 -       err = ip_defrag(skb, user);
819 -       local_bh_enable();
820 -
821 -       if (!err)
822 -               ip_send_check(ip_hdr(skb));
823 -
824 -       return err;
825 -}
826 -
827  static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
828                             unsigned int *dataoff, u_int8_t *protonum)
829  {
830 @@ -144,28 +129,6 @@ out:
831         return nf_conntrack_confirm(skb);
832  }
833  
834 -static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
835 -                                         struct sk_buff *skb,
836 -                                         const struct net_device *in,
837 -                                         const struct net_device *out,
838 -                                         int (*okfn)(struct sk_buff *))
839 -{
840 -       /* Previously seen (loopback)?  Ignore.  Do this before
841 -          fragment check. */
842 -       if (skb->nfct)
843 -               return NF_ACCEPT;
844 -
845 -       /* Gather fragments. */
846 -       if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
847 -               if (nf_ct_ipv4_gather_frags(skb,
848 -                                           hooknum == NF_INET_PRE_ROUTING ?
849 -                                           IP_DEFRAG_CONNTRACK_IN :
850 -                                           IP_DEFRAG_CONNTRACK_OUT))
851 -                       return NF_STOLEN;
852 -       }
853 -       return NF_ACCEPT;
854 -}
855 -
856  static unsigned int ipv4_conntrack_in(unsigned int hooknum,
857                                       struct sk_buff *skb,
858                                       const struct net_device *in,
859 @@ -195,13 +158,6 @@ static unsigned int ipv4_conntrack_local(unsigned int hooknum,
860     make it the first hook. */
861  static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
862         {
863 -               .hook           = ipv4_conntrack_defrag,
864 -               .owner          = THIS_MODULE,
865 -               .pf             = PF_INET,
866 -               .hooknum        = NF_INET_PRE_ROUTING,
867 -               .priority       = NF_IP_PRI_CONNTRACK_DEFRAG,
868 -       },
869 -       {
870                 .hook           = ipv4_conntrack_in,
871                 .owner          = THIS_MODULE,
872                 .pf             = PF_INET,
873 @@ -209,13 +165,6 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
874                 .priority       = NF_IP_PRI_CONNTRACK,
875         },
876         {
877 -               .hook           = ipv4_conntrack_defrag,
878 -               .owner          = THIS_MODULE,
879 -               .pf             = PF_INET,
880 -               .hooknum        = NF_INET_LOCAL_OUT,
881 -               .priority       = NF_IP_PRI_CONNTRACK_DEFRAG,
882 -       },
883 -       {
884                 .hook           = ipv4_conntrack_local,
885                 .owner          = THIS_MODULE,
886                 .pf             = PF_INET,
887 @@ -422,6 +371,7 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
888         int ret = 0;
889  
890         need_conntrack();
891 +       nf_defrag_ipv4_enable();
892  
893         ret = nf_register_sockopt(&so_getorigdst);
894         if (ret < 0) {
895 diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c
896 new file mode 100644
897 index 0000000..aa2c50a
898 --- /dev/null
899 +++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
900 @@ -0,0 +1,96 @@
901 +/* (C) 1999-2001 Paul `Rusty' Russell
902 + * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
903 + *
904 + * This program is free software; you can redistribute it and/or modify
905 + * it under the terms of the GNU General Public License version 2 as
906 + * published by the Free Software Foundation.
907 + */
908 +
909 +#include <linux/types.h>
910 +#include <linux/ip.h>
911 +#include <linux/netfilter.h>
912 +#include <linux/module.h>
913 +#include <linux/skbuff.h>
914 +#include <net/route.h>
915 +#include <net/ip.h>
916 +
917 +#include <linux/netfilter_ipv4.h>
918 +#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
919 +
920 +/* Returns new sk_buff, or NULL */
921 +static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
922 +{
923 +       int err;
924 +
925 +       skb_orphan(skb);
926 +
927 +       local_bh_disable();
928 +       err = ip_defrag(skb, user);
929 +       local_bh_enable();
930 +
931 +       if (!err)
932 +               ip_send_check(ip_hdr(skb));
933 +
934 +       return err;
935 +}
936 +
937 +static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
938 +                                         struct sk_buff *skb,
939 +                                         const struct net_device *in,
940 +                                         const struct net_device *out,
941 +                                         int (*okfn)(struct sk_buff *))
942 +{
943 +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
944 +       /* Previously seen (loopback)?  Ignore.  Do this before
945 +          fragment check. */
946 +       if (skb->nfct)
947 +               return NF_ACCEPT;
948 +#endif
949 +
950 +       /* Gather fragments. */
951 +       if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
952 +               if (nf_ct_ipv4_gather_frags(skb,
953 +                                           hooknum == NF_INET_PRE_ROUTING ?
954 +                                           IP_DEFRAG_CONNTRACK_IN :
955 +                                           IP_DEFRAG_CONNTRACK_OUT))
956 +                       return NF_STOLEN;
957 +       }
958 +       return NF_ACCEPT;
959 +}
960 +
961 +static struct nf_hook_ops ipv4_defrag_ops[] = {
962 +       {
963 +               .hook           = ipv4_conntrack_defrag,
964 +               .owner          = THIS_MODULE,
965 +               .pf             = PF_INET,
966 +               .hooknum        = NF_INET_PRE_ROUTING,
967 +               .priority       = NF_IP_PRI_CONNTRACK_DEFRAG,
968 +       },
969 +       {
970 +               .hook           = ipv4_conntrack_defrag,
971 +               .owner          = THIS_MODULE,
972 +               .pf             = PF_INET,
973 +               .hooknum        = NF_INET_LOCAL_OUT,
974 +               .priority       = NF_IP_PRI_CONNTRACK_DEFRAG,
975 +       },
976 +};
977 +
978 +static int __init nf_defrag_init(void)
979 +{
980 +       return nf_register_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
981 +}
982 +
983 +static void __exit nf_defrag_fini(void)
984 +{
985 +       nf_unregister_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
986 +}
987 +
988 +void nf_defrag_ipv4_enable(void)
989 +{
990 +}
991 +EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable);
992 +
993 +module_init(nf_defrag_init);
994 +module_exit(nf_defrag_fini);
995 +
996 +MODULE_LICENSE("GPL");
997 -- 
998 1.5.2.5
999
1000 From 40b01b3ada99906bb5818e15cddfe49344d09fd9 Mon Sep 17 00:00:00 2001
1001 From: KOVACS Krisztian <hidden@sch.bme.hu>
1002 Date: Mon, 28 Apr 2008 14:46:51 +0200
1003 Subject: [PATCH] iptables tproxy core
1004
1005 The iptables tproxy core is a module that contains the common routines used by
1006 various tproxy related modules (TPROXY target and socket match)
1007
1008 Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
1009 ---
1010  include/net/netfilter/nf_tproxy_core.h |   32 +++++++++++
1011  net/netfilter/Kconfig                  |   15 +++++
1012  net/netfilter/Makefile                 |    3 +
1013  net/netfilter/nf_tproxy_core.c         |   96 ++++++++++++++++++++++++++++++++
1014  4 files changed, 146 insertions(+), 0 deletions(-)
1015
1016 diff --git a/include/net/netfilter/nf_tproxy_core.h b/include/net/netfilter/nf_tproxy_core.h
1017 new file mode 100644
1018 index 0000000..208b46f
1019 --- /dev/null
1020 +++ b/include/net/netfilter/nf_tproxy_core.h
1021 @@ -0,0 +1,32 @@
1022 +#ifndef _NF_TPROXY_CORE_H
1023 +#define _NF_TPROXY_CORE_H
1024 +
1025 +#include <linux/types.h>
1026 +#include <linux/in.h>
1027 +#include <linux/skbuff.h>
1028 +#include <net/sock.h>
1029 +#include <net/inet_sock.h>
1030 +#include <net/tcp.h>
1031 +
1032 +/* look up and get a reference to a matching socket */
1033 +extern struct sock *
1034 +nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
1035 +                     const __be32 saddr, const __be32 daddr,
1036 +                     const __be16 sport, const __be16 dport,
1037 +                     const struct net_device *in, bool listening);
1038 +
1039 +static inline void
1040 +nf_tproxy_put_sock(struct sock *sk)
1041 +{
1042 +       /* TIME_WAIT inet sockets have to be handled differently */
1043 +       if ((sk->sk_protocol == IPPROTO_TCP) && (sk->sk_state == TCP_TIME_WAIT))
1044 +               inet_twsk_put(inet_twsk(sk));
1045 +       else
1046 +               sock_put(sk);
1047 +}
1048 +
1049 +/* assign a socket to the skb -- consumes sk */
1050 +int
1051 +nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk);
1052 +
1053 +#endif
1054 diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
1055 index c1fc0f1..de42858 100644
1056 --- a/net/netfilter/Kconfig
1057 +++ b/net/netfilter/Kconfig
1058 @@ -277,6 +277,21 @@ config NF_CT_NETLINK
1059         help
1060           This option enables support for a netlink-based userspace interface
1061  
1062 +# transparent proxy support
1063 +config NETFILTER_TPROXY
1064 +       tristate "Transparent proxying support (EXPERIMENTAL)"
1065 +       depends on EXPERIMENTAL
1066 +       depends on IP_NF_MANGLE
1067 +       depends on NETFILTER_ADVANCED
1068 +       help
1069 +         This option enables transparent proxying support, that is,
1070 +         support for handling non-locally bound IPv4 TCP and UDP sockets.
1071 +         For it to work you will have to configure certain iptables rules
1072 +         and use policy routing. For more information on how to set it up
1073 +         see Documentation/networking/tproxy.txt.
1074 +
1075 +         To compile it as a module, choose M here.  If unsure, say N.
1076 +
1077  config NETFILTER_XTABLES
1078         tristate "Netfilter Xtables support (required for ip_tables)"
1079         default m if NETFILTER_ADVANCED=n
1080 diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
1081 index 5c4b183..d644e82 100644
1082 --- a/net/netfilter/Makefile
1083 +++ b/net/netfilter/Makefile
1084 @@ -34,6 +34,9 @@ obj-$(CONFIG_NF_CONNTRACK_SANE) += nf_conntrack_sane.o
1085  obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o
1086  obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o
1087  
1088 +# transparent proxy support
1089 +obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o
1090 +
1091  # generic X tables 
1092  obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
1093  
1094 diff --git a/net/netfilter/nf_tproxy_core.c b/net/netfilter/nf_tproxy_core.c
1095 new file mode 100644
1096 index 0000000..8a6075d
1097 --- /dev/null
1098 +++ b/net/netfilter/nf_tproxy_core.c
1099 @@ -0,0 +1,96 @@
1100 +/*
1101 + * Transparent proxy support for Linux/iptables
1102 + *
1103 + * Copyright (c) 2006-2007 BalaBit IT Ltd.
1104 + * Author: Balazs Scheidler, Krisztian Kovacs
1105 + *
1106 + * This program is free software; you can redistribute it and/or modify
1107 + * it under the terms of the GNU General Public License version 2 as
1108 + * published by the Free Software Foundation.
1109 + *
1110 + */
1111 +
1112 +#include <linux/version.h>
1113 +#include <linux/module.h>
1114 +
1115 +#include <linux/net.h>
1116 +#include <linux/if.h>
1117 +#include <linux/netdevice.h>
1118 +#include <net/udp.h>
1119 +#include <net/netfilter/nf_tproxy_core.h>
1120 +
1121 +struct sock *
1122 +nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
1123 +                     const __be32 saddr, const __be32 daddr,
1124 +                     const __be16 sport, const __be16 dport,
1125 +                     const struct net_device *in, bool listening_only)
1126 +{
1127 +       struct sock *sk;
1128 +
1129 +       /* look up socket */
1130 +       switch (protocol) {
1131 +       case IPPROTO_TCP:
1132 +               if (listening_only)
1133 +                       sk = __inet_lookup_listener(net, &tcp_hashinfo,
1134 +                                                   daddr, ntohs(dport),
1135 +                                                   in->ifindex);
1136 +               else
1137 +                       sk = __inet_lookup(net, &tcp_hashinfo,
1138 +                                          saddr, sport, daddr, dport,
1139 +                                          in->ifindex);
1140 +               break;
1141 +       case IPPROTO_UDP:
1142 +               sk = udp4_lib_lookup(net, saddr, sport, daddr, dport,
1143 +                                    in->ifindex);
1144 +               break;
1145 +       default:
1146 +               WARN_ON(1);
1147 +               sk = NULL;
1148 +       }
1149 +
1150 +       pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u sock %p\n",
1151 +                protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), sk);
1152 +
1153 +       return sk;
1154 +}
1155 +EXPORT_SYMBOL_GPL(nf_tproxy_get_sock_v4);
1156 +
1157 +static void
1158 +nf_tproxy_destructor(struct sk_buff *skb)
1159 +{
1160 +       struct sock *sk = skb->sk;
1161 +
1162 +       skb->sk = NULL;
1163 +       skb->destructor = NULL;
1164 +
1165 +       if (sk)
1166 +               nf_tproxy_put_sock(sk);
1167 +}
1168 +
1169 +/* consumes sk */
1170 +int
1171 +nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk)
1172 +{
1173 +       if (inet_sk(sk)->transparent) {
1174 +               skb->sk = sk;
1175 +               skb->destructor = nf_tproxy_destructor;
1176 +               return 1;
1177 +       } else
1178 +               nf_tproxy_put_sock(sk);
1179 +
1180 +       return 0;
1181 +}
1182 +EXPORT_SYMBOL_GPL(nf_tproxy_assign_sock);
1183 +
1184 +static int __init nf_tproxy_init(void)
1185 +{
1186 +       pr_info("NF_TPROXY: Transparent proxy support initialized, version 4.1.0\n");
1187 +       pr_info("NF_TPROXY: Copyright (c) 2006-2007 BalaBit IT Ltd.\n");
1188 +       return 0;
1189 +}
1190 +
1191 +module_init(nf_tproxy_init);
1192 +
1193 +MODULE_LICENSE("GPL");
1194 +MODULE_AUTHOR("Krisztian Kovacs");
1195 +MODULE_DESCRIPTION("Transparent proxy support core routines");
1196 -- 
1197 1.5.2.5
1198
1199 From 7962977079ac28db798ab5b11ee31df6566fb472 Mon Sep 17 00:00:00 2001
1200 From: KOVACS Krisztian <hidden@sch.bme.hu>
1201 Date: Mon, 28 Apr 2008 14:46:52 +0200
1202 Subject: [PATCH] iptables socket match
1203
1204 Add iptables 'socket' match, which matches packets for which a TCP/UDP
1205 socket lookup succeeds.
1206
1207 Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
1208 Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
1209 ---
1210  net/netfilter/Kconfig     |   15 +++++
1211  net/netfilter/Makefile    |    1 +
1212  net/netfilter/xt_socket.c |  133 +++++++++++++++++++++++++++++++++++++++++++++
1213  3 files changed, 149 insertions(+), 0 deletions(-)
1214
1215 diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
1216 index de42858..ce21278 100644
1217 --- a/net/netfilter/Kconfig
1218 +++ b/net/netfilter/Kconfig
1219 @@ -748,6 +748,21 @@ config NETFILTER_XT_MATCH_SCTP
1220           If you want to compile it as a module, say M here and read
1221           <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
1222  
1223 +config NETFILTER_XT_MATCH_SOCKET
1224 +       tristate '"socket" match support (EXPERIMENTAL)'
1225 +       depends on EXPERIMENTAL
1226 +       depends on NETFILTER_TPROXY
1227 +       depends on NETFILTER_XTABLES
1228 +       depends on NETFILTER_ADVANCED
1229 +       select NF_DEFRAG_IPV4
1230 +       help
1231 +         This option adds a `socket' match, which can be used to match
1232 +         packets for which a TCP or UDP socket lookup finds a valid socket.
1233 +         It can be used in combination with the MARK target and policy
1234 +         routing to implement full featured non-locally bound sockets.
1235 +
1236 +         To compile it as a module, choose M here.  If unsure, say N.
1237 +
1238  config NETFILTER_XT_MATCH_STATE
1239         tristate '"state" match support'
1240         depends on NETFILTER_XTABLES
1241 diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
1242 index d644e82..6d2eee6 100644
1243 --- a/net/netfilter/Makefile
1244 +++ b/net/netfilter/Makefile
1245 @@ -80,6 +80,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o
1246  obj-$(CONFIG_NETFILTER_XT_MATCH_RATEEST) += xt_rateest.o
1247  obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
1248  obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
1249 +obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
1250  obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
1251  obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
1252  obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
1253 diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c
1254 new file mode 100644
1255 index 0000000..fa33358
1256 --- /dev/null
1257 +++ b/net/netfilter/xt_socket.c
1258 @@ -0,0 +1,133 @@
1259 +/*
1260 + * Transparent proxy support for Linux/iptables
1261 + *
1262 + * Copyright (C) 2007 BalaBit IT Ltd.
1263 + * Author: Krisztian Kovacs
1264 + *
1265 + * This program is free software; you can redistribute it and/or modify
1266 + * it under the terms of the GNU General Public License version 2 as
1267 + * published by the Free Software Foundation.
1268 + *
1269 + */
1270 +
1271 +#include <linux/module.h>
1272 +#include <linux/skbuff.h>
1273 +#include <linux/netfilter/x_tables.h>
1274 +#include <linux/netfilter_ipv4/ip_tables.h>
1275 +#include <net/tcp.h>
1276 +#include <net/udp.h>
1277 +#include <net/sock.h>
1278 +#include <net/inet_sock.h>
1279 +#include <net/netfilter/nf_tproxy_core.h>
1280 +#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
1281 +
1282 +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
1283 +#define XT_SOCKET_HAVE_CONNTRACK 1
1284 +#include <net/netfilter/nf_conntrack.h>
1285 +#endif
1286 +
1287 +static bool
1288 +socket_mt(const struct sk_buff *skb,
1289 +         const struct net_device *in,
1290 +         const struct net_device *out,
1291 +         const struct xt_match *match,
1292 +         const void *matchinfo,
1293 +         int offset,
1294 +         unsigned int protoff,
1295 +         bool *hotdrop)
1296 +{
1297 +       const struct iphdr *iph = ip_hdr(skb);
1298 +       struct udphdr _hdr, *hp;
1299 +       struct sock *sk;
1300 +       __be32 daddr;
1301 +       __be16 dport;
1302 +#ifdef XT_SOCKET_HAVE_CONNTRACK
1303 +       struct nf_conn const *ct;
1304 +       enum ip_conntrack_info ctinfo;
1305 +#endif
1306 +
1307 +       hp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_hdr), &_hdr);
1308 +       if (hp == NULL)
1309 +               return false;
1310 +
1311 +       daddr = iph->daddr;
1312 +       dport = hp->dest;
1313 +
1314 +#ifdef XT_SOCKET_HAVE_CONNTRACK
1315 +       /* Do the lookup with the original socket address in case this is a 
1316 +        * reply packet of an established SNAT-ted connection. */
1317 +       ct = nf_ct_get(skb, &ctinfo);
1318 +       if (ct && (ct != &nf_conntrack_untracked) &&
1319 +           (ctinfo == IP_CT_IS_REPLY + IP_CT_ESTABLISHED) &&
1320 +           (ct->status & IPS_SRC_NAT_DONE)) {
1321 +               daddr = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip;
1322 +               dport = (iph->protocol == IPPROTO_TCP) ?
1323 +                       ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.tcp.port :
1324 +                       ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port;
1325 +       }
1326 +#endif
1327 +
1328 +       sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol,
1329 +                                  iph->saddr, daddr,
1330 +                                  hp->source, dport, in, false);
1331 +       if (sk != NULL) {
1332 +               bool wildcard = (inet_sk(sk)->rcv_saddr == 0);
1333 +
1334 +               nf_tproxy_put_sock(sk);
1335 +               if (wildcard)
1336 +                       sk = NULL;
1337 +       }
1338 +
1339 +       pr_debug("socket match: proto %u %08x:%u -> %08x:%u (orig %08x:%u) sock %p\n",
1340 +                iph->protocol, ntohl(iph->saddr), ntohs(hp->source),
1341 +                ntohl(daddr), ntohs(dport),
1342 +                ntohl(iph->daddr), ntohs(hp->dest), sk);
1343 +
1344 +       return (sk != NULL);
1345 +}
1346 +
1347 +static bool
1348 +socket_mt_check(const char *tablename,
1349 +               const void *entry,
1350 +               const struct xt_match *match,
1351 +               void *matchinfo,
1352 +               unsigned int hook_mask)
1353 +{
1354 +       const struct ipt_ip *i = entry;
1355 +
1356 +       if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP)
1357 +           && !(i->invflags & IPT_INV_PROTO))
1358 +               return true;
1359 +
1360 +       pr_info("xt_socket: Can be used only in combination with "
1361 +               "either -p tcp or -p udp\n");
1362 +       return false;
1363 +}
1364 +
1365 +static struct xt_match socket_mt_reg __read_mostly = {
1366 +       .name           = "socket",
1367 +       .family         = AF_INET,
1368 +       .match          = socket_mt,
1369 +       .checkentry     = socket_mt_check,
1370 +       .hooks          = 1 << NF_INET_PRE_ROUTING,
1371 +       .me             = THIS_MODULE,
1372 +};
1373 +
1374 +static int __init socket_mt_init(void)
1375 +{
1376 +       nf_defrag_ipv4_enable();
1377 +       return xt_register_match(&socket_mt_reg);
1378 +}
1379 +
1380 +static void __exit socket_mt_exit(void)
1381 +{
1382 +       xt_unregister_match(&socket_mt_reg);
1383 +}
1384 +
1385 +module_init(socket_mt_init);
1386 +module_exit(socket_mt_exit);
1387 +
1388 +MODULE_LICENSE("GPL");
1389 +MODULE_AUTHOR("Krisztian Kovacs");
1390 +MODULE_DESCRIPTION("x_tables socket match module");
1391 +MODULE_ALIAS("ipt_socket");
1392 -- 
1393 1.5.2.5
1394
1395 From cb15c50f3d6419fec98bc309b5e4ea31b665cb8d Mon Sep 17 00:00:00 2001
1396 From: KOVACS Krisztian <hidden@sch.bme.hu>
1397 Date: Mon, 28 Apr 2008 14:46:52 +0200
1398 Subject: [PATCH] iptables TPROXY target
1399
1400 The TPROXY target implements redirection of non-local TCP/UDP traffic to local
1401 sockets. Additionally, it's possible to manipulate the packet mark if and only
1402 if a socket has been found. (We need this because we cannot use multiple
1403 targets in the same iptables rule.)
1404
1405 Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
1406 Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
1407 ---
1408  include/linux/netfilter/xt_TPROXY.h |   14 ++++
1409  net/netfilter/Kconfig               |   15 +++++
1410  net/netfilter/Makefile              |    1 +
1411  net/netfilter/xt_TPROXY.c           |  112 +++++++++++++++++++++++++++++++++++
1412  4 files changed, 142 insertions(+), 0 deletions(-)
1413
1414 diff --git a/include/linux/netfilter/xt_TPROXY.h b/include/linux/netfilter/xt_TPROXY.h
1415 new file mode 100644
1416 index 0000000..152e8f9
1417 --- /dev/null
1418 +++ b/include/linux/netfilter/xt_TPROXY.h
1419 @@ -0,0 +1,14 @@
1420 +#ifndef _XT_TPROXY_H_target
1421 +#define _XT_TPROXY_H_target
1422 +
1423 +/* TPROXY target is capable of marking the packet to perform
1424 + * redirection. We can get rid of that whenever we get support for
1425 + * mutliple targets in the same rule. */
1426 +struct xt_tproxy_target_info {
1427 +       u_int32_t mark_mask;
1428 +       u_int32_t mark_value;
1429 +       __be32 laddr;
1430 +       __be16 lport;
1431 +};
1432 +
1433 +#endif /* _XT_TPROXY_H_target */
1434 diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
1435 index ce21278..d36018d 100644
1436 --- a/net/netfilter/Kconfig
1437 +++ b/net/netfilter/Kconfig
1438 @@ -411,6 +411,21 @@ config NETFILTER_XT_TARGET_RATEEST
1439  
1440           To compile it as a module, choose M here.  If unsure, say N.
1441  
1442 +config NETFILTER_XT_TARGET_TPROXY
1443 +       tristate '"TPROXY" target support (EXPERIMENTAL)'
1444 +       depends on EXPERIMENTAL
1445 +       depends on NETFILTER_TPROXY
1446 +       depends on NETFILTER_XTABLES
1447 +       depends on NETFILTER_ADVANCED
1448 +       select NF_DEFRAG_IPV4
1449 +       help
1450 +         This option adds a `TPROXY' target, which is somewhat similar to
1451 +         REDIRECT.  It can only be used in the mangle table and is useful
1452 +         to redirect traffic to a transparent proxy.  It does _not_ depend
1453 +         on Netfilter connection tracking and NAT, unlike REDIRECT.
1454 +
1455 +         To compile it as a module, choose M here.  If unsure, say N.
1456 +
1457  config NETFILTER_XT_TARGET_TRACE
1458         tristate  '"TRACE" target support'
1459         depends on NETFILTER_XTABLES
1460 diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
1461 index 6d2eee6..04844d0 100644
1462 --- a/net/netfilter/Makefile
1463 +++ b/net/netfilter/Makefile
1464 @@ -51,6 +51,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
1465  obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
1466  obj-$(CONFIG_NETFILTER_XT_TARGET_RATEEST) += xt_RATEEST.o
1467  obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
1468 +obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o
1469  obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
1470  obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o
1471  obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
1472 diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c
1473 new file mode 100644
1474 index 0000000..183f251
1475 --- /dev/null
1476 +++ b/net/netfilter/xt_TPROXY.c
1477 @@ -0,0 +1,112 @@
1478 +/*
1479 + * Transparent proxy support for Linux/iptables
1480 + *
1481 + * Copyright (c) 2006-2007 BalaBit IT Ltd.
1482 + * Author: Balazs Scheidler, Krisztian Kovacs
1483 + *
1484 + * This program is free software; you can redistribute it and/or modify
1485 + * it under the terms of the GNU General Public License version 2 as
1486 + * published by the Free Software Foundation.
1487 + *
1488 + */
1489 +
1490 +#include <linux/module.h>
1491 +#include <linux/skbuff.h>
1492 +#include <linux/ip.h>
1493 +#include <net/checksum.h>
1494 +#include <net/udp.h>
1495 +#include <net/inet_sock.h>
1496 +
1497 +#include <linux/netfilter/x_tables.h>
1498 +#include <linux/netfilter_ipv4/ip_tables.h>
1499 +#include <linux/netfilter/xt_TPROXY.h>
1500 +
1501 +#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
1502 +#include <net/netfilter/nf_tproxy_core.h>
1503 +
1504 +static unsigned int
1505 +tproxy_tg(struct sk_buff *skb,
1506 +         const struct net_device *in,
1507 +         const struct net_device *out,
1508 +         unsigned int hooknum,
1509 +         const struct xt_target *target,
1510 +         const void *targinfo)
1511 +{
1512 +       const struct iphdr *iph = ip_hdr(skb);
1513 +       const struct xt_tproxy_target_info *tgi = targinfo;
1514 +       struct udphdr _hdr, *hp;
1515 +       struct sock *sk;
1516 +
1517 +       hp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_hdr), &_hdr);
1518 +       if (hp == NULL)
1519 +               return NF_DROP;
1520 +
1521 +       sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol,
1522 +                                  iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr,
1523 +                                  hp->source, tgi->lport ? tgi->lport : hp->dest,
1524 +                                  in, true);
1525 +
1526 +       /* NOTE: assign_sock consumes our sk reference */
1527 +       if (sk && nf_tproxy_assign_sock(skb, sk)) {
1528 +               /* This should be in a separate target, but we don't do multiple
1529 +                  targets on the same rule yet */
1530 +               skb->mark = (skb->mark & ~tgi->mark_mask) ^ tgi->mark_value;
1531 +
1532 +               pr_debug("redirecting: proto %u %08x:%u -> %08x:%u, mark: %x\n",
1533 +                        iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
1534 +                        ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark);
1535 +               return NF_ACCEPT;
1536 +       }
1537 +
1538 +       pr_debug("no socket, dropping: proto %u %08x:%u -> %08x:%u, mark: %x\n",
1539 +                iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
1540 +                ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark);
1541 +       return NF_DROP;
1542 +}
1543 +
1544 +static bool
1545 +tproxy_tg_check(const char *tablename,
1546 +               const void *entry,
1547 +               const struct xt_target *target,
1548 +               void *targetinfo,
1549 +               unsigned int hook_mask)
1550 +{
1551 +       const struct ipt_ip *i = entry;
1552 +
1553 +       if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP)
1554 +           && !(i->invflags & IPT_INV_PROTO))
1555 +               return true;
1556 +
1557 +       pr_info("xt_TPROXY: Can be used only in combination with "
1558 +               "either -p tcp or -p udp\n");
1559 +       return false;
1560 +}
1561 +
1562 +static struct xt_target tproxy_tg_reg __read_mostly = {
1563 +       .name           = "TPROXY",
1564 +       .family         = AF_INET,
1565 +       .table          = "mangle",
1566 +       .target         = tproxy_tg,
1567 +       .targetsize     = sizeof(struct xt_tproxy_target_info),
1568 +       .checkentry     = tproxy_tg_check,
1569 +       .hooks          = 1 << NF_INET_PRE_ROUTING,
1570 +       .me             = THIS_MODULE,
1571 +};
1572 +
1573 +static int __init tproxy_tg_init(void)
1574 +{
1575 +       nf_defrag_ipv4_enable();
1576 +       return xt_register_target(&tproxy_tg_reg);
1577 +}
1578 +
1579 +static void __exit tproxy_tg_exit(void)
1580 +{
1581 +       xt_unregister_target(&tproxy_tg_reg);
1582 +}
1583 +
1584 +module_init(tproxy_tg_init);
1585 +module_exit(tproxy_tg_exit);
1586 +MODULE_LICENSE("GPL");
1587 +MODULE_AUTHOR("Krisztian Kovacs");
1588 +MODULE_DESCRIPTION("Netfilter transparent proxy (TPROXY) target module.");
1589 +MODULE_ALIAS("ipt_TPROXY");
1590 -- 
1591 1.5.2.5
1592
1593 From 1ba926a05e2c25585f15e7c9f895557e6a48407f Mon Sep 17 00:00:00 2001
1594 From: KOVACS Krisztian <hidden@sch.bme.hu>
1595 Date: Mon, 28 Apr 2008 14:46:53 +0200
1596 Subject: [PATCH] Don't lookup the socket if there's a socket attached to the skb
1597
1598 Use the socket cached in the TPROXY target if it's present.
1599
1600 Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
1601 ---
1602  net/ipv4/tcp_ipv4.c |    9 +++++++++
1603  1 files changed, 9 insertions(+), 0 deletions(-)
1604
1605 diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
1606 index 58873ad..8937675 100644
1607 --- a/net/ipv4/tcp_ipv4.c
1608 +++ b/net/ipv4/tcp_ipv4.c
1609 @@ -1647,8 +1647,17 @@ int tcp_v4_rcv(struct sk_buff *skb)
1610         TCP_SKB_CB(skb)->flags   = iph->tos;
1611         TCP_SKB_CB(skb)->sacked  = 0;
1612  
1613 +#if defined(CONFIG_NETFILTER_TPROXY) || defined(CONFIG_NETFILTER_TPROXY_MODULE)
1614 +       if (unlikely(skb->sk)) {
1615 +               /* steal reference */
1616 +               sk = skb->sk;
1617 +               skb->destructor = NULL;
1618 +               skb->sk = NULL;
1619 +       } else
1620 +#endif
1621         sk = __inet_lookup(dev_net(skb->dev), &tcp_hashinfo, iph->saddr,
1622                         th->source, iph->daddr, th->dest, inet_iif(skb));
1623 +
1624         if (!sk)
1625                 goto no_tcp_socket;
1626  
1627 -- 
1628 1.5.2.5
1629
1630 From 8b291305fd4891a92118cf358666f25a0e42ca00 Mon Sep 17 00:00:00 2001
1631 From: KOVACS Krisztian <hidden@sch.bme.hu>
1632 Date: Mon, 28 Apr 2008 14:46:53 +0200
1633 Subject: [PATCH] Don't lookup the socket if there's a socket attached to the skb
1634
1635 Use the socket cached in the TPROXY target if it's present.
1636
1637 Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
1638 ---
1639  net/ipv4/udp.c |   16 ++++++++++++++++
1640  1 files changed, 16 insertions(+), 0 deletions(-)
1641
1642 diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
1643 index 672d0d4..c29597c 100644
1644 --- a/net/ipv4/udp.c
1645 +++ b/net/ipv4/udp.c
1646 @@ -364,6 +364,14 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct hlist_head udptable[])
1647         int harderr;
1648         int err;
1649  
1650 +#if defined(CONFIG_NETFILTER_TPROXY) || defined(CONFIG_NETFILTER_TPROXY_MODULE)
1651 +       if (unlikely(skb->sk)) {
1652 +               /* steal reference */
1653 +               sk = skb->sk;
1654 +               skb->destructor = NULL;
1655 +               skb->sk = NULL;
1656 +       } else
1657 +#endif
1658         sk = __udp4_lib_lookup(dev_net(skb->dev), iph->daddr, uh->dest,
1659                         iph->saddr, uh->source, skb->dev->ifindex, udptable);
1660         if (sk == NULL) {
1661 @@ -1188,6 +1196,14 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
1662         if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
1663                 return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable);
1664  
1665 +#if defined(CONFIG_NETFILTER_TPROXY) || defined(CONFIG_NETFILTER_TPROXY_MODULE)
1666 +       if (unlikely(skb->sk)) {
1667 +               /* steal reference */
1668 +               sk = skb->sk;
1669 +               skb->destructor = NULL;
1670 +               skb->sk = NULL;
1671 +       } else
1672 +#endif
1673         sk = __udp4_lib_lookup(dev_net(skb->dev), saddr, uh->source, daddr,
1674                         uh->dest, inet_iif(skb), udptable);
1675  
1676 -- 
1677 1.5.2.5
1678
1679 From 6e33de49987ecc73930148c88f07f61527929dcc Mon Sep 17 00:00:00 2001
1680 From: KOVACS Krisztian <hidden@sch.bme.hu>
1681 Date: Mon, 28 Apr 2008 14:46:53 +0200
1682 Subject: [PATCH] Add documentation
1683
1684 Add basic usage instructions to Documentation/networking.
1685
1686 Signed-off-by: KOVACS Krisztian <hidden@sch.bme.hu>
1687 ---
1688  Documentation/networking/tproxy.txt |   62 +++++++++++++++++++++++++++++++++++
1689  1 files changed, 62 insertions(+), 0 deletions(-)
1690
1691 diff --git a/Documentation/networking/tproxy.txt b/Documentation/networking/tproxy.txt
1692 new file mode 100644
1693 index 0000000..dfcb613
1694 --- /dev/null
1695 +++ b/Documentation/networking/tproxy.txt
1696 @@ -0,0 +1,62 @@
1697 +Transparent proxy support
1698 +=========================
1699 +
1700 +This feature adds Linux 2.2-like transparent proxy support to current kernels.
1701 +To use it, enable NETFILTER_TPROXY, the socket match and the TPROXY target in
1702 +your kernel config. You will need policy routing too, so be sure to enable that
1703 +as well.
1704 +
1705 +1. Making non-local sockets work
1706 +================================
1707 +
1708 +The idea is that you identify packets with destination address matching a local
1709 +socket your box, set the packet mark to a certain value, and then match on that
1710 +value using policy routing to have those packets delivered locally:
1711 +
1712 +# iptables -t mangle -N DIVERT
1713 +# iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
1714 +# iptables -t mangle -A DIVERT -j MARK --set-mark 1
1715 +# iptables -t mangle -A DIVERT -j ACCEPT
1716 +
1717 +# ip rule add fwmark 1 lookup 100
1718 +# ip route add local 0.0.0.0/0 dev lo table 100
1719 +
1720 +Because of certain restrictions in the IPv4 routing output code you'll have to
1721 +modify your application to allow it sending datagrams _from_ non-local IP
1722 +addresses. All you have to do is to enable the (SOL_IP, IP_TRANSPARENT) socket
1723 +option before calling bind:
1724 +
1725 +fd = socket(AF_INET, SOCK_STREAM, 0);
1726 +/* - 8< -*/
1727 +int value = 1;
1728 +setsockopt(fd, SOL_IP, IP_TRANSPARENT, &value, sizeof(value));
1729 +/* - 8< -*/
1730 +name.sin_family = AF_INET;
1731 +name.sin_port = htons(0xCAFE);
1732 +name.sin_addr.s_addr = htonl(0xDEADBEEF);
1733 +bind(fd, &name, sizeof(name));
1734 +
1735 +A trivial patch for netcat is available here:
1736 +http://people.netfilter.org/hidden/tproxy/netcat-ip_transparent-support.patch
1737 +
1738 +
1739 +2. Redirecting traffic
1740 +======================
1741 +
1742 +Transparent proxying often involves "intercepting" traffic on a router. This is
1743 +usually done with the iptables REDIRECT target, however, there are serious
1744 +limitations of that method. One of the major issues is that it actually
1745 +modifies the packets to change the destination address -- which might not be
1746 +acceptable in certain situations. (Think of proxying UDP for example: you won't
1747 +be able to find out the original destination address. Even in case of TCP
1748 +getting the original destination address is racy.)
1749 +
1750 +The 'TPROXY' target provides similar functionality without relying on NAT. Simply
1751 +add rules like this to the iptables ruleset above:
1752 +
1753 +# iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY \
1754 +  --tproxy-mark 0x1/0x1 --on-port 50080
1755 +
1756 +Note that for this to work you'll have to modify the proxy to enable (SOL_IP,
1757 +IP_TRANSPARENT) for the listening socket.
1758 +
1759 -- 
1760 1.5.2.5
1761
This page took 0.169851 seconds and 3 git commands to generate.