diff options
author | Balazs Scheidler <bazsi@balabit.hu> | 2010-10-21 10:12:14 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-10-21 10:12:14 -0400 |
commit | 3b9afb29917f4ab08decf358ecfd354a72a91ac0 (patch) | |
tree | fbc5b5d684ddb8ea276d93ad5890eab55001c896 | |
parent | 0a513f6af962525ed4b3395f8c8d5daae8682aa9 (diff) |
tproxy: added IPv6 socket lookup function to nf_tproxy_core
Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
Signed-off-by: KOVACS Krisztian <hidden@balabit.hu>
Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r-- | include/net/netfilter/nf_tproxy_core.h | 72 |
1 files changed, 71 insertions, 1 deletions
diff --git a/include/net/netfilter/nf_tproxy_core.h b/include/net/netfilter/nf_tproxy_core.h index 1027d7f901a0..cd85b3bc8327 100644 --- a/include/net/netfilter/nf_tproxy_core.h +++ b/include/net/netfilter/nf_tproxy_core.h | |||
@@ -5,7 +5,8 @@ | |||
5 | #include <linux/in.h> | 5 | #include <linux/in.h> |
6 | #include <linux/skbuff.h> | 6 | #include <linux/skbuff.h> |
7 | #include <net/sock.h> | 7 | #include <net/sock.h> |
8 | #include <net/inet_sock.h> | 8 | #include <net/inet_hashtables.h> |
9 | #include <net/inet6_hashtables.h> | ||
9 | #include <net/tcp.h> | 10 | #include <net/tcp.h> |
10 | 11 | ||
11 | #define NFT_LOOKUP_ANY 0 | 12 | #define NFT_LOOKUP_ANY 0 |
@@ -130,6 +131,75 @@ nf_tproxy_get_sock_v4(struct net *net, const u8 protocol, | |||
130 | return sk; | 131 | return sk; |
131 | } | 132 | } |
132 | 133 | ||
134 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
135 | static inline struct sock * | ||
136 | nf_tproxy_get_sock_v6(struct net *net, const u8 protocol, | ||
137 | const struct in6_addr *saddr, const struct in6_addr *daddr, | ||
138 | const __be16 sport, const __be16 dport, | ||
139 | const struct net_device *in, int lookup_type) | ||
140 | { | ||
141 | struct sock *sk; | ||
142 | |||
143 | /* look up socket */ | ||
144 | switch (protocol) { | ||
145 | case IPPROTO_TCP: | ||
146 | switch (lookup_type) { | ||
147 | case NFT_LOOKUP_ANY: | ||
148 | sk = inet6_lookup(net, &tcp_hashinfo, | ||
149 | saddr, sport, daddr, dport, | ||
150 | in->ifindex); | ||
151 | break; | ||
152 | case NFT_LOOKUP_LISTENER: | ||
153 | sk = inet6_lookup_listener(net, &tcp_hashinfo, | ||
154 | daddr, ntohs(dport), | ||
155 | in->ifindex); | ||
156 | |||
157 | /* NOTE: we return listeners even if bound to | ||
158 | * 0.0.0.0, those are filtered out in | ||
159 | * xt_socket, since xt_TPROXY needs 0 bound | ||
160 | * listeners too */ | ||
161 | |||
162 | break; | ||
163 | case NFT_LOOKUP_ESTABLISHED: | ||
164 | sk = __inet6_lookup_established(net, &tcp_hashinfo, | ||
165 | saddr, sport, daddr, ntohs(dport), | ||
166 | in->ifindex); | ||
167 | break; | ||
168 | default: | ||
169 | WARN_ON(1); | ||
170 | sk = NULL; | ||
171 | break; | ||
172 | } | ||
173 | break; | ||
174 | case IPPROTO_UDP: | ||
175 | sk = udp6_lib_lookup(net, saddr, sport, daddr, dport, | ||
176 | in->ifindex); | ||
177 | if (sk && lookup_type != NFT_LOOKUP_ANY) { | ||
178 | int connected = (sk->sk_state == TCP_ESTABLISHED); | ||
179 | int wildcard = ipv6_addr_any(&inet6_sk(sk)->rcv_saddr); | ||
180 | |||
181 | /* NOTE: we return listeners even if bound to | ||
182 | * 0.0.0.0, those are filtered out in | ||
183 | * xt_socket, since xt_TPROXY needs 0 bound | ||
184 | * listeners too */ | ||
185 | if ((lookup_type == NFT_LOOKUP_ESTABLISHED && (!connected || wildcard)) || | ||
186 | (lookup_type == NFT_LOOKUP_LISTENER && connected)) { | ||
187 | sock_put(sk); | ||
188 | sk = NULL; | ||
189 | } | ||
190 | } | ||
191 | break; | ||
192 | default: | ||
193 | WARN_ON(1); | ||
194 | sk = NULL; | ||
195 | } | ||
196 | |||
197 | pr_debug("tproxy socket lookup: proto %u %pI6:%u -> %pI6:%u, lookup type: %d, sock %p\n", | ||
198 | protocol, saddr, ntohs(sport), daddr, ntohs(dport), lookup_type, sk); | ||
199 | |||
200 | return sk; | ||
201 | } | ||
202 | #endif | ||
133 | 203 | ||
134 | static inline void | 204 | static inline void |
135 | nf_tproxy_put_sock(struct sock *sk) | 205 | nf_tproxy_put_sock(struct sock *sk) |