TProxy for IPv6
Subsystems (4)
cover TProxy for IPv6
[ Sorry if this reaches you twice, I sent to the wrong address the first time ]
I've just pushed a set of patches that implement TProxy for IPv6 to
http://git.balabit.hu/bazsi/tproxy-2.6.git
The patches are also posted in reply to this mail.
Although some work is still needed, basic testing shows that it works all right.
The accompanying iptables patches are available at
http://git.balabit.hu/bazsi/iptables-tproxy.git
There are some things left to do:
* the recognition of related ICMPv6 packets missing (from xt_socket.c)
* I should probably split xt_TPROXY/xt_socket to IPv4 and IPv6 modules, as right now those depend on both stacks at the same time.
I'm on a holiday right now, thus I might not respond to comments in a timely manner, however I'm interested in any comments/feedback nevertheless.
Harry, I didn't remember that you actually wanted to work on TProxy for IPv6, I just vaguely remembered that there was someone asking for IPv6 support, thus I implemented this without being in the know. If you started hacking, I hope that we didn't completely duplicate effort. I'd appreciate help in the missing bits and/or testing whichever fits you best.
Also, I have written a Python test script to test TProxy functionality automatically both for IPv4 and IPv6, I can post that as well if anyone is interested.
Balazs Scheidler (11):
TProxy: kick out TIME_WAIT sockets in case a new connection comes in
with the same tuple
TProxy: add lookup type checks for UDP in nf_tproxy_get_sock_v4()
TProxy: reuse a 32bit hole in struct ipv6_pinfo
TProxy: split off ipv6 defragmentation to a separate module
TProxy: added const specifiers to udp lookup functions
TProxy: added udp6_lib_lookup function
TProxy: implement IPv6 "local" routing type
TProxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is
enabled
TProxy: added IPv6 socket lookup function to nf_tproxy_core
TProxy: added IPv6 support to the TPROXY target
TProxy: added IPv6 support to the socket match
include/linux/ipv6.h | 3 +- include/linux/netfilter/xt_TPROXY.h | 15 +- include/net/netfilter/ipv6/nf_defrag_ipv6.h | 6 + include/net/netfilter/nf_tproxy_core.h | 192 +++++++++++++++++++- include/net/udp.h | 3 + net/ipv6/af_inet6.c | 2 +- net/ipv6/netfilter/Makefile | 5 +- net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 58 +------ net/ipv6/netfilter/nf_conntrack_reasm.c | 12 +- net/ipv6/netfilter/nf_defrag_ipv6_hooks.c | 109 +++++++++++ net/ipv6/route.c | 6 +- net/ipv6/udp.c | 16 ++- net/netfilter/nf_tproxy_core.c | 35 ---- net/netfilter/xt_TPROXY.c | 239 +++++++++++++++++++++--- net/netfilter/xt_socket.c | 113 +++++++++++- 15 files changed, 675 insertions(+), 139 deletions(-) create mode 100644 include/net/netfilter/ipv6/nf_defrag_ipv6.h create mode 100644 net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
PATCH 1/11 TProxy: kick out TIME_WAIT sockets in case a new connection comes in with the same tuple
Without tproxy redirections an incoming SYN kicks out conflicting TIME_WAIT sockets, in order to handle clients that reuse ports within the TIME_WAIT period.
The same mechanism didn't work in case TProxy is involved in finding the proper socket, as the time_wait processing code looked up the listening socket assuming that the listener addr/port matches those of the established connection.
This is not the case with TProxy as the listener addr/port is possibly changed with the tproxy rule.
--- include/net/netfilter/nf_tproxy_core.h | 6 ++++- net/netfilter/nf_tproxy_core.c | 29 +++++++++++++++++++------- net/netfilter/xt_TPROXY.c | 35 ++++++++++++++++++++++++++++--- net/netfilter/xt_socket.c | 2 +- 4 files changed, 58 insertions(+), 14 deletions(-)
include/net/netfilter/nf_tproxy_core.h +5 -1
@@ -8,12 +8,16 @@#include <net/inet_sock.h> #include <net/tcp.h> +#define NFT_LOOKUP_ANY 0 +#define NFT_LOOKUP_LISTENER 1 +#define NFT_LOOKUP_ESTABLISHED 2 +/* look up and get a reference to a matching socket */ extern struct sock *nf_tproxy_get_sock_v4 (struct net *net,const u8 protocol,const __be32 saddr,const __be32 daddr,const __be16 sport,const __be16 dport, -const struct net_device *in,bool listening); +const struct net_device *in,int lookup_type);static inline void nf_tproxy_put_sock (struct sock *sk)
net/netfilter/nf_tproxy_core.c +21 -8
@@ -22,21 +22,34 @@ struct sock * nf_tproxy_get_sock_v4(struct net *net, const u8 protocol, const __be32 saddr, const __be32 daddr, const __be16 sport, const __be16 dport, - const struct net_device *in, bool listening_only) + const struct net_device *in, int lookup_type) { struct sock *sk;/* look up socket */ switch (protocol) { case IPPROTO_TCP: - if (listening_only) - sk = __inet_lookup_listener(net, &tcp_hashinfo, - daddr, ntohs(dport), - in->ifindex); - else + switch (lookup_type) { + case NFT_LOOKUP_ANY: sk = __inet_lookup(net, &tcp_hashinfo, saddr, sport, daddr, dport, in->ifindex); + break; + case NFT_LOOKUP_LISTENER: + sk = inet_lookup_listener(net, &tcp_hashinfo, + daddr, dport, + in->ifindex); + break; + case NFT_LOOKUP_ESTABLISHED: + sk = inet_lookup_established(net, &tcp_hashinfo, + saddr, sport, daddr, dport, + in->ifindex); + break; + default: + WARN_ON(1); + sk = NULL; + break; + } break; case IPPROTO_UDP: sk = udp4_lib_lookup(net, saddr, sport, daddr, dport,
@@ -47,8 +60,8 @@ nf_tproxy_get_sock_v4(struct net *net, const u8 protocol, sk =NULL ; } -pr_debug ("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, listener only: %d, sock %p\n" , - protocol,ntohl (saddr),ntohs (sport),ntohl (daddr),ntohs (dport), listening_only, sk); +pr_debug ("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, lookup type: %d, sock %p\n" , + protocol,ntohl (saddr),ntohs (sport),ntohl (daddr),ntohs (dport), lookup_type, sk);return sk; }
net/netfilter/xt_TPROXY.c +32 -5
@@ -29,7 +29,7 @@ tproxy_tg(struct sk_buff *skb, const struct xt_target_param *par) {const struct iphdr *iph =ip_hdr (skb);const struct xt_tproxy_target_info *tgi = par->targinfo; -struct udphdr _hdr, *hp; +struct tcphdr _hdr, *hp;struct sock *sk; hp =skb_header_pointer (skb,ip_hdrlen (skb),sizeof (_hdr), &_hdr);
@@ -37,10 +37,37 @@ tproxy_tg(struct sk_buff *skb, const struct xt_target_param *par)return NF_DROP ; sk =nf_tproxy_get_sock_v4 (dev_net (skb->dev), iph->protocol, - iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr, - hp->source, tgi->lport ? tgi->lport : hp->dest, - par->in, true); - + iph->saddr, iph->daddr, + hp->source, hp->dest, + par->in,NFT_LOOKUP_ESTABLISHED ); + +/* udp has no TCP_TIME_WAIT state, so we never enter here */ +if (sk && sk->sk_state ==TCP_TIME_WAIT && + hp->syn && !hp->rst && !hp->ack && !hp->fin) { +struct sock *sk2; + +/* Hm.. we got a SYN to a TIME_WAIT socket, let's see if +* there's a listener on the redirected port +*/ + sk2 =nf_tproxy_get_sock_v4 (dev_net (skb->dev), iph->protocol, + iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr, + hp->source, tgi->lport ? tgi->lport : hp->dest, + par->in,NFT_LOOKUP_LISTENER ); +if (sk2) { + +/* yeah, there's one, let's kill the TIME_WAIT +* socket and redirect to the listener +*/ +inet_twsk_deschedule (inet_twsk (sk), &tcp_death_row); +inet_twsk_put (inet_twsk (sk)); + sk = sk2; + } + }else if (!sk) { + sk =nf_tproxy_get_sock_v4 (dev_net (skb->dev), iph->protocol, + iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr, + hp->source, tgi->lport ? tgi->lport : hp->dest, + par->in,NFT_LOOKUP_LISTENER ); + }/* NOTE: assign_sock consumes our sk reference */ if (sk &&nf_tproxy_assign_sock (skb, sk)) {/* This should be in a separate target, but we don't do multiple
net/netfilter/xt_socket.c +1 -1
@@ -142,7 +142,7 @@ socket_match(const struct sk_buff *skb, const struct xt_match_param *par,#endif sk =nf_tproxy_get_sock_v4 (dev_net (skb->dev), protocol, - saddr, daddr, sport, dport, par->in, false); + saddr, daddr, sport, dport, par->in,NFT_LOOKUP_ANY );if (sk !=NULL ) {bool wildcard;bool transparent = true;
Signature · 1 line
1.6.0.4
PATCH 2/11 TProxy: add lookup type checks for UDP in nf_tproxy_get_sock_v4()
In reply to Balazs ScheidlerAlso, inline this function as the lookup_type is always a literal and inlineing removes branches performed at runtime.
--- include/net/netfilter/nf_tproxy_core.h | 116 +++++++++++++++++++++++++++++++- net/netfilter/nf_tproxy_core.c | 48 ------------- 2 files changed, 114 insertions(+), 50 deletions(-)
include/net/netfilter/nf_tproxy_core.h +114 -2
@@ -13,11 +13,123 @@#define NFT_LOOKUP_ESTABLISHED 2/* look up and get a reference to a matching socket */ -extern struct sock * + + +/* This function is used by the 'TPROXY' target and the 'socket' +* match. The following lookups are supported: +* +* Explicit TProxy target rule +* =========================== +* +* This is used when the user wants to intercept a connection matching +* an explicit iptables rule. In this case the sockets are assumed +* matching in preference order: +* +* - match: if there's a fully established connection matching the +* _packet_ tuple, it is returned, assuming the redirection +* already took place and we process a packet belonging to an +* established connection +* +* - match: if there's a listening socket matching the redirection +* (e.g. on-port & on-ip of the connection), it is returned, +* regardless if it was bound to 0.0.0.0 or an explicit +* address. The reasoning is that if there's an explicit rule, it +* does not really matter if the listener is bound to an interface +* or to 0. The user already stated that he wants redirection +* (since he added the rule). +* +* "socket" match based redirection (no specific rule) +* =================================================== +* +* There are connections with dynamic endpoints (e.g. FTP data +* connection) that the user is unable to add explicit rules +* for. These are taken care of by a generic "socket" rule. It is +* assumed that the proxy application is trusted to open such +* connections without explicit iptables rule (except of course the +* generic 'socket' rule). In this case the following sockets are +* matched in preference order: +* +* - match: if there's a fully established connection matching the +* _packet_ tuple +* +* - match: if there's a non-zero bound listener (possibly with a +* non-local address) We don't accept zero-bound listeners, since +* then local services could intercept traffic going through the +* box. +* +* Please note that there's an overlap between what a TPROXY target +* and a socket match will match. Normally if you have both rules the +* "socket" match will be the first one, effectively all packets +* belonging to established connections going through that one. +*/ +static inline struct sock *nf_tproxy_get_sock_v4 (struct net *net,const u8 protocol,const __be32 saddr,const __be32 daddr,const __be16 sport,const __be16 dport, -const struct net_device *in,int lookup_type); +const struct net_device *in,int lookup_type) +{ +struct sock *sk; + +/* look up socket */ +switch (protocol) { +case IPPROTO_TCP : +switch (lookup_type) { +case NFT_LOOKUP_ANY : + sk =__inet_lookup (net, &tcp_hashinfo, + saddr, sport, daddr, dport, + in->ifindex); +break ; +case NFT_LOOKUP_LISTENER : + sk =inet_lookup_listener (net, &tcp_hashinfo, + daddr, dport, + in->ifindex); + +/* NOTE: we return listeners even if bound to +* 0.0.0.0, those are filtered out in +* xt_socket, since xt_TPROXY needs 0 bound +* listeners too */ + +break ; +case NFT_LOOKUP_ESTABLISHED : + sk =inet_lookup_established (net, &tcp_hashinfo, + saddr, sport, daddr, dport, + in->ifindex); +break ; +default : +WARN_ON (1 ); + sk =NULL ; +break ; + } +break ; +case IPPROTO_UDP : + sk =udp4_lib_lookup (net, saddr, sport, daddr, dport, + in->ifindex); +if (sk && lookup_type !=NFT_LOOKUP_ANY ) { +int connected = (sk->sk_state ==TCP_ESTABLISHED ); +int wildcard = (inet_sk (sk)->rcv_saddr ==0 ); + +/* NOTE: we return listeners even if bound to +* 0.0.0.0, those are filtered out in +* xt_socket, since xt_TPROXY needs 0 bound +* listeners too */ +if ((lookup_type ==NFT_LOOKUP_ESTABLISHED && (!connected || wildcard)) || + (lookup_type ==NFT_LOOKUP_LISTENER && connected)) { +sock_put (sk); + sk =NULL ; + } + } +break ; +default : +WARN_ON (1 ); + sk =NULL ; + } + +pr_debug ("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, lookup type: %d, sock %p\n" , + protocol,ntohl (saddr),ntohs (sport),ntohl (daddr),ntohs (dport), lookup_type, sk); + +return sk; +} +static inline void nf_tproxy_put_sock (struct sock *sk)
net/netfilter/nf_tproxy_core.c +0 -48
54 lines not on this page · raw message
Signature · 1 line
1.6.0.4
PATCH 3/11 TProxy: reuse a 32bit hole in struct ipv6_pinfo
In reply to Balazs ScheidlerWhile looking for a place to add a new bitfield in ipv6_pinfo, I've found a 32 bit hole (in 64 bit mode) at the beginning of the struct. Since dst_cookie is used in the output fastpath, I've moved this field to fill the hole, thus decreasing the struct size on 64 bit platforms by 4 bytes.
On 32 bit platforms the struct size doesn't change.
--- include/linux/ipv6.h | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
include/linux/ipv6.h +1 -2
@@ -285,6 +285,7 @@ struct ipv6_pinfo {struct in6_addr saddr;struct in6_addr rcv_saddr;struct in6_addr daddr; +__u32 dst_cookie;struct in6_pktinfo sticky_pktinfo;struct in6_addr *daddr_cache;#ifdef CONFIG_IPV6_SUBTREES
@@ -348,8 +349,6 @@ struct ipv6_pinfo {*/ __u8 tclass; -__u32 dst_cookie; -struct ipv6_mc_socklist *ipv6_mc_list;struct ipv6_ac_socklist *ipv6_ac_list;struct ipv6_fl_socklist *ipv6_fl_list;
Signature · 1 line
1.6.0.4
Re: [PATCH 03/11] TProxy: reuse a 32bit hole in struct ipv6_pinfo
Quoted 5 lines · Balazs Scheidler
While looking for a place to add a new bitfield in
ipv6_pinfo, I've found a 32 bit hole (in 64 bit mode) at the beginning of the struct. Sincedst_cookieis used in the output fastpath, I've moved this field to fill the hole, thus decreasing the struct size on 64 bit platforms by 4 bytes.
Hm? I do not see a size reduction. pahole(1) tells me [for a base of v2.6.31-rc1-103-g644fc2c] the size is the same before and after.
p.2 renamed from p.1 +5 -5
@@ -21824,10 +21824,8 @@ struct ipv6_pinfo { struct in6_addr saddr; /* 0 16 */ struct in6_addr rcv_saddr; /* 16 16 */ struct in6_addr daddr; /* 32 16 */ - struct in6_pktinfo sticky_pktinfo; /* 48 20 */ - - /* XXX 4 bytes hole, try to pack */ - + __u32 dst_cookie; /* 48 4 */ + struct in6_pktinfo sticky_pktinfo; /* 52 20 */ /* --- cacheline 1 boundary (64 bytes) was 8 bytes ago --- */ struct in6_addr * daddr_cache; /* 72 8 */ struct in6_addr * saddr_cache; /* 80 8 */
@@ -21862,7 +21860,9 @@ struct ipv6_pinfo { __u8 ipv6only:1; /* 106: 3 1 */ __u8 srcprefs:3; /* 106: 0 1 */ __u8 tclass; /* 107 1 */ - __u32 dst_cookie; /* 108 4 */ + + /* XXX 4 bytes hole, try to pack */ + struct ipv6_mc_socklist * ipv6_mc_list; /* 112 8 */ struct ipv6_ac_socklist * ipv6_ac_list; /* 120 8 */ /* --- cacheline 2 boundary (128 bytes) --- */
Re: [PATCH 03/11] TProxy: reuse a 32bit hole in struct ipv6_pinfo
Quoted 10 lines · Jan Engelhardt
Quoted 5 lines · Balazs Scheidler
While looking for a place to add a new bitfield in
ipv6_pinfo, I've found a 32 bit hole (in 64 bit mode) at the beginning of the struct. Sincedst_cookieis used in the output fastpath, I've moved this field to fill the hole, thus decreasing the struct size on 64 bit platforms by 4 bytes.Hm? I do not see a size reduction. pahole(1) tells me [for a base of v2.6.31-rc1-103-g644fc2c] the size is the same before and after.
you are right. I was inserting another bitfield and with that the size didn't grow. at the end the bitfield wasn't needed, but I still felt that dst_cookie should be moved to the first cacheline. it is used in the output fastpath.
However since that's not necessarily worth in itself I can completely drop this patch.
An updated version follows.
By the way, what should be the proper procedure for posting patches that are tproxy specific but touch the core networking code? Should those go through Patrick, or should I just post them to netdev? Or just cross-post the patch series to both lists?
commit 5ddc846b926be02c6cab93406d6e8adb1e3c9124
Author: Balazs Scheidler <[email protected]> Date: Sun Aug 30 08:52:01 2009 +0200
TProxy: move dst_cookie to the first cacheline in ipv6_pinfo
While looking for a place to add a new bitfield in ipv6_pinfo, I've found a 32 bit hole (in 64 bit mode) at the beginning of the struct. Since dst_cookie is used in the output fastpath, I've moved this field to fill the hole. The original place of dst_cookie is now empty, but can become a place to add further fields to the struct.
include/linux/ipv6.h +2 -1
@@ -285,6 +285,7 @@ struct ipv6_pinfo {struct in6_addr saddr;struct in6_addr rcv_saddr;struct in6_addr daddr; +__u32 dst_cookie;struct in6_pktinfo sticky_pktinfo;struct in6_addr *daddr_cache;#ifdef CONFIG_IPV6_SUBTREES
@@ -348,7 +349,7 @@ struct ipv6_pinfo {*/ __u8 tclass; -__u32 dst_cookie; +/* 32 bits hole on 64 bit platforms */ struct ipv6_mc_socklist *ipv6_mc_list;struct ipv6_ac_socklist *ipv6_ac_list;
Quoted 29 lines
p.2 renamed from p.1 +5
-5@@ -21824,10 +21824,8 @@ struct ipv6_pinfo { struct in6_addr saddr; /* 0 16 */ struct in6_addr rcv_saddr; /* 16 16 */ struct in6_addr daddr; /* 32 16 */ - struct in6_pktinfo sticky_pktinfo; /* 48 20 */ - - /* XXX 4 bytes hole, try to pack */ - + __u32 dst_cookie; /* 48 4 */ + struct in6_pktinfo sticky_pktinfo; /* 52 20 */ /* --- cacheline 1 boundary (64 bytes) was 8 bytes ago --- */ struct in6_addr * daddr_cache; /* 72 8 */ struct in6_addr * saddr_cache; /* 80 8 */@@ -21862,7 +21860,9 @@ struct ipv6_pinfo { __u8 ipv6only:1; /* 106: 3 1 */ __u8 srcprefs:3; /* 106: 0 1 */ __u8 tclass; /* 107 1 */ - __u32 dst_cookie; /* 108 4 */ + + /* XXX 4 bytes hole, try to pack */ + struct ipv6_mc_socklist * ipv6_mc_list; /* 112 8 */ struct ipv6_ac_socklist * ipv6_ac_list; /* 120 8 */ /* --- cacheline 2 boundary (128 bytes) --- */
Signature · 1 line
Bazsi
Re: [PATCH 03/11] TProxy: reuse a 32bit hole in struct ipv6_pinfo
Quoted 5 lines · Balazs Scheidler
By the way, what should be the proper procedure for posting patches that are tproxy specific but touch the core networking code? Should those go through Patrick, or should I just post them to netdev? Or just cross-post the patch series to both lists?
Depends on whether you are trying to get attention on a patch or whether you go for sneaky inclusion ;-)
Re: [PATCH 03/11] TProxy: reuse a 32bit hole in struct ipv6_pinfo
In reply to Balazs ScheidlerQuoted 4 lines · Balazs Scheidler
By the way, what should be the proper procedure for posting patches that are tproxy specific but touch the core networking code? Should those go through Patrick, or should I just post them to netdev? Or just cross-post the patch series to both lists?
When further netfilter patches depend on those changes, they should probably go through me, but you should CC netdev and the maintainers of the code in question.
PATCH 4/11 TProxy: split off ipv6 defragmentation to a separate module
In reply to Balazs ScheidlerLike with IPv4, TProxy needs IP defragmentation but does not require connection tracking. Since defragmentation was coupled with conntrack, I split off the two, creating an nf_defrag_ipv6 module, similar to the already existing nf_defrag_ipv4.
--- include/net/netfilter/ipv6/nf_defrag_ipv6.h | 6 ++ net/ipv6/netfilter/Makefile | 5 +- net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 58 +------------ net/ipv6/netfilter/nf_conntrack_reasm.c | 12 ++- net/ipv6/netfilter/nf_defrag_ipv6_hooks.c | 109 ++++++++++++++++++++++++ 5 files changed, 131 insertions(+), 59 deletions(-) create mode 100644 include/net/netfilter/ipv6/nf_defrag_ipv6.h create mode 100644 net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
include/net/netfilter/ipv6/nf_defrag_ipv6.h new file +6 -0
@@ -0,0 +1,6 @@ +#ifndef _NF_DEFRAG_IPV6_H +#define _NF_DEFRAG_IPV6_H + +extern void nf_defrag_ipv6_enable (void ); + +#endif /* _NF_DEFRAG_IPV6_H */
net/ipv6/netfilter/Makefile +3 -2
@@ -11,10 +11,11 @@ obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o # objects for l3 independent conntrack -nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o +nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o +nf_defrag_ipv6-objs := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o # l3 independent conntrack -obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o +obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o nf_defrag_ipv6.o # matches obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +3 -55
110 lines not on this page · raw message
net/ipv6/netfilter/nf_conntrack_reasm.c +10 -2
@@ -73,8 +73,8 @@ struct nf_ct_frag6_queuestatic struct inet_frags nf_frags;static struct netns_frags nf_init_frags; -#ifdef CONFIG_SYSCTL -struct ctl_table nf_ct_ipv6_sysctl_table[] = { +#if defined(CONFIG_SYSCTL) +struct ctl_table nf_ct_frag6_sysctl_table[] = { { .procname = "nf_conntrack_frag6_timeout", .data = &nf_init_frags.timeout,
@@ -100,6 +100,8 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = { }, { .ctl_name = 0 } }; + +static struct ctl_table_header *nf_ct_frag6_sysctl_header =NULL ;#endif static unsigned int nf_hashfn (struct inet_frag_queue *q)
@@ -675,11 +677,17 @@ int nf_ct_frag6_init(void)inet_frags_init_net (&nf_init_frags);inet_frags_init (&nf_frags); +if (!(nf_ct_frag6_sysctl_header =register_sysctl_paths (nf_net_netfilter_sysctl_path, nf_ct_frag6_sysctl_table))) { +return -ENOMEM ; + }return 0 ; }void nf_ct_frag6_cleanup (void ) { +unregister_sysctl_table (nf_ct_frag6_sysctl_header); + nf_ct_frag6_sysctl_header =NULL ; +inet_frags_fini (&nf_frags); nf_init_frags.low_thresh =0 ;
net/ipv6/netfilter/nf_defrag_ipv6_hooks.c new file +109 -0
109 lines not on this page · raw message
Signature · 1 line
1.6.0.4
PATCH 5/11 TProxy: added const specifiers to udp lookup functions
In reply to Balazs ScheidlerThe parameters for various UDP lookup functions were non-const, even though they could be const. TProxy has some const references and instead of downcasting it, I added const specifiers along the path.
--- net/ipv6/udp.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)
net/ipv6/udp.c +4 -4
@@ -88,8 +88,8 @@ int udp_v6_get_port(struct sock *sk, unsigned short snum)static inline int compute_score (struct sock *sk,struct net *net,unsigned short hnum, -struct in6_addr *saddr,__be16 sport, -struct in6_addr *daddr,__be16 dport, +const struct in6_addr *saddr,__be16 sport, +const struct in6_addr *daddr,__be16 dport,int dif) {int score =-1 ;
@@ -125,8 +125,8 @@ static inline int compute_score(struct sock *sk, struct net *net, }static struct sock *__udp6_lib_lookup (struct net *net, -struct in6_addr *saddr,__be16 sport, -struct in6_addr *daddr,__be16 dport, +const struct in6_addr *saddr,__be16 sport, +const struct in6_addr *daddr,__be16 dport,int dif,struct udp_table *udptable) {struct sock *sk, *result;
Signature · 1 line
1.6.0.4
PATCH 6/11 TProxy: added udp6_lib_lookup function
In reply to Balazs ScheidlerJust like with IPv4, we need access to the UDP hash table to look up local sockets, but instead of exporting the global udp_table, export a lookup function.
--- include/net/udp.h | 3 +++ net/ipv6/udp.c | 8 ++++++++ 2 files changed, 11 insertions(+), 0 deletions(-)
include/net/udp.h +3 -0
@@ -150,6 +150,9 @@ extern int udp_lib_setsockopt(struct sock *sk, int level, int optname,extern struct sock *udp4_lib_lookup (struct net *net,__be32 saddr,__be16 sport,__be32 daddr,__be16 dport,int dif); +extern struct sock *udp6_lib_lookup (struct net *net,const struct in6_addr *saddr,__be16 sport, +const struct in6_addr *daddr,__be16 dport, +int dif);/* * SNMP statistics for UDP and UDP-Lite
net/ipv6/udp.c +8 -0
@@ -182,6 +182,14 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb, udptable); } +struct sock *udp6_lib_lookup (struct net *net,const struct in6_addr *saddr,__be16 sport, +const struct in6_addr *daddr,__be16 dport,int dif) +{ +return __udp6_lib_lookup (net, saddr, sport, daddr, dport, dif, &udp_table); +} +EXPORT_SYMBOL_GPL (udp6_lib_lookup); + +/* * This should be easy, if there is something there we * return it, otherwise we block.
Signature · 1 line
1.6.0.4
PATCH 7/11 TProxy: implement IPv6 "local" routing type
In reply to Balazs ScheidlerIPv4 policy routing (and the ip command) allows to add a routing rule with 'local' type, however this did not work with IPv6. This patch implements the 'local' routing type by redirecting all such packets to the local IP stack.
--- net/ipv6/route.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)
net/ipv6/route.c +5 -1
@@ -1174,6 +1174,8 @@ int ip6_route_add(struct fib6_config *cfg)if (addr_type &IPV6_ADDR_MULTICAST ) rt->u.dst.input = ip6_mc_input; +else if (cfg->fc_flags &RTF_LOCAL ) + rt->u.dst.input = ip6_input;else rt->u.dst.input = ip6_forward;
@@ -1195,7 +1197,7 @@ int ip6_route_add(struct fib6_config *cfg)they would result in kernel looping; promote them to reject routes */ if ((cfg->fc_flags &RTF_REJECT ) || - (dev && (dev->flags&IFF_LOOPBACK ) && !(addr_type&IPV6_ADDR_LOOPBACK ))) { + (((cfg->fc_flags &RTF_LOCAL ) ==0 ) && (dev && (dev->flags&IFF_LOOPBACK ) && !(addr_type&IPV6_ADDR_LOOPBACK )))) {/* hold loopback dev/idev if we haven't done so. */ if (dev != net->loopback_dev) {if (dev) {
@@ -2086,6 +2088,8 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,if (rtm->rtm_type ==RTN_UNREACHABLE ) cfg->fc_flags |=RTF_REJECT ; +else if (rtm->rtm_type ==RTN_LOCAL ) + cfg->fc_flags |=RTF_LOCAL ; cfg->fc_nlinfo.pid =NETLINK_CB (skb).pid; cfg->fc_nlinfo.nlh = nlh;
Signature · 1 line
1.6.0.4
PATCH 8/11 TProxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is enabled
In reply to Balazs Scheidler--- net/ipv6/af_inet6.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
net/ipv6/af_inet6.c +1 -1
@@ -338,7 +338,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)*/ v4addr =LOOPBACK4_IPV6 ;if (!(addr_type &IPV6_ADDR_MULTICAST )) { -if (!ipv6_chk_addr (net, &addr->sin6_addr, +if (!inet->transparent && !ipv6_chk_addr (net, &addr->sin6_addr, dev,0 )) {if (dev)dev_put (dev);
Signature · 1 line
1.6.0.4
PATCH 9/11 TProxy: added IPv6 socket lookup function to nf_tproxy_core
In reply to Balazs Scheidler--- include/net/netfilter/nf_tproxy_core.h | 72 +++++++++++++++++++++++++++++++- 1 files changed, 71 insertions(+), 1 deletions(-)
include/net/netfilter/nf_tproxy_core.h +71 -1
@@ -5,7 +5,8 @@#include <linux/in.h> #include <linux/skbuff.h> #include <net/sock.h> -#include <net/inet_sock.h> +#include <net/inet_hashtables.h> +#include <net/inet6_hashtables.h> #include <net/tcp.h> #define NFT_LOOKUP_ANY 0
@@ -130,6 +131,75 @@ nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,return sk; } +#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE ) +static inline struct sock * +nf_tproxy_get_sock_v6 (struct net *net,const u8 protocol, +const struct in6_addr *saddr,const struct in6_addr *daddr, +const __be16 sport,const __be16 dport, +const struct net_device *in,int lookup_type) +{ +struct sock *sk; + +/* look up socket */ +switch (protocol) { +case IPPROTO_TCP : +switch (lookup_type) { +case NFT_LOOKUP_ANY : + sk =inet6_lookup (net, &tcp_hashinfo, + saddr, sport, daddr, dport, + in->ifindex); +break ; +case NFT_LOOKUP_LISTENER : + sk =inet6_lookup_listener (net, &tcp_hashinfo, + daddr,ntohs (dport), + in->ifindex); + +/* NOTE: we return listeners even if bound to +* 0.0.0.0, those are filtered out in +* xt_socket, since xt_TPROXY needs 0 bound +* listeners too */ + +break ; +case NFT_LOOKUP_ESTABLISHED : + sk =__inet6_lookup_established (net, &tcp_hashinfo, + saddr, sport, daddr,ntohs (dport), + in->ifindex); +break ; +default : +WARN_ON (1 ); + sk =NULL ; +break ; + } +break ; +case IPPROTO_UDP : + sk =udp6_lib_lookup (net, saddr, sport, daddr, dport, + in->ifindex); +if (sk && lookup_type !=NFT_LOOKUP_ANY ) { +int connected = (sk->sk_state ==TCP_ESTABLISHED ); +int wildcard =ipv6_addr_any (&inet6_sk (sk)->rcv_saddr); + +/* NOTE: we return listeners even if bound to +* 0.0.0.0, those are filtered out in +* xt_socket, since xt_TPROXY needs 0 bound +* listeners too */ +if ((lookup_type ==NFT_LOOKUP_ESTABLISHED && (!connected || wildcard)) || + (lookup_type ==NFT_LOOKUP_LISTENER && connected)) { +sock_put (sk); + sk =NULL ; + } + } +break ; +default : +WARN_ON (1 ); + sk =NULL ; + } + +pr_debug ("tproxy socket lookup: proto %u %pI6:%u -> %pI6:%u, lookup type: %d, sock %p\n" , + protocol, saddr,ntohs (sport), daddr,ntohs (dport), lookup_type, sk); + +return sk; +} +#endif static inline void nf_tproxy_put_sock (struct sock *sk)
Signature · 1 line
1.6.0.4
PATCH 10/11 TProxy: added IPv6 support to the TPROXY target
In reply to Balazs ScheidlerThis requires a new revision as the old target structure was IPv4 specific.
--- include/linux/netfilter/xt_TPROXY.h | 15 ++- net/netfilter/xt_TPROXY.c | 248 +++++++++++++++++++++++++++++------ 2 files changed, 218 insertions(+), 45 deletions(-)
include/linux/netfilter/xt_TPROXY.h +11 -4
@@ -1,14 +1,21 @@ -#ifndef _XT_TPROXY_H_target -#define _XT_TPROXY_H_target +#ifndef _XT_TPROXY_H +#define _XT_TPROXY_H/* TPROXY target is capable of marking the packet to perform * redirection. We can get rid of that whenever we get support for * mutliple targets in the same rule. */ -struct xt_tproxy_target_info { +struct xt_tproxy_target_info_v0 {u_int32_t mark_mask;u_int32_t mark_value;__be32 laddr;__be16 lport; }; -#endif /* _XT_TPROXY_H_target */ +struct xt_tproxy_target_info_v1 { +u_int32_t mark_mask; +u_int32_t mark_value; +union nf_inet_addr laddr; +__be16 lport; +}; + +#endif /* _XT_TPROXY_H */
net/netfilter/xt_TPROXY.c +207 -41
319 lines not on this page · raw message
Signature · 1 line
1.6.0.4
PATCH 11/11 TProxy: added IPv6 support to the socket match
In reply to Balazs Scheidler--- net/netfilter/xt_socket.c | 111 ++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 105 insertions(+), 6 deletions(-)
net/netfilter/xt_socket.c +105 -6
@@ -14,6 +14,7 @@#include <linux/skbuff.h> #include <linux/netfilter/x_tables.h> #include <linux/netfilter_ipv4/ip_tables.h> +#include <linux/netfilter_ipv6/ip6_tables.h> #include <net/tcp.h> #include <net/udp.h> #include <net/icmp.h>
@@ -21,6 +22,7 @@#include <net/inet_sock.h> #include <net/netfilter/nf_tproxy_core.h> #include <net/netfilter/ipv4/nf_defrag_ipv4.h> +#include <net/netfilter/ipv6/nf_defrag_ipv6.h> #include <linux/netfilter/xt_socket.h>
@@ -30,7 +32,7 @@#endif static int -extract_icmp_fields(const struct sk_buff *skb, +extract_icmp4_fields(const struct sk_buff *skb, u8 *protocol, __be32 *raddr, __be32 *laddr,
@@ -115,7 +117,7 @@ socket_match(const struct sk_buff *skb, const struct xt_match_param *par, dport = hp->dest; }else if (iph->protocol ==IPPROTO_ICMP ) { -if (extract_icmp_fields (skb, &protocol, &saddr, &daddr, +if (extract_icmp4_fields (skb, &protocol, &saddr, &daddr, &sport, &dport))return false; }else {
@@ -175,23 +177,107 @@ socket_match(const struct sk_buff *skb, const struct xt_match_param *par, }static bool -socket_mt_v0 (const struct sk_buff *skb,const struct xt_match_param *par) +socket_mt4_v0 (const struct sk_buff *skb,const struct xt_match_param *par) {return socket_match (skb, par,NULL ); }static bool -socket_mt_v1 (const struct sk_buff *skb,const struct xt_match_param *par) +socket_mt4_v1 (const struct sk_buff *skb,const struct xt_match_param *par) {return socket_match (skb, par, par->matchinfo); } +#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE ) + +static int +extract_icmp6_fields (const struct sk_buff *skb, +u8 *protocol, +struct in6_addr **raddr, +struct in6_addr **laddr, +__be16 *rport, +__be16 *lport) +{ +return 1 ; +} + +static bool +socket_mt6_v1 (const struct sk_buff *skb,const struct xt_match_param *par) +{ +struct ipv6hdr *iph =ipv6_hdr (skb); +struct udphdr _hdr, *hp =NULL ; +struct sock *sk; +struct in6_addr *daddr, *saddr; +__be16 dport, sport; +int thoff; +u8 tproto; +const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo; + + tproto =ipv6_find_hdr (skb, &thoff,-1 ,NULL ); +if (tproto <0 ) { +pr_debug ("socket match: Unable to find transport header in IPv6 packet, dropping\n" ); +return NF_DROP ; + } + +if (tproto ==IPPROTO_UDP || tproto ==IPPROTO_TCP ) { + hp =skb_header_pointer (skb, thoff, +sizeof (_hdr), &_hdr); +if (hp ==NULL ) +return false; + + saddr = &iph->saddr; + sport = hp->source; + daddr = &iph->daddr; + dport = hp->dest; + + }else if (tproto ==IPPROTO_ICMP ) { +if (extract_icmp6_fields (skb, &tproto, &saddr, &daddr, + &sport, &dport)) +return false; + }else { +return false; + } + + sk =nf_tproxy_get_sock_v6 (dev_net (skb->dev), tproto, + saddr, daddr, sport, dport, par->in,NFT_LOOKUP_ANY ); +if (sk !=NULL ) { +bool wildcard; +bool transparent = true; + +/* Ignore sockets listening on INADDR_ANY */ + wildcard = (sk->sk_state !=TCP_TIME_WAIT && +ipv6_addr_any (&inet6_sk (sk)->rcv_saddr)); + +/* Ignore non-transparent sockets, +if XT_SOCKET_TRANSPARENT is used */ +if (info && info->flags &XT_SOCKET_TRANSPARENT ) + transparent = ((sk->sk_state !=TCP_TIME_WAIT && +inet_sk (sk)->transparent) || + (sk->sk_state ==TCP_TIME_WAIT && +inet_twsk (sk)->tw_transparent)); + +nf_tproxy_put_sock (sk); + +if (wildcard || !transparent) + sk =NULL ; + } + +pr_debug ("socket match: proto %u %pI6:%u -> %pI6:%u " +"(orig %pI6:%u) sock %p\n" , + tproto, saddr,ntohs (sport), + daddr,ntohs (dport), + &iph->daddr, hp ?ntohs (hp->dest) :0 , sk); + +return (sk !=NULL ); +} +#endif +static struct xt_match socket_mt_reg[]__read_mostly = { { .name ="socket" , .revision =0 , .family =NFPROTO_IPV4 , - .match = socket_mt_v0, + .match = socket_mt4_v0, .hooks =1 <<NF_INET_PRE_ROUTING , .me =THIS_MODULE , },
@@ -199,16 +285,28 @@ static struct xt_match socket_mt_reg[] __read_mostly = { .name = "socket", .revision = 1, .family = NFPROTO_IPV4, - .match = socket_mt_v1, + .match = socket_mt4_v1, + .matchsize = sizeof(struct xt_socket_mtinfo1), + .hooks = 1 << NF_INET_PRE_ROUTING, + .me = THIS_MODULE, + }, +#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE ) + { + .name = "socket", + .revision = 1, + .family = NFPROTO_IPV6, + .match = socket_mt6_v1, .matchsize = sizeof(struct xt_socket_mtinfo1), .hooks = 1 << NF_INET_PRE_ROUTING, .me = THIS_MODULE, }, +#endif };static int __init socket_mt_init (void ) {nf_defrag_ipv4_enable (); +nf_defrag_ipv6_enable ();return xt_register_matches (socket_mt_reg,ARRAY_SIZE (socket_mt_reg)); }
@@ -224,3 +322,4 @@ MODULE_LICENSE("GPL");MODULE_AUTHOR ("Krisztian Kovacs, Balazs Scheidler" );MODULE_DESCRIPTION ("x_tables socket match module" );MODULE_ALIAS ("ipt_socket" ); +MODULE_ALIAS ("ip6t_socket" );
Signature · 1 line
1.6.0.4
Quoted 31 lines · Balazs Scheidler
[ Sorry if this reaches you twice, I sent to the wrong address the first time ]
I've just pushed a set of patches that implement TProxy for IPv6 to
http://git.balabit.hu/bazsi/tproxy-2.6.git
The patches are also posted in reply to this mail.
Although some work is still needed, basic testing shows that it works all right.
The accompanying iptables patches are available at
http://git.balabit.hu/bazsi/iptables-tproxy.git
There are some things left to do:
* the recognition of related ICMPv6 packets missing (from
xt_socket.c)* I should probably split xt_TPROXY/xt_socket to IPv4 and IPv6 modules, as right now those depend on both stacks at the same time.
I'm on a holiday right now, thus I might not respond to comments in a timely manner, however I'm interested in any comments/feedback nevertheless.
Harry, I didn't remember that you actually wanted to work on TProxy for IPv6, I just vaguely remembered that there was someone asking for IPv6 support, thus I implemented this without being in the know. If you started hacking, I hope that we didn't completely duplicate effort. I'd appreciate help in the missing bits and/or testing whichever fits you best.
Quoted 3 lines
Also, I have written a Python test script to test TProxy functionality automatically both for IPv4 and IPv6, I can post that as well if anyone is interested.
I'm interested :)
Now that you have done this I'm going to have to find a robust userland run-time test to see if the underlying TPROXY is v4-only or v6-enabled. If anyone has suggestions they would be welcome.
Thank you very much by the way.
Amos Jeffries
Squid Proxy Project
Quoted 10 lines · Amos Jeffries
Quoted 4 lines
Also, I have written a Python test script to test TProxy functionality automatically both for IPv4 and IPv6, I can post that as well if anyone is interested.
I'm interested :)
Now that you have done this I'm going to have to find a robust userland run-time test to see if the underlying TPROXY is v4-only or v6-enabled. If anyone has suggestions they would be welcome.
Would this perhaps suffice?
assert(socket(PF_INET6, ...) >= 0); assert(setsockopt(fd, SOL_IP, IP_TRANSPARENT, ...) == 0); assert(bind(fd, {::2}) == 0);
At least something like that I remember to have used to determine tproxy-2.x ipv4 availability in the days. (I.e. seeing if setsockopt failed.)
Quoted 12 lines · Jan Engelhardt
Quoted 8 lines · Amos Jeffries
Quoted 3 lines
Also, I have written a Python test script to test TProxy functionality automatically both for IPv4 and IPv6, I can post that as well if anyone is interested.
I'm interested :)
Now that you have done this I'm going to have to find a robust userland run-time test to see if the underlying TPROXY is v4-only or v6-enabled. If anyone has suggestions they would be welcome.
Would this perhaps suffice?
Quoted 7 lines
assert(socket(PF_INET6, ...) >= 0);assert(setsockopt(fd, SOL_IP, IP_TRANSPARENT, ...) == 0);assert(bind(fd, {::2}) == 0);At least something like that I remember to have used to determine tproxy-2.x ipv4 availability in the days. (I.e. seeing if setsockopt failed.)
Thanks Jan. I gave a variant that a try. It does seem to detect the feature support nicely.
However, trying to bind the real IP:port soon after results in "(98) Address already in use" even with a shutdown(tmp_sock,...) added to clean up after the test.
AYJ
Quoted 8 lines · Amos Jeffries
Quoted 7 lines
assert(socket(PF_INET6, ...) >= 0);assert(setsockopt(fd, SOL_IP, IP_TRANSPARENT, ...) == 0);assert(bind(fd, {::2}) == 0);At least something like that I remember to have used to determine tproxy-2.x ipv4 availability in the days. (I.e. seeing if setsockopt failed.)
Quoted 6 lines
Thanks Jan. I gave a variant that a try. It does seem to detect the feature support nicely.
However, trying to bind the real IP:port soon after results in "(98) Address already in use" even with a
shutdown(tmp_sock,...)added to clean up after the test.
Odd, since binding to port 0 should give you a random one, and there are plenty.
Does SO_REUSEADDR help it a bit?
Quoted 11 lines · Jan Engelhardt
Quoted 10 lines · Amos Jeffries
Quoted 7 lines
assert(socket(PF_INET6, ...) >= 0);assert(setsockopt(fd, SOL_IP, IP_TRANSPARENT, ...) == 0);assert(bind(fd, {::2}) == 0);At least something like that I remember to have used to determine tproxy-2.x ipv4 availability in the days. (I.e. seeing if setsockopt failed.)
Thanks Jan. I gave a variant that a try. It does seem to detect the feature support nicely.
Quoted 7 lines
Quoted 3 lines
However, trying to bind the real IP:port soon after results in "(98) Address already in use" even with a
shutdown(tmp_sock,...)added to clean up after the test.Odd, since binding to port 0 should give you a random one, and there are plenty.
DoesSO_REUSEADDRhelp it a bit?
um... thanks for the hint.
I was re-using a handy address object without un-setting the port. It works fully now.
AYJ
Quoted 36 lines · Amos Jeffries
Quoted 31 lines · Balazs Scheidler
[ Sorry if this reaches you twice, I sent to the wrong address the first time ]
I've just pushed a set of patches that implement TProxy for IPv6 to
http://git.balabit.hu/bazsi/tproxy-2.6.git
The patches are also posted in reply to this mail.
Although some work is still needed, basic testing shows that it works all right.
The accompanying iptables patches are available at
http://git.balabit.hu/bazsi/iptables-tproxy.git
There are some things left to do:
* the recognition of related ICMPv6 packets missing (from
xt_socket.c)* I should probably split xt_TPROXY/xt_socket to IPv4 and IPv6 modules, as right now those depend on both stacks at the same time.
I'm on a holiday right now, thus I might not respond to comments in a timely manner, however I'm interested in any comments/feedback nevertheless.
Harry, I didn't remember that you actually wanted to work on TProxy for IPv6, I just vaguely remembered that there was someone asking for IPv6 support, thus I implemented this without being in the know. If you started hacking, I hope that we didn't completely duplicate effort. I'd appreciate help in the missing bits and/or testing whichever fits you best.
Quoted 3 lines
Also, I have written a Python test script to test TProxy functionality automatically both for IPv4 and IPv6, I can post that as well if anyone is interested.
Quoted 7 lines
I'm interested :)
Now that you have done this I'm going to have to find a robust userland run-time test to see if the underlying TPROXY is v4-only or v6-enabled. If anyone has suggestions they would be welcome.
Thank you very much by the way.
The script I wrote is not a runtime test, it is a functional test that tests various TPROXY scenarios for proper functionality.
It basically assumes that:
1) you run it on the 'client' host, and it has ssh connectivity to the
'tproxy' host
2) it assumes that IP/route configuration is already prepared
3) it uses hardwired IP addresses, but generates iptables/ip6tables
rules automatically
I used a virtual machine running on my development computer to do the testing.
IPV6 topology:
dead:1::1/64 is the client
dead:1::2/64 is the proxy box
dead:2::1/64 is the server behind the proxy box
The script basically copies an agent script to the other box (test-agent.py) and uses that to change iptables config/start listeners as needed. Then initiates tcp/udp connections to the target host and checks if the proper listener received the new connection or a bogus one.
I'm not that responsive these days, but I'm glad to help.
Last but not least, here's the gitweb interface:
http://git.balabit.hu/?p=bazsi/tproxy-test.git;a=summary
and the git URL
git://git.balabit.hu/bazsi/tproxy-test.git
Signature · 1 line
Bazsi
Quoted 69 lines · Balazs Scheidler
Quoted 32 lines · Amos Jeffries
Quoted 31 lines · Balazs Scheidler
[ Sorry if this reaches you twice, I sent to the wrong address the first time ]
I've just pushed a set of patches that implement TProxy for IPv6 to
http://git.balabit.hu/bazsi/tproxy-2.6.git
The patches are also posted in reply to this mail.
Although some work is still needed, basic testing shows that it works all right.
The accompanying iptables patches are available at
http://git.balabit.hu/bazsi/iptables-tproxy.git
There are some things left to do:
* the recognition of related ICMPv6 packets missing (from
xt_socket.c)* I should probably split xt_TPROXY/xt_socket to IPv4 and IPv6 modules, as right now those depend on both stacks at the same time.
I'm on a holiday right now, thus I might not respond to comments in a timely manner, however I'm interested in any comments/feedback nevertheless.
Harry, I didn't remember that you actually wanted to work on TProxy for IPv6, I just vaguely remembered that there was someone asking for IPv6 support, thus I implemented this without being in the know. If you started hacking, I hope that we didn't completely duplicate effort. I'd appreciate help in the missing bits and/or testing whichever fits you best.
Quoted 8 lines
Quoted 3 lines
Also, I have written a Python test script to test TProxy functionality automatically both for IPv4 and IPv6, I can post that as well if anyone is interested.
I'm interested :)
Now that you have done this I'm going to have to find a robust userland run-time test to see if the underlying TPROXY is v4-only or v6-enabled. If anyone has suggestions they would be welcome.
Thank you very much by the way.
The script I wrote is not a runtime test, it is a functional test that tests various TPROXY scenarios for proper functionality.
It basically assumes that:
1) you run it on the 'client' host, and it has ssh connectivity to the
'tproxy' host
2) it assumes that IP/route configuration is already prepared
3) it uses hardwired IP addresses, but generates iptables/ip6tables
rules automaticallyI used a virtual machine running on my development computer to do the testing.
IPV6 topology:
dead:1::1/64 is the client
dead:1::2/64 is the proxy box
dead:2::1/64 is the server behind the proxy boxThe script basically copies an agent script to the other box (
test-agent.py) and uses that to change iptables config/start listeners as needed. Then initiates tcp/udp connections to the target host and checks if the proper listener received the new connection or a bogus one.I'm not that responsive these days, but I'm glad to help.
Quoted 8 lines
Last but not least, here's the gitweb interface:
http://git.balabit.hu/?p=bazsi/tproxy-test.git;a=summary
and the git URL
git://git.balabit.hu/bazsi/tproxy-test.git
I thought is was something like that. Thanks.
This is going to be helpful testing the various distro packages to see whats they have turned on/off. The newest FAQ for our users.
AYJ
A message that is not in the archive (sent off-list or not yet received): 1252059564.7452.17.camel@nyarlathotep
A message that is not in the archive (sent off-list or not yet received): [email protected]
Hi,
This is just a short note that I've updated the git repository and added your patches to the tree (the UDP and ICMP related bits), although I haven't had time to write proper changelogs and integrate related patches to one, I figured it's better to say I did so instead of waiting for code to rot in the git repo.
I hope I get another shot to do a formal release in the coming days.
Quoted 26 lines · Balazs Scheidler
Quoted 16 lines · Harry Mason
Quoted 10 lines · Amos Jeffries
Quoted 3 lines · Balazs Scheidler
I've just pushed a set of patches that implement TProxy for IPv6 to
I'm interested :)
Amos Jeffries
Squid Proxy ProjectIn TProxy for IPv4 there's support for the
SO_ORIGINAL_DSTsockopt, which returns the original destination of the request. I needed this option in my prototype to do TRT but I assume Squid will need it too for transparent proxying.Quoted 5 lines
I've ported this feature to Balazs's implementation; Git bundle attached.
Balazs, does this look OK to be merged with your patches?
Amos, this might help you test Squid with IPv6; hopefully the API I chose won't need to change but I'm very new to kernel development.I'll check what I could pick from this and your previous bundle (which as I see was only sent in private) and push another round of patches.
Signature · 1 line
Bazsi