aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Attila Toth <panther@balabit.hu>2009-06-09 09:16:34 -0400
committerPatrick McHardy <kaber@trash.net>2009-06-09 09:16:34 -0400
commita31e1ffd2231b8fdf7eda9ed750a4a0df9bcad4e (patch)
tree1b3447d8492b282a34fb2c5f3f6c5def545628ea
parent11eeef41d5f63c7d2f7fdfcc733eb7fb137cc384 (diff)
netfilter: xt_socket: added new revision of the 'socket' match supporting flags
If the XT_SOCKET_TRANSPARENT flag is set, enabled 'transparent' socket option is required for the socket to be matched. Signed-off-by: Laszlo Attila Toth <panther@balabit.hu> Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--include/linux/netfilter/xt_socket.h12
-rw-r--r--net/netfilter/xt_socket.c63
2 files changed, 64 insertions, 11 deletions
diff --git a/include/linux/netfilter/xt_socket.h b/include/linux/netfilter/xt_socket.h
new file mode 100644
index 000000000000..6f475b8ff34b
--- /dev/null
+++ b/include/linux/netfilter/xt_socket.h
@@ -0,0 +1,12 @@
1#ifndef _XT_SOCKET_H
2#define _XT_SOCKET_H
3
4enum {
5 XT_SOCKET_TRANSPARENT = 1 << 0,
6};
7
8struct xt_socket_mtinfo1 {
9 __u8 flags;
10};
11
12#endif /* _XT_SOCKET_H */
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c
index 1acc089be7e9..ebf00ad5b194 100644
--- a/net/netfilter/xt_socket.c
+++ b/net/netfilter/xt_socket.c
@@ -22,6 +22,8 @@
22#include <net/netfilter/nf_tproxy_core.h> 22#include <net/netfilter/nf_tproxy_core.h>
23#include <net/netfilter/ipv4/nf_defrag_ipv4.h> 23#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
24 24
25#include <linux/netfilter/xt_socket.h>
26
25#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 27#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
26#define XT_SOCKET_HAVE_CONNTRACK 1 28#define XT_SOCKET_HAVE_CONNTRACK 1
27#include <net/netfilter/nf_conntrack.h> 29#include <net/netfilter/nf_conntrack.h>
@@ -86,7 +88,8 @@ extract_icmp_fields(const struct sk_buff *skb,
86 88
87 89
88static bool 90static bool
89socket_mt(const struct sk_buff *skb, const struct xt_match_param *par) 91socket_match(const struct sk_buff *skb, const struct xt_match_param *par,
92 const struct xt_socket_mtinfo1 *info)
90{ 93{
91 const struct iphdr *iph = ip_hdr(skb); 94 const struct iphdr *iph = ip_hdr(skb);
92 struct udphdr _hdr, *hp = NULL; 95 struct udphdr _hdr, *hp = NULL;
@@ -141,10 +144,24 @@ socket_mt(const struct sk_buff *skb, const struct xt_match_param *par)
141 sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), protocol, 144 sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), protocol,
142 saddr, daddr, sport, dport, par->in, false); 145 saddr, daddr, sport, dport, par->in, false);
143 if (sk != NULL) { 146 if (sk != NULL) {
144 bool wildcard = (sk->sk_state != TCP_TIME_WAIT && inet_sk(sk)->rcv_saddr == 0); 147 bool wildcard;
148 bool transparent = true;
149
150 /* Ignore sockets listening on INADDR_ANY */
151 wildcard = (sk->sk_state != TCP_TIME_WAIT &&
152 inet_sk(sk)->rcv_saddr == 0);
153
154 /* Ignore non-transparent sockets,
155 if XT_SOCKET_TRANSPARENT is used */
156 if (info && info->flags & XT_SOCKET_TRANSPARENT)
157 transparent = ((sk->sk_state != TCP_TIME_WAIT &&
158 inet_sk(sk)->transparent) ||
159 (sk->sk_state == TCP_TIME_WAIT &&
160 inet_twsk(sk)->tw_transparent));
145 161
146 nf_tproxy_put_sock(sk); 162 nf_tproxy_put_sock(sk);
147 if (wildcard) 163
164 if (wildcard || !transparent)
148 sk = NULL; 165 sk = NULL;
149 } 166 }
150 167
@@ -157,23 +174,47 @@ socket_mt(const struct sk_buff *skb, const struct xt_match_param *par)
157 return (sk != NULL); 174 return (sk != NULL);
158} 175}
159 176
160static struct xt_match socket_mt_reg __read_mostly = { 177static bool
161 .name = "socket", 178socket_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
162 .family = AF_INET, 179{
163 .match = socket_mt, 180 return socket_match(skb, par, NULL);
164 .hooks = 1 << NF_INET_PRE_ROUTING, 181}
165 .me = THIS_MODULE, 182
183static bool
184socket_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
185{
186 return socket_match(skb, par, par->matchinfo);
187}
188
189static struct xt_match socket_mt_reg[] __read_mostly = {
190 {
191 .name = "socket",
192 .revision = 0,
193 .family = NFPROTO_IPV4,
194 .match = socket_mt_v0,
195 .hooks = 1 << NF_INET_PRE_ROUTING,
196 .me = THIS_MODULE,
197 },
198 {
199 .name = "socket",
200 .revision = 1,
201 .family = NFPROTO_IPV4,
202 .match = socket_mt_v1,
203 .matchsize = sizeof(struct xt_socket_mtinfo1),
204 .hooks = 1 << NF_INET_PRE_ROUTING,
205 .me = THIS_MODULE,
206 },
166}; 207};
167 208
168static int __init socket_mt_init(void) 209static int __init socket_mt_init(void)
169{ 210{
170 nf_defrag_ipv4_enable(); 211 nf_defrag_ipv4_enable();
171 return xt_register_match(&socket_mt_reg); 212 return xt_register_matches(socket_mt_reg, ARRAY_SIZE(socket_mt_reg));
172} 213}
173 214
174static void __exit socket_mt_exit(void) 215static void __exit socket_mt_exit(void)
175{ 216{
176 xt_unregister_match(&socket_mt_reg); 217 xt_unregister_matches(socket_mt_reg, ARRAY_SIZE(socket_mt_reg));
177} 218}
178 219
179module_init(socket_mt_init); 220module_init(socket_mt_init);