diff options
author | Laszlo Attila Toth <panther@balabit.hu> | 2009-06-09 09:16:34 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2009-06-09 09:16:34 -0400 |
commit | a31e1ffd2231b8fdf7eda9ed750a4a0df9bcad4e (patch) | |
tree | 1b3447d8492b282a34fb2c5f3f6c5def545628ea | |
parent | 11eeef41d5f63c7d2f7fdfcc733eb7fb137cc384 (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.h | 12 | ||||
-rw-r--r-- | net/netfilter/xt_socket.c | 63 |
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 | |||
4 | enum { | ||
5 | XT_SOCKET_TRANSPARENT = 1 << 0, | ||
6 | }; | ||
7 | |||
8 | struct 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 | ||
88 | static bool | 90 | static bool |
89 | socket_mt(const struct sk_buff *skb, const struct xt_match_param *par) | 91 | socket_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 | ||
160 | static struct xt_match socket_mt_reg __read_mostly = { | 177 | static bool |
161 | .name = "socket", | 178 | socket_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 | |
183 | static bool | ||
184 | socket_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par) | ||
185 | { | ||
186 | return socket_match(skb, par, par->matchinfo); | ||
187 | } | ||
188 | |||
189 | static 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 | ||
168 | static int __init socket_mt_init(void) | 209 | static 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 | ||
174 | static void __exit socket_mt_exit(void) | 215 | static 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 | ||
179 | module_init(socket_mt_init); | 220 | module_init(socket_mt_init); |