Commit 3b9afb29 authored by Balazs Scheidler's avatar Balazs Scheidler Committed by Patrick McHardy

tproxy: added IPv6 socket lookup function to nf_tproxy_core

Signed-off-by: default avatarBalazs Scheidler <bazsi@balabit.hu>
Signed-off-by: default avatarKOVACS Krisztian <hidden@balabit.hu>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent 0a513f6a
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
#include <linux/in.h> #include <linux/in.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/inet_sock.h> #include <net/inet_hashtables.h>
#include <net/inet6_hashtables.h>
#include <net/tcp.h> #include <net/tcp.h>
#define NFT_LOOKUP_ANY 0 #define NFT_LOOKUP_ANY 0
...@@ -130,6 +131,75 @@ nf_tproxy_get_sock_v4(struct net *net, const u8 protocol, ...@@ -130,6 +131,75 @@ nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
return sk; 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 static inline void
nf_tproxy_put_sock(struct sock *sk) nf_tproxy_put_sock(struct sock *sk)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment