diff options
author | David S. Miller <davem@davemloft.net> | 2008-10-08 12:50:38 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-10-08 12:50:38 -0400 |
commit | 364ae953a48152be11f1aa424cbfd943b7762b0d (patch) | |
tree | 6873b352af1aa2dd6baa223b951eff4d6e74b1ae /net/ipv4 | |
parent | 075f664689b40217539ebfe856fab73d302a15f1 (diff) | |
parent | f39a9410ed0503278fd5edc559fa019051413039 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
Diffstat (limited to 'net/ipv4')
33 files changed, 606 insertions, 1093 deletions
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index 01671ad51ed3..6efdb70b3eb2 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c | |||
@@ -12,6 +12,7 @@ | |||
12 | /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */ | 12 | /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */ |
13 | int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | 13 | int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) |
14 | { | 14 | { |
15 | struct net *net = dev_net(skb->dst->dev); | ||
15 | const struct iphdr *iph = ip_hdr(skb); | 16 | const struct iphdr *iph = ip_hdr(skb); |
16 | struct rtable *rt; | 17 | struct rtable *rt; |
17 | struct flowi fl = {}; | 18 | struct flowi fl = {}; |
@@ -19,7 +20,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
19 | unsigned int hh_len; | 20 | unsigned int hh_len; |
20 | unsigned int type; | 21 | unsigned int type; |
21 | 22 | ||
22 | type = inet_addr_type(&init_net, iph->saddr); | 23 | type = inet_addr_type(net, iph->saddr); |
23 | if (skb->sk && inet_sk(skb->sk)->transparent) | 24 | if (skb->sk && inet_sk(skb->sk)->transparent) |
24 | type = RTN_LOCAL; | 25 | type = RTN_LOCAL; |
25 | if (addr_type == RTN_UNSPEC) | 26 | if (addr_type == RTN_UNSPEC) |
@@ -36,7 +37,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
36 | fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; | 37 | fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; |
37 | fl.mark = skb->mark; | 38 | fl.mark = skb->mark; |
38 | fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; | 39 | fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; |
39 | if (ip_route_output_key(&init_net, &rt, &fl) != 0) | 40 | if (ip_route_output_key(net, &rt, &fl) != 0) |
40 | return -1; | 41 | return -1; |
41 | 42 | ||
42 | /* Drop old route. */ | 43 | /* Drop old route. */ |
@@ -46,7 +47,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
46 | /* non-local src, find valid iif to satisfy | 47 | /* non-local src, find valid iif to satisfy |
47 | * rp-filter when calling ip_route_input. */ | 48 | * rp-filter when calling ip_route_input. */ |
48 | fl.nl_u.ip4_u.daddr = iph->saddr; | 49 | fl.nl_u.ip4_u.daddr = iph->saddr; |
49 | if (ip_route_output_key(&init_net, &rt, &fl) != 0) | 50 | if (ip_route_output_key(net, &rt, &fl) != 0) |
50 | return -1; | 51 | return -1; |
51 | 52 | ||
52 | odst = skb->dst; | 53 | odst = skb->dst; |
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 90eb7cb47e77..3816e1dc9295 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -5,10 +5,15 @@ | |||
5 | menu "IP: Netfilter Configuration" | 5 | menu "IP: Netfilter Configuration" |
6 | depends on INET && NETFILTER | 6 | depends on INET && NETFILTER |
7 | 7 | ||
8 | config NF_DEFRAG_IPV4 | ||
9 | tristate | ||
10 | default n | ||
11 | |||
8 | config NF_CONNTRACK_IPV4 | 12 | config NF_CONNTRACK_IPV4 |
9 | tristate "IPv4 connection tracking support (required for NAT)" | 13 | tristate "IPv4 connection tracking support (required for NAT)" |
10 | depends on NF_CONNTRACK | 14 | depends on NF_CONNTRACK |
11 | default m if NETFILTER_ADVANCED=n | 15 | default m if NETFILTER_ADVANCED=n |
16 | select NF_DEFRAG_IPV4 | ||
12 | ---help--- | 17 | ---help--- |
13 | Connection tracking keeps a record of what packets have passed | 18 | Connection tracking keeps a record of what packets have passed |
14 | through your machine, in order to figure out how they are related | 19 | through your machine, in order to figure out how they are related |
@@ -56,23 +61,30 @@ config IP_NF_IPTABLES | |||
56 | 61 | ||
57 | To compile it as a module, choose M here. If unsure, say N. | 62 | To compile it as a module, choose M here. If unsure, say N. |
58 | 63 | ||
64 | if IP_NF_IPTABLES | ||
65 | |||
59 | # The matches. | 66 | # The matches. |
60 | config IP_NF_MATCH_RECENT | 67 | config IP_NF_MATCH_ADDRTYPE |
61 | tristate '"recent" match support' | 68 | tristate '"addrtype" address type match support' |
62 | depends on IP_NF_IPTABLES | ||
63 | depends on NETFILTER_ADVANCED | 69 | depends on NETFILTER_ADVANCED |
64 | help | 70 | help |
65 | This match is used for creating one or many lists of recently | 71 | This option allows you to match what routing thinks of an address, |
66 | used addresses and then matching against that/those list(s). | 72 | eg. UNICAST, LOCAL, BROADCAST, ... |
67 | 73 | ||
68 | Short options are available by using 'iptables -m recent -h' | 74 | If you want to compile it as a module, say M here and read |
69 | Official Website: <http://snowman.net/projects/ipt_recent/> | 75 | <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. |
76 | |||
77 | config IP_NF_MATCH_AH | ||
78 | tristate '"ah" match support' | ||
79 | depends on NETFILTER_ADVANCED | ||
80 | help | ||
81 | This match extension allows you to match a range of SPIs | ||
82 | inside AH header of IPSec packets. | ||
70 | 83 | ||
71 | To compile it as a module, choose M here. If unsure, say N. | 84 | To compile it as a module, choose M here. If unsure, say N. |
72 | 85 | ||
73 | config IP_NF_MATCH_ECN | 86 | config IP_NF_MATCH_ECN |
74 | tristate '"ecn" match support' | 87 | tristate '"ecn" match support' |
75 | depends on IP_NF_IPTABLES | ||
76 | depends on NETFILTER_ADVANCED | 88 | depends on NETFILTER_ADVANCED |
77 | help | 89 | help |
78 | This option adds a `ECN' match, which allows you to match against | 90 | This option adds a `ECN' match, which allows you to match against |
@@ -80,19 +92,8 @@ config IP_NF_MATCH_ECN | |||
80 | 92 | ||
81 | To compile it as a module, choose M here. If unsure, say N. | 93 | To compile it as a module, choose M here. If unsure, say N. |
82 | 94 | ||
83 | config IP_NF_MATCH_AH | ||
84 | tristate '"ah" match support' | ||
85 | depends on IP_NF_IPTABLES | ||
86 | depends on NETFILTER_ADVANCED | ||
87 | help | ||
88 | This match extension allows you to match a range of SPIs | ||
89 | inside AH header of IPSec packets. | ||
90 | |||
91 | To compile it as a module, choose M here. If unsure, say N. | ||
92 | |||
93 | config IP_NF_MATCH_TTL | 95 | config IP_NF_MATCH_TTL |
94 | tristate '"ttl" match support' | 96 | tristate '"ttl" match support' |
95 | depends on IP_NF_IPTABLES | ||
96 | depends on NETFILTER_ADVANCED | 97 | depends on NETFILTER_ADVANCED |
97 | help | 98 | help |
98 | This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user | 99 | This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user |
@@ -100,21 +101,9 @@ config IP_NF_MATCH_TTL | |||
100 | 101 | ||
101 | To compile it as a module, choose M here. If unsure, say N. | 102 | To compile it as a module, choose M here. If unsure, say N. |
102 | 103 | ||
103 | config IP_NF_MATCH_ADDRTYPE | ||
104 | tristate '"addrtype" address type match support' | ||
105 | depends on IP_NF_IPTABLES | ||
106 | depends on NETFILTER_ADVANCED | ||
107 | help | ||
108 | This option allows you to match what routing thinks of an address, | ||
109 | eg. UNICAST, LOCAL, BROADCAST, ... | ||
110 | |||
111 | If you want to compile it as a module, say M here and read | ||
112 | <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. | ||
113 | |||
114 | # `filter', generic and specific targets | 104 | # `filter', generic and specific targets |
115 | config IP_NF_FILTER | 105 | config IP_NF_FILTER |
116 | tristate "Packet filtering" | 106 | tristate "Packet filtering" |
117 | depends on IP_NF_IPTABLES | ||
118 | default m if NETFILTER_ADVANCED=n | 107 | default m if NETFILTER_ADVANCED=n |
119 | help | 108 | help |
120 | Packet filtering defines a table `filter', which has a series of | 109 | Packet filtering defines a table `filter', which has a series of |
@@ -136,7 +125,6 @@ config IP_NF_TARGET_REJECT | |||
136 | 125 | ||
137 | config IP_NF_TARGET_LOG | 126 | config IP_NF_TARGET_LOG |
138 | tristate "LOG target support" | 127 | tristate "LOG target support" |
139 | depends on IP_NF_IPTABLES | ||
140 | default m if NETFILTER_ADVANCED=n | 128 | default m if NETFILTER_ADVANCED=n |
141 | help | 129 | help |
142 | This option adds a `LOG' target, which allows you to create rules in | 130 | This option adds a `LOG' target, which allows you to create rules in |
@@ -146,7 +134,6 @@ config IP_NF_TARGET_LOG | |||
146 | 134 | ||
147 | config IP_NF_TARGET_ULOG | 135 | config IP_NF_TARGET_ULOG |
148 | tristate "ULOG target support" | 136 | tristate "ULOG target support" |
149 | depends on IP_NF_IPTABLES | ||
150 | default m if NETFILTER_ADVANCED=n | 137 | default m if NETFILTER_ADVANCED=n |
151 | ---help--- | 138 | ---help--- |
152 | 139 | ||
@@ -167,7 +154,7 @@ config IP_NF_TARGET_ULOG | |||
167 | # NAT + specific targets: nf_conntrack | 154 | # NAT + specific targets: nf_conntrack |
168 | config NF_NAT | 155 | config NF_NAT |
169 | tristate "Full NAT" | 156 | tristate "Full NAT" |
170 | depends on IP_NF_IPTABLES && NF_CONNTRACK_IPV4 | 157 | depends on NF_CONNTRACK_IPV4 |
171 | default m if NETFILTER_ADVANCED=n | 158 | default m if NETFILTER_ADVANCED=n |
172 | help | 159 | help |
173 | The Full NAT option allows masquerading, port forwarding and other | 160 | The Full NAT option allows masquerading, port forwarding and other |
@@ -194,26 +181,26 @@ config IP_NF_TARGET_MASQUERADE | |||
194 | 181 | ||
195 | To compile it as a module, choose M here. If unsure, say N. | 182 | To compile it as a module, choose M here. If unsure, say N. |
196 | 183 | ||
197 | config IP_NF_TARGET_REDIRECT | 184 | config IP_NF_TARGET_NETMAP |
198 | tristate "REDIRECT target support" | 185 | tristate "NETMAP target support" |
199 | depends on NF_NAT | 186 | depends on NF_NAT |
200 | depends on NETFILTER_ADVANCED | 187 | depends on NETFILTER_ADVANCED |
201 | help | 188 | help |
202 | REDIRECT is a special case of NAT: all incoming connections are | 189 | NETMAP is an implementation of static 1:1 NAT mapping of network |
203 | mapped onto the incoming interface's address, causing the packets to | 190 | addresses. It maps the network address part, while keeping the host |
204 | come to the local machine instead of passing through. This is | 191 | address part intact. |
205 | useful for transparent proxies. | ||
206 | 192 | ||
207 | To compile it as a module, choose M here. If unsure, say N. | 193 | To compile it as a module, choose M here. If unsure, say N. |
208 | 194 | ||
209 | config IP_NF_TARGET_NETMAP | 195 | config IP_NF_TARGET_REDIRECT |
210 | tristate "NETMAP target support" | 196 | tristate "REDIRECT target support" |
211 | depends on NF_NAT | 197 | depends on NF_NAT |
212 | depends on NETFILTER_ADVANCED | 198 | depends on NETFILTER_ADVANCED |
213 | help | 199 | help |
214 | NETMAP is an implementation of static 1:1 NAT mapping of network | 200 | REDIRECT is a special case of NAT: all incoming connections are |
215 | addresses. It maps the network address part, while keeping the host | 201 | mapped onto the incoming interface's address, causing the packets to |
216 | address part intact. | 202 | come to the local machine instead of passing through. This is |
203 | useful for transparent proxies. | ||
217 | 204 | ||
218 | To compile it as a module, choose M here. If unsure, say N. | 205 | To compile it as a module, choose M here. If unsure, say N. |
219 | 206 | ||
@@ -262,44 +249,43 @@ config NF_NAT_PROTO_SCTP | |||
262 | 249 | ||
263 | config NF_NAT_FTP | 250 | config NF_NAT_FTP |
264 | tristate | 251 | tristate |
265 | depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT | 252 | depends on NF_CONNTRACK && NF_NAT |
266 | default NF_NAT && NF_CONNTRACK_FTP | 253 | default NF_NAT && NF_CONNTRACK_FTP |
267 | 254 | ||
268 | config NF_NAT_IRC | 255 | config NF_NAT_IRC |
269 | tristate | 256 | tristate |
270 | depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT | 257 | depends on NF_CONNTRACK && NF_NAT |
271 | default NF_NAT && NF_CONNTRACK_IRC | 258 | default NF_NAT && NF_CONNTRACK_IRC |
272 | 259 | ||
273 | config NF_NAT_TFTP | 260 | config NF_NAT_TFTP |
274 | tristate | 261 | tristate |
275 | depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT | 262 | depends on NF_CONNTRACK && NF_NAT |
276 | default NF_NAT && NF_CONNTRACK_TFTP | 263 | default NF_NAT && NF_CONNTRACK_TFTP |
277 | 264 | ||
278 | config NF_NAT_AMANDA | 265 | config NF_NAT_AMANDA |
279 | tristate | 266 | tristate |
280 | depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT | 267 | depends on NF_CONNTRACK && NF_NAT |
281 | default NF_NAT && NF_CONNTRACK_AMANDA | 268 | default NF_NAT && NF_CONNTRACK_AMANDA |
282 | 269 | ||
283 | config NF_NAT_PPTP | 270 | config NF_NAT_PPTP |
284 | tristate | 271 | tristate |
285 | depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT | 272 | depends on NF_CONNTRACK && NF_NAT |
286 | default NF_NAT && NF_CONNTRACK_PPTP | 273 | default NF_NAT && NF_CONNTRACK_PPTP |
287 | select NF_NAT_PROTO_GRE | 274 | select NF_NAT_PROTO_GRE |
288 | 275 | ||
289 | config NF_NAT_H323 | 276 | config NF_NAT_H323 |
290 | tristate | 277 | tristate |
291 | depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT | 278 | depends on NF_CONNTRACK && NF_NAT |
292 | default NF_NAT && NF_CONNTRACK_H323 | 279 | default NF_NAT && NF_CONNTRACK_H323 |
293 | 280 | ||
294 | config NF_NAT_SIP | 281 | config NF_NAT_SIP |
295 | tristate | 282 | tristate |
296 | depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT | 283 | depends on NF_CONNTRACK && NF_NAT |
297 | default NF_NAT && NF_CONNTRACK_SIP | 284 | default NF_NAT && NF_CONNTRACK_SIP |
298 | 285 | ||
299 | # mangle + specific targets | 286 | # mangle + specific targets |
300 | config IP_NF_MANGLE | 287 | config IP_NF_MANGLE |
301 | tristate "Packet mangling" | 288 | tristate "Packet mangling" |
302 | depends on IP_NF_IPTABLES | ||
303 | default m if NETFILTER_ADVANCED=n | 289 | default m if NETFILTER_ADVANCED=n |
304 | help | 290 | help |
305 | This option adds a `mangle' table to iptables: see the man page for | 291 | This option adds a `mangle' table to iptables: see the man page for |
@@ -308,6 +294,19 @@ config IP_NF_MANGLE | |||
308 | 294 | ||
309 | To compile it as a module, choose M here. If unsure, say N. | 295 | To compile it as a module, choose M here. If unsure, say N. |
310 | 296 | ||
297 | config IP_NF_TARGET_CLUSTERIP | ||
298 | tristate "CLUSTERIP target support (EXPERIMENTAL)" | ||
299 | depends on IP_NF_MANGLE && EXPERIMENTAL | ||
300 | depends on NF_CONNTRACK_IPV4 | ||
301 | depends on NETFILTER_ADVANCED | ||
302 | select NF_CONNTRACK_MARK | ||
303 | help | ||
304 | The CLUSTERIP target allows you to build load-balancing clusters of | ||
305 | network servers without having a dedicated load-balancing | ||
306 | router/server/switch. | ||
307 | |||
308 | To compile it as a module, choose M here. If unsure, say N. | ||
309 | |||
311 | config IP_NF_TARGET_ECN | 310 | config IP_NF_TARGET_ECN |
312 | tristate "ECN target support" | 311 | tristate "ECN target support" |
313 | depends on IP_NF_MANGLE | 312 | depends on IP_NF_MANGLE |
@@ -338,23 +337,9 @@ config IP_NF_TARGET_TTL | |||
338 | 337 | ||
339 | To compile it as a module, choose M here. If unsure, say N. | 338 | To compile it as a module, choose M here. If unsure, say N. |
340 | 339 | ||
341 | config IP_NF_TARGET_CLUSTERIP | ||
342 | tristate "CLUSTERIP target support (EXPERIMENTAL)" | ||
343 | depends on IP_NF_MANGLE && EXPERIMENTAL | ||
344 | depends on NF_CONNTRACK_IPV4 | ||
345 | depends on NETFILTER_ADVANCED | ||
346 | select NF_CONNTRACK_MARK | ||
347 | help | ||
348 | The CLUSTERIP target allows you to build load-balancing clusters of | ||
349 | network servers without having a dedicated load-balancing | ||
350 | router/server/switch. | ||
351 | |||
352 | To compile it as a module, choose M here. If unsure, say N. | ||
353 | |||
354 | # raw + specific targets | 340 | # raw + specific targets |
355 | config IP_NF_RAW | 341 | config IP_NF_RAW |
356 | tristate 'raw table support (required for NOTRACK/TRACE)' | 342 | tristate 'raw table support (required for NOTRACK/TRACE)' |
357 | depends on IP_NF_IPTABLES | ||
358 | depends on NETFILTER_ADVANCED | 343 | depends on NETFILTER_ADVANCED |
359 | help | 344 | help |
360 | This option adds a `raw' table to iptables. This table is the very | 345 | This option adds a `raw' table to iptables. This table is the very |
@@ -367,7 +352,6 @@ config IP_NF_RAW | |||
367 | # security table for MAC policy | 352 | # security table for MAC policy |
368 | config IP_NF_SECURITY | 353 | config IP_NF_SECURITY |
369 | tristate "Security table" | 354 | tristate "Security table" |
370 | depends on IP_NF_IPTABLES | ||
371 | depends on SECURITY | 355 | depends on SECURITY |
372 | depends on NETFILTER_ADVANCED | 356 | depends on NETFILTER_ADVANCED |
373 | help | 357 | help |
@@ -376,6 +360,8 @@ config IP_NF_SECURITY | |||
376 | 360 | ||
377 | If unsure, say N. | 361 | If unsure, say N. |
378 | 362 | ||
363 | endif # IP_NF_IPTABLES | ||
364 | |||
379 | # ARP tables | 365 | # ARP tables |
380 | config IP_NF_ARPTABLES | 366 | config IP_NF_ARPTABLES |
381 | tristate "ARP tables support" | 367 | tristate "ARP tables support" |
@@ -388,9 +374,10 @@ config IP_NF_ARPTABLES | |||
388 | 374 | ||
389 | To compile it as a module, choose M here. If unsure, say N. | 375 | To compile it as a module, choose M here. If unsure, say N. |
390 | 376 | ||
377 | if IP_NF_ARPTABLES | ||
378 | |||
391 | config IP_NF_ARPFILTER | 379 | config IP_NF_ARPFILTER |
392 | tristate "ARP packet filtering" | 380 | tristate "ARP packet filtering" |
393 | depends on IP_NF_ARPTABLES | ||
394 | help | 381 | help |
395 | ARP packet filtering defines a table `filter', which has a series of | 382 | ARP packet filtering defines a table `filter', which has a series of |
396 | rules for simple ARP packet filtering at local input and | 383 | rules for simple ARP packet filtering at local input and |
@@ -401,10 +388,11 @@ config IP_NF_ARPFILTER | |||
401 | 388 | ||
402 | config IP_NF_ARP_MANGLE | 389 | config IP_NF_ARP_MANGLE |
403 | tristate "ARP payload mangling" | 390 | tristate "ARP payload mangling" |
404 | depends on IP_NF_ARPTABLES | ||
405 | help | 391 | help |
406 | Allows altering the ARP packet payload: source and destination | 392 | Allows altering the ARP packet payload: source and destination |
407 | hardware and network addresses. | 393 | hardware and network addresses. |
408 | 394 | ||
395 | endif # IP_NF_ARPTABLES | ||
396 | |||
409 | endmenu | 397 | endmenu |
410 | 398 | ||
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 3f31291f37ce..5f9b650d90fc 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
@@ -18,6 +18,9 @@ obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o | |||
18 | 18 | ||
19 | obj-$(CONFIG_NF_NAT) += nf_nat.o | 19 | obj-$(CONFIG_NF_NAT) += nf_nat.o |
20 | 20 | ||
21 | # defrag | ||
22 | obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o | ||
23 | |||
21 | # NAT helpers (nf_conntrack) | 24 | # NAT helpers (nf_conntrack) |
22 | obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o | 25 | obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o |
23 | obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o | 26 | obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o |
@@ -48,7 +51,6 @@ obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o | |||
48 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o | 51 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o |
49 | obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o | 52 | obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o |
50 | obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o | 53 | obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o |
51 | obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o | ||
52 | obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o | 54 | obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o |
53 | 55 | ||
54 | # targets | 56 | # targets |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 03e83a65aec5..8d70d29f1ccf 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -200,15 +200,12 @@ static inline int arp_checkentry(const struct arpt_arp *arp) | |||
200 | return 1; | 200 | return 1; |
201 | } | 201 | } |
202 | 202 | ||
203 | static unsigned int arpt_error(struct sk_buff *skb, | 203 | static unsigned int |
204 | const struct net_device *in, | 204 | arpt_error(struct sk_buff *skb, const struct xt_target_param *par) |
205 | const struct net_device *out, | ||
206 | unsigned int hooknum, | ||
207 | const struct xt_target *target, | ||
208 | const void *targinfo) | ||
209 | { | 205 | { |
210 | if (net_ratelimit()) | 206 | if (net_ratelimit()) |
211 | printk("arp_tables: error: '%s'\n", (char *)targinfo); | 207 | printk("arp_tables: error: '%s'\n", |
208 | (const char *)par->targinfo); | ||
212 | 209 | ||
213 | return NF_DROP; | 210 | return NF_DROP; |
214 | } | 211 | } |
@@ -232,6 +229,7 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
232 | const char *indev, *outdev; | 229 | const char *indev, *outdev; |
233 | void *table_base; | 230 | void *table_base; |
234 | const struct xt_table_info *private; | 231 | const struct xt_table_info *private; |
232 | struct xt_target_param tgpar; | ||
235 | 233 | ||
236 | if (!pskb_may_pull(skb, arp_hdr_len(skb->dev))) | 234 | if (!pskb_may_pull(skb, arp_hdr_len(skb->dev))) |
237 | return NF_DROP; | 235 | return NF_DROP; |
@@ -245,6 +243,11 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
245 | e = get_entry(table_base, private->hook_entry[hook]); | 243 | e = get_entry(table_base, private->hook_entry[hook]); |
246 | back = get_entry(table_base, private->underflow[hook]); | 244 | back = get_entry(table_base, private->underflow[hook]); |
247 | 245 | ||
246 | tgpar.in = in; | ||
247 | tgpar.out = out; | ||
248 | tgpar.hooknum = hook; | ||
249 | tgpar.family = NFPROTO_ARP; | ||
250 | |||
248 | arp = arp_hdr(skb); | 251 | arp = arp_hdr(skb); |
249 | do { | 252 | do { |
250 | if (arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) { | 253 | if (arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) { |
@@ -290,11 +293,10 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
290 | /* Targets which reenter must return | 293 | /* Targets which reenter must return |
291 | * abs. verdicts | 294 | * abs. verdicts |
292 | */ | 295 | */ |
296 | tgpar.target = t->u.kernel.target; | ||
297 | tgpar.targinfo = t->data; | ||
293 | verdict = t->u.kernel.target->target(skb, | 298 | verdict = t->u.kernel.target->target(skb, |
294 | in, out, | 299 | &tgpar); |
295 | hook, | ||
296 | t->u.kernel.target, | ||
297 | t->data); | ||
298 | 300 | ||
299 | /* Target might have changed stuff. */ | 301 | /* Target might have changed stuff. */ |
300 | arp = arp_hdr(skb); | 302 | arp = arp_hdr(skb); |
@@ -456,23 +458,24 @@ static inline int check_entry(struct arpt_entry *e, const char *name) | |||
456 | 458 | ||
457 | static inline int check_target(struct arpt_entry *e, const char *name) | 459 | static inline int check_target(struct arpt_entry *e, const char *name) |
458 | { | 460 | { |
459 | struct arpt_entry_target *t; | 461 | struct arpt_entry_target *t = arpt_get_target(e); |
460 | struct xt_target *target; | ||
461 | int ret; | 462 | int ret; |
462 | 463 | struct xt_tgchk_param par = { | |
463 | t = arpt_get_target(e); | 464 | .table = name, |
464 | target = t->u.kernel.target; | 465 | .entryinfo = e, |
465 | 466 | .target = t->u.kernel.target, | |
466 | ret = xt_check_target(target, NF_ARP, t->u.target_size - sizeof(*t), | 467 | .targinfo = t->data, |
467 | name, e->comefrom, 0, 0); | 468 | .hook_mask = e->comefrom, |
468 | if (!ret && t->u.kernel.target->checkentry | 469 | .family = NFPROTO_ARP, |
469 | && !t->u.kernel.target->checkentry(name, e, target, t->data, | 470 | }; |
470 | e->comefrom)) { | 471 | |
472 | ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false); | ||
473 | if (ret < 0) { | ||
471 | duprintf("arp_tables: check failed for `%s'.\n", | 474 | duprintf("arp_tables: check failed for `%s'.\n", |
472 | t->u.kernel.target->name); | 475 | t->u.kernel.target->name); |
473 | ret = -EINVAL; | 476 | return ret; |
474 | } | 477 | } |
475 | return ret; | 478 | return 0; |
476 | } | 479 | } |
477 | 480 | ||
478 | static inline int | 481 | static inline int |
@@ -488,7 +491,8 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size, | |||
488 | return ret; | 491 | return ret; |
489 | 492 | ||
490 | t = arpt_get_target(e); | 493 | t = arpt_get_target(e); |
491 | target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, | 494 | target = try_then_request_module(xt_find_target(NFPROTO_ARP, |
495 | t->u.user.name, | ||
492 | t->u.user.revision), | 496 | t->u.user.revision), |
493 | "arpt_%s", t->u.user.name); | 497 | "arpt_%s", t->u.user.name); |
494 | if (IS_ERR(target) || !target) { | 498 | if (IS_ERR(target) || !target) { |
@@ -554,15 +558,19 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, | |||
554 | 558 | ||
555 | static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i) | 559 | static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i) |
556 | { | 560 | { |
561 | struct xt_tgdtor_param par; | ||
557 | struct arpt_entry_target *t; | 562 | struct arpt_entry_target *t; |
558 | 563 | ||
559 | if (i && (*i)-- == 0) | 564 | if (i && (*i)-- == 0) |
560 | return 1; | 565 | return 1; |
561 | 566 | ||
562 | t = arpt_get_target(e); | 567 | t = arpt_get_target(e); |
563 | if (t->u.kernel.target->destroy) | 568 | par.target = t->u.kernel.target; |
564 | t->u.kernel.target->destroy(t->u.kernel.target, t->data); | 569 | par.targinfo = t->data; |
565 | module_put(t->u.kernel.target->me); | 570 | par.family = NFPROTO_ARP; |
571 | if (par.target->destroy != NULL) | ||
572 | par.target->destroy(&par); | ||
573 | module_put(par.target->me); | ||
566 | return 0; | 574 | return 0; |
567 | } | 575 | } |
568 | 576 | ||
@@ -788,7 +796,7 @@ static void compat_standard_from_user(void *dst, void *src) | |||
788 | int v = *(compat_int_t *)src; | 796 | int v = *(compat_int_t *)src; |
789 | 797 | ||
790 | if (v > 0) | 798 | if (v > 0) |
791 | v += xt_compat_calc_jump(NF_ARP, v); | 799 | v += xt_compat_calc_jump(NFPROTO_ARP, v); |
792 | memcpy(dst, &v, sizeof(v)); | 800 | memcpy(dst, &v, sizeof(v)); |
793 | } | 801 | } |
794 | 802 | ||
@@ -797,7 +805,7 @@ static int compat_standard_to_user(void __user *dst, void *src) | |||
797 | compat_int_t cv = *(int *)src; | 805 | compat_int_t cv = *(int *)src; |
798 | 806 | ||
799 | if (cv > 0) | 807 | if (cv > 0) |
800 | cv -= xt_compat_calc_jump(NF_ARP, cv); | 808 | cv -= xt_compat_calc_jump(NFPROTO_ARP, cv); |
801 | return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0; | 809 | return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0; |
802 | } | 810 | } |
803 | 811 | ||
@@ -815,7 +823,7 @@ static int compat_calc_entry(struct arpt_entry *e, | |||
815 | t = arpt_get_target(e); | 823 | t = arpt_get_target(e); |
816 | off += xt_compat_target_offset(t->u.kernel.target); | 824 | off += xt_compat_target_offset(t->u.kernel.target); |
817 | newinfo->size -= off; | 825 | newinfo->size -= off; |
818 | ret = xt_compat_add_offset(NF_ARP, entry_offset, off); | 826 | ret = xt_compat_add_offset(NFPROTO_ARP, entry_offset, off); |
819 | if (ret) | 827 | if (ret) |
820 | return ret; | 828 | return ret; |
821 | 829 | ||
@@ -866,9 +874,9 @@ static int get_info(struct net *net, void __user *user, int *len, int compat) | |||
866 | name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; | 874 | name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; |
867 | #ifdef CONFIG_COMPAT | 875 | #ifdef CONFIG_COMPAT |
868 | if (compat) | 876 | if (compat) |
869 | xt_compat_lock(NF_ARP); | 877 | xt_compat_lock(NFPROTO_ARP); |
870 | #endif | 878 | #endif |
871 | t = try_then_request_module(xt_find_table_lock(net, NF_ARP, name), | 879 | t = try_then_request_module(xt_find_table_lock(net, NFPROTO_ARP, name), |
872 | "arptable_%s", name); | 880 | "arptable_%s", name); |
873 | if (t && !IS_ERR(t)) { | 881 | if (t && !IS_ERR(t)) { |
874 | struct arpt_getinfo info; | 882 | struct arpt_getinfo info; |
@@ -878,7 +886,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat) | |||
878 | if (compat) { | 886 | if (compat) { |
879 | struct xt_table_info tmp; | 887 | struct xt_table_info tmp; |
880 | ret = compat_table_info(private, &tmp); | 888 | ret = compat_table_info(private, &tmp); |
881 | xt_compat_flush_offsets(NF_ARP); | 889 | xt_compat_flush_offsets(NFPROTO_ARP); |
882 | private = &tmp; | 890 | private = &tmp; |
883 | } | 891 | } |
884 | #endif | 892 | #endif |
@@ -901,7 +909,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat) | |||
901 | ret = t ? PTR_ERR(t) : -ENOENT; | 909 | ret = t ? PTR_ERR(t) : -ENOENT; |
902 | #ifdef CONFIG_COMPAT | 910 | #ifdef CONFIG_COMPAT |
903 | if (compat) | 911 | if (compat) |
904 | xt_compat_unlock(NF_ARP); | 912 | xt_compat_unlock(NFPROTO_ARP); |
905 | #endif | 913 | #endif |
906 | return ret; | 914 | return ret; |
907 | } | 915 | } |
@@ -925,7 +933,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr, | |||
925 | return -EINVAL; | 933 | return -EINVAL; |
926 | } | 934 | } |
927 | 935 | ||
928 | t = xt_find_table_lock(net, NF_ARP, get.name); | 936 | t = xt_find_table_lock(net, NFPROTO_ARP, get.name); |
929 | if (t && !IS_ERR(t)) { | 937 | if (t && !IS_ERR(t)) { |
930 | const struct xt_table_info *private = t->private; | 938 | const struct xt_table_info *private = t->private; |
931 | 939 | ||
@@ -967,7 +975,7 @@ static int __do_replace(struct net *net, const char *name, | |||
967 | goto out; | 975 | goto out; |
968 | } | 976 | } |
969 | 977 | ||
970 | t = try_then_request_module(xt_find_table_lock(net, NF_ARP, name), | 978 | t = try_then_request_module(xt_find_table_lock(net, NFPROTO_ARP, name), |
971 | "arptable_%s", name); | 979 | "arptable_%s", name); |
972 | if (!t || IS_ERR(t)) { | 980 | if (!t || IS_ERR(t)) { |
973 | ret = t ? PTR_ERR(t) : -ENOENT; | 981 | ret = t ? PTR_ERR(t) : -ENOENT; |
@@ -1134,7 +1142,7 @@ static int do_add_counters(struct net *net, void __user *user, unsigned int len, | |||
1134 | goto free; | 1142 | goto free; |
1135 | } | 1143 | } |
1136 | 1144 | ||
1137 | t = xt_find_table_lock(net, NF_ARP, name); | 1145 | t = xt_find_table_lock(net, NFPROTO_ARP, name); |
1138 | if (!t || IS_ERR(t)) { | 1146 | if (!t || IS_ERR(t)) { |
1139 | ret = t ? PTR_ERR(t) : -ENOENT; | 1147 | ret = t ? PTR_ERR(t) : -ENOENT; |
1140 | goto free; | 1148 | goto free; |
@@ -1218,7 +1226,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, | |||
1218 | entry_offset = (void *)e - (void *)base; | 1226 | entry_offset = (void *)e - (void *)base; |
1219 | 1227 | ||
1220 | t = compat_arpt_get_target(e); | 1228 | t = compat_arpt_get_target(e); |
1221 | target = try_then_request_module(xt_find_target(NF_ARP, | 1229 | target = try_then_request_module(xt_find_target(NFPROTO_ARP, |
1222 | t->u.user.name, | 1230 | t->u.user.name, |
1223 | t->u.user.revision), | 1231 | t->u.user.revision), |
1224 | "arpt_%s", t->u.user.name); | 1232 | "arpt_%s", t->u.user.name); |
@@ -1232,7 +1240,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, | |||
1232 | 1240 | ||
1233 | off += xt_compat_target_offset(target); | 1241 | off += xt_compat_target_offset(target); |
1234 | *size += off; | 1242 | *size += off; |
1235 | ret = xt_compat_add_offset(NF_ARP, entry_offset, off); | 1243 | ret = xt_compat_add_offset(NFPROTO_ARP, entry_offset, off); |
1236 | if (ret) | 1244 | if (ret) |
1237 | goto release_target; | 1245 | goto release_target; |
1238 | 1246 | ||
@@ -1333,7 +1341,7 @@ static int translate_compat_table(const char *name, | |||
1333 | 1341 | ||
1334 | duprintf("translate_compat_table: size %u\n", info->size); | 1342 | duprintf("translate_compat_table: size %u\n", info->size); |
1335 | j = 0; | 1343 | j = 0; |
1336 | xt_compat_lock(NF_ARP); | 1344 | xt_compat_lock(NFPROTO_ARP); |
1337 | /* Walk through entries, checking offsets. */ | 1345 | /* Walk through entries, checking offsets. */ |
1338 | ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, | 1346 | ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, |
1339 | check_compat_entry_size_and_hooks, | 1347 | check_compat_entry_size_and_hooks, |
@@ -1383,8 +1391,8 @@ static int translate_compat_table(const char *name, | |||
1383 | ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, | 1391 | ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, |
1384 | compat_copy_entry_from_user, | 1392 | compat_copy_entry_from_user, |
1385 | &pos, &size, name, newinfo, entry1); | 1393 | &pos, &size, name, newinfo, entry1); |
1386 | xt_compat_flush_offsets(NF_ARP); | 1394 | xt_compat_flush_offsets(NFPROTO_ARP); |
1387 | xt_compat_unlock(NF_ARP); | 1395 | xt_compat_unlock(NFPROTO_ARP); |
1388 | if (ret) | 1396 | if (ret) |
1389 | goto free_newinfo; | 1397 | goto free_newinfo; |
1390 | 1398 | ||
@@ -1420,8 +1428,8 @@ out: | |||
1420 | COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); | 1428 | COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); |
1421 | return ret; | 1429 | return ret; |
1422 | out_unlock: | 1430 | out_unlock: |
1423 | xt_compat_flush_offsets(NF_ARP); | 1431 | xt_compat_flush_offsets(NFPROTO_ARP); |
1424 | xt_compat_unlock(NF_ARP); | 1432 | xt_compat_unlock(NFPROTO_ARP); |
1425 | goto out; | 1433 | goto out; |
1426 | } | 1434 | } |
1427 | 1435 | ||
@@ -1607,8 +1615,8 @@ static int compat_get_entries(struct net *net, | |||
1607 | return -EINVAL; | 1615 | return -EINVAL; |
1608 | } | 1616 | } |
1609 | 1617 | ||
1610 | xt_compat_lock(NF_ARP); | 1618 | xt_compat_lock(NFPROTO_ARP); |
1611 | t = xt_find_table_lock(net, NF_ARP, get.name); | 1619 | t = xt_find_table_lock(net, NFPROTO_ARP, get.name); |
1612 | if (t && !IS_ERR(t)) { | 1620 | if (t && !IS_ERR(t)) { |
1613 | const struct xt_table_info *private = t->private; | 1621 | const struct xt_table_info *private = t->private; |
1614 | struct xt_table_info info; | 1622 | struct xt_table_info info; |
@@ -1623,13 +1631,13 @@ static int compat_get_entries(struct net *net, | |||
1623 | private->size, get.size); | 1631 | private->size, get.size); |
1624 | ret = -EAGAIN; | 1632 | ret = -EAGAIN; |
1625 | } | 1633 | } |
1626 | xt_compat_flush_offsets(NF_ARP); | 1634 | xt_compat_flush_offsets(NFPROTO_ARP); |
1627 | module_put(t->me); | 1635 | module_put(t->me); |
1628 | xt_table_unlock(t); | 1636 | xt_table_unlock(t); |
1629 | } else | 1637 | } else |
1630 | ret = t ? PTR_ERR(t) : -ENOENT; | 1638 | ret = t ? PTR_ERR(t) : -ENOENT; |
1631 | 1639 | ||
1632 | xt_compat_unlock(NF_ARP); | 1640 | xt_compat_unlock(NFPROTO_ARP); |
1633 | return ret; | 1641 | return ret; |
1634 | } | 1642 | } |
1635 | 1643 | ||
@@ -1709,7 +1717,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len | |||
1709 | break; | 1717 | break; |
1710 | } | 1718 | } |
1711 | 1719 | ||
1712 | try_then_request_module(xt_find_revision(NF_ARP, rev.name, | 1720 | try_then_request_module(xt_find_revision(NFPROTO_ARP, rev.name, |
1713 | rev.revision, 1, &ret), | 1721 | rev.revision, 1, &ret), |
1714 | "arpt_%s", rev.name); | 1722 | "arpt_%s", rev.name); |
1715 | break; | 1723 | break; |
@@ -1787,7 +1795,7 @@ void arpt_unregister_table(struct xt_table *table) | |||
1787 | static struct xt_target arpt_standard_target __read_mostly = { | 1795 | static struct xt_target arpt_standard_target __read_mostly = { |
1788 | .name = ARPT_STANDARD_TARGET, | 1796 | .name = ARPT_STANDARD_TARGET, |
1789 | .targetsize = sizeof(int), | 1797 | .targetsize = sizeof(int), |
1790 | .family = NF_ARP, | 1798 | .family = NFPROTO_ARP, |
1791 | #ifdef CONFIG_COMPAT | 1799 | #ifdef CONFIG_COMPAT |
1792 | .compatsize = sizeof(compat_int_t), | 1800 | .compatsize = sizeof(compat_int_t), |
1793 | .compat_from_user = compat_standard_from_user, | 1801 | .compat_from_user = compat_standard_from_user, |
@@ -1799,7 +1807,7 @@ static struct xt_target arpt_error_target __read_mostly = { | |||
1799 | .name = ARPT_ERROR_TARGET, | 1807 | .name = ARPT_ERROR_TARGET, |
1800 | .target = arpt_error, | 1808 | .target = arpt_error, |
1801 | .targetsize = ARPT_FUNCTION_MAXNAMELEN, | 1809 | .targetsize = ARPT_FUNCTION_MAXNAMELEN, |
1802 | .family = NF_ARP, | 1810 | .family = NFPROTO_ARP, |
1803 | }; | 1811 | }; |
1804 | 1812 | ||
1805 | static struct nf_sockopt_ops arpt_sockopts = { | 1813 | static struct nf_sockopt_ops arpt_sockopts = { |
@@ -1821,12 +1829,12 @@ static struct nf_sockopt_ops arpt_sockopts = { | |||
1821 | 1829 | ||
1822 | static int __net_init arp_tables_net_init(struct net *net) | 1830 | static int __net_init arp_tables_net_init(struct net *net) |
1823 | { | 1831 | { |
1824 | return xt_proto_init(net, NF_ARP); | 1832 | return xt_proto_init(net, NFPROTO_ARP); |
1825 | } | 1833 | } |
1826 | 1834 | ||
1827 | static void __net_exit arp_tables_net_exit(struct net *net) | 1835 | static void __net_exit arp_tables_net_exit(struct net *net) |
1828 | { | 1836 | { |
1829 | xt_proto_fini(net, NF_ARP); | 1837 | xt_proto_fini(net, NFPROTO_ARP); |
1830 | } | 1838 | } |
1831 | 1839 | ||
1832 | static struct pernet_operations arp_tables_net_ops = { | 1840 | static struct pernet_operations arp_tables_net_ops = { |
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c index a385959d2655..b0d5b1d0a769 100644 --- a/net/ipv4/netfilter/arpt_mangle.c +++ b/net/ipv4/netfilter/arpt_mangle.c | |||
@@ -9,12 +9,9 @@ MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); | |||
9 | MODULE_DESCRIPTION("arptables arp payload mangle target"); | 9 | MODULE_DESCRIPTION("arptables arp payload mangle target"); |
10 | 10 | ||
11 | static unsigned int | 11 | static unsigned int |
12 | target(struct sk_buff *skb, | 12 | target(struct sk_buff *skb, const struct xt_target_param *par) |
13 | const struct net_device *in, const struct net_device *out, | ||
14 | unsigned int hooknum, const struct xt_target *target, | ||
15 | const void *targinfo) | ||
16 | { | 13 | { |
17 | const struct arpt_mangle *mangle = targinfo; | 14 | const struct arpt_mangle *mangle = par->targinfo; |
18 | const struct arphdr *arp; | 15 | const struct arphdr *arp; |
19 | unsigned char *arpptr; | 16 | unsigned char *arpptr; |
20 | int pln, hln; | 17 | int pln, hln; |
@@ -57,11 +54,9 @@ target(struct sk_buff *skb, | |||
57 | return mangle->target; | 54 | return mangle->target; |
58 | } | 55 | } |
59 | 56 | ||
60 | static bool | 57 | static bool checkentry(const struct xt_tgchk_param *par) |
61 | checkentry(const char *tablename, const void *e, const struct xt_target *target, | ||
62 | void *targinfo, unsigned int hook_mask) | ||
63 | { | 58 | { |
64 | const struct arpt_mangle *mangle = targinfo; | 59 | const struct arpt_mangle *mangle = par->targinfo; |
65 | 60 | ||
66 | if (mangle->flags & ~ARPT_MANGLE_MASK || | 61 | if (mangle->flags & ~ARPT_MANGLE_MASK || |
67 | !(mangle->flags & ARPT_MANGLE_MASK)) | 62 | !(mangle->flags & ARPT_MANGLE_MASK)) |
@@ -75,7 +70,7 @@ checkentry(const char *tablename, const void *e, const struct xt_target *target, | |||
75 | 70 | ||
76 | static struct xt_target arpt_mangle_reg __read_mostly = { | 71 | static struct xt_target arpt_mangle_reg __read_mostly = { |
77 | .name = "mangle", | 72 | .name = "mangle", |
78 | .family = NF_ARP, | 73 | .family = NFPROTO_ARP, |
79 | .target = target, | 74 | .target = target, |
80 | .targetsize = sizeof(struct arpt_mangle), | 75 | .targetsize = sizeof(struct arpt_mangle), |
81 | .checkentry = checkentry, | 76 | .checkentry = checkentry, |
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c index 082f5dd3156c..bee3d117661a 100644 --- a/net/ipv4/netfilter/arptable_filter.c +++ b/net/ipv4/netfilter/arptable_filter.c | |||
@@ -51,7 +51,7 @@ static struct xt_table packet_filter = { | |||
51 | .lock = __RW_LOCK_UNLOCKED(packet_filter.lock), | 51 | .lock = __RW_LOCK_UNLOCKED(packet_filter.lock), |
52 | .private = NULL, | 52 | .private = NULL, |
53 | .me = THIS_MODULE, | 53 | .me = THIS_MODULE, |
54 | .af = NF_ARP, | 54 | .af = NFPROTO_ARP, |
55 | }; | 55 | }; |
56 | 56 | ||
57 | /* The work comes in here from netfilter.c */ | 57 | /* The work comes in here from netfilter.c */ |
@@ -89,21 +89,21 @@ static struct nf_hook_ops arpt_ops[] __read_mostly = { | |||
89 | { | 89 | { |
90 | .hook = arpt_in_hook, | 90 | .hook = arpt_in_hook, |
91 | .owner = THIS_MODULE, | 91 | .owner = THIS_MODULE, |
92 | .pf = NF_ARP, | 92 | .pf = NFPROTO_ARP, |
93 | .hooknum = NF_ARP_IN, | 93 | .hooknum = NF_ARP_IN, |
94 | .priority = NF_IP_PRI_FILTER, | 94 | .priority = NF_IP_PRI_FILTER, |
95 | }, | 95 | }, |
96 | { | 96 | { |
97 | .hook = arpt_out_hook, | 97 | .hook = arpt_out_hook, |
98 | .owner = THIS_MODULE, | 98 | .owner = THIS_MODULE, |
99 | .pf = NF_ARP, | 99 | .pf = NFPROTO_ARP, |
100 | .hooknum = NF_ARP_OUT, | 100 | .hooknum = NF_ARP_OUT, |
101 | .priority = NF_IP_PRI_FILTER, | 101 | .priority = NF_IP_PRI_FILTER, |
102 | }, | 102 | }, |
103 | { | 103 | { |
104 | .hook = arpt_forward_hook, | 104 | .hook = arpt_forward_hook, |
105 | .owner = THIS_MODULE, | 105 | .owner = THIS_MODULE, |
106 | .pf = NF_ARP, | 106 | .pf = NFPROTO_ARP, |
107 | .hooknum = NF_ARP_FORWARD, | 107 | .hooknum = NF_ARP_FORWARD, |
108 | .priority = NF_IP_PRI_FILTER, | 108 | .priority = NF_IP_PRI_FILTER, |
109 | }, | 109 | }, |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 4e7c719445c2..213fb27debc1 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -171,31 +171,25 @@ ip_checkentry(const struct ipt_ip *ip) | |||
171 | } | 171 | } |
172 | 172 | ||
173 | static unsigned int | 173 | static unsigned int |
174 | ipt_error(struct sk_buff *skb, | 174 | ipt_error(struct sk_buff *skb, const struct xt_target_param *par) |
175 | const struct net_device *in, | ||
176 | const struct net_device *out, | ||
177 | unsigned int hooknum, | ||
178 | const struct xt_target *target, | ||
179 | const void *targinfo) | ||
180 | { | 175 | { |
181 | if (net_ratelimit()) | 176 | if (net_ratelimit()) |
182 | printk("ip_tables: error: `%s'\n", (char *)targinfo); | 177 | printk("ip_tables: error: `%s'\n", |
178 | (const char *)par->targinfo); | ||
183 | 179 | ||
184 | return NF_DROP; | 180 | return NF_DROP; |
185 | } | 181 | } |
186 | 182 | ||
187 | /* Performance critical - called for every packet */ | 183 | /* Performance critical - called for every packet */ |
188 | static inline bool | 184 | static inline bool |
189 | do_match(struct ipt_entry_match *m, | 185 | do_match(struct ipt_entry_match *m, const struct sk_buff *skb, |
190 | const struct sk_buff *skb, | 186 | struct xt_match_param *par) |
191 | const struct net_device *in, | ||
192 | const struct net_device *out, | ||
193 | int offset, | ||
194 | bool *hotdrop) | ||
195 | { | 187 | { |
188 | par->match = m->u.kernel.match; | ||
189 | par->matchinfo = m->data; | ||
190 | |||
196 | /* Stop iteration if it doesn't match */ | 191 | /* Stop iteration if it doesn't match */ |
197 | if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data, | 192 | if (!m->u.kernel.match->match(skb, par)) |
198 | offset, ip_hdrlen(skb), hotdrop)) | ||
199 | return true; | 193 | return true; |
200 | else | 194 | else |
201 | return false; | 195 | return false; |
@@ -326,7 +320,6 @@ ipt_do_table(struct sk_buff *skb, | |||
326 | struct xt_table *table) | 320 | struct xt_table *table) |
327 | { | 321 | { |
328 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); | 322 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); |
329 | u_int16_t offset; | ||
330 | const struct iphdr *ip; | 323 | const struct iphdr *ip; |
331 | u_int16_t datalen; | 324 | u_int16_t datalen; |
332 | bool hotdrop = false; | 325 | bool hotdrop = false; |
@@ -336,6 +329,8 @@ ipt_do_table(struct sk_buff *skb, | |||
336 | void *table_base; | 329 | void *table_base; |
337 | struct ipt_entry *e, *back; | 330 | struct ipt_entry *e, *back; |
338 | struct xt_table_info *private; | 331 | struct xt_table_info *private; |
332 | struct xt_match_param mtpar; | ||
333 | struct xt_target_param tgpar; | ||
339 | 334 | ||
340 | /* Initialization */ | 335 | /* Initialization */ |
341 | ip = ip_hdr(skb); | 336 | ip = ip_hdr(skb); |
@@ -348,7 +343,13 @@ ipt_do_table(struct sk_buff *skb, | |||
348 | * things we don't know, ie. tcp syn flag or ports). If the | 343 | * things we don't know, ie. tcp syn flag or ports). If the |
349 | * rule is also a fragment-specific rule, non-fragments won't | 344 | * rule is also a fragment-specific rule, non-fragments won't |
350 | * match it. */ | 345 | * match it. */ |
351 | offset = ntohs(ip->frag_off) & IP_OFFSET; | 346 | mtpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; |
347 | mtpar.thoff = ip_hdrlen(skb); | ||
348 | mtpar.hotdrop = &hotdrop; | ||
349 | mtpar.in = tgpar.in = in; | ||
350 | mtpar.out = tgpar.out = out; | ||
351 | mtpar.family = tgpar.family = NFPROTO_IPV4; | ||
352 | tgpar.hooknum = hook; | ||
352 | 353 | ||
353 | read_lock_bh(&table->lock); | 354 | read_lock_bh(&table->lock); |
354 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); | 355 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); |
@@ -362,12 +363,11 @@ ipt_do_table(struct sk_buff *skb, | |||
362 | do { | 363 | do { |
363 | IP_NF_ASSERT(e); | 364 | IP_NF_ASSERT(e); |
364 | IP_NF_ASSERT(back); | 365 | IP_NF_ASSERT(back); |
365 | if (ip_packet_match(ip, indev, outdev, &e->ip, offset)) { | 366 | if (ip_packet_match(ip, indev, outdev, |
367 | &e->ip, mtpar.fragoff)) { | ||
366 | struct ipt_entry_target *t; | 368 | struct ipt_entry_target *t; |
367 | 369 | ||
368 | if (IPT_MATCH_ITERATE(e, do_match, | 370 | if (IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) |
369 | skb, in, out, | ||
370 | offset, &hotdrop) != 0) | ||
371 | goto no_match; | 371 | goto no_match; |
372 | 372 | ||
373 | ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); | 373 | ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); |
@@ -413,16 +413,14 @@ ipt_do_table(struct sk_buff *skb, | |||
413 | } else { | 413 | } else { |
414 | /* Targets which reenter must return | 414 | /* Targets which reenter must return |
415 | abs. verdicts */ | 415 | abs. verdicts */ |
416 | tgpar.target = t->u.kernel.target; | ||
417 | tgpar.targinfo = t->data; | ||
416 | #ifdef CONFIG_NETFILTER_DEBUG | 418 | #ifdef CONFIG_NETFILTER_DEBUG |
417 | ((struct ipt_entry *)table_base)->comefrom | 419 | ((struct ipt_entry *)table_base)->comefrom |
418 | = 0xeeeeeeec; | 420 | = 0xeeeeeeec; |
419 | #endif | 421 | #endif |
420 | verdict = t->u.kernel.target->target(skb, | 422 | verdict = t->u.kernel.target->target(skb, |
421 | in, out, | 423 | &tgpar); |
422 | hook, | ||
423 | t->u.kernel.target, | ||
424 | t->data); | ||
425 | |||
426 | #ifdef CONFIG_NETFILTER_DEBUG | 424 | #ifdef CONFIG_NETFILTER_DEBUG |
427 | if (((struct ipt_entry *)table_base)->comefrom | 425 | if (((struct ipt_entry *)table_base)->comefrom |
428 | != 0xeeeeeeec | 426 | != 0xeeeeeeec |
@@ -575,12 +573,17 @@ mark_source_chains(struct xt_table_info *newinfo, | |||
575 | static int | 573 | static int |
576 | cleanup_match(struct ipt_entry_match *m, unsigned int *i) | 574 | cleanup_match(struct ipt_entry_match *m, unsigned int *i) |
577 | { | 575 | { |
576 | struct xt_mtdtor_param par; | ||
577 | |||
578 | if (i && (*i)-- == 0) | 578 | if (i && (*i)-- == 0) |
579 | return 1; | 579 | return 1; |
580 | 580 | ||
581 | if (m->u.kernel.match->destroy) | 581 | par.match = m->u.kernel.match; |
582 | m->u.kernel.match->destroy(m->u.kernel.match, m->data); | 582 | par.matchinfo = m->data; |
583 | module_put(m->u.kernel.match->me); | 583 | par.family = NFPROTO_IPV4; |
584 | if (par.match->destroy != NULL) | ||
585 | par.match->destroy(&par); | ||
586 | module_put(par.match->me); | ||
584 | return 0; | 587 | return 0; |
585 | } | 588 | } |
586 | 589 | ||
@@ -606,34 +609,28 @@ check_entry(struct ipt_entry *e, const char *name) | |||
606 | } | 609 | } |
607 | 610 | ||
608 | static int | 611 | static int |
609 | check_match(struct ipt_entry_match *m, const char *name, | 612 | check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par, |
610 | const struct ipt_ip *ip, | 613 | unsigned int *i) |
611 | unsigned int hookmask, unsigned int *i) | ||
612 | { | 614 | { |
613 | struct xt_match *match; | 615 | const struct ipt_ip *ip = par->entryinfo; |
614 | int ret; | 616 | int ret; |
615 | 617 | ||
616 | match = m->u.kernel.match; | 618 | par->match = m->u.kernel.match; |
617 | ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m), | 619 | par->matchinfo = m->data; |
618 | name, hookmask, ip->proto, | 620 | |
619 | ip->invflags & IPT_INV_PROTO); | 621 | ret = xt_check_match(par, m->u.match_size - sizeof(*m), |
620 | if (!ret && m->u.kernel.match->checkentry | 622 | ip->proto, ip->invflags & IPT_INV_PROTO); |
621 | && !m->u.kernel.match->checkentry(name, ip, match, m->data, | 623 | if (ret < 0) { |
622 | hookmask)) { | ||
623 | duprintf("ip_tables: check failed for `%s'.\n", | 624 | duprintf("ip_tables: check failed for `%s'.\n", |
624 | m->u.kernel.match->name); | 625 | par.match->name); |
625 | ret = -EINVAL; | 626 | return ret; |
626 | } | 627 | } |
627 | if (!ret) | 628 | ++*i; |
628 | (*i)++; | 629 | return 0; |
629 | return ret; | ||
630 | } | 630 | } |
631 | 631 | ||
632 | static int | 632 | static int |
633 | find_check_match(struct ipt_entry_match *m, | 633 | find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par, |
634 | const char *name, | ||
635 | const struct ipt_ip *ip, | ||
636 | unsigned int hookmask, | ||
637 | unsigned int *i) | 634 | unsigned int *i) |
638 | { | 635 | { |
639 | struct xt_match *match; | 636 | struct xt_match *match; |
@@ -648,7 +645,7 @@ find_check_match(struct ipt_entry_match *m, | |||
648 | } | 645 | } |
649 | m->u.kernel.match = match; | 646 | m->u.kernel.match = match; |
650 | 647 | ||
651 | ret = check_match(m, name, ip, hookmask, i); | 648 | ret = check_match(m, par, i); |
652 | if (ret) | 649 | if (ret) |
653 | goto err; | 650 | goto err; |
654 | 651 | ||
@@ -660,23 +657,25 @@ err: | |||
660 | 657 | ||
661 | static int check_target(struct ipt_entry *e, const char *name) | 658 | static int check_target(struct ipt_entry *e, const char *name) |
662 | { | 659 | { |
663 | struct ipt_entry_target *t; | 660 | struct ipt_entry_target *t = ipt_get_target(e); |
664 | struct xt_target *target; | 661 | struct xt_tgchk_param par = { |
662 | .table = name, | ||
663 | .entryinfo = e, | ||
664 | .target = t->u.kernel.target, | ||
665 | .targinfo = t->data, | ||
666 | .hook_mask = e->comefrom, | ||
667 | .family = NFPROTO_IPV4, | ||
668 | }; | ||
665 | int ret; | 669 | int ret; |
666 | 670 | ||
667 | t = ipt_get_target(e); | 671 | ret = xt_check_target(&par, t->u.target_size - sizeof(*t), |
668 | target = t->u.kernel.target; | 672 | e->ip.proto, e->ip.invflags & IPT_INV_PROTO); |
669 | ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), | 673 | if (ret < 0) { |
670 | name, e->comefrom, e->ip.proto, | ||
671 | e->ip.invflags & IPT_INV_PROTO); | ||
672 | if (!ret && t->u.kernel.target->checkentry | ||
673 | && !t->u.kernel.target->checkentry(name, e, target, t->data, | ||
674 | e->comefrom)) { | ||
675 | duprintf("ip_tables: check failed for `%s'.\n", | 674 | duprintf("ip_tables: check failed for `%s'.\n", |
676 | t->u.kernel.target->name); | 675 | t->u.kernel.target->name); |
677 | ret = -EINVAL; | 676 | return ret; |
678 | } | 677 | } |
679 | return ret; | 678 | return 0; |
680 | } | 679 | } |
681 | 680 | ||
682 | static int | 681 | static int |
@@ -687,14 +686,18 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size, | |||
687 | struct xt_target *target; | 686 | struct xt_target *target; |
688 | int ret; | 687 | int ret; |
689 | unsigned int j; | 688 | unsigned int j; |
689 | struct xt_mtchk_param mtpar; | ||
690 | 690 | ||
691 | ret = check_entry(e, name); | 691 | ret = check_entry(e, name); |
692 | if (ret) | 692 | if (ret) |
693 | return ret; | 693 | return ret; |
694 | 694 | ||
695 | j = 0; | 695 | j = 0; |
696 | ret = IPT_MATCH_ITERATE(e, find_check_match, name, &e->ip, | 696 | mtpar.table = name; |
697 | e->comefrom, &j); | 697 | mtpar.entryinfo = &e->ip; |
698 | mtpar.hook_mask = e->comefrom; | ||
699 | mtpar.family = NFPROTO_IPV4; | ||
700 | ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j); | ||
698 | if (ret != 0) | 701 | if (ret != 0) |
699 | goto cleanup_matches; | 702 | goto cleanup_matches; |
700 | 703 | ||
@@ -769,6 +772,7 @@ check_entry_size_and_hooks(struct ipt_entry *e, | |||
769 | static int | 772 | static int |
770 | cleanup_entry(struct ipt_entry *e, unsigned int *i) | 773 | cleanup_entry(struct ipt_entry *e, unsigned int *i) |
771 | { | 774 | { |
775 | struct xt_tgdtor_param par; | ||
772 | struct ipt_entry_target *t; | 776 | struct ipt_entry_target *t; |
773 | 777 | ||
774 | if (i && (*i)-- == 0) | 778 | if (i && (*i)-- == 0) |
@@ -777,9 +781,13 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i) | |||
777 | /* Cleanup all matches */ | 781 | /* Cleanup all matches */ |
778 | IPT_MATCH_ITERATE(e, cleanup_match, NULL); | 782 | IPT_MATCH_ITERATE(e, cleanup_match, NULL); |
779 | t = ipt_get_target(e); | 783 | t = ipt_get_target(e); |
780 | if (t->u.kernel.target->destroy) | 784 | |
781 | t->u.kernel.target->destroy(t->u.kernel.target, t->data); | 785 | par.target = t->u.kernel.target; |
782 | module_put(t->u.kernel.target->me); | 786 | par.targinfo = t->data; |
787 | par.family = NFPROTO_IPV4; | ||
788 | if (par.target->destroy != NULL) | ||
789 | par.target->destroy(&par); | ||
790 | module_put(par.target->me); | ||
783 | return 0; | 791 | return 0; |
784 | } | 792 | } |
785 | 793 | ||
@@ -1648,12 +1656,16 @@ static int | |||
1648 | compat_check_entry(struct ipt_entry *e, const char *name, | 1656 | compat_check_entry(struct ipt_entry *e, const char *name, |
1649 | unsigned int *i) | 1657 | unsigned int *i) |
1650 | { | 1658 | { |
1659 | struct xt_mtchk_param mtpar; | ||
1651 | unsigned int j; | 1660 | unsigned int j; |
1652 | int ret; | 1661 | int ret; |
1653 | 1662 | ||
1654 | j = 0; | 1663 | j = 0; |
1655 | ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, | 1664 | mtpar.table = name; |
1656 | e->comefrom, &j); | 1665 | mtpar.entryinfo = &e->ip; |
1666 | mtpar.hook_mask = e->comefrom; | ||
1667 | mtpar.family = NFPROTO_IPV4; | ||
1668 | ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j); | ||
1657 | if (ret) | 1669 | if (ret) |
1658 | goto cleanup_matches; | 1670 | goto cleanup_matches; |
1659 | 1671 | ||
@@ -2121,30 +2133,23 @@ icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code, | |||
2121 | } | 2133 | } |
2122 | 2134 | ||
2123 | static bool | 2135 | static bool |
2124 | icmp_match(const struct sk_buff *skb, | 2136 | icmp_match(const struct sk_buff *skb, const struct xt_match_param *par) |
2125 | const struct net_device *in, | ||
2126 | const struct net_device *out, | ||
2127 | const struct xt_match *match, | ||
2128 | const void *matchinfo, | ||
2129 | int offset, | ||
2130 | unsigned int protoff, | ||
2131 | bool *hotdrop) | ||
2132 | { | 2137 | { |
2133 | const struct icmphdr *ic; | 2138 | const struct icmphdr *ic; |
2134 | struct icmphdr _icmph; | 2139 | struct icmphdr _icmph; |
2135 | const struct ipt_icmp *icmpinfo = matchinfo; | 2140 | const struct ipt_icmp *icmpinfo = par->matchinfo; |
2136 | 2141 | ||
2137 | /* Must not be a fragment. */ | 2142 | /* Must not be a fragment. */ |
2138 | if (offset) | 2143 | if (par->fragoff != 0) |
2139 | return false; | 2144 | return false; |
2140 | 2145 | ||
2141 | ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph); | 2146 | ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph); |
2142 | if (ic == NULL) { | 2147 | if (ic == NULL) { |
2143 | /* We've been asked to examine this packet, and we | 2148 | /* We've been asked to examine this packet, and we |
2144 | * can't. Hence, no choice but to drop. | 2149 | * can't. Hence, no choice but to drop. |
2145 | */ | 2150 | */ |
2146 | duprintf("Dropping evil ICMP tinygram.\n"); | 2151 | duprintf("Dropping evil ICMP tinygram.\n"); |
2147 | *hotdrop = true; | 2152 | *par->hotdrop = true; |
2148 | return false; | 2153 | return false; |
2149 | } | 2154 | } |
2150 | 2155 | ||
@@ -2155,15 +2160,9 @@ icmp_match(const struct sk_buff *skb, | |||
2155 | !!(icmpinfo->invflags&IPT_ICMP_INV)); | 2160 | !!(icmpinfo->invflags&IPT_ICMP_INV)); |
2156 | } | 2161 | } |
2157 | 2162 | ||
2158 | /* Called when user tries to insert an entry of this type. */ | 2163 | static bool icmp_checkentry(const struct xt_mtchk_param *par) |
2159 | static bool | ||
2160 | icmp_checkentry(const char *tablename, | ||
2161 | const void *entry, | ||
2162 | const struct xt_match *match, | ||
2163 | void *matchinfo, | ||
2164 | unsigned int hook_mask) | ||
2165 | { | 2164 | { |
2166 | const struct ipt_icmp *icmpinfo = matchinfo; | 2165 | const struct ipt_icmp *icmpinfo = par->matchinfo; |
2167 | 2166 | ||
2168 | /* Must specify no unknown invflags */ | 2167 | /* Must specify no unknown invflags */ |
2169 | return !(icmpinfo->invflags & ~IPT_ICMP_INV); | 2168 | return !(icmpinfo->invflags & ~IPT_ICMP_INV); |
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index fafe8ebb4c55..7ac1677419a9 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -281,11 +281,9 @@ clusterip_responsible(const struct clusterip_config *config, u_int32_t hash) | |||
281 | ***********************************************************************/ | 281 | ***********************************************************************/ |
282 | 282 | ||
283 | static unsigned int | 283 | static unsigned int |
284 | clusterip_tg(struct sk_buff *skb, const struct net_device *in, | 284 | clusterip_tg(struct sk_buff *skb, const struct xt_target_param *par) |
285 | const struct net_device *out, unsigned int hooknum, | ||
286 | const struct xt_target *target, const void *targinfo) | ||
287 | { | 285 | { |
288 | const struct ipt_clusterip_tgt_info *cipinfo = targinfo; | 286 | const struct ipt_clusterip_tgt_info *cipinfo = par->targinfo; |
289 | struct nf_conn *ct; | 287 | struct nf_conn *ct; |
290 | enum ip_conntrack_info ctinfo; | 288 | enum ip_conntrack_info ctinfo; |
291 | u_int32_t hash; | 289 | u_int32_t hash; |
@@ -349,13 +347,10 @@ clusterip_tg(struct sk_buff *skb, const struct net_device *in, | |||
349 | return XT_CONTINUE; | 347 | return XT_CONTINUE; |
350 | } | 348 | } |
351 | 349 | ||
352 | static bool | 350 | static bool clusterip_tg_check(const struct xt_tgchk_param *par) |
353 | clusterip_tg_check(const char *tablename, const void *e_void, | ||
354 | const struct xt_target *target, void *targinfo, | ||
355 | unsigned int hook_mask) | ||
356 | { | 351 | { |
357 | struct ipt_clusterip_tgt_info *cipinfo = targinfo; | 352 | struct ipt_clusterip_tgt_info *cipinfo = par->targinfo; |
358 | const struct ipt_entry *e = e_void; | 353 | const struct ipt_entry *e = par->entryinfo; |
359 | 354 | ||
360 | struct clusterip_config *config; | 355 | struct clusterip_config *config; |
361 | 356 | ||
@@ -406,9 +401,9 @@ clusterip_tg_check(const char *tablename, const void *e_void, | |||
406 | } | 401 | } |
407 | cipinfo->config = config; | 402 | cipinfo->config = config; |
408 | 403 | ||
409 | if (nf_ct_l3proto_try_module_get(target->family) < 0) { | 404 | if (nf_ct_l3proto_try_module_get(par->target->family) < 0) { |
410 | printk(KERN_WARNING "can't load conntrack support for " | 405 | printk(KERN_WARNING "can't load conntrack support for " |
411 | "proto=%u\n", target->family); | 406 | "proto=%u\n", par->target->family); |
412 | return false; | 407 | return false; |
413 | } | 408 | } |
414 | 409 | ||
@@ -416,9 +411,9 @@ clusterip_tg_check(const char *tablename, const void *e_void, | |||
416 | } | 411 | } |
417 | 412 | ||
418 | /* drop reference count of cluster config when rule is deleted */ | 413 | /* drop reference count of cluster config when rule is deleted */ |
419 | static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo) | 414 | static void clusterip_tg_destroy(const struct xt_tgdtor_param *par) |
420 | { | 415 | { |
421 | const struct ipt_clusterip_tgt_info *cipinfo = targinfo; | 416 | const struct ipt_clusterip_tgt_info *cipinfo = par->targinfo; |
422 | 417 | ||
423 | /* if no more entries are referencing the config, remove it | 418 | /* if no more entries are referencing the config, remove it |
424 | * from the list and destroy the proc entry */ | 419 | * from the list and destroy the proc entry */ |
@@ -426,7 +421,7 @@ static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo) | |||
426 | 421 | ||
427 | clusterip_config_put(cipinfo->config); | 422 | clusterip_config_put(cipinfo->config); |
428 | 423 | ||
429 | nf_ct_l3proto_module_put(target->family); | 424 | nf_ct_l3proto_module_put(par->target->family); |
430 | } | 425 | } |
431 | 426 | ||
432 | #ifdef CONFIG_COMPAT | 427 | #ifdef CONFIG_COMPAT |
@@ -445,7 +440,7 @@ struct compat_ipt_clusterip_tgt_info | |||
445 | 440 | ||
446 | static struct xt_target clusterip_tg_reg __read_mostly = { | 441 | static struct xt_target clusterip_tg_reg __read_mostly = { |
447 | .name = "CLUSTERIP", | 442 | .name = "CLUSTERIP", |
448 | .family = AF_INET, | 443 | .family = NFPROTO_IPV4, |
449 | .target = clusterip_tg, | 444 | .target = clusterip_tg, |
450 | .checkentry = clusterip_tg_check, | 445 | .checkentry = clusterip_tg_check, |
451 | .destroy = clusterip_tg_destroy, | 446 | .destroy = clusterip_tg_destroy, |
@@ -546,7 +541,7 @@ arp_mangle(unsigned int hook, | |||
546 | 541 | ||
547 | static struct nf_hook_ops cip_arp_ops __read_mostly = { | 542 | static struct nf_hook_ops cip_arp_ops __read_mostly = { |
548 | .hook = arp_mangle, | 543 | .hook = arp_mangle, |
549 | .pf = NF_ARP, | 544 | .pf = NFPROTO_ARP, |
550 | .hooknum = NF_ARP_OUT, | 545 | .hooknum = NF_ARP_OUT, |
551 | .priority = -1 | 546 | .priority = -1 |
552 | }; | 547 | }; |
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c index d60139c134ca..f7e2fa0974dc 100644 --- a/net/ipv4/netfilter/ipt_ECN.c +++ b/net/ipv4/netfilter/ipt_ECN.c | |||
@@ -77,11 +77,9 @@ set_ect_tcp(struct sk_buff *skb, const struct ipt_ECN_info *einfo) | |||
77 | } | 77 | } |
78 | 78 | ||
79 | static unsigned int | 79 | static unsigned int |
80 | ecn_tg(struct sk_buff *skb, const struct net_device *in, | 80 | ecn_tg(struct sk_buff *skb, const struct xt_target_param *par) |
81 | const struct net_device *out, unsigned int hooknum, | ||
82 | const struct xt_target *target, const void *targinfo) | ||
83 | { | 81 | { |
84 | const struct ipt_ECN_info *einfo = targinfo; | 82 | const struct ipt_ECN_info *einfo = par->targinfo; |
85 | 83 | ||
86 | if (einfo->operation & IPT_ECN_OP_SET_IP) | 84 | if (einfo->operation & IPT_ECN_OP_SET_IP) |
87 | if (!set_ect_ip(skb, einfo)) | 85 | if (!set_ect_ip(skb, einfo)) |
@@ -95,13 +93,10 @@ ecn_tg(struct sk_buff *skb, const struct net_device *in, | |||
95 | return XT_CONTINUE; | 93 | return XT_CONTINUE; |
96 | } | 94 | } |
97 | 95 | ||
98 | static bool | 96 | static bool ecn_tg_check(const struct xt_tgchk_param *par) |
99 | ecn_tg_check(const char *tablename, const void *e_void, | ||
100 | const struct xt_target *target, void *targinfo, | ||
101 | unsigned int hook_mask) | ||
102 | { | 97 | { |
103 | const struct ipt_ECN_info *einfo = targinfo; | 98 | const struct ipt_ECN_info *einfo = par->targinfo; |
104 | const struct ipt_entry *e = e_void; | 99 | const struct ipt_entry *e = par->entryinfo; |
105 | 100 | ||
106 | if (einfo->operation & IPT_ECN_OP_MASK) { | 101 | if (einfo->operation & IPT_ECN_OP_MASK) { |
107 | printk(KERN_WARNING "ECN: unsupported ECN operation %x\n", | 102 | printk(KERN_WARNING "ECN: unsupported ECN operation %x\n", |
@@ -124,7 +119,7 @@ ecn_tg_check(const char *tablename, const void *e_void, | |||
124 | 119 | ||
125 | static struct xt_target ecn_tg_reg __read_mostly = { | 120 | static struct xt_target ecn_tg_reg __read_mostly = { |
126 | .name = "ECN", | 121 | .name = "ECN", |
127 | .family = AF_INET, | 122 | .family = NFPROTO_IPV4, |
128 | .target = ecn_tg, | 123 | .target = ecn_tg, |
129 | .targetsize = sizeof(struct ipt_ECN_info), | 124 | .targetsize = sizeof(struct ipt_ECN_info), |
130 | .table = "mangle", | 125 | .table = "mangle", |
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index 0af14137137b..fc6ce04a3e35 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c | |||
@@ -375,7 +375,7 @@ static struct nf_loginfo default_loginfo = { | |||
375 | }; | 375 | }; |
376 | 376 | ||
377 | static void | 377 | static void |
378 | ipt_log_packet(unsigned int pf, | 378 | ipt_log_packet(u_int8_t pf, |
379 | unsigned int hooknum, | 379 | unsigned int hooknum, |
380 | const struct sk_buff *skb, | 380 | const struct sk_buff *skb, |
381 | const struct net_device *in, | 381 | const struct net_device *in, |
@@ -426,28 +426,23 @@ ipt_log_packet(unsigned int pf, | |||
426 | } | 426 | } |
427 | 427 | ||
428 | static unsigned int | 428 | static unsigned int |
429 | log_tg(struct sk_buff *skb, const struct net_device *in, | 429 | log_tg(struct sk_buff *skb, const struct xt_target_param *par) |
430 | const struct net_device *out, unsigned int hooknum, | ||
431 | const struct xt_target *target, const void *targinfo) | ||
432 | { | 430 | { |
433 | const struct ipt_log_info *loginfo = targinfo; | 431 | const struct ipt_log_info *loginfo = par->targinfo; |
434 | struct nf_loginfo li; | 432 | struct nf_loginfo li; |
435 | 433 | ||
436 | li.type = NF_LOG_TYPE_LOG; | 434 | li.type = NF_LOG_TYPE_LOG; |
437 | li.u.log.level = loginfo->level; | 435 | li.u.log.level = loginfo->level; |
438 | li.u.log.logflags = loginfo->logflags; | 436 | li.u.log.logflags = loginfo->logflags; |
439 | 437 | ||
440 | ipt_log_packet(PF_INET, hooknum, skb, in, out, &li, | 438 | ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in, par->out, &li, |
441 | loginfo->prefix); | 439 | loginfo->prefix); |
442 | return XT_CONTINUE; | 440 | return XT_CONTINUE; |
443 | } | 441 | } |
444 | 442 | ||
445 | static bool | 443 | static bool log_tg_check(const struct xt_tgchk_param *par) |
446 | log_tg_check(const char *tablename, const void *e, | ||
447 | const struct xt_target *target, void *targinfo, | ||
448 | unsigned int hook_mask) | ||
449 | { | 444 | { |
450 | const struct ipt_log_info *loginfo = targinfo; | 445 | const struct ipt_log_info *loginfo = par->targinfo; |
451 | 446 | ||
452 | if (loginfo->level >= 8) { | 447 | if (loginfo->level >= 8) { |
453 | pr_debug("LOG: level %u >= 8\n", loginfo->level); | 448 | pr_debug("LOG: level %u >= 8\n", loginfo->level); |
@@ -463,7 +458,7 @@ log_tg_check(const char *tablename, const void *e, | |||
463 | 458 | ||
464 | static struct xt_target log_tg_reg __read_mostly = { | 459 | static struct xt_target log_tg_reg __read_mostly = { |
465 | .name = "LOG", | 460 | .name = "LOG", |
466 | .family = AF_INET, | 461 | .family = NFPROTO_IPV4, |
467 | .target = log_tg, | 462 | .target = log_tg, |
468 | .targetsize = sizeof(struct ipt_log_info), | 463 | .targetsize = sizeof(struct ipt_log_info), |
469 | .checkentry = log_tg_check, | 464 | .checkentry = log_tg_check, |
@@ -483,7 +478,7 @@ static int __init log_tg_init(void) | |||
483 | ret = xt_register_target(&log_tg_reg); | 478 | ret = xt_register_target(&log_tg_reg); |
484 | if (ret < 0) | 479 | if (ret < 0) |
485 | return ret; | 480 | return ret; |
486 | nf_log_register(PF_INET, &ipt_log_logger); | 481 | nf_log_register(NFPROTO_IPV4, &ipt_log_logger); |
487 | return 0; | 482 | return 0; |
488 | } | 483 | } |
489 | 484 | ||
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c index 0841aefaa503..f389f60cb105 100644 --- a/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c | |||
@@ -31,12 +31,9 @@ MODULE_DESCRIPTION("Xtables: automatic-address SNAT"); | |||
31 | static DEFINE_RWLOCK(masq_lock); | 31 | static DEFINE_RWLOCK(masq_lock); |
32 | 32 | ||
33 | /* FIXME: Multiple targets. --RR */ | 33 | /* FIXME: Multiple targets. --RR */ |
34 | static bool | 34 | static bool masquerade_tg_check(const struct xt_tgchk_param *par) |
35 | masquerade_tg_check(const char *tablename, const void *e, | ||
36 | const struct xt_target *target, void *targinfo, | ||
37 | unsigned int hook_mask) | ||
38 | { | 35 | { |
39 | const struct nf_nat_multi_range_compat *mr = targinfo; | 36 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
40 | 37 | ||
41 | if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { | 38 | if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { |
42 | pr_debug("masquerade_check: bad MAP_IPS.\n"); | 39 | pr_debug("masquerade_check: bad MAP_IPS.\n"); |
@@ -50,9 +47,7 @@ masquerade_tg_check(const char *tablename, const void *e, | |||
50 | } | 47 | } |
51 | 48 | ||
52 | static unsigned int | 49 | static unsigned int |
53 | masquerade_tg(struct sk_buff *skb, const struct net_device *in, | 50 | masquerade_tg(struct sk_buff *skb, const struct xt_target_param *par) |
54 | const struct net_device *out, unsigned int hooknum, | ||
55 | const struct xt_target *target, const void *targinfo) | ||
56 | { | 51 | { |
57 | struct nf_conn *ct; | 52 | struct nf_conn *ct; |
58 | struct nf_conn_nat *nat; | 53 | struct nf_conn_nat *nat; |
@@ -62,7 +57,7 @@ masquerade_tg(struct sk_buff *skb, const struct net_device *in, | |||
62 | const struct rtable *rt; | 57 | const struct rtable *rt; |
63 | __be32 newsrc; | 58 | __be32 newsrc; |
64 | 59 | ||
65 | NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING); | 60 | NF_CT_ASSERT(par->hooknum == NF_INET_POST_ROUTING); |
66 | 61 | ||
67 | ct = nf_ct_get(skb, &ctinfo); | 62 | ct = nf_ct_get(skb, &ctinfo); |
68 | nat = nfct_nat(ct); | 63 | nat = nfct_nat(ct); |
@@ -76,16 +71,16 @@ masquerade_tg(struct sk_buff *skb, const struct net_device *in, | |||
76 | if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip == 0) | 71 | if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip == 0) |
77 | return NF_ACCEPT; | 72 | return NF_ACCEPT; |
78 | 73 | ||
79 | mr = targinfo; | 74 | mr = par->targinfo; |
80 | rt = skb->rtable; | 75 | rt = skb->rtable; |
81 | newsrc = inet_select_addr(out, rt->rt_gateway, RT_SCOPE_UNIVERSE); | 76 | newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE); |
82 | if (!newsrc) { | 77 | if (!newsrc) { |
83 | printk("MASQUERADE: %s ate my IP address\n", out->name); | 78 | printk("MASQUERADE: %s ate my IP address\n", par->out->name); |
84 | return NF_DROP; | 79 | return NF_DROP; |
85 | } | 80 | } |
86 | 81 | ||
87 | write_lock_bh(&masq_lock); | 82 | write_lock_bh(&masq_lock); |
88 | nat->masq_index = out->ifindex; | 83 | nat->masq_index = par->out->ifindex; |
89 | write_unlock_bh(&masq_lock); | 84 | write_unlock_bh(&masq_lock); |
90 | 85 | ||
91 | /* Transfer from original range. */ | 86 | /* Transfer from original range. */ |
@@ -119,9 +114,7 @@ static int masq_device_event(struct notifier_block *this, | |||
119 | void *ptr) | 114 | void *ptr) |
120 | { | 115 | { |
121 | const struct net_device *dev = ptr; | 116 | const struct net_device *dev = ptr; |
122 | 117 | struct net *net = dev_net(dev); | |
123 | if (!net_eq(dev_net(dev), &init_net)) | ||
124 | return NOTIFY_DONE; | ||
125 | 118 | ||
126 | if (event == NETDEV_DOWN) { | 119 | if (event == NETDEV_DOWN) { |
127 | /* Device was downed. Search entire table for | 120 | /* Device was downed. Search entire table for |
@@ -129,7 +122,8 @@ static int masq_device_event(struct notifier_block *this, | |||
129 | and forget them. */ | 122 | and forget them. */ |
130 | NF_CT_ASSERT(dev->ifindex != 0); | 123 | NF_CT_ASSERT(dev->ifindex != 0); |
131 | 124 | ||
132 | nf_ct_iterate_cleanup(device_cmp, (void *)(long)dev->ifindex); | 125 | nf_ct_iterate_cleanup(net, device_cmp, |
126 | (void *)(long)dev->ifindex); | ||
133 | } | 127 | } |
134 | 128 | ||
135 | return NOTIFY_DONE; | 129 | return NOTIFY_DONE; |
@@ -153,7 +147,7 @@ static struct notifier_block masq_inet_notifier = { | |||
153 | 147 | ||
154 | static struct xt_target masquerade_tg_reg __read_mostly = { | 148 | static struct xt_target masquerade_tg_reg __read_mostly = { |
155 | .name = "MASQUERADE", | 149 | .name = "MASQUERADE", |
156 | .family = AF_INET, | 150 | .family = NFPROTO_IPV4, |
157 | .target = masquerade_tg, | 151 | .target = masquerade_tg, |
158 | .targetsize = sizeof(struct nf_nat_multi_range_compat), | 152 | .targetsize = sizeof(struct nf_nat_multi_range_compat), |
159 | .table = "nat", | 153 | .table = "nat", |
diff --git a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c index 6739abfd1521..7c29582d4ec8 100644 --- a/net/ipv4/netfilter/ipt_NETMAP.c +++ b/net/ipv4/netfilter/ipt_NETMAP.c | |||
@@ -22,12 +22,9 @@ MODULE_LICENSE("GPL"); | |||
22 | MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>"); | 22 | MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>"); |
23 | MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets"); | 23 | MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets"); |
24 | 24 | ||
25 | static bool | 25 | static bool netmap_tg_check(const struct xt_tgchk_param *par) |
26 | netmap_tg_check(const char *tablename, const void *e, | ||
27 | const struct xt_target *target, void *targinfo, | ||
28 | unsigned int hook_mask) | ||
29 | { | 26 | { |
30 | const struct nf_nat_multi_range_compat *mr = targinfo; | 27 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
31 | 28 | ||
32 | if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) { | 29 | if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) { |
33 | pr_debug("NETMAP:check: bad MAP_IPS.\n"); | 30 | pr_debug("NETMAP:check: bad MAP_IPS.\n"); |
@@ -41,24 +38,23 @@ netmap_tg_check(const char *tablename, const void *e, | |||
41 | } | 38 | } |
42 | 39 | ||
43 | static unsigned int | 40 | static unsigned int |
44 | netmap_tg(struct sk_buff *skb, const struct net_device *in, | 41 | netmap_tg(struct sk_buff *skb, const struct xt_target_param *par) |
45 | const struct net_device *out, unsigned int hooknum, | ||
46 | const struct xt_target *target, const void *targinfo) | ||
47 | { | 42 | { |
48 | struct nf_conn *ct; | 43 | struct nf_conn *ct; |
49 | enum ip_conntrack_info ctinfo; | 44 | enum ip_conntrack_info ctinfo; |
50 | __be32 new_ip, netmask; | 45 | __be32 new_ip, netmask; |
51 | const struct nf_nat_multi_range_compat *mr = targinfo; | 46 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
52 | struct nf_nat_range newrange; | 47 | struct nf_nat_range newrange; |
53 | 48 | ||
54 | NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING | 49 | NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING || |
55 | || hooknum == NF_INET_POST_ROUTING | 50 | par->hooknum == NF_INET_POST_ROUTING || |
56 | || hooknum == NF_INET_LOCAL_OUT); | 51 | par->hooknum == NF_INET_LOCAL_OUT); |
57 | ct = nf_ct_get(skb, &ctinfo); | 52 | ct = nf_ct_get(skb, &ctinfo); |
58 | 53 | ||
59 | netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip); | 54 | netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip); |
60 | 55 | ||
61 | if (hooknum == NF_INET_PRE_ROUTING || hooknum == NF_INET_LOCAL_OUT) | 56 | if (par->hooknum == NF_INET_PRE_ROUTING || |
57 | par->hooknum == NF_INET_LOCAL_OUT) | ||
62 | new_ip = ip_hdr(skb)->daddr & ~netmask; | 58 | new_ip = ip_hdr(skb)->daddr & ~netmask; |
63 | else | 59 | else |
64 | new_ip = ip_hdr(skb)->saddr & ~netmask; | 60 | new_ip = ip_hdr(skb)->saddr & ~netmask; |
@@ -70,12 +66,12 @@ netmap_tg(struct sk_buff *skb, const struct net_device *in, | |||
70 | mr->range[0].min, mr->range[0].max }); | 66 | mr->range[0].min, mr->range[0].max }); |
71 | 67 | ||
72 | /* Hand modified range to generic setup. */ | 68 | /* Hand modified range to generic setup. */ |
73 | return nf_nat_setup_info(ct, &newrange, HOOK2MANIP(hooknum)); | 69 | return nf_nat_setup_info(ct, &newrange, HOOK2MANIP(par->hooknum)); |
74 | } | 70 | } |
75 | 71 | ||
76 | static struct xt_target netmap_tg_reg __read_mostly = { | 72 | static struct xt_target netmap_tg_reg __read_mostly = { |
77 | .name = "NETMAP", | 73 | .name = "NETMAP", |
78 | .family = AF_INET, | 74 | .family = NFPROTO_IPV4, |
79 | .target = netmap_tg, | 75 | .target = netmap_tg, |
80 | .targetsize = sizeof(struct nf_nat_multi_range_compat), | 76 | .targetsize = sizeof(struct nf_nat_multi_range_compat), |
81 | .table = "nat", | 77 | .table = "nat", |
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c index 5c6292449d13..698e5e78685b 100644 --- a/net/ipv4/netfilter/ipt_REDIRECT.c +++ b/net/ipv4/netfilter/ipt_REDIRECT.c | |||
@@ -26,12 +26,9 @@ MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); | |||
26 | MODULE_DESCRIPTION("Xtables: Connection redirection to localhost"); | 26 | MODULE_DESCRIPTION("Xtables: Connection redirection to localhost"); |
27 | 27 | ||
28 | /* FIXME: Take multiple ranges --RR */ | 28 | /* FIXME: Take multiple ranges --RR */ |
29 | static bool | 29 | static bool redirect_tg_check(const struct xt_tgchk_param *par) |
30 | redirect_tg_check(const char *tablename, const void *e, | ||
31 | const struct xt_target *target, void *targinfo, | ||
32 | unsigned int hook_mask) | ||
33 | { | 30 | { |
34 | const struct nf_nat_multi_range_compat *mr = targinfo; | 31 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
35 | 32 | ||
36 | if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { | 33 | if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { |
37 | pr_debug("redirect_check: bad MAP_IPS.\n"); | 34 | pr_debug("redirect_check: bad MAP_IPS.\n"); |
@@ -45,24 +42,22 @@ redirect_tg_check(const char *tablename, const void *e, | |||
45 | } | 42 | } |
46 | 43 | ||
47 | static unsigned int | 44 | static unsigned int |
48 | redirect_tg(struct sk_buff *skb, const struct net_device *in, | 45 | redirect_tg(struct sk_buff *skb, const struct xt_target_param *par) |
49 | const struct net_device *out, unsigned int hooknum, | ||
50 | const struct xt_target *target, const void *targinfo) | ||
51 | { | 46 | { |
52 | struct nf_conn *ct; | 47 | struct nf_conn *ct; |
53 | enum ip_conntrack_info ctinfo; | 48 | enum ip_conntrack_info ctinfo; |
54 | __be32 newdst; | 49 | __be32 newdst; |
55 | const struct nf_nat_multi_range_compat *mr = targinfo; | 50 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
56 | struct nf_nat_range newrange; | 51 | struct nf_nat_range newrange; |
57 | 52 | ||
58 | NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING | 53 | NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING || |
59 | || hooknum == NF_INET_LOCAL_OUT); | 54 | par->hooknum == NF_INET_LOCAL_OUT); |
60 | 55 | ||
61 | ct = nf_ct_get(skb, &ctinfo); | 56 | ct = nf_ct_get(skb, &ctinfo); |
62 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); | 57 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); |
63 | 58 | ||
64 | /* Local packets: make them go to loopback */ | 59 | /* Local packets: make them go to loopback */ |
65 | if (hooknum == NF_INET_LOCAL_OUT) | 60 | if (par->hooknum == NF_INET_LOCAL_OUT) |
66 | newdst = htonl(0x7F000001); | 61 | newdst = htonl(0x7F000001); |
67 | else { | 62 | else { |
68 | struct in_device *indev; | 63 | struct in_device *indev; |
@@ -92,7 +87,7 @@ redirect_tg(struct sk_buff *skb, const struct net_device *in, | |||
92 | 87 | ||
93 | static struct xt_target redirect_tg_reg __read_mostly = { | 88 | static struct xt_target redirect_tg_reg __read_mostly = { |
94 | .name = "REDIRECT", | 89 | .name = "REDIRECT", |
95 | .family = AF_INET, | 90 | .family = NFPROTO_IPV4, |
96 | .target = redirect_tg, | 91 | .target = redirect_tg, |
97 | .targetsize = sizeof(struct nf_nat_multi_range_compat), | 92 | .targetsize = sizeof(struct nf_nat_multi_range_compat), |
98 | .table = "nat", | 93 | .table = "nat", |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 2639872849da..0b4b6e0ff2b9 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -136,11 +136,9 @@ static inline void send_unreach(struct sk_buff *skb_in, int code) | |||
136 | } | 136 | } |
137 | 137 | ||
138 | static unsigned int | 138 | static unsigned int |
139 | reject_tg(struct sk_buff *skb, const struct net_device *in, | 139 | reject_tg(struct sk_buff *skb, const struct xt_target_param *par) |
140 | const struct net_device *out, unsigned int hooknum, | ||
141 | const struct xt_target *target, const void *targinfo) | ||
142 | { | 140 | { |
143 | const struct ipt_reject_info *reject = targinfo; | 141 | const struct ipt_reject_info *reject = par->targinfo; |
144 | 142 | ||
145 | /* WARNING: This code causes reentry within iptables. | 143 | /* WARNING: This code causes reentry within iptables. |
146 | This means that the iptables jump stack is now crap. We | 144 | This means that the iptables jump stack is now crap. We |
@@ -168,7 +166,7 @@ reject_tg(struct sk_buff *skb, const struct net_device *in, | |||
168 | send_unreach(skb, ICMP_PKT_FILTERED); | 166 | send_unreach(skb, ICMP_PKT_FILTERED); |
169 | break; | 167 | break; |
170 | case IPT_TCP_RESET: | 168 | case IPT_TCP_RESET: |
171 | send_reset(skb, hooknum); | 169 | send_reset(skb, par->hooknum); |
172 | case IPT_ICMP_ECHOREPLY: | 170 | case IPT_ICMP_ECHOREPLY: |
173 | /* Doesn't happen. */ | 171 | /* Doesn't happen. */ |
174 | break; | 172 | break; |
@@ -177,13 +175,10 @@ reject_tg(struct sk_buff *skb, const struct net_device *in, | |||
177 | return NF_DROP; | 175 | return NF_DROP; |
178 | } | 176 | } |
179 | 177 | ||
180 | static bool | 178 | static bool reject_tg_check(const struct xt_tgchk_param *par) |
181 | reject_tg_check(const char *tablename, const void *e_void, | ||
182 | const struct xt_target *target, void *targinfo, | ||
183 | unsigned int hook_mask) | ||
184 | { | 179 | { |
185 | const struct ipt_reject_info *rejinfo = targinfo; | 180 | const struct ipt_reject_info *rejinfo = par->targinfo; |
186 | const struct ipt_entry *e = e_void; | 181 | const struct ipt_entry *e = par->entryinfo; |
187 | 182 | ||
188 | if (rejinfo->with == IPT_ICMP_ECHOREPLY) { | 183 | if (rejinfo->with == IPT_ICMP_ECHOREPLY) { |
189 | printk("ipt_REJECT: ECHOREPLY no longer supported.\n"); | 184 | printk("ipt_REJECT: ECHOREPLY no longer supported.\n"); |
@@ -201,7 +196,7 @@ reject_tg_check(const char *tablename, const void *e_void, | |||
201 | 196 | ||
202 | static struct xt_target reject_tg_reg __read_mostly = { | 197 | static struct xt_target reject_tg_reg __read_mostly = { |
203 | .name = "REJECT", | 198 | .name = "REJECT", |
204 | .family = AF_INET, | 199 | .family = NFPROTO_IPV4, |
205 | .target = reject_tg, | 200 | .target = reject_tg, |
206 | .targetsize = sizeof(struct ipt_reject_info), | 201 | .targetsize = sizeof(struct ipt_reject_info), |
207 | .table = "filter", | 202 | .table = "filter", |
diff --git a/net/ipv4/netfilter/ipt_TTL.c b/net/ipv4/netfilter/ipt_TTL.c index 30eed65e7338..6d76aae90cc0 100644 --- a/net/ipv4/netfilter/ipt_TTL.c +++ b/net/ipv4/netfilter/ipt_TTL.c | |||
@@ -20,12 +20,10 @@ MODULE_DESCRIPTION("Xtables: IPv4 TTL field modification target"); | |||
20 | MODULE_LICENSE("GPL"); | 20 | MODULE_LICENSE("GPL"); |
21 | 21 | ||
22 | static unsigned int | 22 | static unsigned int |
23 | ttl_tg(struct sk_buff *skb, const struct net_device *in, | 23 | ttl_tg(struct sk_buff *skb, const struct xt_target_param *par) |
24 | const struct net_device *out, unsigned int hooknum, | ||
25 | const struct xt_target *target, const void *targinfo) | ||
26 | { | 24 | { |
27 | struct iphdr *iph; | 25 | struct iphdr *iph; |
28 | const struct ipt_TTL_info *info = targinfo; | 26 | const struct ipt_TTL_info *info = par->targinfo; |
29 | int new_ttl; | 27 | int new_ttl; |
30 | 28 | ||
31 | if (!skb_make_writable(skb, skb->len)) | 29 | if (!skb_make_writable(skb, skb->len)) |
@@ -61,12 +59,9 @@ ttl_tg(struct sk_buff *skb, const struct net_device *in, | |||
61 | return XT_CONTINUE; | 59 | return XT_CONTINUE; |
62 | } | 60 | } |
63 | 61 | ||
64 | static bool | 62 | static bool ttl_tg_check(const struct xt_tgchk_param *par) |
65 | ttl_tg_check(const char *tablename, const void *e, | ||
66 | const struct xt_target *target, void *targinfo, | ||
67 | unsigned int hook_mask) | ||
68 | { | 63 | { |
69 | const struct ipt_TTL_info *info = targinfo; | 64 | const struct ipt_TTL_info *info = par->targinfo; |
70 | 65 | ||
71 | if (info->mode > IPT_TTL_MAXMODE) { | 66 | if (info->mode > IPT_TTL_MAXMODE) { |
72 | printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n", | 67 | printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n", |
@@ -80,7 +75,7 @@ ttl_tg_check(const char *tablename, const void *e, | |||
80 | 75 | ||
81 | static struct xt_target ttl_tg_reg __read_mostly = { | 76 | static struct xt_target ttl_tg_reg __read_mostly = { |
82 | .name = "TTL", | 77 | .name = "TTL", |
83 | .family = AF_INET, | 78 | .family = NFPROTO_IPV4, |
84 | .target = ttl_tg, | 79 | .target = ttl_tg, |
85 | .targetsize = sizeof(struct ipt_TTL_info), | 80 | .targetsize = sizeof(struct ipt_TTL_info), |
86 | .table = "mangle", | 81 | .table = "mangle", |
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index b192756c6d0d..18a2826b57c6 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c | |||
@@ -281,18 +281,14 @@ alloc_failure: | |||
281 | } | 281 | } |
282 | 282 | ||
283 | static unsigned int | 283 | static unsigned int |
284 | ulog_tg(struct sk_buff *skb, const struct net_device *in, | 284 | ulog_tg(struct sk_buff *skb, const struct xt_target_param *par) |
285 | const struct net_device *out, unsigned int hooknum, | ||
286 | const struct xt_target *target, const void *targinfo) | ||
287 | { | 285 | { |
288 | struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo; | 286 | ipt_ulog_packet(par->hooknum, skb, par->in, par->out, |
289 | 287 | par->targinfo, NULL); | |
290 | ipt_ulog_packet(hooknum, skb, in, out, loginfo, NULL); | ||
291 | |||
292 | return XT_CONTINUE; | 288 | return XT_CONTINUE; |
293 | } | 289 | } |
294 | 290 | ||
295 | static void ipt_logfn(unsigned int pf, | 291 | static void ipt_logfn(u_int8_t pf, |
296 | unsigned int hooknum, | 292 | unsigned int hooknum, |
297 | const struct sk_buff *skb, | 293 | const struct sk_buff *skb, |
298 | const struct net_device *in, | 294 | const struct net_device *in, |
@@ -317,12 +313,9 @@ static void ipt_logfn(unsigned int pf, | |||
317 | ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); | 313 | ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); |
318 | } | 314 | } |
319 | 315 | ||
320 | static bool | 316 | static bool ulog_tg_check(const struct xt_tgchk_param *par) |
321 | ulog_tg_check(const char *tablename, const void *e, | ||
322 | const struct xt_target *target, void *targinfo, | ||
323 | unsigned int hookmask) | ||
324 | { | 317 | { |
325 | const struct ipt_ulog_info *loginfo = targinfo; | 318 | const struct ipt_ulog_info *loginfo = par->targinfo; |
326 | 319 | ||
327 | if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') { | 320 | if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') { |
328 | pr_debug("ipt_ULOG: prefix term %i\n", | 321 | pr_debug("ipt_ULOG: prefix term %i\n", |
@@ -374,7 +367,7 @@ static int ulog_tg_compat_to_user(void __user *dst, void *src) | |||
374 | 367 | ||
375 | static struct xt_target ulog_tg_reg __read_mostly = { | 368 | static struct xt_target ulog_tg_reg __read_mostly = { |
376 | .name = "ULOG", | 369 | .name = "ULOG", |
377 | .family = AF_INET, | 370 | .family = NFPROTO_IPV4, |
378 | .target = ulog_tg, | 371 | .target = ulog_tg, |
379 | .targetsize = sizeof(struct ipt_ulog_info), | 372 | .targetsize = sizeof(struct ipt_ulog_info), |
380 | .checkentry = ulog_tg_check, | 373 | .checkentry = ulog_tg_check, |
@@ -419,7 +412,7 @@ static int __init ulog_tg_init(void) | |||
419 | return ret; | 412 | return ret; |
420 | } | 413 | } |
421 | if (nflog) | 414 | if (nflog) |
422 | nf_log_register(PF_INET, &ipt_ulog_logger); | 415 | nf_log_register(NFPROTO_IPV4, &ipt_ulog_logger); |
423 | 416 | ||
424 | return 0; | 417 | return 0; |
425 | } | 418 | } |
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c index 462a22c97877..88762f02779d 100644 --- a/net/ipv4/netfilter/ipt_addrtype.c +++ b/net/ipv4/netfilter/ipt_addrtype.c | |||
@@ -30,12 +30,9 @@ static inline bool match_type(const struct net_device *dev, __be32 addr, | |||
30 | } | 30 | } |
31 | 31 | ||
32 | static bool | 32 | static bool |
33 | addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in, | 33 | addrtype_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par) |
34 | const struct net_device *out, const struct xt_match *match, | ||
35 | const void *matchinfo, int offset, unsigned int protoff, | ||
36 | bool *hotdrop) | ||
37 | { | 34 | { |
38 | const struct ipt_addrtype_info *info = matchinfo; | 35 | const struct ipt_addrtype_info *info = par->matchinfo; |
39 | const struct iphdr *iph = ip_hdr(skb); | 36 | const struct iphdr *iph = ip_hdr(skb); |
40 | bool ret = true; | 37 | bool ret = true; |
41 | 38 | ||
@@ -50,20 +47,17 @@ addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in, | |||
50 | } | 47 | } |
51 | 48 | ||
52 | static bool | 49 | static bool |
53 | addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in, | 50 | addrtype_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par) |
54 | const struct net_device *out, const struct xt_match *match, | ||
55 | const void *matchinfo, int offset, unsigned int protoff, | ||
56 | bool *hotdrop) | ||
57 | { | 51 | { |
58 | const struct ipt_addrtype_info_v1 *info = matchinfo; | 52 | const struct ipt_addrtype_info_v1 *info = par->matchinfo; |
59 | const struct iphdr *iph = ip_hdr(skb); | 53 | const struct iphdr *iph = ip_hdr(skb); |
60 | const struct net_device *dev = NULL; | 54 | const struct net_device *dev = NULL; |
61 | bool ret = true; | 55 | bool ret = true; |
62 | 56 | ||
63 | if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) | 57 | if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) |
64 | dev = in; | 58 | dev = par->in; |
65 | else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) | 59 | else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) |
66 | dev = out; | 60 | dev = par->out; |
67 | 61 | ||
68 | if (info->source) | 62 | if (info->source) |
69 | ret &= match_type(dev, iph->saddr, info->source) ^ | 63 | ret &= match_type(dev, iph->saddr, info->source) ^ |
@@ -74,12 +68,9 @@ addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in, | |||
74 | return ret; | 68 | return ret; |
75 | } | 69 | } |
76 | 70 | ||
77 | static bool | 71 | static bool addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par) |
78 | addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void, | ||
79 | const struct xt_match *match, void *matchinfo, | ||
80 | unsigned int hook_mask) | ||
81 | { | 72 | { |
82 | struct ipt_addrtype_info_v1 *info = matchinfo; | 73 | struct ipt_addrtype_info_v1 *info = par->matchinfo; |
83 | 74 | ||
84 | if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN && | 75 | if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN && |
85 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { | 76 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { |
@@ -88,14 +79,16 @@ addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void, | |||
88 | return false; | 79 | return false; |
89 | } | 80 | } |
90 | 81 | ||
91 | if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN) && | 82 | if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) | |
83 | (1 << NF_INET_LOCAL_IN)) && | ||
92 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { | 84 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { |
93 | printk(KERN_ERR "ipt_addrtype: output interface limitation " | 85 | printk(KERN_ERR "ipt_addrtype: output interface limitation " |
94 | "not valid in PRE_ROUTING and INPUT\n"); | 86 | "not valid in PRE_ROUTING and INPUT\n"); |
95 | return false; | 87 | return false; |
96 | } | 88 | } |
97 | 89 | ||
98 | if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT) && | 90 | if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) | |
91 | (1 << NF_INET_LOCAL_OUT)) && | ||
99 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { | 92 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { |
100 | printk(KERN_ERR "ipt_addrtype: input interface limitation " | 93 | printk(KERN_ERR "ipt_addrtype: input interface limitation " |
101 | "not valid in POST_ROUTING and OUTPUT\n"); | 94 | "not valid in POST_ROUTING and OUTPUT\n"); |
@@ -108,14 +101,14 @@ addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void, | |||
108 | static struct xt_match addrtype_mt_reg[] __read_mostly = { | 101 | static struct xt_match addrtype_mt_reg[] __read_mostly = { |
109 | { | 102 | { |
110 | .name = "addrtype", | 103 | .name = "addrtype", |
111 | .family = AF_INET, | 104 | .family = NFPROTO_IPV4, |
112 | .match = addrtype_mt_v0, | 105 | .match = addrtype_mt_v0, |
113 | .matchsize = sizeof(struct ipt_addrtype_info), | 106 | .matchsize = sizeof(struct ipt_addrtype_info), |
114 | .me = THIS_MODULE | 107 | .me = THIS_MODULE |
115 | }, | 108 | }, |
116 | { | 109 | { |
117 | .name = "addrtype", | 110 | .name = "addrtype", |
118 | .family = AF_INET, | 111 | .family = NFPROTO_IPV4, |
119 | .revision = 1, | 112 | .revision = 1, |
120 | .match = addrtype_mt_v1, | 113 | .match = addrtype_mt_v1, |
121 | .checkentry = addrtype_mt_checkentry_v1, | 114 | .checkentry = addrtype_mt_checkentry_v1, |
diff --git a/net/ipv4/netfilter/ipt_ah.c b/net/ipv4/netfilter/ipt_ah.c index e977989629c7..0104c0b399de 100644 --- a/net/ipv4/netfilter/ipt_ah.c +++ b/net/ipv4/netfilter/ipt_ah.c | |||
@@ -36,27 +36,23 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert) | |||
36 | return r; | 36 | return r; |
37 | } | 37 | } |
38 | 38 | ||
39 | static bool | 39 | static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
40 | ah_mt(const struct sk_buff *skb, const struct net_device *in, | ||
41 | const struct net_device *out, const struct xt_match *match, | ||
42 | const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) | ||
43 | { | 40 | { |
44 | struct ip_auth_hdr _ahdr; | 41 | struct ip_auth_hdr _ahdr; |
45 | const struct ip_auth_hdr *ah; | 42 | const struct ip_auth_hdr *ah; |
46 | const struct ipt_ah *ahinfo = matchinfo; | 43 | const struct ipt_ah *ahinfo = par->matchinfo; |
47 | 44 | ||
48 | /* Must not be a fragment. */ | 45 | /* Must not be a fragment. */ |
49 | if (offset) | 46 | if (par->fragoff != 0) |
50 | return false; | 47 | return false; |
51 | 48 | ||
52 | ah = skb_header_pointer(skb, protoff, | 49 | ah = skb_header_pointer(skb, par->thoff, sizeof(_ahdr), &_ahdr); |
53 | sizeof(_ahdr), &_ahdr); | ||
54 | if (ah == NULL) { | 50 | if (ah == NULL) { |
55 | /* We've been asked to examine this packet, and we | 51 | /* We've been asked to examine this packet, and we |
56 | * can't. Hence, no choice but to drop. | 52 | * can't. Hence, no choice but to drop. |
57 | */ | 53 | */ |
58 | duprintf("Dropping evil AH tinygram.\n"); | 54 | duprintf("Dropping evil AH tinygram.\n"); |
59 | *hotdrop = true; | 55 | *par->hotdrop = true; |
60 | return 0; | 56 | return 0; |
61 | } | 57 | } |
62 | 58 | ||
@@ -65,13 +61,9 @@ ah_mt(const struct sk_buff *skb, const struct net_device *in, | |||
65 | !!(ahinfo->invflags & IPT_AH_INV_SPI)); | 61 | !!(ahinfo->invflags & IPT_AH_INV_SPI)); |
66 | } | 62 | } |
67 | 63 | ||
68 | /* Called when user tries to insert an entry of this type. */ | 64 | static bool ah_mt_check(const struct xt_mtchk_param *par) |
69 | static bool | ||
70 | ah_mt_check(const char *tablename, const void *ip_void, | ||
71 | const struct xt_match *match, void *matchinfo, | ||
72 | unsigned int hook_mask) | ||
73 | { | 65 | { |
74 | const struct ipt_ah *ahinfo = matchinfo; | 66 | const struct ipt_ah *ahinfo = par->matchinfo; |
75 | 67 | ||
76 | /* Must specify no unknown invflags */ | 68 | /* Must specify no unknown invflags */ |
77 | if (ahinfo->invflags & ~IPT_AH_INV_MASK) { | 69 | if (ahinfo->invflags & ~IPT_AH_INV_MASK) { |
@@ -83,7 +75,7 @@ ah_mt_check(const char *tablename, const void *ip_void, | |||
83 | 75 | ||
84 | static struct xt_match ah_mt_reg __read_mostly = { | 76 | static struct xt_match ah_mt_reg __read_mostly = { |
85 | .name = "ah", | 77 | .name = "ah", |
86 | .family = AF_INET, | 78 | .family = NFPROTO_IPV4, |
87 | .match = ah_mt, | 79 | .match = ah_mt, |
88 | .matchsize = sizeof(struct ipt_ah), | 80 | .matchsize = sizeof(struct ipt_ah), |
89 | .proto = IPPROTO_AH, | 81 | .proto = IPPROTO_AH, |
diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c index 749de8284ce5..6289b64144c6 100644 --- a/net/ipv4/netfilter/ipt_ecn.c +++ b/net/ipv4/netfilter/ipt_ecn.c | |||
@@ -67,12 +67,9 @@ static inline bool match_tcp(const struct sk_buff *skb, | |||
67 | return true; | 67 | return true; |
68 | } | 68 | } |
69 | 69 | ||
70 | static bool | 70 | static bool ecn_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
71 | ecn_mt(const struct sk_buff *skb, const struct net_device *in, | ||
72 | const struct net_device *out, const struct xt_match *match, | ||
73 | const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) | ||
74 | { | 71 | { |
75 | const struct ipt_ecn_info *info = matchinfo; | 72 | const struct ipt_ecn_info *info = par->matchinfo; |
76 | 73 | ||
77 | if (info->operation & IPT_ECN_OP_MATCH_IP) | 74 | if (info->operation & IPT_ECN_OP_MATCH_IP) |
78 | if (!match_ip(skb, info)) | 75 | if (!match_ip(skb, info)) |
@@ -81,20 +78,17 @@ ecn_mt(const struct sk_buff *skb, const struct net_device *in, | |||
81 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) { | 78 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) { |
82 | if (ip_hdr(skb)->protocol != IPPROTO_TCP) | 79 | if (ip_hdr(skb)->protocol != IPPROTO_TCP) |
83 | return false; | 80 | return false; |
84 | if (!match_tcp(skb, info, hotdrop)) | 81 | if (!match_tcp(skb, info, par->hotdrop)) |
85 | return false; | 82 | return false; |
86 | } | 83 | } |
87 | 84 | ||
88 | return true; | 85 | return true; |
89 | } | 86 | } |
90 | 87 | ||
91 | static bool | 88 | static bool ecn_mt_check(const struct xt_mtchk_param *par) |
92 | ecn_mt_check(const char *tablename, const void *ip_void, | ||
93 | const struct xt_match *match, void *matchinfo, | ||
94 | unsigned int hook_mask) | ||
95 | { | 89 | { |
96 | const struct ipt_ecn_info *info = matchinfo; | 90 | const struct ipt_ecn_info *info = par->matchinfo; |
97 | const struct ipt_ip *ip = ip_void; | 91 | const struct ipt_ip *ip = par->entryinfo; |
98 | 92 | ||
99 | if (info->operation & IPT_ECN_OP_MATCH_MASK) | 93 | if (info->operation & IPT_ECN_OP_MATCH_MASK) |
100 | return false; | 94 | return false; |
@@ -114,7 +108,7 @@ ecn_mt_check(const char *tablename, const void *ip_void, | |||
114 | 108 | ||
115 | static struct xt_match ecn_mt_reg __read_mostly = { | 109 | static struct xt_match ecn_mt_reg __read_mostly = { |
116 | .name = "ecn", | 110 | .name = "ecn", |
117 | .family = AF_INET, | 111 | .family = NFPROTO_IPV4, |
118 | .match = ecn_mt, | 112 | .match = ecn_mt, |
119 | .matchsize = sizeof(struct ipt_ecn_info), | 113 | .matchsize = sizeof(struct ipt_ecn_info), |
120 | .checkentry = ecn_mt_check, | 114 | .checkentry = ecn_mt_check, |
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c deleted file mode 100644 index 3974d7cae5c0..000000000000 --- a/net/ipv4/netfilter/ipt_recent.c +++ /dev/null | |||
@@ -1,501 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2006 Patrick McHardy <kaber@trash.net> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This is a replacement of the old ipt_recent module, which carried the | ||
9 | * following copyright notice: | ||
10 | * | ||
11 | * Author: Stephen Frost <sfrost@snowman.net> | ||
12 | * Copyright 2002-2003, Stephen Frost, 2.5.x port by laforge@netfilter.org | ||
13 | */ | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/ip.h> | ||
16 | #include <linux/moduleparam.h> | ||
17 | #include <linux/proc_fs.h> | ||
18 | #include <linux/seq_file.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/ctype.h> | ||
21 | #include <linux/list.h> | ||
22 | #include <linux/random.h> | ||
23 | #include <linux/jhash.h> | ||
24 | #include <linux/bitops.h> | ||
25 | #include <linux/skbuff.h> | ||
26 | #include <linux/inet.h> | ||
27 | #include <net/net_namespace.h> | ||
28 | |||
29 | #include <linux/netfilter/x_tables.h> | ||
30 | #include <linux/netfilter_ipv4/ipt_recent.h> | ||
31 | |||
32 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
33 | MODULE_DESCRIPTION("Xtables: \"recently-seen\" host matching for IPv4"); | ||
34 | MODULE_LICENSE("GPL"); | ||
35 | |||
36 | static unsigned int ip_list_tot = 100; | ||
37 | static unsigned int ip_pkt_list_tot = 20; | ||
38 | static unsigned int ip_list_hash_size = 0; | ||
39 | static unsigned int ip_list_perms = 0644; | ||
40 | static unsigned int ip_list_uid = 0; | ||
41 | static unsigned int ip_list_gid = 0; | ||
42 | module_param(ip_list_tot, uint, 0400); | ||
43 | module_param(ip_pkt_list_tot, uint, 0400); | ||
44 | module_param(ip_list_hash_size, uint, 0400); | ||
45 | module_param(ip_list_perms, uint, 0400); | ||
46 | module_param(ip_list_uid, uint, 0400); | ||
47 | module_param(ip_list_gid, uint, 0400); | ||
48 | MODULE_PARM_DESC(ip_list_tot, "number of IPs to remember per list"); | ||
49 | MODULE_PARM_DESC(ip_pkt_list_tot, "number of packets per IP to remember (max. 255)"); | ||
50 | MODULE_PARM_DESC(ip_list_hash_size, "size of hash table used to look up IPs"); | ||
51 | MODULE_PARM_DESC(ip_list_perms, "permissions on /proc/net/ipt_recent/* files"); | ||
52 | MODULE_PARM_DESC(ip_list_uid,"owner of /proc/net/ipt_recent/* files"); | ||
53 | MODULE_PARM_DESC(ip_list_gid,"owning group of /proc/net/ipt_recent/* files"); | ||
54 | |||
55 | struct recent_entry { | ||
56 | struct list_head list; | ||
57 | struct list_head lru_list; | ||
58 | __be32 addr; | ||
59 | u_int8_t ttl; | ||
60 | u_int8_t index; | ||
61 | u_int16_t nstamps; | ||
62 | unsigned long stamps[0]; | ||
63 | }; | ||
64 | |||
65 | struct recent_table { | ||
66 | struct list_head list; | ||
67 | char name[IPT_RECENT_NAME_LEN]; | ||
68 | #ifdef CONFIG_PROC_FS | ||
69 | struct proc_dir_entry *proc; | ||
70 | #endif | ||
71 | unsigned int refcnt; | ||
72 | unsigned int entries; | ||
73 | struct list_head lru_list; | ||
74 | struct list_head iphash[0]; | ||
75 | }; | ||
76 | |||
77 | static LIST_HEAD(tables); | ||
78 | static DEFINE_SPINLOCK(recent_lock); | ||
79 | static DEFINE_MUTEX(recent_mutex); | ||
80 | |||
81 | #ifdef CONFIG_PROC_FS | ||
82 | static struct proc_dir_entry *proc_dir; | ||
83 | static const struct file_operations recent_fops; | ||
84 | #endif | ||
85 | |||
86 | static u_int32_t hash_rnd; | ||
87 | static int hash_rnd_initted; | ||
88 | |||
89 | static unsigned int recent_entry_hash(__be32 addr) | ||
90 | { | ||
91 | if (!hash_rnd_initted) { | ||
92 | get_random_bytes(&hash_rnd, 4); | ||
93 | hash_rnd_initted = 1; | ||
94 | } | ||
95 | return jhash_1word((__force u32)addr, hash_rnd) & (ip_list_hash_size - 1); | ||
96 | } | ||
97 | |||
98 | static struct recent_entry * | ||
99 | recent_entry_lookup(const struct recent_table *table, __be32 addr, u_int8_t ttl) | ||
100 | { | ||
101 | struct recent_entry *e; | ||
102 | unsigned int h; | ||
103 | |||
104 | h = recent_entry_hash(addr); | ||
105 | list_for_each_entry(e, &table->iphash[h], list) | ||
106 | if (e->addr == addr && (ttl == e->ttl || !ttl || !e->ttl)) | ||
107 | return e; | ||
108 | return NULL; | ||
109 | } | ||
110 | |||
111 | static void recent_entry_remove(struct recent_table *t, struct recent_entry *e) | ||
112 | { | ||
113 | list_del(&e->list); | ||
114 | list_del(&e->lru_list); | ||
115 | kfree(e); | ||
116 | t->entries--; | ||
117 | } | ||
118 | |||
119 | static struct recent_entry * | ||
120 | recent_entry_init(struct recent_table *t, __be32 addr, u_int8_t ttl) | ||
121 | { | ||
122 | struct recent_entry *e; | ||
123 | |||
124 | if (t->entries >= ip_list_tot) { | ||
125 | e = list_entry(t->lru_list.next, struct recent_entry, lru_list); | ||
126 | recent_entry_remove(t, e); | ||
127 | } | ||
128 | e = kmalloc(sizeof(*e) + sizeof(e->stamps[0]) * ip_pkt_list_tot, | ||
129 | GFP_ATOMIC); | ||
130 | if (e == NULL) | ||
131 | return NULL; | ||
132 | e->addr = addr; | ||
133 | e->ttl = ttl; | ||
134 | e->stamps[0] = jiffies; | ||
135 | e->nstamps = 1; | ||
136 | e->index = 1; | ||
137 | list_add_tail(&e->list, &t->iphash[recent_entry_hash(addr)]); | ||
138 | list_add_tail(&e->lru_list, &t->lru_list); | ||
139 | t->entries++; | ||
140 | return e; | ||
141 | } | ||
142 | |||
143 | static void recent_entry_update(struct recent_table *t, struct recent_entry *e) | ||
144 | { | ||
145 | e->stamps[e->index++] = jiffies; | ||
146 | if (e->index > e->nstamps) | ||
147 | e->nstamps = e->index; | ||
148 | e->index %= ip_pkt_list_tot; | ||
149 | list_move_tail(&e->lru_list, &t->lru_list); | ||
150 | } | ||
151 | |||
152 | static struct recent_table *recent_table_lookup(const char *name) | ||
153 | { | ||
154 | struct recent_table *t; | ||
155 | |||
156 | list_for_each_entry(t, &tables, list) | ||
157 | if (!strcmp(t->name, name)) | ||
158 | return t; | ||
159 | return NULL; | ||
160 | } | ||
161 | |||
162 | static void recent_table_flush(struct recent_table *t) | ||
163 | { | ||
164 | struct recent_entry *e, *next; | ||
165 | unsigned int i; | ||
166 | |||
167 | for (i = 0; i < ip_list_hash_size; i++) | ||
168 | list_for_each_entry_safe(e, next, &t->iphash[i], list) | ||
169 | recent_entry_remove(t, e); | ||
170 | } | ||
171 | |||
172 | static bool | ||
173 | recent_mt(const struct sk_buff *skb, const struct net_device *in, | ||
174 | const struct net_device *out, const struct xt_match *match, | ||
175 | const void *matchinfo, int offset, unsigned int protoff, | ||
176 | bool *hotdrop) | ||
177 | { | ||
178 | const struct ipt_recent_info *info = matchinfo; | ||
179 | struct recent_table *t; | ||
180 | struct recent_entry *e; | ||
181 | __be32 addr; | ||
182 | u_int8_t ttl; | ||
183 | bool ret = info->invert; | ||
184 | |||
185 | if (info->side == IPT_RECENT_DEST) | ||
186 | addr = ip_hdr(skb)->daddr; | ||
187 | else | ||
188 | addr = ip_hdr(skb)->saddr; | ||
189 | |||
190 | ttl = ip_hdr(skb)->ttl; | ||
191 | /* use TTL as seen before forwarding */ | ||
192 | if (out && !skb->sk) | ||
193 | ttl++; | ||
194 | |||
195 | spin_lock_bh(&recent_lock); | ||
196 | t = recent_table_lookup(info->name); | ||
197 | e = recent_entry_lookup(t, addr, | ||
198 | info->check_set & IPT_RECENT_TTL ? ttl : 0); | ||
199 | if (e == NULL) { | ||
200 | if (!(info->check_set & IPT_RECENT_SET)) | ||
201 | goto out; | ||
202 | e = recent_entry_init(t, addr, ttl); | ||
203 | if (e == NULL) | ||
204 | *hotdrop = true; | ||
205 | ret = !ret; | ||
206 | goto out; | ||
207 | } | ||
208 | |||
209 | if (info->check_set & IPT_RECENT_SET) | ||
210 | ret = !ret; | ||
211 | else if (info->check_set & IPT_RECENT_REMOVE) { | ||
212 | recent_entry_remove(t, e); | ||
213 | ret = !ret; | ||
214 | } else if (info->check_set & (IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) { | ||
215 | unsigned long time = jiffies - info->seconds * HZ; | ||
216 | unsigned int i, hits = 0; | ||
217 | |||
218 | for (i = 0; i < e->nstamps; i++) { | ||
219 | if (info->seconds && time_after(time, e->stamps[i])) | ||
220 | continue; | ||
221 | if (++hits >= info->hit_count) { | ||
222 | ret = !ret; | ||
223 | break; | ||
224 | } | ||
225 | } | ||
226 | } | ||
227 | |||
228 | if (info->check_set & IPT_RECENT_SET || | ||
229 | (info->check_set & IPT_RECENT_UPDATE && ret)) { | ||
230 | recent_entry_update(t, e); | ||
231 | e->ttl = ttl; | ||
232 | } | ||
233 | out: | ||
234 | spin_unlock_bh(&recent_lock); | ||
235 | return ret; | ||
236 | } | ||
237 | |||
238 | static bool | ||
239 | recent_mt_check(const char *tablename, const void *ip, | ||
240 | const struct xt_match *match, void *matchinfo, | ||
241 | unsigned int hook_mask) | ||
242 | { | ||
243 | const struct ipt_recent_info *info = matchinfo; | ||
244 | struct recent_table *t; | ||
245 | unsigned i; | ||
246 | bool ret = false; | ||
247 | |||
248 | if (hweight8(info->check_set & | ||
249 | (IPT_RECENT_SET | IPT_RECENT_REMOVE | | ||
250 | IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) != 1) | ||
251 | return false; | ||
252 | if ((info->check_set & (IPT_RECENT_SET | IPT_RECENT_REMOVE)) && | ||
253 | (info->seconds || info->hit_count)) | ||
254 | return false; | ||
255 | if (info->hit_count > ip_pkt_list_tot) | ||
256 | return false; | ||
257 | if (info->name[0] == '\0' || | ||
258 | strnlen(info->name, IPT_RECENT_NAME_LEN) == IPT_RECENT_NAME_LEN) | ||
259 | return false; | ||
260 | |||
261 | mutex_lock(&recent_mutex); | ||
262 | t = recent_table_lookup(info->name); | ||
263 | if (t != NULL) { | ||
264 | t->refcnt++; | ||
265 | ret = true; | ||
266 | goto out; | ||
267 | } | ||
268 | |||
269 | t = kzalloc(sizeof(*t) + sizeof(t->iphash[0]) * ip_list_hash_size, | ||
270 | GFP_KERNEL); | ||
271 | if (t == NULL) | ||
272 | goto out; | ||
273 | t->refcnt = 1; | ||
274 | strcpy(t->name, info->name); | ||
275 | INIT_LIST_HEAD(&t->lru_list); | ||
276 | for (i = 0; i < ip_list_hash_size; i++) | ||
277 | INIT_LIST_HEAD(&t->iphash[i]); | ||
278 | #ifdef CONFIG_PROC_FS | ||
279 | t->proc = proc_create(t->name, ip_list_perms, proc_dir, &recent_fops); | ||
280 | if (t->proc == NULL) { | ||
281 | kfree(t); | ||
282 | goto out; | ||
283 | } | ||
284 | t->proc->uid = ip_list_uid; | ||
285 | t->proc->gid = ip_list_gid; | ||
286 | t->proc->data = t; | ||
287 | #endif | ||
288 | spin_lock_bh(&recent_lock); | ||
289 | list_add_tail(&t->list, &tables); | ||
290 | spin_unlock_bh(&recent_lock); | ||
291 | ret = true; | ||
292 | out: | ||
293 | mutex_unlock(&recent_mutex); | ||
294 | return ret; | ||
295 | } | ||
296 | |||
297 | static void recent_mt_destroy(const struct xt_match *match, void *matchinfo) | ||
298 | { | ||
299 | const struct ipt_recent_info *info = matchinfo; | ||
300 | struct recent_table *t; | ||
301 | |||
302 | mutex_lock(&recent_mutex); | ||
303 | t = recent_table_lookup(info->name); | ||
304 | if (--t->refcnt == 0) { | ||
305 | spin_lock_bh(&recent_lock); | ||
306 | list_del(&t->list); | ||
307 | spin_unlock_bh(&recent_lock); | ||
308 | #ifdef CONFIG_PROC_FS | ||
309 | remove_proc_entry(t->name, proc_dir); | ||
310 | #endif | ||
311 | recent_table_flush(t); | ||
312 | kfree(t); | ||
313 | } | ||
314 | mutex_unlock(&recent_mutex); | ||
315 | } | ||
316 | |||
317 | #ifdef CONFIG_PROC_FS | ||
318 | struct recent_iter_state { | ||
319 | struct recent_table *table; | ||
320 | unsigned int bucket; | ||
321 | }; | ||
322 | |||
323 | static void *recent_seq_start(struct seq_file *seq, loff_t *pos) | ||
324 | __acquires(recent_lock) | ||
325 | { | ||
326 | struct recent_iter_state *st = seq->private; | ||
327 | const struct recent_table *t = st->table; | ||
328 | struct recent_entry *e; | ||
329 | loff_t p = *pos; | ||
330 | |||
331 | spin_lock_bh(&recent_lock); | ||
332 | |||
333 | for (st->bucket = 0; st->bucket < ip_list_hash_size; st->bucket++) | ||
334 | list_for_each_entry(e, &t->iphash[st->bucket], list) | ||
335 | if (p-- == 0) | ||
336 | return e; | ||
337 | return NULL; | ||
338 | } | ||
339 | |||
340 | static void *recent_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||
341 | { | ||
342 | struct recent_iter_state *st = seq->private; | ||
343 | const struct recent_table *t = st->table; | ||
344 | struct recent_entry *e = v; | ||
345 | struct list_head *head = e->list.next; | ||
346 | |||
347 | while (head == &t->iphash[st->bucket]) { | ||
348 | if (++st->bucket >= ip_list_hash_size) | ||
349 | return NULL; | ||
350 | head = t->iphash[st->bucket].next; | ||
351 | } | ||
352 | (*pos)++; | ||
353 | return list_entry(head, struct recent_entry, list); | ||
354 | } | ||
355 | |||
356 | static void recent_seq_stop(struct seq_file *s, void *v) | ||
357 | __releases(recent_lock) | ||
358 | { | ||
359 | spin_unlock_bh(&recent_lock); | ||
360 | } | ||
361 | |||
362 | static int recent_seq_show(struct seq_file *seq, void *v) | ||
363 | { | ||
364 | const struct recent_entry *e = v; | ||
365 | unsigned int i; | ||
366 | |||
367 | i = (e->index - 1) % ip_pkt_list_tot; | ||
368 | seq_printf(seq, "src=%u.%u.%u.%u ttl: %u last_seen: %lu oldest_pkt: %u", | ||
369 | NIPQUAD(e->addr), e->ttl, e->stamps[i], e->index); | ||
370 | for (i = 0; i < e->nstamps; i++) | ||
371 | seq_printf(seq, "%s %lu", i ? "," : "", e->stamps[i]); | ||
372 | seq_printf(seq, "\n"); | ||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | static const struct seq_operations recent_seq_ops = { | ||
377 | .start = recent_seq_start, | ||
378 | .next = recent_seq_next, | ||
379 | .stop = recent_seq_stop, | ||
380 | .show = recent_seq_show, | ||
381 | }; | ||
382 | |||
383 | static int recent_seq_open(struct inode *inode, struct file *file) | ||
384 | { | ||
385 | struct proc_dir_entry *pde = PDE(inode); | ||
386 | struct recent_iter_state *st; | ||
387 | |||
388 | st = __seq_open_private(file, &recent_seq_ops, sizeof(*st)); | ||
389 | if (st == NULL) | ||
390 | return -ENOMEM; | ||
391 | |||
392 | st->table = pde->data; | ||
393 | return 0; | ||
394 | } | ||
395 | |||
396 | static ssize_t recent_proc_write(struct file *file, const char __user *input, | ||
397 | size_t size, loff_t *loff) | ||
398 | { | ||
399 | const struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode); | ||
400 | struct recent_table *t = pde->data; | ||
401 | struct recent_entry *e; | ||
402 | char buf[sizeof("+255.255.255.255")], *c = buf; | ||
403 | __be32 addr; | ||
404 | int add; | ||
405 | |||
406 | if (size > sizeof(buf)) | ||
407 | size = sizeof(buf); | ||
408 | if (copy_from_user(buf, input, size)) | ||
409 | return -EFAULT; | ||
410 | while (isspace(*c)) | ||
411 | c++; | ||
412 | |||
413 | if (size - (c - buf) < 5) | ||
414 | return c - buf; | ||
415 | if (!strncmp(c, "clear", 5)) { | ||
416 | c += 5; | ||
417 | spin_lock_bh(&recent_lock); | ||
418 | recent_table_flush(t); | ||
419 | spin_unlock_bh(&recent_lock); | ||
420 | return c - buf; | ||
421 | } | ||
422 | |||
423 | switch (*c) { | ||
424 | case '-': | ||
425 | add = 0; | ||
426 | c++; | ||
427 | break; | ||
428 | case '+': | ||
429 | c++; | ||
430 | default: | ||
431 | add = 1; | ||
432 | break; | ||
433 | } | ||
434 | addr = in_aton(c); | ||
435 | |||
436 | spin_lock_bh(&recent_lock); | ||
437 | e = recent_entry_lookup(t, addr, 0); | ||
438 | if (e == NULL) { | ||
439 | if (add) | ||
440 | recent_entry_init(t, addr, 0); | ||
441 | } else { | ||
442 | if (add) | ||
443 | recent_entry_update(t, e); | ||
444 | else | ||
445 | recent_entry_remove(t, e); | ||
446 | } | ||
447 | spin_unlock_bh(&recent_lock); | ||
448 | return size; | ||
449 | } | ||
450 | |||
451 | static const struct file_operations recent_fops = { | ||
452 | .open = recent_seq_open, | ||
453 | .read = seq_read, | ||
454 | .write = recent_proc_write, | ||
455 | .release = seq_release_private, | ||
456 | .owner = THIS_MODULE, | ||
457 | }; | ||
458 | #endif /* CONFIG_PROC_FS */ | ||
459 | |||
460 | static struct xt_match recent_mt_reg __read_mostly = { | ||
461 | .name = "recent", | ||
462 | .family = AF_INET, | ||
463 | .match = recent_mt, | ||
464 | .matchsize = sizeof(struct ipt_recent_info), | ||
465 | .checkentry = recent_mt_check, | ||
466 | .destroy = recent_mt_destroy, | ||
467 | .me = THIS_MODULE, | ||
468 | }; | ||
469 | |||
470 | static int __init recent_mt_init(void) | ||
471 | { | ||
472 | int err; | ||
473 | |||
474 | if (!ip_list_tot || !ip_pkt_list_tot || ip_pkt_list_tot > 255) | ||
475 | return -EINVAL; | ||
476 | ip_list_hash_size = 1 << fls(ip_list_tot); | ||
477 | |||
478 | err = xt_register_match(&recent_mt_reg); | ||
479 | #ifdef CONFIG_PROC_FS | ||
480 | if (err) | ||
481 | return err; | ||
482 | proc_dir = proc_mkdir("ipt_recent", init_net.proc_net); | ||
483 | if (proc_dir == NULL) { | ||
484 | xt_unregister_match(&recent_mt_reg); | ||
485 | err = -ENOMEM; | ||
486 | } | ||
487 | #endif | ||
488 | return err; | ||
489 | } | ||
490 | |||
491 | static void __exit recent_mt_exit(void) | ||
492 | { | ||
493 | BUG_ON(!list_empty(&tables)); | ||
494 | xt_unregister_match(&recent_mt_reg); | ||
495 | #ifdef CONFIG_PROC_FS | ||
496 | remove_proc_entry("ipt_recent", init_net.proc_net); | ||
497 | #endif | ||
498 | } | ||
499 | |||
500 | module_init(recent_mt_init); | ||
501 | module_exit(recent_mt_exit); | ||
diff --git a/net/ipv4/netfilter/ipt_ttl.c b/net/ipv4/netfilter/ipt_ttl.c index e0b8caeb710c..297f1cbf4ff5 100644 --- a/net/ipv4/netfilter/ipt_ttl.c +++ b/net/ipv4/netfilter/ipt_ttl.c | |||
@@ -18,12 +18,9 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | |||
18 | MODULE_DESCRIPTION("Xtables: IPv4 TTL field match"); | 18 | MODULE_DESCRIPTION("Xtables: IPv4 TTL field match"); |
19 | MODULE_LICENSE("GPL"); | 19 | MODULE_LICENSE("GPL"); |
20 | 20 | ||
21 | static bool | 21 | static bool ttl_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
22 | ttl_mt(const struct sk_buff *skb, const struct net_device *in, | ||
23 | const struct net_device *out, const struct xt_match *match, | ||
24 | const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) | ||
25 | { | 22 | { |
26 | const struct ipt_ttl_info *info = matchinfo; | 23 | const struct ipt_ttl_info *info = par->matchinfo; |
27 | const u8 ttl = ip_hdr(skb)->ttl; | 24 | const u8 ttl = ip_hdr(skb)->ttl; |
28 | 25 | ||
29 | switch (info->mode) { | 26 | switch (info->mode) { |
@@ -46,7 +43,7 @@ ttl_mt(const struct sk_buff *skb, const struct net_device *in, | |||
46 | 43 | ||
47 | static struct xt_match ttl_mt_reg __read_mostly = { | 44 | static struct xt_match ttl_mt_reg __read_mostly = { |
48 | .name = "ttl", | 45 | .name = "ttl", |
49 | .family = AF_INET, | 46 | .family = NFPROTO_IPV4, |
50 | .match = ttl_mt, | 47 | .match = ttl_mt, |
51 | .matchsize = sizeof(struct ipt_ttl_info), | 48 | .matchsize = sizeof(struct ipt_ttl_info), |
52 | .me = THIS_MODULE, | 49 | .me = THIS_MODULE, |
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 1ea677dcf845..c9224310ebae 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c | |||
@@ -70,7 +70,7 @@ ipt_local_in_hook(unsigned int hook, | |||
70 | int (*okfn)(struct sk_buff *)) | 70 | int (*okfn)(struct sk_buff *)) |
71 | { | 71 | { |
72 | return ipt_do_table(skb, hook, in, out, | 72 | return ipt_do_table(skb, hook, in, out, |
73 | nf_local_in_net(in, out)->ipv4.iptable_filter); | 73 | dev_net(in)->ipv4.iptable_filter); |
74 | } | 74 | } |
75 | 75 | ||
76 | static unsigned int | 76 | static unsigned int |
@@ -81,7 +81,7 @@ ipt_hook(unsigned int hook, | |||
81 | int (*okfn)(struct sk_buff *)) | 81 | int (*okfn)(struct sk_buff *)) |
82 | { | 82 | { |
83 | return ipt_do_table(skb, hook, in, out, | 83 | return ipt_do_table(skb, hook, in, out, |
84 | nf_forward_net(in, out)->ipv4.iptable_filter); | 84 | dev_net(in)->ipv4.iptable_filter); |
85 | } | 85 | } |
86 | 86 | ||
87 | static unsigned int | 87 | static unsigned int |
@@ -101,7 +101,7 @@ ipt_local_out_hook(unsigned int hook, | |||
101 | } | 101 | } |
102 | 102 | ||
103 | return ipt_do_table(skb, hook, in, out, | 103 | return ipt_do_table(skb, hook, in, out, |
104 | nf_local_out_net(in, out)->ipv4.iptable_filter); | 104 | dev_net(out)->ipv4.iptable_filter); |
105 | } | 105 | } |
106 | 106 | ||
107 | static struct nf_hook_ops ipt_ops[] __read_mostly = { | 107 | static struct nf_hook_ops ipt_ops[] __read_mostly = { |
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index da59182f2226..69f2c4287146 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c | |||
@@ -81,7 +81,7 @@ ipt_pre_routing_hook(unsigned int hook, | |||
81 | int (*okfn)(struct sk_buff *)) | 81 | int (*okfn)(struct sk_buff *)) |
82 | { | 82 | { |
83 | return ipt_do_table(skb, hook, in, out, | 83 | return ipt_do_table(skb, hook, in, out, |
84 | nf_pre_routing_net(in, out)->ipv4.iptable_mangle); | 84 | dev_net(in)->ipv4.iptable_mangle); |
85 | } | 85 | } |
86 | 86 | ||
87 | static unsigned int | 87 | static unsigned int |
@@ -92,7 +92,7 @@ ipt_post_routing_hook(unsigned int hook, | |||
92 | int (*okfn)(struct sk_buff *)) | 92 | int (*okfn)(struct sk_buff *)) |
93 | { | 93 | { |
94 | return ipt_do_table(skb, hook, in, out, | 94 | return ipt_do_table(skb, hook, in, out, |
95 | nf_post_routing_net(in, out)->ipv4.iptable_mangle); | 95 | dev_net(out)->ipv4.iptable_mangle); |
96 | } | 96 | } |
97 | 97 | ||
98 | static unsigned int | 98 | static unsigned int |
@@ -103,7 +103,7 @@ ipt_local_in_hook(unsigned int hook, | |||
103 | int (*okfn)(struct sk_buff *)) | 103 | int (*okfn)(struct sk_buff *)) |
104 | { | 104 | { |
105 | return ipt_do_table(skb, hook, in, out, | 105 | return ipt_do_table(skb, hook, in, out, |
106 | nf_local_in_net(in, out)->ipv4.iptable_mangle); | 106 | dev_net(in)->ipv4.iptable_mangle); |
107 | } | 107 | } |
108 | 108 | ||
109 | static unsigned int | 109 | static unsigned int |
@@ -114,7 +114,7 @@ ipt_forward_hook(unsigned int hook, | |||
114 | int (*okfn)(struct sk_buff *)) | 114 | int (*okfn)(struct sk_buff *)) |
115 | { | 115 | { |
116 | return ipt_do_table(skb, hook, in, out, | 116 | return ipt_do_table(skb, hook, in, out, |
117 | nf_forward_net(in, out)->ipv4.iptable_mangle); | 117 | dev_net(in)->ipv4.iptable_mangle); |
118 | } | 118 | } |
119 | 119 | ||
120 | static unsigned int | 120 | static unsigned int |
@@ -147,7 +147,7 @@ ipt_local_hook(unsigned int hook, | |||
147 | tos = iph->tos; | 147 | tos = iph->tos; |
148 | 148 | ||
149 | ret = ipt_do_table(skb, hook, in, out, | 149 | ret = ipt_do_table(skb, hook, in, out, |
150 | nf_local_out_net(in, out)->ipv4.iptable_mangle); | 150 | dev_net(out)->ipv4.iptable_mangle); |
151 | /* Reroute for ANY change. */ | 151 | /* Reroute for ANY change. */ |
152 | if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) { | 152 | if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) { |
153 | iph = ip_hdr(skb); | 153 | iph = ip_hdr(skb); |
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index fddce7754b72..8faebfe638f1 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c | |||
@@ -53,7 +53,7 @@ ipt_hook(unsigned int hook, | |||
53 | int (*okfn)(struct sk_buff *)) | 53 | int (*okfn)(struct sk_buff *)) |
54 | { | 54 | { |
55 | return ipt_do_table(skb, hook, in, out, | 55 | return ipt_do_table(skb, hook, in, out, |
56 | nf_pre_routing_net(in, out)->ipv4.iptable_raw); | 56 | dev_net(in)->ipv4.iptable_raw); |
57 | } | 57 | } |
58 | 58 | ||
59 | static unsigned int | 59 | static unsigned int |
@@ -72,7 +72,7 @@ ipt_local_hook(unsigned int hook, | |||
72 | return NF_ACCEPT; | 72 | return NF_ACCEPT; |
73 | } | 73 | } |
74 | return ipt_do_table(skb, hook, in, out, | 74 | return ipt_do_table(skb, hook, in, out, |
75 | nf_local_out_net(in, out)->ipv4.iptable_raw); | 75 | dev_net(out)->ipv4.iptable_raw); |
76 | } | 76 | } |
77 | 77 | ||
78 | /* 'raw' is the very first table. */ | 78 | /* 'raw' is the very first table. */ |
diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c index db6d312128e1..36f3be3cc428 100644 --- a/net/ipv4/netfilter/iptable_security.c +++ b/net/ipv4/netfilter/iptable_security.c | |||
@@ -73,7 +73,7 @@ ipt_local_in_hook(unsigned int hook, | |||
73 | int (*okfn)(struct sk_buff *)) | 73 | int (*okfn)(struct sk_buff *)) |
74 | { | 74 | { |
75 | return ipt_do_table(skb, hook, in, out, | 75 | return ipt_do_table(skb, hook, in, out, |
76 | nf_local_in_net(in, out)->ipv4.iptable_security); | 76 | dev_net(in)->ipv4.iptable_security); |
77 | } | 77 | } |
78 | 78 | ||
79 | static unsigned int | 79 | static unsigned int |
@@ -84,7 +84,7 @@ ipt_forward_hook(unsigned int hook, | |||
84 | int (*okfn)(struct sk_buff *)) | 84 | int (*okfn)(struct sk_buff *)) |
85 | { | 85 | { |
86 | return ipt_do_table(skb, hook, in, out, | 86 | return ipt_do_table(skb, hook, in, out, |
87 | nf_forward_net(in, out)->ipv4.iptable_security); | 87 | dev_net(in)->ipv4.iptable_security); |
88 | } | 88 | } |
89 | 89 | ||
90 | static unsigned int | 90 | static unsigned int |
@@ -103,7 +103,7 @@ ipt_local_out_hook(unsigned int hook, | |||
103 | return NF_ACCEPT; | 103 | return NF_ACCEPT; |
104 | } | 104 | } |
105 | return ipt_do_table(skb, hook, in, out, | 105 | return ipt_do_table(skb, hook, in, out, |
106 | nf_local_out_net(in, out)->ipv4.iptable_security); | 106 | dev_net(out)->ipv4.iptable_security); |
107 | } | 107 | } |
108 | 108 | ||
109 | static struct nf_hook_ops ipt_ops[] __read_mostly = { | 109 | static struct nf_hook_ops ipt_ops[] __read_mostly = { |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 5a955c440364..4a7c35275396 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
@@ -1,3 +1,4 @@ | |||
1 | |||
1 | /* (C) 1999-2001 Paul `Rusty' Russell | 2 | /* (C) 1999-2001 Paul `Rusty' Russell |
2 | * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> | 3 | * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> |
3 | * | 4 | * |
@@ -24,6 +25,7 @@ | |||
24 | #include <net/netfilter/nf_conntrack_core.h> | 25 | #include <net/netfilter/nf_conntrack_core.h> |
25 | #include <net/netfilter/ipv4/nf_conntrack_ipv4.h> | 26 | #include <net/netfilter/ipv4/nf_conntrack_ipv4.h> |
26 | #include <net/netfilter/nf_nat_helper.h> | 27 | #include <net/netfilter/nf_nat_helper.h> |
28 | #include <net/netfilter/ipv4/nf_defrag_ipv4.h> | ||
27 | 29 | ||
28 | int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, | 30 | int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, |
29 | struct nf_conn *ct, | 31 | struct nf_conn *ct, |
@@ -63,23 +65,6 @@ static int ipv4_print_tuple(struct seq_file *s, | |||
63 | NIPQUAD(tuple->dst.u3.ip)); | 65 | NIPQUAD(tuple->dst.u3.ip)); |
64 | } | 66 | } |
65 | 67 | ||
66 | /* Returns new sk_buff, or NULL */ | ||
67 | static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user) | ||
68 | { | ||
69 | int err; | ||
70 | |||
71 | skb_orphan(skb); | ||
72 | |||
73 | local_bh_disable(); | ||
74 | err = ip_defrag(skb, user); | ||
75 | local_bh_enable(); | ||
76 | |||
77 | if (!err) | ||
78 | ip_send_check(ip_hdr(skb)); | ||
79 | |||
80 | return err; | ||
81 | } | ||
82 | |||
83 | static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, | 68 | static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, |
84 | unsigned int *dataoff, u_int8_t *protonum) | 69 | unsigned int *dataoff, u_int8_t *protonum) |
85 | { | 70 | { |
@@ -144,35 +129,13 @@ out: | |||
144 | return nf_conntrack_confirm(skb); | 129 | return nf_conntrack_confirm(skb); |
145 | } | 130 | } |
146 | 131 | ||
147 | static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, | ||
148 | struct sk_buff *skb, | ||
149 | const struct net_device *in, | ||
150 | const struct net_device *out, | ||
151 | int (*okfn)(struct sk_buff *)) | ||
152 | { | ||
153 | /* Previously seen (loopback)? Ignore. Do this before | ||
154 | fragment check. */ | ||
155 | if (skb->nfct) | ||
156 | return NF_ACCEPT; | ||
157 | |||
158 | /* Gather fragments. */ | ||
159 | if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { | ||
160 | if (nf_ct_ipv4_gather_frags(skb, | ||
161 | hooknum == NF_INET_PRE_ROUTING ? | ||
162 | IP_DEFRAG_CONNTRACK_IN : | ||
163 | IP_DEFRAG_CONNTRACK_OUT)) | ||
164 | return NF_STOLEN; | ||
165 | } | ||
166 | return NF_ACCEPT; | ||
167 | } | ||
168 | |||
169 | static unsigned int ipv4_conntrack_in(unsigned int hooknum, | 132 | static unsigned int ipv4_conntrack_in(unsigned int hooknum, |
170 | struct sk_buff *skb, | 133 | struct sk_buff *skb, |
171 | const struct net_device *in, | 134 | const struct net_device *in, |
172 | const struct net_device *out, | 135 | const struct net_device *out, |
173 | int (*okfn)(struct sk_buff *)) | 136 | int (*okfn)(struct sk_buff *)) |
174 | { | 137 | { |
175 | return nf_conntrack_in(PF_INET, hooknum, skb); | 138 | return nf_conntrack_in(dev_net(in), PF_INET, hooknum, skb); |
176 | } | 139 | } |
177 | 140 | ||
178 | static unsigned int ipv4_conntrack_local(unsigned int hooknum, | 141 | static unsigned int ipv4_conntrack_local(unsigned int hooknum, |
@@ -188,20 +151,13 @@ static unsigned int ipv4_conntrack_local(unsigned int hooknum, | |||
188 | printk("ipt_hook: happy cracking.\n"); | 151 | printk("ipt_hook: happy cracking.\n"); |
189 | return NF_ACCEPT; | 152 | return NF_ACCEPT; |
190 | } | 153 | } |
191 | return nf_conntrack_in(PF_INET, hooknum, skb); | 154 | return nf_conntrack_in(dev_net(out), PF_INET, hooknum, skb); |
192 | } | 155 | } |
193 | 156 | ||
194 | /* Connection tracking may drop packets, but never alters them, so | 157 | /* Connection tracking may drop packets, but never alters them, so |
195 | make it the first hook. */ | 158 | make it the first hook. */ |
196 | static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = { | 159 | static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = { |
197 | { | 160 | { |
198 | .hook = ipv4_conntrack_defrag, | ||
199 | .owner = THIS_MODULE, | ||
200 | .pf = PF_INET, | ||
201 | .hooknum = NF_INET_PRE_ROUTING, | ||
202 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, | ||
203 | }, | ||
204 | { | ||
205 | .hook = ipv4_conntrack_in, | 161 | .hook = ipv4_conntrack_in, |
206 | .owner = THIS_MODULE, | 162 | .owner = THIS_MODULE, |
207 | .pf = PF_INET, | 163 | .pf = PF_INET, |
@@ -209,13 +165,6 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = { | |||
209 | .priority = NF_IP_PRI_CONNTRACK, | 165 | .priority = NF_IP_PRI_CONNTRACK, |
210 | }, | 166 | }, |
211 | { | 167 | { |
212 | .hook = ipv4_conntrack_defrag, | ||
213 | .owner = THIS_MODULE, | ||
214 | .pf = PF_INET, | ||
215 | .hooknum = NF_INET_LOCAL_OUT, | ||
216 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, | ||
217 | }, | ||
218 | { | ||
219 | .hook = ipv4_conntrack_local, | 168 | .hook = ipv4_conntrack_local, |
220 | .owner = THIS_MODULE, | 169 | .owner = THIS_MODULE, |
221 | .pf = PF_INET, | 170 | .pf = PF_INET, |
@@ -254,7 +203,7 @@ static ctl_table ip_ct_sysctl_table[] = { | |||
254 | { | 203 | { |
255 | .ctl_name = NET_IPV4_NF_CONNTRACK_COUNT, | 204 | .ctl_name = NET_IPV4_NF_CONNTRACK_COUNT, |
256 | .procname = "ip_conntrack_count", | 205 | .procname = "ip_conntrack_count", |
257 | .data = &nf_conntrack_count, | 206 | .data = &init_net.ct.count, |
258 | .maxlen = sizeof(int), | 207 | .maxlen = sizeof(int), |
259 | .mode = 0444, | 208 | .mode = 0444, |
260 | .proc_handler = &proc_dointvec, | 209 | .proc_handler = &proc_dointvec, |
@@ -270,7 +219,7 @@ static ctl_table ip_ct_sysctl_table[] = { | |||
270 | { | 219 | { |
271 | .ctl_name = NET_IPV4_NF_CONNTRACK_CHECKSUM, | 220 | .ctl_name = NET_IPV4_NF_CONNTRACK_CHECKSUM, |
272 | .procname = "ip_conntrack_checksum", | 221 | .procname = "ip_conntrack_checksum", |
273 | .data = &nf_conntrack_checksum, | 222 | .data = &init_net.ct.sysctl_checksum, |
274 | .maxlen = sizeof(int), | 223 | .maxlen = sizeof(int), |
275 | .mode = 0644, | 224 | .mode = 0644, |
276 | .proc_handler = &proc_dointvec, | 225 | .proc_handler = &proc_dointvec, |
@@ -278,7 +227,7 @@ static ctl_table ip_ct_sysctl_table[] = { | |||
278 | { | 227 | { |
279 | .ctl_name = NET_IPV4_NF_CONNTRACK_LOG_INVALID, | 228 | .ctl_name = NET_IPV4_NF_CONNTRACK_LOG_INVALID, |
280 | .procname = "ip_conntrack_log_invalid", | 229 | .procname = "ip_conntrack_log_invalid", |
281 | .data = &nf_ct_log_invalid, | 230 | .data = &init_net.ct.sysctl_log_invalid, |
282 | .maxlen = sizeof(unsigned int), | 231 | .maxlen = sizeof(unsigned int), |
283 | .mode = 0644, | 232 | .mode = 0644, |
284 | .proc_handler = &proc_dointvec_minmax, | 233 | .proc_handler = &proc_dointvec_minmax, |
@@ -323,7 +272,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len) | |||
323 | return -EINVAL; | 272 | return -EINVAL; |
324 | } | 273 | } |
325 | 274 | ||
326 | h = nf_conntrack_find_get(&tuple); | 275 | h = nf_conntrack_find_get(sock_net(sk), &tuple); |
327 | if (h) { | 276 | if (h) { |
328 | struct sockaddr_in sin; | 277 | struct sockaddr_in sin; |
329 | struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h); | 278 | struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h); |
@@ -422,6 +371,7 @@ static int __init nf_conntrack_l3proto_ipv4_init(void) | |||
422 | int ret = 0; | 371 | int ret = 0; |
423 | 372 | ||
424 | need_conntrack(); | 373 | need_conntrack(); |
374 | nf_defrag_ipv4_enable(); | ||
425 | 375 | ||
426 | ret = nf_register_sockopt(&so_getorigdst); | 376 | ret = nf_register_sockopt(&so_getorigdst); |
427 | if (ret < 0) { | 377 | if (ret < 0) { |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c index 3a020720e40b..313ebf00ee36 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | |||
@@ -21,18 +21,20 @@ | |||
21 | #include <net/netfilter/nf_conntrack_acct.h> | 21 | #include <net/netfilter/nf_conntrack_acct.h> |
22 | 22 | ||
23 | struct ct_iter_state { | 23 | struct ct_iter_state { |
24 | struct seq_net_private p; | ||
24 | unsigned int bucket; | 25 | unsigned int bucket; |
25 | }; | 26 | }; |
26 | 27 | ||
27 | static struct hlist_node *ct_get_first(struct seq_file *seq) | 28 | static struct hlist_node *ct_get_first(struct seq_file *seq) |
28 | { | 29 | { |
30 | struct net *net = seq_file_net(seq); | ||
29 | struct ct_iter_state *st = seq->private; | 31 | struct ct_iter_state *st = seq->private; |
30 | struct hlist_node *n; | 32 | struct hlist_node *n; |
31 | 33 | ||
32 | for (st->bucket = 0; | 34 | for (st->bucket = 0; |
33 | st->bucket < nf_conntrack_htable_size; | 35 | st->bucket < nf_conntrack_htable_size; |
34 | st->bucket++) { | 36 | st->bucket++) { |
35 | n = rcu_dereference(nf_conntrack_hash[st->bucket].first); | 37 | n = rcu_dereference(net->ct.hash[st->bucket].first); |
36 | if (n) | 38 | if (n) |
37 | return n; | 39 | return n; |
38 | } | 40 | } |
@@ -42,13 +44,14 @@ static struct hlist_node *ct_get_first(struct seq_file *seq) | |||
42 | static struct hlist_node *ct_get_next(struct seq_file *seq, | 44 | static struct hlist_node *ct_get_next(struct seq_file *seq, |
43 | struct hlist_node *head) | 45 | struct hlist_node *head) |
44 | { | 46 | { |
47 | struct net *net = seq_file_net(seq); | ||
45 | struct ct_iter_state *st = seq->private; | 48 | struct ct_iter_state *st = seq->private; |
46 | 49 | ||
47 | head = rcu_dereference(head->next); | 50 | head = rcu_dereference(head->next); |
48 | while (head == NULL) { | 51 | while (head == NULL) { |
49 | if (++st->bucket >= nf_conntrack_htable_size) | 52 | if (++st->bucket >= nf_conntrack_htable_size) |
50 | return NULL; | 53 | return NULL; |
51 | head = rcu_dereference(nf_conntrack_hash[st->bucket].first); | 54 | head = rcu_dereference(net->ct.hash[st->bucket].first); |
52 | } | 55 | } |
53 | return head; | 56 | return head; |
54 | } | 57 | } |
@@ -158,8 +161,8 @@ static const struct seq_operations ct_seq_ops = { | |||
158 | 161 | ||
159 | static int ct_open(struct inode *inode, struct file *file) | 162 | static int ct_open(struct inode *inode, struct file *file) |
160 | { | 163 | { |
161 | return seq_open_private(file, &ct_seq_ops, | 164 | return seq_open_net(inode, file, &ct_seq_ops, |
162 | sizeof(struct ct_iter_state)); | 165 | sizeof(struct ct_iter_state)); |
163 | } | 166 | } |
164 | 167 | ||
165 | static const struct file_operations ct_file_ops = { | 168 | static const struct file_operations ct_file_ops = { |
@@ -167,21 +170,23 @@ static const struct file_operations ct_file_ops = { | |||
167 | .open = ct_open, | 170 | .open = ct_open, |
168 | .read = seq_read, | 171 | .read = seq_read, |
169 | .llseek = seq_lseek, | 172 | .llseek = seq_lseek, |
170 | .release = seq_release_private, | 173 | .release = seq_release_net, |
171 | }; | 174 | }; |
172 | 175 | ||
173 | /* expects */ | 176 | /* expects */ |
174 | struct ct_expect_iter_state { | 177 | struct ct_expect_iter_state { |
178 | struct seq_net_private p; | ||
175 | unsigned int bucket; | 179 | unsigned int bucket; |
176 | }; | 180 | }; |
177 | 181 | ||
178 | static struct hlist_node *ct_expect_get_first(struct seq_file *seq) | 182 | static struct hlist_node *ct_expect_get_first(struct seq_file *seq) |
179 | { | 183 | { |
184 | struct net *net = seq_file_net(seq); | ||
180 | struct ct_expect_iter_state *st = seq->private; | 185 | struct ct_expect_iter_state *st = seq->private; |
181 | struct hlist_node *n; | 186 | struct hlist_node *n; |
182 | 187 | ||
183 | for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) { | 188 | for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) { |
184 | n = rcu_dereference(nf_ct_expect_hash[st->bucket].first); | 189 | n = rcu_dereference(net->ct.expect_hash[st->bucket].first); |
185 | if (n) | 190 | if (n) |
186 | return n; | 191 | return n; |
187 | } | 192 | } |
@@ -191,13 +196,14 @@ static struct hlist_node *ct_expect_get_first(struct seq_file *seq) | |||
191 | static struct hlist_node *ct_expect_get_next(struct seq_file *seq, | 196 | static struct hlist_node *ct_expect_get_next(struct seq_file *seq, |
192 | struct hlist_node *head) | 197 | struct hlist_node *head) |
193 | { | 198 | { |
199 | struct net *net = seq_file_net(seq); | ||
194 | struct ct_expect_iter_state *st = seq->private; | 200 | struct ct_expect_iter_state *st = seq->private; |
195 | 201 | ||
196 | head = rcu_dereference(head->next); | 202 | head = rcu_dereference(head->next); |
197 | while (head == NULL) { | 203 | while (head == NULL) { |
198 | if (++st->bucket >= nf_ct_expect_hsize) | 204 | if (++st->bucket >= nf_ct_expect_hsize) |
199 | return NULL; | 205 | return NULL; |
200 | head = rcu_dereference(nf_ct_expect_hash[st->bucket].first); | 206 | head = rcu_dereference(net->ct.expect_hash[st->bucket].first); |
201 | } | 207 | } |
202 | return head; | 208 | return head; |
203 | } | 209 | } |
@@ -265,8 +271,8 @@ static const struct seq_operations exp_seq_ops = { | |||
265 | 271 | ||
266 | static int exp_open(struct inode *inode, struct file *file) | 272 | static int exp_open(struct inode *inode, struct file *file) |
267 | { | 273 | { |
268 | return seq_open_private(file, &exp_seq_ops, | 274 | return seq_open_net(inode, file, &exp_seq_ops, |
269 | sizeof(struct ct_expect_iter_state)); | 275 | sizeof(struct ct_expect_iter_state)); |
270 | } | 276 | } |
271 | 277 | ||
272 | static const struct file_operations ip_exp_file_ops = { | 278 | static const struct file_operations ip_exp_file_ops = { |
@@ -274,11 +280,12 @@ static const struct file_operations ip_exp_file_ops = { | |||
274 | .open = exp_open, | 280 | .open = exp_open, |
275 | .read = seq_read, | 281 | .read = seq_read, |
276 | .llseek = seq_lseek, | 282 | .llseek = seq_lseek, |
277 | .release = seq_release_private, | 283 | .release = seq_release_net, |
278 | }; | 284 | }; |
279 | 285 | ||
280 | static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) | 286 | static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) |
281 | { | 287 | { |
288 | struct net *net = seq_file_net(seq); | ||
282 | int cpu; | 289 | int cpu; |
283 | 290 | ||
284 | if (*pos == 0) | 291 | if (*pos == 0) |
@@ -288,7 +295,7 @@ static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) | |||
288 | if (!cpu_possible(cpu)) | 295 | if (!cpu_possible(cpu)) |
289 | continue; | 296 | continue; |
290 | *pos = cpu+1; | 297 | *pos = cpu+1; |
291 | return &per_cpu(nf_conntrack_stat, cpu); | 298 | return per_cpu_ptr(net->ct.stat, cpu); |
292 | } | 299 | } |
293 | 300 | ||
294 | return NULL; | 301 | return NULL; |
@@ -296,13 +303,14 @@ static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) | |||
296 | 303 | ||
297 | static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 304 | static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
298 | { | 305 | { |
306 | struct net *net = seq_file_net(seq); | ||
299 | int cpu; | 307 | int cpu; |
300 | 308 | ||
301 | for (cpu = *pos; cpu < NR_CPUS; ++cpu) { | 309 | for (cpu = *pos; cpu < NR_CPUS; ++cpu) { |
302 | if (!cpu_possible(cpu)) | 310 | if (!cpu_possible(cpu)) |
303 | continue; | 311 | continue; |
304 | *pos = cpu+1; | 312 | *pos = cpu+1; |
305 | return &per_cpu(nf_conntrack_stat, cpu); | 313 | return per_cpu_ptr(net->ct.stat, cpu); |
306 | } | 314 | } |
307 | 315 | ||
308 | return NULL; | 316 | return NULL; |
@@ -314,7 +322,8 @@ static void ct_cpu_seq_stop(struct seq_file *seq, void *v) | |||
314 | 322 | ||
315 | static int ct_cpu_seq_show(struct seq_file *seq, void *v) | 323 | static int ct_cpu_seq_show(struct seq_file *seq, void *v) |
316 | { | 324 | { |
317 | unsigned int nr_conntracks = atomic_read(&nf_conntrack_count); | 325 | struct net *net = seq_file_net(seq); |
326 | unsigned int nr_conntracks = atomic_read(&net->ct.count); | ||
318 | const struct ip_conntrack_stat *st = v; | 327 | const struct ip_conntrack_stat *st = v; |
319 | 328 | ||
320 | if (v == SEQ_START_TOKEN) { | 329 | if (v == SEQ_START_TOKEN) { |
@@ -354,7 +363,8 @@ static const struct seq_operations ct_cpu_seq_ops = { | |||
354 | 363 | ||
355 | static int ct_cpu_seq_open(struct inode *inode, struct file *file) | 364 | static int ct_cpu_seq_open(struct inode *inode, struct file *file) |
356 | { | 365 | { |
357 | return seq_open(file, &ct_cpu_seq_ops); | 366 | return seq_open_net(inode, file, &ct_cpu_seq_ops, |
367 | sizeof(struct seq_net_private)); | ||
358 | } | 368 | } |
359 | 369 | ||
360 | static const struct file_operations ct_cpu_seq_fops = { | 370 | static const struct file_operations ct_cpu_seq_fops = { |
@@ -362,39 +372,54 @@ static const struct file_operations ct_cpu_seq_fops = { | |||
362 | .open = ct_cpu_seq_open, | 372 | .open = ct_cpu_seq_open, |
363 | .read = seq_read, | 373 | .read = seq_read, |
364 | .llseek = seq_lseek, | 374 | .llseek = seq_lseek, |
365 | .release = seq_release, | 375 | .release = seq_release_net, |
366 | }; | 376 | }; |
367 | 377 | ||
368 | int __init nf_conntrack_ipv4_compat_init(void) | 378 | static int __net_init ip_conntrack_net_init(struct net *net) |
369 | { | 379 | { |
370 | struct proc_dir_entry *proc, *proc_exp, *proc_stat; | 380 | struct proc_dir_entry *proc, *proc_exp, *proc_stat; |
371 | 381 | ||
372 | proc = proc_net_fops_create(&init_net, "ip_conntrack", 0440, &ct_file_ops); | 382 | proc = proc_net_fops_create(net, "ip_conntrack", 0440, &ct_file_ops); |
373 | if (!proc) | 383 | if (!proc) |
374 | goto err1; | 384 | goto err1; |
375 | 385 | ||
376 | proc_exp = proc_net_fops_create(&init_net, "ip_conntrack_expect", 0440, | 386 | proc_exp = proc_net_fops_create(net, "ip_conntrack_expect", 0440, |
377 | &ip_exp_file_ops); | 387 | &ip_exp_file_ops); |
378 | if (!proc_exp) | 388 | if (!proc_exp) |
379 | goto err2; | 389 | goto err2; |
380 | 390 | ||
381 | proc_stat = proc_create("ip_conntrack", S_IRUGO, | 391 | proc_stat = proc_create("ip_conntrack", S_IRUGO, |
382 | init_net.proc_net_stat, &ct_cpu_seq_fops); | 392 | net->proc_net_stat, &ct_cpu_seq_fops); |
383 | if (!proc_stat) | 393 | if (!proc_stat) |
384 | goto err3; | 394 | goto err3; |
385 | return 0; | 395 | return 0; |
386 | 396 | ||
387 | err3: | 397 | err3: |
388 | proc_net_remove(&init_net, "ip_conntrack_expect"); | 398 | proc_net_remove(net, "ip_conntrack_expect"); |
389 | err2: | 399 | err2: |
390 | proc_net_remove(&init_net, "ip_conntrack"); | 400 | proc_net_remove(net, "ip_conntrack"); |
391 | err1: | 401 | err1: |
392 | return -ENOMEM; | 402 | return -ENOMEM; |
393 | } | 403 | } |
394 | 404 | ||
405 | static void __net_exit ip_conntrack_net_exit(struct net *net) | ||
406 | { | ||
407 | remove_proc_entry("ip_conntrack", net->proc_net_stat); | ||
408 | proc_net_remove(net, "ip_conntrack_expect"); | ||
409 | proc_net_remove(net, "ip_conntrack"); | ||
410 | } | ||
411 | |||
412 | static struct pernet_operations ip_conntrack_net_ops = { | ||
413 | .init = ip_conntrack_net_init, | ||
414 | .exit = ip_conntrack_net_exit, | ||
415 | }; | ||
416 | |||
417 | int __init nf_conntrack_ipv4_compat_init(void) | ||
418 | { | ||
419 | return register_pernet_subsys(&ip_conntrack_net_ops); | ||
420 | } | ||
421 | |||
395 | void __exit nf_conntrack_ipv4_compat_fini(void) | 422 | void __exit nf_conntrack_ipv4_compat_fini(void) |
396 | { | 423 | { |
397 | remove_proc_entry("ip_conntrack", init_net.proc_net_stat); | 424 | unregister_pernet_subsys(&ip_conntrack_net_ops); |
398 | proc_net_remove(&init_net, "ip_conntrack_expect"); | ||
399 | proc_net_remove(&init_net, "ip_conntrack"); | ||
400 | } | 425 | } |
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 97791048fa9b..4e8879220222 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c | |||
@@ -79,7 +79,7 @@ static int icmp_packet(struct nf_conn *ct, | |||
79 | const struct sk_buff *skb, | 79 | const struct sk_buff *skb, |
80 | unsigned int dataoff, | 80 | unsigned int dataoff, |
81 | enum ip_conntrack_info ctinfo, | 81 | enum ip_conntrack_info ctinfo, |
82 | int pf, | 82 | u_int8_t pf, |
83 | unsigned int hooknum) | 83 | unsigned int hooknum) |
84 | { | 84 | { |
85 | /* Try to delete connection immediately after all replies: | 85 | /* Try to delete connection immediately after all replies: |
@@ -91,7 +91,7 @@ static int icmp_packet(struct nf_conn *ct, | |||
91 | nf_ct_kill_acct(ct, ctinfo, skb); | 91 | nf_ct_kill_acct(ct, ctinfo, skb); |
92 | } else { | 92 | } else { |
93 | atomic_inc(&ct->proto.icmp.count); | 93 | atomic_inc(&ct->proto.icmp.count); |
94 | nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb); | 94 | nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct); |
95 | nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout); | 95 | nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout); |
96 | } | 96 | } |
97 | 97 | ||
@@ -123,7 +123,7 @@ static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb, | |||
123 | 123 | ||
124 | /* Returns conntrack if it dealt with ICMP, and filled in skb fields */ | 124 | /* Returns conntrack if it dealt with ICMP, and filled in skb fields */ |
125 | static int | 125 | static int |
126 | icmp_error_message(struct sk_buff *skb, | 126 | icmp_error_message(struct net *net, struct sk_buff *skb, |
127 | enum ip_conntrack_info *ctinfo, | 127 | enum ip_conntrack_info *ctinfo, |
128 | unsigned int hooknum) | 128 | unsigned int hooknum) |
129 | { | 129 | { |
@@ -155,7 +155,7 @@ icmp_error_message(struct sk_buff *skb, | |||
155 | 155 | ||
156 | *ctinfo = IP_CT_RELATED; | 156 | *ctinfo = IP_CT_RELATED; |
157 | 157 | ||
158 | h = nf_conntrack_find_get(&innertuple); | 158 | h = nf_conntrack_find_get(net, &innertuple); |
159 | if (!h) { | 159 | if (!h) { |
160 | pr_debug("icmp_error_message: no match\n"); | 160 | pr_debug("icmp_error_message: no match\n"); |
161 | return -NF_ACCEPT; | 161 | return -NF_ACCEPT; |
@@ -172,8 +172,8 @@ icmp_error_message(struct sk_buff *skb, | |||
172 | 172 | ||
173 | /* Small and modified version of icmp_rcv */ | 173 | /* Small and modified version of icmp_rcv */ |
174 | static int | 174 | static int |
175 | icmp_error(struct sk_buff *skb, unsigned int dataoff, | 175 | icmp_error(struct net *net, struct sk_buff *skb, unsigned int dataoff, |
176 | enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum) | 176 | enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum) |
177 | { | 177 | { |
178 | const struct icmphdr *icmph; | 178 | const struct icmphdr *icmph; |
179 | struct icmphdr _ih; | 179 | struct icmphdr _ih; |
@@ -181,16 +181,16 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff, | |||
181 | /* Not enough header? */ | 181 | /* Not enough header? */ |
182 | icmph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_ih), &_ih); | 182 | icmph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_ih), &_ih); |
183 | if (icmph == NULL) { | 183 | if (icmph == NULL) { |
184 | if (LOG_INVALID(IPPROTO_ICMP)) | 184 | if (LOG_INVALID(net, IPPROTO_ICMP)) |
185 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, | 185 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
186 | "nf_ct_icmp: short packet "); | 186 | "nf_ct_icmp: short packet "); |
187 | return -NF_ACCEPT; | 187 | return -NF_ACCEPT; |
188 | } | 188 | } |
189 | 189 | ||
190 | /* See ip_conntrack_proto_tcp.c */ | 190 | /* See ip_conntrack_proto_tcp.c */ |
191 | if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && | 191 | if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && |
192 | nf_ip_checksum(skb, hooknum, dataoff, 0)) { | 192 | nf_ip_checksum(skb, hooknum, dataoff, 0)) { |
193 | if (LOG_INVALID(IPPROTO_ICMP)) | 193 | if (LOG_INVALID(net, IPPROTO_ICMP)) |
194 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, | 194 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
195 | "nf_ct_icmp: bad HW ICMP checksum "); | 195 | "nf_ct_icmp: bad HW ICMP checksum "); |
196 | return -NF_ACCEPT; | 196 | return -NF_ACCEPT; |
@@ -203,7 +203,7 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff, | |||
203 | * discarded. | 203 | * discarded. |
204 | */ | 204 | */ |
205 | if (icmph->type > NR_ICMP_TYPES) { | 205 | if (icmph->type > NR_ICMP_TYPES) { |
206 | if (LOG_INVALID(IPPROTO_ICMP)) | 206 | if (LOG_INVALID(net, IPPROTO_ICMP)) |
207 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, | 207 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
208 | "nf_ct_icmp: invalid ICMP type "); | 208 | "nf_ct_icmp: invalid ICMP type "); |
209 | return -NF_ACCEPT; | 209 | return -NF_ACCEPT; |
@@ -217,7 +217,7 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff, | |||
217 | && icmph->type != ICMP_REDIRECT) | 217 | && icmph->type != ICMP_REDIRECT) |
218 | return NF_ACCEPT; | 218 | return NF_ACCEPT; |
219 | 219 | ||
220 | return icmp_error_message(skb, ctinfo, hooknum); | 220 | return icmp_error_message(net, skb, ctinfo, hooknum); |
221 | } | 221 | } |
222 | 222 | ||
223 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 223 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) |
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c new file mode 100644 index 000000000000..aa2c50a180f7 --- /dev/null +++ b/net/ipv4/netfilter/nf_defrag_ipv4.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* (C) 1999-2001 Paul `Rusty' Russell | ||
2 | * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/types.h> | ||
10 | #include <linux/ip.h> | ||
11 | #include <linux/netfilter.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/skbuff.h> | ||
14 | #include <net/route.h> | ||
15 | #include <net/ip.h> | ||
16 | |||
17 | #include <linux/netfilter_ipv4.h> | ||
18 | #include <net/netfilter/ipv4/nf_defrag_ipv4.h> | ||
19 | |||
20 | /* Returns new sk_buff, or NULL */ | ||
21 | static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user) | ||
22 | { | ||
23 | int err; | ||
24 | |||
25 | skb_orphan(skb); | ||
26 | |||
27 | local_bh_disable(); | ||
28 | err = ip_defrag(skb, user); | ||
29 | local_bh_enable(); | ||
30 | |||
31 | if (!err) | ||
32 | ip_send_check(ip_hdr(skb)); | ||
33 | |||
34 | return err; | ||
35 | } | ||
36 | |||
37 | static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, | ||
38 | struct sk_buff *skb, | ||
39 | const struct net_device *in, | ||
40 | const struct net_device *out, | ||
41 | int (*okfn)(struct sk_buff *)) | ||
42 | { | ||
43 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | ||
44 | /* Previously seen (loopback)? Ignore. Do this before | ||
45 | fragment check. */ | ||
46 | if (skb->nfct) | ||
47 | return NF_ACCEPT; | ||
48 | #endif | ||
49 | |||
50 | /* Gather fragments. */ | ||
51 | if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { | ||
52 | if (nf_ct_ipv4_gather_frags(skb, | ||
53 | hooknum == NF_INET_PRE_ROUTING ? | ||
54 | IP_DEFRAG_CONNTRACK_IN : | ||
55 | IP_DEFRAG_CONNTRACK_OUT)) | ||
56 | return NF_STOLEN; | ||
57 | } | ||
58 | return NF_ACCEPT; | ||
59 | } | ||
60 | |||
61 | static struct nf_hook_ops ipv4_defrag_ops[] = { | ||
62 | { | ||
63 | .hook = ipv4_conntrack_defrag, | ||
64 | .owner = THIS_MODULE, | ||
65 | .pf = PF_INET, | ||
66 | .hooknum = NF_INET_PRE_ROUTING, | ||
67 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, | ||
68 | }, | ||
69 | { | ||
70 | .hook = ipv4_conntrack_defrag, | ||
71 | .owner = THIS_MODULE, | ||
72 | .pf = PF_INET, | ||
73 | .hooknum = NF_INET_LOCAL_OUT, | ||
74 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, | ||
75 | }, | ||
76 | }; | ||
77 | |||
78 | static int __init nf_defrag_init(void) | ||
79 | { | ||
80 | return nf_register_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops)); | ||
81 | } | ||
82 | |||
83 | static void __exit nf_defrag_fini(void) | ||
84 | { | ||
85 | nf_unregister_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops)); | ||
86 | } | ||
87 | |||
88 | void nf_defrag_ipv4_enable(void) | ||
89 | { | ||
90 | } | ||
91 | EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable); | ||
92 | |||
93 | module_init(nf_defrag_init); | ||
94 | module_exit(nf_defrag_fini); | ||
95 | |||
96 | MODULE_LICENSE("GPL"); | ||
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 6c6a3cba8d50..2ac9eaf1a8c9 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c | |||
@@ -37,9 +37,6 @@ static struct nf_conntrack_l3proto *l3proto __read_mostly; | |||
37 | 37 | ||
38 | /* Calculated at init based on memory size */ | 38 | /* Calculated at init based on memory size */ |
39 | static unsigned int nf_nat_htable_size __read_mostly; | 39 | static unsigned int nf_nat_htable_size __read_mostly; |
40 | static int nf_nat_vmalloced; | ||
41 | |||
42 | static struct hlist_head *bysource __read_mostly; | ||
43 | 40 | ||
44 | #define MAX_IP_NAT_PROTO 256 | 41 | #define MAX_IP_NAT_PROTO 256 |
45 | static const struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO] | 42 | static const struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO] |
@@ -145,7 +142,8 @@ same_src(const struct nf_conn *ct, | |||
145 | 142 | ||
146 | /* Only called for SRC manip */ | 143 | /* Only called for SRC manip */ |
147 | static int | 144 | static int |
148 | find_appropriate_src(const struct nf_conntrack_tuple *tuple, | 145 | find_appropriate_src(struct net *net, |
146 | const struct nf_conntrack_tuple *tuple, | ||
149 | struct nf_conntrack_tuple *result, | 147 | struct nf_conntrack_tuple *result, |
150 | const struct nf_nat_range *range) | 148 | const struct nf_nat_range *range) |
151 | { | 149 | { |
@@ -155,7 +153,7 @@ find_appropriate_src(const struct nf_conntrack_tuple *tuple, | |||
155 | const struct hlist_node *n; | 153 | const struct hlist_node *n; |
156 | 154 | ||
157 | rcu_read_lock(); | 155 | rcu_read_lock(); |
158 | hlist_for_each_entry_rcu(nat, n, &bysource[h], bysource) { | 156 | hlist_for_each_entry_rcu(nat, n, &net->ipv4.nat_bysource[h], bysource) { |
159 | ct = nat->ct; | 157 | ct = nat->ct; |
160 | if (same_src(ct, tuple)) { | 158 | if (same_src(ct, tuple)) { |
161 | /* Copy source part from reply tuple. */ | 159 | /* Copy source part from reply tuple. */ |
@@ -231,6 +229,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, | |||
231 | struct nf_conn *ct, | 229 | struct nf_conn *ct, |
232 | enum nf_nat_manip_type maniptype) | 230 | enum nf_nat_manip_type maniptype) |
233 | { | 231 | { |
232 | struct net *net = nf_ct_net(ct); | ||
234 | const struct nf_nat_protocol *proto; | 233 | const struct nf_nat_protocol *proto; |
235 | 234 | ||
236 | /* 1) If this srcip/proto/src-proto-part is currently mapped, | 235 | /* 1) If this srcip/proto/src-proto-part is currently mapped, |
@@ -242,7 +241,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, | |||
242 | manips not an issue. */ | 241 | manips not an issue. */ |
243 | if (maniptype == IP_NAT_MANIP_SRC && | 242 | if (maniptype == IP_NAT_MANIP_SRC && |
244 | !(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) { | 243 | !(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) { |
245 | if (find_appropriate_src(orig_tuple, tuple, range)) { | 244 | if (find_appropriate_src(net, orig_tuple, tuple, range)) { |
246 | pr_debug("get_unique_tuple: Found current src map\n"); | 245 | pr_debug("get_unique_tuple: Found current src map\n"); |
247 | if (!nf_nat_used_tuple(tuple, ct)) | 246 | if (!nf_nat_used_tuple(tuple, ct)) |
248 | return; | 247 | return; |
@@ -283,6 +282,7 @@ nf_nat_setup_info(struct nf_conn *ct, | |||
283 | const struct nf_nat_range *range, | 282 | const struct nf_nat_range *range, |
284 | enum nf_nat_manip_type maniptype) | 283 | enum nf_nat_manip_type maniptype) |
285 | { | 284 | { |
285 | struct net *net = nf_ct_net(ct); | ||
286 | struct nf_conntrack_tuple curr_tuple, new_tuple; | 286 | struct nf_conntrack_tuple curr_tuple, new_tuple; |
287 | struct nf_conn_nat *nat; | 287 | struct nf_conn_nat *nat; |
288 | int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK); | 288 | int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK); |
@@ -334,7 +334,8 @@ nf_nat_setup_info(struct nf_conn *ct, | |||
334 | /* nf_conntrack_alter_reply might re-allocate exntension aera */ | 334 | /* nf_conntrack_alter_reply might re-allocate exntension aera */ |
335 | nat = nfct_nat(ct); | 335 | nat = nfct_nat(ct); |
336 | nat->ct = ct; | 336 | nat->ct = ct; |
337 | hlist_add_head_rcu(&nat->bysource, &bysource[srchash]); | 337 | hlist_add_head_rcu(&nat->bysource, |
338 | &net->ipv4.nat_bysource[srchash]); | ||
338 | spin_unlock_bh(&nf_nat_lock); | 339 | spin_unlock_bh(&nf_nat_lock); |
339 | } | 340 | } |
340 | 341 | ||
@@ -583,6 +584,40 @@ static struct nf_ct_ext_type nat_extend __read_mostly = { | |||
583 | .flags = NF_CT_EXT_F_PREALLOC, | 584 | .flags = NF_CT_EXT_F_PREALLOC, |
584 | }; | 585 | }; |
585 | 586 | ||
587 | static int __net_init nf_nat_net_init(struct net *net) | ||
588 | { | ||
589 | net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size, | ||
590 | &net->ipv4.nat_vmalloced); | ||
591 | if (!net->ipv4.nat_bysource) | ||
592 | return -ENOMEM; | ||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | /* Clear NAT section of all conntracks, in case we're loaded again. */ | ||
597 | static int clean_nat(struct nf_conn *i, void *data) | ||
598 | { | ||
599 | struct nf_conn_nat *nat = nfct_nat(i); | ||
600 | |||
601 | if (!nat) | ||
602 | return 0; | ||
603 | memset(nat, 0, sizeof(*nat)); | ||
604 | i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST); | ||
605 | return 0; | ||
606 | } | ||
607 | |||
608 | static void __net_exit nf_nat_net_exit(struct net *net) | ||
609 | { | ||
610 | nf_ct_iterate_cleanup(net, &clean_nat, NULL); | ||
611 | synchronize_rcu(); | ||
612 | nf_ct_free_hashtable(net->ipv4.nat_bysource, net->ipv4.nat_vmalloced, | ||
613 | nf_nat_htable_size); | ||
614 | } | ||
615 | |||
616 | static struct pernet_operations nf_nat_net_ops = { | ||
617 | .init = nf_nat_net_init, | ||
618 | .exit = nf_nat_net_exit, | ||
619 | }; | ||
620 | |||
586 | static int __init nf_nat_init(void) | 621 | static int __init nf_nat_init(void) |
587 | { | 622 | { |
588 | size_t i; | 623 | size_t i; |
@@ -599,12 +634,9 @@ static int __init nf_nat_init(void) | |||
599 | /* Leave them the same for the moment. */ | 634 | /* Leave them the same for the moment. */ |
600 | nf_nat_htable_size = nf_conntrack_htable_size; | 635 | nf_nat_htable_size = nf_conntrack_htable_size; |
601 | 636 | ||
602 | bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size, | 637 | ret = register_pernet_subsys(&nf_nat_net_ops); |
603 | &nf_nat_vmalloced); | 638 | if (ret < 0) |
604 | if (!bysource) { | ||
605 | ret = -ENOMEM; | ||
606 | goto cleanup_extend; | 639 | goto cleanup_extend; |
607 | } | ||
608 | 640 | ||
609 | /* Sew in builtin protocols. */ | 641 | /* Sew in builtin protocols. */ |
610 | spin_lock_bh(&nf_nat_lock); | 642 | spin_lock_bh(&nf_nat_lock); |
@@ -629,23 +661,9 @@ static int __init nf_nat_init(void) | |||
629 | return ret; | 661 | return ret; |
630 | } | 662 | } |
631 | 663 | ||
632 | /* Clear NAT section of all conntracks, in case we're loaded again. */ | ||
633 | static int clean_nat(struct nf_conn *i, void *data) | ||
634 | { | ||
635 | struct nf_conn_nat *nat = nfct_nat(i); | ||
636 | |||
637 | if (!nat) | ||
638 | return 0; | ||
639 | memset(nat, 0, sizeof(*nat)); | ||
640 | i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST); | ||
641 | return 0; | ||
642 | } | ||
643 | |||
644 | static void __exit nf_nat_cleanup(void) | 664 | static void __exit nf_nat_cleanup(void) |
645 | { | 665 | { |
646 | nf_ct_iterate_cleanup(&clean_nat, NULL); | 666 | unregister_pernet_subsys(&nf_nat_net_ops); |
647 | synchronize_rcu(); | ||
648 | nf_ct_free_hashtable(bysource, nf_nat_vmalloced, nf_nat_htable_size); | ||
649 | nf_ct_l3proto_put(l3proto); | 667 | nf_ct_l3proto_put(l3proto); |
650 | nf_ct_extend_unregister(&nat_extend); | 668 | nf_ct_extend_unregister(&nat_extend); |
651 | rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL); | 669 | rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL); |
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c index 112dcfa12900..cf7a42bf9820 100644 --- a/net/ipv4/netfilter/nf_nat_helper.c +++ b/net/ipv4/netfilter/nf_nat_helper.c | |||
@@ -193,7 +193,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb, | |||
193 | nf_conntrack_tcp_update(skb, ip_hdrlen(skb), | 193 | nf_conntrack_tcp_update(skb, ip_hdrlen(skb), |
194 | ct, CTINFO2DIR(ctinfo)); | 194 | ct, CTINFO2DIR(ctinfo)); |
195 | 195 | ||
196 | nf_conntrack_event_cache(IPCT_NATSEQADJ, skb); | 196 | nf_conntrack_event_cache(IPCT_NATSEQADJ, ct); |
197 | } | 197 | } |
198 | return 1; | 198 | return 1; |
199 | } | 199 | } |
diff --git a/net/ipv4/netfilter/nf_nat_pptp.c b/net/ipv4/netfilter/nf_nat_pptp.c index da3d91a5ef5c..9eb171056c63 100644 --- a/net/ipv4/netfilter/nf_nat_pptp.c +++ b/net/ipv4/netfilter/nf_nat_pptp.c | |||
@@ -40,6 +40,7 @@ MODULE_ALIAS("ip_nat_pptp"); | |||
40 | static void pptp_nat_expected(struct nf_conn *ct, | 40 | static void pptp_nat_expected(struct nf_conn *ct, |
41 | struct nf_conntrack_expect *exp) | 41 | struct nf_conntrack_expect *exp) |
42 | { | 42 | { |
43 | struct net *net = nf_ct_net(ct); | ||
43 | const struct nf_conn *master = ct->master; | 44 | const struct nf_conn *master = ct->master; |
44 | struct nf_conntrack_expect *other_exp; | 45 | struct nf_conntrack_expect *other_exp; |
45 | struct nf_conntrack_tuple t; | 46 | struct nf_conntrack_tuple t; |
@@ -73,7 +74,7 @@ static void pptp_nat_expected(struct nf_conn *ct, | |||
73 | 74 | ||
74 | pr_debug("trying to unexpect other dir: "); | 75 | pr_debug("trying to unexpect other dir: "); |
75 | nf_ct_dump_tuple_ip(&t); | 76 | nf_ct_dump_tuple_ip(&t); |
76 | other_exp = nf_ct_expect_find_get(&t); | 77 | other_exp = nf_ct_expect_find_get(net, &t); |
77 | if (other_exp) { | 78 | if (other_exp) { |
78 | nf_ct_unexpect_related(other_exp); | 79 | nf_ct_unexpect_related(other_exp); |
79 | nf_ct_expect_put(other_exp); | 80 | nf_ct_expect_put(other_exp); |
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c index e8b4d0d4439e..bea54a685109 100644 --- a/net/ipv4/netfilter/nf_nat_rule.c +++ b/net/ipv4/netfilter/nf_nat_rule.c | |||
@@ -33,7 +33,7 @@ static struct | |||
33 | struct ipt_replace repl; | 33 | struct ipt_replace repl; |
34 | struct ipt_standard entries[3]; | 34 | struct ipt_standard entries[3]; |
35 | struct ipt_error term; | 35 | struct ipt_error term; |
36 | } nat_initial_table __initdata = { | 36 | } nat_initial_table __net_initdata = { |
37 | .repl = { | 37 | .repl = { |
38 | .name = "nat", | 38 | .name = "nat", |
39 | .valid_hooks = NAT_VALID_HOOKS, | 39 | .valid_hooks = NAT_VALID_HOOKS, |
@@ -58,47 +58,42 @@ static struct | |||
58 | .term = IPT_ERROR_INIT, /* ERROR */ | 58 | .term = IPT_ERROR_INIT, /* ERROR */ |
59 | }; | 59 | }; |
60 | 60 | ||
61 | static struct xt_table __nat_table = { | 61 | static struct xt_table nat_table = { |
62 | .name = "nat", | 62 | .name = "nat", |
63 | .valid_hooks = NAT_VALID_HOOKS, | 63 | .valid_hooks = NAT_VALID_HOOKS, |
64 | .lock = __RW_LOCK_UNLOCKED(__nat_table.lock), | 64 | .lock = __RW_LOCK_UNLOCKED(__nat_table.lock), |
65 | .me = THIS_MODULE, | 65 | .me = THIS_MODULE, |
66 | .af = AF_INET, | 66 | .af = AF_INET, |
67 | }; | 67 | }; |
68 | static struct xt_table *nat_table; | ||
69 | 68 | ||
70 | /* Source NAT */ | 69 | /* Source NAT */ |
71 | static unsigned int ipt_snat_target(struct sk_buff *skb, | 70 | static unsigned int |
72 | const struct net_device *in, | 71 | ipt_snat_target(struct sk_buff *skb, const struct xt_target_param *par) |
73 | const struct net_device *out, | ||
74 | unsigned int hooknum, | ||
75 | const struct xt_target *target, | ||
76 | const void *targinfo) | ||
77 | { | 72 | { |
78 | struct nf_conn *ct; | 73 | struct nf_conn *ct; |
79 | enum ip_conntrack_info ctinfo; | 74 | enum ip_conntrack_info ctinfo; |
80 | const struct nf_nat_multi_range_compat *mr = targinfo; | 75 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
81 | 76 | ||
82 | NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING); | 77 | NF_CT_ASSERT(par->hooknum == NF_INET_POST_ROUTING); |
83 | 78 | ||
84 | ct = nf_ct_get(skb, &ctinfo); | 79 | ct = nf_ct_get(skb, &ctinfo); |
85 | 80 | ||
86 | /* Connection must be valid and new. */ | 81 | /* Connection must be valid and new. */ |
87 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || | 82 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || |
88 | ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)); | 83 | ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)); |
89 | NF_CT_ASSERT(out); | 84 | NF_CT_ASSERT(par->out != NULL); |
90 | 85 | ||
91 | return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC); | 86 | return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC); |
92 | } | 87 | } |
93 | 88 | ||
94 | /* Before 2.6.11 we did implicit source NAT if required. Warn about change. */ | 89 | /* Before 2.6.11 we did implicit source NAT if required. Warn about change. */ |
95 | static void warn_if_extra_mangle(__be32 dstip, __be32 srcip) | 90 | static void warn_if_extra_mangle(struct net *net, __be32 dstip, __be32 srcip) |
96 | { | 91 | { |
97 | static int warned = 0; | 92 | static int warned = 0; |
98 | struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } }; | 93 | struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } }; |
99 | struct rtable *rt; | 94 | struct rtable *rt; |
100 | 95 | ||
101 | if (ip_route_output_key(&init_net, &rt, &fl) != 0) | 96 | if (ip_route_output_key(net, &rt, &fl) != 0) |
102 | return; | 97 | return; |
103 | 98 | ||
104 | if (rt->rt_src != srcip && !warned) { | 99 | if (rt->rt_src != srcip && !warned) { |
@@ -110,40 +105,32 @@ static void warn_if_extra_mangle(__be32 dstip, __be32 srcip) | |||
110 | ip_rt_put(rt); | 105 | ip_rt_put(rt); |
111 | } | 106 | } |
112 | 107 | ||
113 | static unsigned int ipt_dnat_target(struct sk_buff *skb, | 108 | static unsigned int |
114 | const struct net_device *in, | 109 | ipt_dnat_target(struct sk_buff *skb, const struct xt_target_param *par) |
115 | const struct net_device *out, | ||
116 | unsigned int hooknum, | ||
117 | const struct xt_target *target, | ||
118 | const void *targinfo) | ||
119 | { | 110 | { |
120 | struct nf_conn *ct; | 111 | struct nf_conn *ct; |
121 | enum ip_conntrack_info ctinfo; | 112 | enum ip_conntrack_info ctinfo; |
122 | const struct nf_nat_multi_range_compat *mr = targinfo; | 113 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
123 | 114 | ||
124 | NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING || | 115 | NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING || |
125 | hooknum == NF_INET_LOCAL_OUT); | 116 | par->hooknum == NF_INET_LOCAL_OUT); |
126 | 117 | ||
127 | ct = nf_ct_get(skb, &ctinfo); | 118 | ct = nf_ct_get(skb, &ctinfo); |
128 | 119 | ||
129 | /* Connection must be valid and new. */ | 120 | /* Connection must be valid and new. */ |
130 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); | 121 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); |
131 | 122 | ||
132 | if (hooknum == NF_INET_LOCAL_OUT && | 123 | if (par->hooknum == NF_INET_LOCAL_OUT && |
133 | mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) | 124 | mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) |
134 | warn_if_extra_mangle(ip_hdr(skb)->daddr, | 125 | warn_if_extra_mangle(dev_net(par->out), ip_hdr(skb)->daddr, |
135 | mr->range[0].min_ip); | 126 | mr->range[0].min_ip); |
136 | 127 | ||
137 | return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST); | 128 | return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST); |
138 | } | 129 | } |
139 | 130 | ||
140 | static bool ipt_snat_checkentry(const char *tablename, | 131 | static bool ipt_snat_checkentry(const struct xt_tgchk_param *par) |
141 | const void *entry, | ||
142 | const struct xt_target *target, | ||
143 | void *targinfo, | ||
144 | unsigned int hook_mask) | ||
145 | { | 132 | { |
146 | const struct nf_nat_multi_range_compat *mr = targinfo; | 133 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
147 | 134 | ||
148 | /* Must be a valid range */ | 135 | /* Must be a valid range */ |
149 | if (mr->rangesize != 1) { | 136 | if (mr->rangesize != 1) { |
@@ -153,13 +140,9 @@ static bool ipt_snat_checkentry(const char *tablename, | |||
153 | return true; | 140 | return true; |
154 | } | 141 | } |
155 | 142 | ||
156 | static bool ipt_dnat_checkentry(const char *tablename, | 143 | static bool ipt_dnat_checkentry(const struct xt_tgchk_param *par) |
157 | const void *entry, | ||
158 | const struct xt_target *target, | ||
159 | void *targinfo, | ||
160 | unsigned int hook_mask) | ||
161 | { | 144 | { |
162 | const struct nf_nat_multi_range_compat *mr = targinfo; | 145 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
163 | 146 | ||
164 | /* Must be a valid range */ | 147 | /* Must be a valid range */ |
165 | if (mr->rangesize != 1) { | 148 | if (mr->rangesize != 1) { |
@@ -194,9 +177,10 @@ int nf_nat_rule_find(struct sk_buff *skb, | |||
194 | const struct net_device *out, | 177 | const struct net_device *out, |
195 | struct nf_conn *ct) | 178 | struct nf_conn *ct) |
196 | { | 179 | { |
180 | struct net *net = nf_ct_net(ct); | ||
197 | int ret; | 181 | int ret; |
198 | 182 | ||
199 | ret = ipt_do_table(skb, hooknum, in, out, nat_table); | 183 | ret = ipt_do_table(skb, hooknum, in, out, net->ipv4.nat_table); |
200 | 184 | ||
201 | if (ret == NF_ACCEPT) { | 185 | if (ret == NF_ACCEPT) { |
202 | if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum))) | 186 | if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum))) |
@@ -226,14 +210,32 @@ static struct xt_target ipt_dnat_reg __read_mostly = { | |||
226 | .family = AF_INET, | 210 | .family = AF_INET, |
227 | }; | 211 | }; |
228 | 212 | ||
213 | static int __net_init nf_nat_rule_net_init(struct net *net) | ||
214 | { | ||
215 | net->ipv4.nat_table = ipt_register_table(net, &nat_table, | ||
216 | &nat_initial_table.repl); | ||
217 | if (IS_ERR(net->ipv4.nat_table)) | ||
218 | return PTR_ERR(net->ipv4.nat_table); | ||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | static void __net_exit nf_nat_rule_net_exit(struct net *net) | ||
223 | { | ||
224 | ipt_unregister_table(net->ipv4.nat_table); | ||
225 | } | ||
226 | |||
227 | static struct pernet_operations nf_nat_rule_net_ops = { | ||
228 | .init = nf_nat_rule_net_init, | ||
229 | .exit = nf_nat_rule_net_exit, | ||
230 | }; | ||
231 | |||
229 | int __init nf_nat_rule_init(void) | 232 | int __init nf_nat_rule_init(void) |
230 | { | 233 | { |
231 | int ret; | 234 | int ret; |
232 | 235 | ||
233 | nat_table = ipt_register_table(&init_net, &__nat_table, | 236 | ret = register_pernet_subsys(&nf_nat_rule_net_ops); |
234 | &nat_initial_table.repl); | 237 | if (ret != 0) |
235 | if (IS_ERR(nat_table)) | 238 | goto out; |
236 | return PTR_ERR(nat_table); | ||
237 | ret = xt_register_target(&ipt_snat_reg); | 239 | ret = xt_register_target(&ipt_snat_reg); |
238 | if (ret != 0) | 240 | if (ret != 0) |
239 | goto unregister_table; | 241 | goto unregister_table; |
@@ -247,8 +249,8 @@ int __init nf_nat_rule_init(void) | |||
247 | unregister_snat: | 249 | unregister_snat: |
248 | xt_unregister_target(&ipt_snat_reg); | 250 | xt_unregister_target(&ipt_snat_reg); |
249 | unregister_table: | 251 | unregister_table: |
250 | ipt_unregister_table(nat_table); | 252 | unregister_pernet_subsys(&nf_nat_rule_net_ops); |
251 | 253 | out: | |
252 | return ret; | 254 | return ret; |
253 | } | 255 | } |
254 | 256 | ||
@@ -256,5 +258,5 @@ void nf_nat_rule_cleanup(void) | |||
256 | { | 258 | { |
257 | xt_unregister_target(&ipt_dnat_reg); | 259 | xt_unregister_target(&ipt_dnat_reg); |
258 | xt_unregister_target(&ipt_snat_reg); | 260 | xt_unregister_target(&ipt_snat_reg); |
259 | ipt_unregister_table(nat_table); | 261 | unregister_pernet_subsys(&nf_nat_rule_net_ops); |
260 | } | 262 | } |