diff options
author | Harald Welte <laforge@netfilter.org> | 2006-01-12 16:30:04 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-01-12 17:06:43 -0500 |
commit | 2e4e6a17af35be359cc8f1c924f8f198fbd478cc (patch) | |
tree | cb4b5438dcf9ff9d57518a26124308bcbfffd214 /net/ipv4 | |
parent | 880b005f294454d989783d0984dc554dfe3c8214 (diff) |
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
60 files changed, 245 insertions, 3995 deletions
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index a9893ec03e02..db783036e4d8 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -182,6 +182,7 @@ config IP_NF_QUEUE | |||
182 | 182 | ||
183 | config IP_NF_IPTABLES | 183 | config IP_NF_IPTABLES |
184 | tristate "IP tables support (required for filtering/masq/NAT)" | 184 | tristate "IP tables support (required for filtering/masq/NAT)" |
185 | depends on NETFILTER_XTABLES | ||
185 | help | 186 | help |
186 | iptables is a general, extensible packet identification framework. | 187 | iptables is a general, extensible packet identification framework. |
187 | The packet filtering and full NAT (masquerading, port forwarding, | 188 | The packet filtering and full NAT (masquerading, port forwarding, |
@@ -191,16 +192,6 @@ config IP_NF_IPTABLES | |||
191 | To compile it as a module, choose M here. If unsure, say N. | 192 | To compile it as a module, choose M here. If unsure, say N. |
192 | 193 | ||
193 | # The matches. | 194 | # The matches. |
194 | config IP_NF_MATCH_LIMIT | ||
195 | tristate "limit match support" | ||
196 | depends on IP_NF_IPTABLES | ||
197 | help | ||
198 | limit matching allows you to control the rate at which a rule can be | ||
199 | matched: mainly useful in combination with the LOG target ("LOG | ||
200 | target support", below) and to avoid some Denial of Service attacks. | ||
201 | |||
202 | To compile it as a module, choose M here. If unsure, say N. | ||
203 | |||
204 | config IP_NF_MATCH_IPRANGE | 195 | config IP_NF_MATCH_IPRANGE |
205 | tristate "IP range match support" | 196 | tristate "IP range match support" |
206 | depends on IP_NF_IPTABLES | 197 | depends on IP_NF_IPTABLES |
@@ -210,37 +201,6 @@ config IP_NF_MATCH_IPRANGE | |||
210 | 201 | ||
211 | To compile it as a module, choose M here. If unsure, say N. | 202 | To compile it as a module, choose M here. If unsure, say N. |
212 | 203 | ||
213 | config IP_NF_MATCH_MAC | ||
214 | tristate "MAC address match support" | ||
215 | depends on IP_NF_IPTABLES | ||
216 | help | ||
217 | MAC matching allows you to match packets based on the source | ||
218 | Ethernet address of the packet. | ||
219 | |||
220 | To compile it as a module, choose M here. If unsure, say N. | ||
221 | |||
222 | config IP_NF_MATCH_PKTTYPE | ||
223 | tristate "Packet type match support" | ||
224 | depends on IP_NF_IPTABLES | ||
225 | help | ||
226 | Packet type matching allows you to match a packet by | ||
227 | its "class", eg. BROADCAST, MULTICAST, ... | ||
228 | |||
229 | Typical usage: | ||
230 | iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG | ||
231 | |||
232 | To compile it as a module, choose M here. If unsure, say N. | ||
233 | |||
234 | config IP_NF_MATCH_MARK | ||
235 | tristate "netfilter MARK match support" | ||
236 | depends on IP_NF_IPTABLES | ||
237 | help | ||
238 | Netfilter mark matching allows you to match packets based on the | ||
239 | `nfmark' value in the packet. This can be set by the MARK target | ||
240 | (see below). | ||
241 | |||
242 | To compile it as a module, choose M here. If unsure, say N. | ||
243 | |||
244 | config IP_NF_MATCH_MULTIPORT | 204 | config IP_NF_MATCH_MULTIPORT |
245 | tristate "Multiple port match support" | 205 | tristate "Multiple port match support" |
246 | depends on IP_NF_IPTABLES | 206 | depends on IP_NF_IPTABLES |
@@ -301,15 +261,6 @@ config IP_NF_MATCH_AH_ESP | |||
301 | 261 | ||
302 | To compile it as a module, choose M here. If unsure, say N. | 262 | To compile it as a module, choose M here. If unsure, say N. |
303 | 263 | ||
304 | config IP_NF_MATCH_LENGTH | ||
305 | tristate "LENGTH match support" | ||
306 | depends on IP_NF_IPTABLES | ||
307 | help | ||
308 | This option allows you to match the length of a packet against a | ||
309 | specific value or range of values. | ||
310 | |||
311 | To compile it as a module, choose M here. If unsure, say N. | ||
312 | |||
313 | config IP_NF_MATCH_TTL | 264 | config IP_NF_MATCH_TTL |
314 | tristate "TTL match support" | 265 | tristate "TTL match support" |
315 | depends on IP_NF_IPTABLES | 266 | depends on IP_NF_IPTABLES |
@@ -319,50 +270,6 @@ config IP_NF_MATCH_TTL | |||
319 | 270 | ||
320 | To compile it as a module, choose M here. If unsure, say N. | 271 | To compile it as a module, choose M here. If unsure, say N. |
321 | 272 | ||
322 | config IP_NF_MATCH_TCPMSS | ||
323 | tristate "tcpmss match support" | ||
324 | depends on IP_NF_IPTABLES | ||
325 | help | ||
326 | This option adds a `tcpmss' match, which allows you to examine the | ||
327 | MSS value of TCP SYN packets, which control the maximum packet size | ||
328 | for that connection. | ||
329 | |||
330 | To compile it as a module, choose M here. If unsure, say N. | ||
331 | |||
332 | config IP_NF_MATCH_HELPER | ||
333 | tristate "Helper match support" | ||
334 | depends on IP_NF_IPTABLES | ||
335 | depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 | ||
336 | help | ||
337 | Helper matching allows you to match packets in dynamic connections | ||
338 | tracked by a conntrack-helper, ie. ip_conntrack_ftp | ||
339 | |||
340 | To compile it as a module, choose M here. If unsure, say Y. | ||
341 | |||
342 | config IP_NF_MATCH_STATE | ||
343 | tristate "Connection state match support" | ||
344 | depends on IP_NF_IPTABLES | ||
345 | depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 | ||
346 | help | ||
347 | Connection state matching allows you to match packets based on their | ||
348 | relationship to a tracked connection (ie. previous packets). This | ||
349 | is a powerful tool for packet classification. | ||
350 | |||
351 | To compile it as a module, choose M here. If unsure, say N. | ||
352 | |||
353 | config IP_NF_MATCH_CONNTRACK | ||
354 | tristate "Connection tracking match support" | ||
355 | depends on IP_NF_IPTABLES | ||
356 | depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 | ||
357 | help | ||
358 | This is a general conntrack match module, a superset of the state match. | ||
359 | |||
360 | It allows matching on additional conntrack information, which is | ||
361 | useful in complex configurations, such as NAT gateways with multiple | ||
362 | internet links or tunnels. | ||
363 | |||
364 | To compile it as a module, choose M here. If unsure, say N. | ||
365 | |||
366 | config IP_NF_MATCH_OWNER | 273 | config IP_NF_MATCH_OWNER |
367 | tristate "Owner match support" | 274 | tristate "Owner match support" |
368 | depends on IP_NF_IPTABLES | 275 | depends on IP_NF_IPTABLES |
@@ -372,15 +279,6 @@ config IP_NF_MATCH_OWNER | |||
372 | 279 | ||
373 | To compile it as a module, choose M here. If unsure, say N. | 280 | To compile it as a module, choose M here. If unsure, say N. |
374 | 281 | ||
375 | config IP_NF_MATCH_PHYSDEV | ||
376 | tristate "Physdev match support" | ||
377 | depends on IP_NF_IPTABLES && BRIDGE_NETFILTER | ||
378 | help | ||
379 | Physdev packet matching matches against the physical bridge ports | ||
380 | the IP packet arrived on or will leave by. | ||
381 | |||
382 | To compile it as a module, choose M here. If unsure, say N. | ||
383 | |||
384 | config IP_NF_MATCH_ADDRTYPE | 282 | config IP_NF_MATCH_ADDRTYPE |
385 | tristate 'address type match support' | 283 | tristate 'address type match support' |
386 | depends on IP_NF_IPTABLES | 284 | depends on IP_NF_IPTABLES |
@@ -391,75 +289,6 @@ config IP_NF_MATCH_ADDRTYPE | |||
391 | If you want to compile it as a module, say M here and read | 289 | If you want to compile it as a module, say M here and read |
392 | <file:Documentation/modules.txt>. If unsure, say `N'. | 290 | <file:Documentation/modules.txt>. If unsure, say `N'. |
393 | 291 | ||
394 | config IP_NF_MATCH_REALM | ||
395 | tristate 'realm match support' | ||
396 | depends on IP_NF_IPTABLES | ||
397 | select NET_CLS_ROUTE | ||
398 | help | ||
399 | This option adds a `realm' match, which allows you to use the realm | ||
400 | key from the routing subsystem inside iptables. | ||
401 | |||
402 | This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option | ||
403 | in tc world. | ||
404 | |||
405 | If you want to compile it as a module, say M here and read | ||
406 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
407 | |||
408 | config IP_NF_MATCH_SCTP | ||
409 | tristate 'SCTP protocol match support' | ||
410 | depends on IP_NF_IPTABLES | ||
411 | help | ||
412 | With this option enabled, you will be able to use the iptables | ||
413 | `sctp' match in order to match on SCTP source/destination ports | ||
414 | and SCTP chunk types. | ||
415 | |||
416 | If you want to compile it as a module, say M here and read | ||
417 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
418 | |||
419 | config IP_NF_MATCH_DCCP | ||
420 | tristate 'DCCP protocol match support' | ||
421 | depends on IP_NF_IPTABLES | ||
422 | help | ||
423 | With this option enabled, you will be able to use the iptables | ||
424 | `dccp' match in order to match on DCCP source/destination ports | ||
425 | and DCCP flags. | ||
426 | |||
427 | If you want to compile it as a module, say M here and read | ||
428 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
429 | |||
430 | config IP_NF_MATCH_COMMENT | ||
431 | tristate 'comment match support' | ||
432 | depends on IP_NF_IPTABLES | ||
433 | help | ||
434 | This option adds a `comment' dummy-match, which allows you to put | ||
435 | comments in your iptables ruleset. | ||
436 | |||
437 | If you want to compile it as a module, say M here and read | ||
438 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
439 | |||
440 | config IP_NF_MATCH_CONNMARK | ||
441 | tristate 'Connection mark match support' | ||
442 | depends on IP_NF_IPTABLES | ||
443 | depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4) | ||
444 | help | ||
445 | This option adds a `connmark' match, which allows you to match the | ||
446 | connection mark value previously set for the session by `CONNMARK'. | ||
447 | |||
448 | If you want to compile it as a module, say M here and read | ||
449 | <file:Documentation/modules.txt>. The module will be called | ||
450 | ipt_connmark.o. If unsure, say `N'. | ||
451 | |||
452 | config IP_NF_MATCH_CONNBYTES | ||
453 | tristate 'Connection byte/packet counter match support' | ||
454 | depends on IP_NF_IPTABLES | ||
455 | depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || (NF_CT_ACCT && NF_CONNTRACK_IPV4) | ||
456 | help | ||
457 | This option adds a `connbytes' match, which allows you to match the | ||
458 | number of bytes and/or packets for each direction within a connection. | ||
459 | |||
460 | If you want to compile it as a module, say M here and read | ||
461 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
462 | |||
463 | config IP_NF_MATCH_HASHLIMIT | 292 | config IP_NF_MATCH_HASHLIMIT |
464 | tristate 'hashlimit match support' | 293 | tristate 'hashlimit match support' |
465 | depends on IP_NF_IPTABLES | 294 | depends on IP_NF_IPTABLES |
@@ -474,19 +303,6 @@ config IP_NF_MATCH_HASHLIMIT | |||
474 | destination IP' or `500pps from any given source IP' with a single | 303 | destination IP' or `500pps from any given source IP' with a single |
475 | IPtables rule. | 304 | IPtables rule. |
476 | 305 | ||
477 | config IP_NF_MATCH_STRING | ||
478 | tristate 'string match support' | ||
479 | depends on IP_NF_IPTABLES | ||
480 | select TEXTSEARCH | ||
481 | select TEXTSEARCH_KMP | ||
482 | select TEXTSEARCH_BM | ||
483 | select TEXTSEARCH_FSM | ||
484 | help | ||
485 | This option adds a `string' match, which allows you to look for | ||
486 | pattern matchings in packets. | ||
487 | |||
488 | To compile it as a module, choose M here. If unsure, say N. | ||
489 | |||
490 | config IP_NF_MATCH_POLICY | 306 | config IP_NF_MATCH_POLICY |
491 | tristate "IPsec policy match support" | 307 | tristate "IPsec policy match support" |
492 | depends on IP_NF_IPTABLES && XFRM | 308 | depends on IP_NF_IPTABLES && XFRM |
@@ -572,17 +388,6 @@ config IP_NF_TARGET_TCPMSS | |||
572 | 388 | ||
573 | To compile it as a module, choose M here. If unsure, say N. | 389 | To compile it as a module, choose M here. If unsure, say N. |
574 | 390 | ||
575 | config IP_NF_TARGET_NFQUEUE | ||
576 | tristate "NFQUEUE Target Support" | ||
577 | depends on IP_NF_IPTABLES | ||
578 | help | ||
579 | This Target replaced the old obsolete QUEUE target. | ||
580 | |||
581 | As opposed to QUEUE, it supports 65535 different queues, | ||
582 | not just one. | ||
583 | |||
584 | To compile it as a module, choose M here. If unsure, say N. | ||
585 | |||
586 | # NAT + specific targets | 391 | # NAT + specific targets |
587 | config IP_NF_NAT | 392 | config IP_NF_NAT |
588 | tristate "Full NAT" | 393 | tristate "Full NAT" |
@@ -735,31 +540,6 @@ config IP_NF_TARGET_DSCP | |||
735 | 540 | ||
736 | To compile it as a module, choose M here. If unsure, say N. | 541 | To compile it as a module, choose M here. If unsure, say N. |
737 | 542 | ||
738 | config IP_NF_TARGET_MARK | ||
739 | tristate "MARK target support" | ||
740 | depends on IP_NF_MANGLE | ||
741 | help | ||
742 | This option adds a `MARK' target, which allows you to create rules | ||
743 | in the `mangle' table which alter the netfilter mark (nfmark) field | ||
744 | associated with the packet prior to routing. This can change | ||
745 | the routing method (see `Use netfilter MARK value as routing | ||
746 | key') and can also be used by other subsystems to change their | ||
747 | behavior. | ||
748 | |||
749 | To compile it as a module, choose M here. If unsure, say N. | ||
750 | |||
751 | config IP_NF_TARGET_CLASSIFY | ||
752 | tristate "CLASSIFY target support" | ||
753 | depends on IP_NF_MANGLE | ||
754 | help | ||
755 | This option adds a `CLASSIFY' target, which enables the user to set | ||
756 | the priority of a packet. Some qdiscs can use this value for | ||
757 | classification, among these are: | ||
758 | |||
759 | atm, cbq, dsmark, pfifo_fast, htb, prio | ||
760 | |||
761 | To compile it as a module, choose M here. If unsure, say N. | ||
762 | |||
763 | config IP_NF_TARGET_TTL | 543 | config IP_NF_TARGET_TTL |
764 | tristate 'TTL target support' | 544 | tristate 'TTL target support' |
765 | depends on IP_NF_MANGLE | 545 | depends on IP_NF_MANGLE |
@@ -774,19 +554,6 @@ config IP_NF_TARGET_TTL | |||
774 | 554 | ||
775 | To compile it as a module, choose M here. If unsure, say N. | 555 | To compile it as a module, choose M here. If unsure, say N. |
776 | 556 | ||
777 | config IP_NF_TARGET_CONNMARK | ||
778 | tristate 'CONNMARK target support' | ||
779 | depends on IP_NF_MANGLE | ||
780 | depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4) | ||
781 | help | ||
782 | This option adds a `CONNMARK' target, which allows one to manipulate | ||
783 | the connection mark value. Similar to the MARK target, but | ||
784 | affects the connection mark value rather than the packet mark value. | ||
785 | |||
786 | If you want to compile it as a module, say M here and read | ||
787 | <file:Documentation/modules.txt>. The module will be called | ||
788 | ipt_CONNMARK.o. If unsure, say `N'. | ||
789 | |||
790 | config IP_NF_TARGET_CLUSTERIP | 557 | config IP_NF_TARGET_CLUSTERIP |
791 | tristate "CLUSTERIP target support (EXPERIMENTAL)" | 558 | tristate "CLUSTERIP target support (EXPERIMENTAL)" |
792 | depends on IP_NF_MANGLE && EXPERIMENTAL | 559 | depends on IP_NF_MANGLE && EXPERIMENTAL |
@@ -810,23 +577,10 @@ config IP_NF_RAW | |||
810 | If you want to compile it as a module, say M here and read | 577 | If you want to compile it as a module, say M here and read |
811 | <file:Documentation/modules.txt>. If unsure, say `N'. | 578 | <file:Documentation/modules.txt>. If unsure, say `N'. |
812 | 579 | ||
813 | config IP_NF_TARGET_NOTRACK | ||
814 | tristate 'NOTRACK target support' | ||
815 | depends on IP_NF_RAW | ||
816 | depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 | ||
817 | help | ||
818 | The NOTRACK target allows a select rule to specify | ||
819 | which packets *not* to enter the conntrack/NAT | ||
820 | subsystem with all the consequences (no ICMP error tracking, | ||
821 | no protocol helpers for the selected packets). | ||
822 | |||
823 | If you want to compile it as a module, say M here and read | ||
824 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
825 | |||
826 | |||
827 | # ARP tables | 580 | # ARP tables |
828 | config IP_NF_ARPTABLES | 581 | config IP_NF_ARPTABLES |
829 | tristate "ARP tables support" | 582 | tristate "ARP tables support" |
583 | depends on NETFILTER_XTABLES | ||
830 | help | 584 | help |
831 | arptables is a general, extensible packet identification framework. | 585 | arptables is a general, extensible packet identification framework. |
832 | The ARP packet filtering and mangling (manipulation)subsystems | 586 | The ARP packet filtering and mangling (manipulation)subsystems |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 549b01a648b3..bcefe64b9317 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
@@ -47,14 +47,8 @@ obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o | |||
47 | 47 | ||
48 | # matches | 48 | # matches |
49 | obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o | 49 | obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o |
50 | obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o | ||
51 | obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o | 50 | obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o |
52 | obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o | ||
53 | obj-$(CONFIG_IP_NF_MATCH_DCCP) += ipt_dccp.o | ||
54 | obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o | ||
55 | obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o | ||
56 | obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o | 51 | obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o |
57 | obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o | ||
58 | obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o | 52 | obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o |
59 | obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o | 53 | obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o |
60 | obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o | 54 | obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o |
@@ -62,40 +56,25 @@ obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o | |||
62 | obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o | 56 | obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o |
63 | obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o | 57 | obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o |
64 | obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o | 58 | obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o |
65 | obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o | ||
66 | obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o | 59 | obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o |
67 | obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o | ||
68 | obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o | ||
69 | obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o | ||
70 | obj-$(CONFIG_IP_NF_MATCH_CONNBYTES) += ipt_connbytes.o | ||
71 | obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o | ||
72 | obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o | ||
73 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o | 60 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o |
74 | obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o | ||
75 | obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o | 61 | obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o |
76 | obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o | ||
77 | obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o | ||
78 | 62 | ||
79 | # targets | 63 | # targets |
80 | obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o | 64 | obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o |
81 | obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o | 65 | obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o |
82 | obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o | 66 | obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o |
83 | obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o | 67 | obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o |
84 | obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o | ||
85 | obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o | 68 | obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o |
86 | obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o | 69 | obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o |
87 | obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o | 70 | obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o |
88 | obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o | 71 | obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o |
89 | obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o | ||
90 | obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o | 72 | obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o |
91 | obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o | 73 | obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o |
92 | obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK.o | ||
93 | obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o | 74 | obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o |
94 | obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o | 75 | obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o |
95 | obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o | ||
96 | obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o | 76 | obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o |
97 | obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o | 77 | obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o |
98 | obj-$(CONFIG_IP_NF_TARGET_NFQUEUE) += ipt_NFQUEUE.o | ||
99 | 78 | ||
100 | # generic ARP tables | 79 | # generic ARP tables |
101 | obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o | 80 | obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index b6d5284c8020..afe3d8f8177d 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
25 | #include <asm/semaphore.h> | 25 | #include <asm/semaphore.h> |
26 | 26 | ||
27 | #include <linux/netfilter/x_tables.h> | ||
27 | #include <linux/netfilter_arp/arp_tables.h> | 28 | #include <linux/netfilter_arp/arp_tables.h> |
28 | 29 | ||
29 | MODULE_LICENSE("GPL"); | 30 | MODULE_LICENSE("GPL"); |
@@ -55,28 +56,9 @@ do { \ | |||
55 | #else | 56 | #else |
56 | #define ARP_NF_ASSERT(x) | 57 | #define ARP_NF_ASSERT(x) |
57 | #endif | 58 | #endif |
58 | #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) | ||
59 | 59 | ||
60 | static DECLARE_MUTEX(arpt_mutex); | ||
61 | |||
62 | #define ASSERT_READ_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0) | ||
63 | #define ASSERT_WRITE_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0) | ||
64 | #include <linux/netfilter_ipv4/listhelp.h> | 60 | #include <linux/netfilter_ipv4/listhelp.h> |
65 | 61 | ||
66 | struct arpt_table_info { | ||
67 | unsigned int size; | ||
68 | unsigned int number; | ||
69 | unsigned int initial_entries; | ||
70 | unsigned int hook_entry[NF_ARP_NUMHOOKS]; | ||
71 | unsigned int underflow[NF_ARP_NUMHOOKS]; | ||
72 | void *entries[NR_CPUS]; | ||
73 | }; | ||
74 | |||
75 | static LIST_HEAD(arpt_target); | ||
76 | static LIST_HEAD(arpt_tables); | ||
77 | #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) | ||
78 | #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) | ||
79 | |||
80 | static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, | 62 | static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, |
81 | char *hdr_addr, int len) | 63 | char *hdr_addr, int len) |
82 | { | 64 | { |
@@ -223,9 +205,9 @@ static inline int arp_checkentry(const struct arpt_arp *arp) | |||
223 | } | 205 | } |
224 | 206 | ||
225 | static unsigned int arpt_error(struct sk_buff **pskb, | 207 | static unsigned int arpt_error(struct sk_buff **pskb, |
226 | unsigned int hooknum, | ||
227 | const struct net_device *in, | 208 | const struct net_device *in, |
228 | const struct net_device *out, | 209 | const struct net_device *out, |
210 | unsigned int hooknum, | ||
229 | const void *targinfo, | 211 | const void *targinfo, |
230 | void *userinfo) | 212 | void *userinfo) |
231 | { | 213 | { |
@@ -254,6 +236,7 @@ unsigned int arpt_do_table(struct sk_buff **pskb, | |||
254 | struct arpt_entry *e, *back; | 236 | struct arpt_entry *e, *back; |
255 | const char *indev, *outdev; | 237 | const char *indev, *outdev; |
256 | void *table_base; | 238 | void *table_base; |
239 | struct xt_table_info *private = table->private; | ||
257 | 240 | ||
258 | /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ | 241 | /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ |
259 | if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) + | 242 | if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) + |
@@ -265,9 +248,9 @@ unsigned int arpt_do_table(struct sk_buff **pskb, | |||
265 | outdev = out ? out->name : nulldevname; | 248 | outdev = out ? out->name : nulldevname; |
266 | 249 | ||
267 | read_lock_bh(&table->lock); | 250 | read_lock_bh(&table->lock); |
268 | table_base = (void *)table->private->entries[smp_processor_id()]; | 251 | table_base = (void *)private->entries[smp_processor_id()]; |
269 | e = get_entry(table_base, table->private->hook_entry[hook]); | 252 | e = get_entry(table_base, private->hook_entry[hook]); |
270 | back = get_entry(table_base, table->private->underflow[hook]); | 253 | back = get_entry(table_base, private->underflow[hook]); |
271 | 254 | ||
272 | arp = (*pskb)->nh.arph; | 255 | arp = (*pskb)->nh.arph; |
273 | do { | 256 | do { |
@@ -315,8 +298,8 @@ unsigned int arpt_do_table(struct sk_buff **pskb, | |||
315 | * abs. verdicts | 298 | * abs. verdicts |
316 | */ | 299 | */ |
317 | verdict = t->u.kernel.target->target(pskb, | 300 | verdict = t->u.kernel.target->target(pskb, |
318 | hook, | ||
319 | in, out, | 301 | in, out, |
302 | hook, | ||
320 | t->data, | 303 | t->data, |
321 | userdata); | 304 | userdata); |
322 | 305 | ||
@@ -341,106 +324,6 @@ unsigned int arpt_do_table(struct sk_buff **pskb, | |||
341 | return verdict; | 324 | return verdict; |
342 | } | 325 | } |
343 | 326 | ||
344 | /* | ||
345 | * These are weird, but module loading must not be done with mutex | ||
346 | * held (since they will register), and we have to have a single | ||
347 | * function to use try_then_request_module(). | ||
348 | */ | ||
349 | |||
350 | /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ | ||
351 | static inline struct arpt_table *find_table_lock(const char *name) | ||
352 | { | ||
353 | struct arpt_table *t; | ||
354 | |||
355 | if (down_interruptible(&arpt_mutex) != 0) | ||
356 | return ERR_PTR(-EINTR); | ||
357 | |||
358 | list_for_each_entry(t, &arpt_tables, list) | ||
359 | if (strcmp(t->name, name) == 0 && try_module_get(t->me)) | ||
360 | return t; | ||
361 | up(&arpt_mutex); | ||
362 | return NULL; | ||
363 | } | ||
364 | |||
365 | |||
366 | /* Find target, grabs ref. Returns ERR_PTR() on error. */ | ||
367 | static inline struct arpt_target *find_target(const char *name, u8 revision) | ||
368 | { | ||
369 | struct arpt_target *t; | ||
370 | int err = 0; | ||
371 | |||
372 | if (down_interruptible(&arpt_mutex) != 0) | ||
373 | return ERR_PTR(-EINTR); | ||
374 | |||
375 | list_for_each_entry(t, &arpt_target, list) { | ||
376 | if (strcmp(t->name, name) == 0) { | ||
377 | if (t->revision == revision) { | ||
378 | if (try_module_get(t->me)) { | ||
379 | up(&arpt_mutex); | ||
380 | return t; | ||
381 | } | ||
382 | } else | ||
383 | err = -EPROTOTYPE; /* Found something. */ | ||
384 | } | ||
385 | } | ||
386 | up(&arpt_mutex); | ||
387 | return ERR_PTR(err); | ||
388 | } | ||
389 | |||
390 | struct arpt_target *arpt_find_target(const char *name, u8 revision) | ||
391 | { | ||
392 | struct arpt_target *target; | ||
393 | |||
394 | target = try_then_request_module(find_target(name, revision), | ||
395 | "arpt_%s", name); | ||
396 | if (IS_ERR(target) || !target) | ||
397 | return NULL; | ||
398 | return target; | ||
399 | } | ||
400 | |||
401 | static int target_revfn(const char *name, u8 revision, int *bestp) | ||
402 | { | ||
403 | struct arpt_target *t; | ||
404 | int have_rev = 0; | ||
405 | |||
406 | list_for_each_entry(t, &arpt_target, list) { | ||
407 | if (strcmp(t->name, name) == 0) { | ||
408 | if (t->revision > *bestp) | ||
409 | *bestp = t->revision; | ||
410 | if (t->revision == revision) | ||
411 | have_rev =1; | ||
412 | } | ||
413 | } | ||
414 | return have_rev; | ||
415 | } | ||
416 | |||
417 | /* Returns true or false (if no such extension at all) */ | ||
418 | static inline int find_revision(const char *name, u8 revision, | ||
419 | int (*revfn)(const char *, u8, int *), | ||
420 | int *err) | ||
421 | { | ||
422 | int have_rev, best = -1; | ||
423 | |||
424 | if (down_interruptible(&arpt_mutex) != 0) { | ||
425 | *err = -EINTR; | ||
426 | return 1; | ||
427 | } | ||
428 | have_rev = revfn(name, revision, &best); | ||
429 | up(&arpt_mutex); | ||
430 | |||
431 | /* Nothing at all? Return 0 to try loading module. */ | ||
432 | if (best == -1) { | ||
433 | *err = -ENOENT; | ||
434 | return 0; | ||
435 | } | ||
436 | |||
437 | *err = best; | ||
438 | if (!have_rev) | ||
439 | *err = -EPROTONOSUPPORT; | ||
440 | return 1; | ||
441 | } | ||
442 | |||
443 | |||
444 | /* All zeroes == unconditional rule. */ | 327 | /* All zeroes == unconditional rule. */ |
445 | static inline int unconditional(const struct arpt_arp *arp) | 328 | static inline int unconditional(const struct arpt_arp *arp) |
446 | { | 329 | { |
@@ -456,7 +339,7 @@ static inline int unconditional(const struct arpt_arp *arp) | |||
456 | /* Figures out from what hook each rule can be called: returns 0 if | 339 | /* Figures out from what hook each rule can be called: returns 0 if |
457 | * there are loops. Puts hook bitmask in comefrom. | 340 | * there are loops. Puts hook bitmask in comefrom. |
458 | */ | 341 | */ |
459 | static int mark_source_chains(struct arpt_table_info *newinfo, | 342 | static int mark_source_chains(struct xt_table_info *newinfo, |
460 | unsigned int valid_hooks, void *entry0) | 343 | unsigned int valid_hooks, void *entry0) |
461 | { | 344 | { |
462 | unsigned int hook; | 345 | unsigned int hook; |
@@ -587,8 +470,8 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i | |||
587 | } | 470 | } |
588 | 471 | ||
589 | t = arpt_get_target(e); | 472 | t = arpt_get_target(e); |
590 | target = try_then_request_module(find_target(t->u.user.name, | 473 | target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, |
591 | t->u.user.revision), | 474 | t->u.user.revision), |
592 | "arpt_%s", t->u.user.name); | 475 | "arpt_%s", t->u.user.name); |
593 | if (IS_ERR(target) || !target) { | 476 | if (IS_ERR(target) || !target) { |
594 | duprintf("check_entry: `%s' not found\n", t->u.user.name); | 477 | duprintf("check_entry: `%s' not found\n", t->u.user.name); |
@@ -622,7 +505,7 @@ out: | |||
622 | } | 505 | } |
623 | 506 | ||
624 | static inline int check_entry_size_and_hooks(struct arpt_entry *e, | 507 | static inline int check_entry_size_and_hooks(struct arpt_entry *e, |
625 | struct arpt_table_info *newinfo, | 508 | struct xt_table_info *newinfo, |
626 | unsigned char *base, | 509 | unsigned char *base, |
627 | unsigned char *limit, | 510 | unsigned char *limit, |
628 | const unsigned int *hook_entries, | 511 | const unsigned int *hook_entries, |
@@ -656,7 +539,7 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, | |||
656 | < 0 (not ARPT_RETURN). --RR */ | 539 | < 0 (not ARPT_RETURN). --RR */ |
657 | 540 | ||
658 | /* Clear counters and comefrom */ | 541 | /* Clear counters and comefrom */ |
659 | e->counters = ((struct arpt_counters) { 0, 0 }); | 542 | e->counters = ((struct xt_counters) { 0, 0 }); |
660 | e->comefrom = 0; | 543 | e->comefrom = 0; |
661 | 544 | ||
662 | (*i)++; | 545 | (*i)++; |
@@ -683,7 +566,7 @@ static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i) | |||
683 | */ | 566 | */ |
684 | static int translate_table(const char *name, | 567 | static int translate_table(const char *name, |
685 | unsigned int valid_hooks, | 568 | unsigned int valid_hooks, |
686 | struct arpt_table_info *newinfo, | 569 | struct xt_table_info *newinfo, |
687 | void *entry0, | 570 | void *entry0, |
688 | unsigned int size, | 571 | unsigned int size, |
689 | unsigned int number, | 572 | unsigned int number, |
@@ -764,34 +647,9 @@ static int translate_table(const char *name, | |||
764 | return ret; | 647 | return ret; |
765 | } | 648 | } |
766 | 649 | ||
767 | static struct arpt_table_info *replace_table(struct arpt_table *table, | ||
768 | unsigned int num_counters, | ||
769 | struct arpt_table_info *newinfo, | ||
770 | int *error) | ||
771 | { | ||
772 | struct arpt_table_info *oldinfo; | ||
773 | |||
774 | /* Do the substitution. */ | ||
775 | write_lock_bh(&table->lock); | ||
776 | /* Check inside lock: is the old number correct? */ | ||
777 | if (num_counters != table->private->number) { | ||
778 | duprintf("num_counters != table->private->number (%u/%u)\n", | ||
779 | num_counters, table->private->number); | ||
780 | write_unlock_bh(&table->lock); | ||
781 | *error = -EAGAIN; | ||
782 | return NULL; | ||
783 | } | ||
784 | oldinfo = table->private; | ||
785 | table->private = newinfo; | ||
786 | newinfo->initial_entries = oldinfo->initial_entries; | ||
787 | write_unlock_bh(&table->lock); | ||
788 | |||
789 | return oldinfo; | ||
790 | } | ||
791 | |||
792 | /* Gets counters. */ | 650 | /* Gets counters. */ |
793 | static inline int add_entry_to_counter(const struct arpt_entry *e, | 651 | static inline int add_entry_to_counter(const struct arpt_entry *e, |
794 | struct arpt_counters total[], | 652 | struct xt_counters total[], |
795 | unsigned int *i) | 653 | unsigned int *i) |
796 | { | 654 | { |
797 | ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); | 655 | ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); |
@@ -801,7 +659,7 @@ static inline int add_entry_to_counter(const struct arpt_entry *e, | |||
801 | } | 659 | } |
802 | 660 | ||
803 | static inline int set_entry_to_counter(const struct arpt_entry *e, | 661 | static inline int set_entry_to_counter(const struct arpt_entry *e, |
804 | struct arpt_counters total[], | 662 | struct xt_counters total[], |
805 | unsigned int *i) | 663 | unsigned int *i) |
806 | { | 664 | { |
807 | SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); | 665 | SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); |
@@ -810,8 +668,8 @@ static inline int set_entry_to_counter(const struct arpt_entry *e, | |||
810 | return 0; | 668 | return 0; |
811 | } | 669 | } |
812 | 670 | ||
813 | static void get_counters(const struct arpt_table_info *t, | 671 | static void get_counters(const struct xt_table_info *t, |
814 | struct arpt_counters counters[]) | 672 | struct xt_counters counters[]) |
815 | { | 673 | { |
816 | unsigned int cpu; | 674 | unsigned int cpu; |
817 | unsigned int i; | 675 | unsigned int i; |
@@ -849,7 +707,8 @@ static int copy_entries_to_user(unsigned int total_size, | |||
849 | { | 707 | { |
850 | unsigned int off, num, countersize; | 708 | unsigned int off, num, countersize; |
851 | struct arpt_entry *e; | 709 | struct arpt_entry *e; |
852 | struct arpt_counters *counters; | 710 | struct xt_counters *counters; |
711 | struct xt_table_info *private = table->private; | ||
853 | int ret = 0; | 712 | int ret = 0; |
854 | void *loc_cpu_entry; | 713 | void *loc_cpu_entry; |
855 | 714 | ||
@@ -857,18 +716,18 @@ static int copy_entries_to_user(unsigned int total_size, | |||
857 | * (other than comefrom, which userspace doesn't care | 716 | * (other than comefrom, which userspace doesn't care |
858 | * about). | 717 | * about). |
859 | */ | 718 | */ |
860 | countersize = sizeof(struct arpt_counters) * table->private->number; | 719 | countersize = sizeof(struct xt_counters) * private->number; |
861 | counters = vmalloc(countersize); | 720 | counters = vmalloc_node(countersize, numa_node_id()); |
862 | 721 | ||
863 | if (counters == NULL) | 722 | if (counters == NULL) |
864 | return -ENOMEM; | 723 | return -ENOMEM; |
865 | 724 | ||
866 | /* First, sum counters... */ | 725 | /* First, sum counters... */ |
867 | write_lock_bh(&table->lock); | 726 | write_lock_bh(&table->lock); |
868 | get_counters(table->private, counters); | 727 | get_counters(private, counters); |
869 | write_unlock_bh(&table->lock); | 728 | write_unlock_bh(&table->lock); |
870 | 729 | ||
871 | loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; | 730 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; |
872 | /* ... then copy entire thing ... */ | 731 | /* ... then copy entire thing ... */ |
873 | if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { | 732 | if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { |
874 | ret = -EFAULT; | 733 | ret = -EFAULT; |
@@ -911,75 +770,34 @@ static int get_entries(const struct arpt_get_entries *entries, | |||
911 | int ret; | 770 | int ret; |
912 | struct arpt_table *t; | 771 | struct arpt_table *t; |
913 | 772 | ||
914 | t = find_table_lock(entries->name); | 773 | t = xt_find_table_lock(NF_ARP, entries->name); |
915 | if (t || !IS_ERR(t)) { | 774 | if (t || !IS_ERR(t)) { |
775 | struct xt_table_info *private = t->private; | ||
916 | duprintf("t->private->number = %u\n", | 776 | duprintf("t->private->number = %u\n", |
917 | t->private->number); | 777 | private->number); |
918 | if (entries->size == t->private->size) | 778 | if (entries->size == private->size) |
919 | ret = copy_entries_to_user(t->private->size, | 779 | ret = copy_entries_to_user(private->size, |
920 | t, uptr->entrytable); | 780 | t, uptr->entrytable); |
921 | else { | 781 | else { |
922 | duprintf("get_entries: I've got %u not %u!\n", | 782 | duprintf("get_entries: I've got %u not %u!\n", |
923 | t->private->size, | 783 | private->size, entries->size); |
924 | entries->size); | ||
925 | ret = -EINVAL; | 784 | ret = -EINVAL; |
926 | } | 785 | } |
927 | module_put(t->me); | 786 | module_put(t->me); |
928 | up(&arpt_mutex); | 787 | xt_table_unlock(t); |
929 | } else | 788 | } else |
930 | ret = t ? PTR_ERR(t) : -ENOENT; | 789 | ret = t ? PTR_ERR(t) : -ENOENT; |
931 | 790 | ||
932 | return ret; | 791 | return ret; |
933 | } | 792 | } |
934 | 793 | ||
935 | static void free_table_info(struct arpt_table_info *info) | ||
936 | { | ||
937 | int cpu; | ||
938 | for_each_cpu(cpu) { | ||
939 | if (info->size <= PAGE_SIZE) | ||
940 | kfree(info->entries[cpu]); | ||
941 | else | ||
942 | vfree(info->entries[cpu]); | ||
943 | } | ||
944 | kfree(info); | ||
945 | } | ||
946 | |||
947 | static struct arpt_table_info *alloc_table_info(unsigned int size) | ||
948 | { | ||
949 | struct arpt_table_info *newinfo; | ||
950 | int cpu; | ||
951 | |||
952 | newinfo = kzalloc(sizeof(struct arpt_table_info), GFP_KERNEL); | ||
953 | if (!newinfo) | ||
954 | return NULL; | ||
955 | |||
956 | newinfo->size = size; | ||
957 | |||
958 | for_each_cpu(cpu) { | ||
959 | if (size <= PAGE_SIZE) | ||
960 | newinfo->entries[cpu] = kmalloc_node(size, | ||
961 | GFP_KERNEL, | ||
962 | cpu_to_node(cpu)); | ||
963 | else | ||
964 | newinfo->entries[cpu] = vmalloc_node(size, | ||
965 | cpu_to_node(cpu)); | ||
966 | |||
967 | if (newinfo->entries[cpu] == NULL) { | ||
968 | free_table_info(newinfo); | ||
969 | return NULL; | ||
970 | } | ||
971 | } | ||
972 | |||
973 | return newinfo; | ||
974 | } | ||
975 | |||
976 | static int do_replace(void __user *user, unsigned int len) | 794 | static int do_replace(void __user *user, unsigned int len) |
977 | { | 795 | { |
978 | int ret; | 796 | int ret; |
979 | struct arpt_replace tmp; | 797 | struct arpt_replace tmp; |
980 | struct arpt_table *t; | 798 | struct arpt_table *t; |
981 | struct arpt_table_info *newinfo, *oldinfo; | 799 | struct xt_table_info *newinfo, *oldinfo; |
982 | struct arpt_counters *counters; | 800 | struct xt_counters *counters; |
983 | void *loc_cpu_entry, *loc_cpu_old_entry; | 801 | void *loc_cpu_entry, *loc_cpu_old_entry; |
984 | 802 | ||
985 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 803 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
@@ -989,11 +807,7 @@ static int do_replace(void __user *user, unsigned int len) | |||
989 | if (len != sizeof(tmp) + tmp.size) | 807 | if (len != sizeof(tmp) + tmp.size) |
990 | return -ENOPROTOOPT; | 808 | return -ENOPROTOOPT; |
991 | 809 | ||
992 | /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ | 810 | newinfo = xt_alloc_table_info(tmp.size); |
993 | if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) | ||
994 | return -ENOMEM; | ||
995 | |||
996 | newinfo = alloc_table_info(tmp.size); | ||
997 | if (!newinfo) | 811 | if (!newinfo) |
998 | return -ENOMEM; | 812 | return -ENOMEM; |
999 | 813 | ||
@@ -1005,7 +819,7 @@ static int do_replace(void __user *user, unsigned int len) | |||
1005 | goto free_newinfo; | 819 | goto free_newinfo; |
1006 | } | 820 | } |
1007 | 821 | ||
1008 | counters = vmalloc(tmp.num_counters * sizeof(struct arpt_counters)); | 822 | counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters)); |
1009 | if (!counters) { | 823 | if (!counters) { |
1010 | ret = -ENOMEM; | 824 | ret = -ENOMEM; |
1011 | goto free_newinfo; | 825 | goto free_newinfo; |
@@ -1019,7 +833,7 @@ static int do_replace(void __user *user, unsigned int len) | |||
1019 | 833 | ||
1020 | duprintf("arp_tables: Translated table\n"); | 834 | duprintf("arp_tables: Translated table\n"); |
1021 | 835 | ||
1022 | t = try_then_request_module(find_table_lock(tmp.name), | 836 | t = try_then_request_module(xt_find_table_lock(NF_ARP, tmp.name), |
1023 | "arptable_%s", tmp.name); | 837 | "arptable_%s", tmp.name); |
1024 | if (!t || IS_ERR(t)) { | 838 | if (!t || IS_ERR(t)) { |
1025 | ret = t ? PTR_ERR(t) : -ENOENT; | 839 | ret = t ? PTR_ERR(t) : -ENOENT; |
@@ -1034,7 +848,7 @@ static int do_replace(void __user *user, unsigned int len) | |||
1034 | goto put_module; | 848 | goto put_module; |
1035 | } | 849 | } |
1036 | 850 | ||
1037 | oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); | 851 | oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret); |
1038 | if (!oldinfo) | 852 | if (!oldinfo) |
1039 | goto put_module; | 853 | goto put_module; |
1040 | 854 | ||
@@ -1054,23 +868,23 @@ static int do_replace(void __user *user, unsigned int len) | |||
1054 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; | 868 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; |
1055 | ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); | 869 | ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); |
1056 | 870 | ||
1057 | free_table_info(oldinfo); | 871 | xt_free_table_info(oldinfo); |
1058 | if (copy_to_user(tmp.counters, counters, | 872 | if (copy_to_user(tmp.counters, counters, |
1059 | sizeof(struct arpt_counters) * tmp.num_counters) != 0) | 873 | sizeof(struct xt_counters) * tmp.num_counters) != 0) |
1060 | ret = -EFAULT; | 874 | ret = -EFAULT; |
1061 | vfree(counters); | 875 | vfree(counters); |
1062 | up(&arpt_mutex); | 876 | xt_table_unlock(t); |
1063 | return ret; | 877 | return ret; |
1064 | 878 | ||
1065 | put_module: | 879 | put_module: |
1066 | module_put(t->me); | 880 | module_put(t->me); |
1067 | up(&arpt_mutex); | 881 | xt_table_unlock(t); |
1068 | free_newinfo_counters_untrans: | 882 | free_newinfo_counters_untrans: |
1069 | ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); | 883 | ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); |
1070 | free_newinfo_counters: | 884 | free_newinfo_counters: |
1071 | vfree(counters); | 885 | vfree(counters); |
1072 | free_newinfo: | 886 | free_newinfo: |
1073 | free_table_info(newinfo); | 887 | xt_free_table_info(newinfo); |
1074 | return ret; | 888 | return ret; |
1075 | } | 889 | } |
1076 | 890 | ||
@@ -1078,7 +892,7 @@ static int do_replace(void __user *user, unsigned int len) | |||
1078 | * and everything is OK. | 892 | * and everything is OK. |
1079 | */ | 893 | */ |
1080 | static inline int add_counter_to_entry(struct arpt_entry *e, | 894 | static inline int add_counter_to_entry(struct arpt_entry *e, |
1081 | const struct arpt_counters addme[], | 895 | const struct xt_counters addme[], |
1082 | unsigned int *i) | 896 | unsigned int *i) |
1083 | { | 897 | { |
1084 | 898 | ||
@@ -1091,15 +905,16 @@ static inline int add_counter_to_entry(struct arpt_entry *e, | |||
1091 | static int do_add_counters(void __user *user, unsigned int len) | 905 | static int do_add_counters(void __user *user, unsigned int len) |
1092 | { | 906 | { |
1093 | unsigned int i; | 907 | unsigned int i; |
1094 | struct arpt_counters_info tmp, *paddc; | 908 | struct xt_counters_info tmp, *paddc; |
1095 | struct arpt_table *t; | 909 | struct arpt_table *t; |
910 | struct xt_table_info *private; | ||
1096 | int ret = 0; | 911 | int ret = 0; |
1097 | void *loc_cpu_entry; | 912 | void *loc_cpu_entry; |
1098 | 913 | ||
1099 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 914 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
1100 | return -EFAULT; | 915 | return -EFAULT; |
1101 | 916 | ||
1102 | if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct arpt_counters)) | 917 | if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters)) |
1103 | return -EINVAL; | 918 | return -EINVAL; |
1104 | 919 | ||
1105 | paddc = vmalloc(len); | 920 | paddc = vmalloc(len); |
@@ -1111,29 +926,30 @@ static int do_add_counters(void __user *user, unsigned int len) | |||
1111 | goto free; | 926 | goto free; |
1112 | } | 927 | } |
1113 | 928 | ||
1114 | t = find_table_lock(tmp.name); | 929 | t = xt_find_table_lock(NF_ARP, tmp.name); |
1115 | if (!t || IS_ERR(t)) { | 930 | if (!t || IS_ERR(t)) { |
1116 | ret = t ? PTR_ERR(t) : -ENOENT; | 931 | ret = t ? PTR_ERR(t) : -ENOENT; |
1117 | goto free; | 932 | goto free; |
1118 | } | 933 | } |
1119 | 934 | ||
1120 | write_lock_bh(&t->lock); | 935 | write_lock_bh(&t->lock); |
1121 | if (t->private->number != paddc->num_counters) { | 936 | private = t->private; |
937 | if (private->number != paddc->num_counters) { | ||
1122 | ret = -EINVAL; | 938 | ret = -EINVAL; |
1123 | goto unlock_up_free; | 939 | goto unlock_up_free; |
1124 | } | 940 | } |
1125 | 941 | ||
1126 | i = 0; | 942 | i = 0; |
1127 | /* Choose the copy that is on our node */ | 943 | /* Choose the copy that is on our node */ |
1128 | loc_cpu_entry = t->private->entries[smp_processor_id()]; | 944 | loc_cpu_entry = private->entries[smp_processor_id()]; |
1129 | ARPT_ENTRY_ITERATE(loc_cpu_entry, | 945 | ARPT_ENTRY_ITERATE(loc_cpu_entry, |
1130 | t->private->size, | 946 | private->size, |
1131 | add_counter_to_entry, | 947 | add_counter_to_entry, |
1132 | paddc->counters, | 948 | paddc->counters, |
1133 | &i); | 949 | &i); |
1134 | unlock_up_free: | 950 | unlock_up_free: |
1135 | write_unlock_bh(&t->lock); | 951 | write_unlock_bh(&t->lock); |
1136 | up(&arpt_mutex); | 952 | xt_table_unlock(t); |
1137 | module_put(t->me); | 953 | module_put(t->me); |
1138 | free: | 954 | free: |
1139 | vfree(paddc); | 955 | vfree(paddc); |
@@ -1190,25 +1006,26 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len | |||
1190 | } | 1006 | } |
1191 | name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; | 1007 | name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; |
1192 | 1008 | ||
1193 | t = try_then_request_module(find_table_lock(name), | 1009 | t = try_then_request_module(xt_find_table_lock(NF_ARP, name), |
1194 | "arptable_%s", name); | 1010 | "arptable_%s", name); |
1195 | if (t && !IS_ERR(t)) { | 1011 | if (t && !IS_ERR(t)) { |
1196 | struct arpt_getinfo info; | 1012 | struct arpt_getinfo info; |
1013 | struct xt_table_info *private = t->private; | ||
1197 | 1014 | ||
1198 | info.valid_hooks = t->valid_hooks; | 1015 | info.valid_hooks = t->valid_hooks; |
1199 | memcpy(info.hook_entry, t->private->hook_entry, | 1016 | memcpy(info.hook_entry, private->hook_entry, |
1200 | sizeof(info.hook_entry)); | 1017 | sizeof(info.hook_entry)); |
1201 | memcpy(info.underflow, t->private->underflow, | 1018 | memcpy(info.underflow, private->underflow, |
1202 | sizeof(info.underflow)); | 1019 | sizeof(info.underflow)); |
1203 | info.num_entries = t->private->number; | 1020 | info.num_entries = private->number; |
1204 | info.size = t->private->size; | 1021 | info.size = private->size; |
1205 | strcpy(info.name, name); | 1022 | strcpy(info.name, name); |
1206 | 1023 | ||
1207 | if (copy_to_user(user, &info, *len) != 0) | 1024 | if (copy_to_user(user, &info, *len) != 0) |
1208 | ret = -EFAULT; | 1025 | ret = -EFAULT; |
1209 | else | 1026 | else |
1210 | ret = 0; | 1027 | ret = 0; |
1211 | up(&arpt_mutex); | 1028 | xt_table_unlock(t); |
1212 | module_put(t->me); | 1029 | module_put(t->me); |
1213 | } else | 1030 | } else |
1214 | ret = t ? PTR_ERR(t) : -ENOENT; | 1031 | ret = t ? PTR_ERR(t) : -ENOENT; |
@@ -1233,7 +1050,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len | |||
1233 | } | 1050 | } |
1234 | 1051 | ||
1235 | case ARPT_SO_GET_REVISION_TARGET: { | 1052 | case ARPT_SO_GET_REVISION_TARGET: { |
1236 | struct arpt_get_revision rev; | 1053 | struct xt_get_revision rev; |
1237 | 1054 | ||
1238 | if (*len != sizeof(rev)) { | 1055 | if (*len != sizeof(rev)) { |
1239 | ret = -EINVAL; | 1056 | ret = -EINVAL; |
@@ -1244,8 +1061,8 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len | |||
1244 | break; | 1061 | break; |
1245 | } | 1062 | } |
1246 | 1063 | ||
1247 | try_then_request_module(find_revision(rev.name, rev.revision, | 1064 | try_then_request_module(xt_find_revision(NF_ARP, rev.name, |
1248 | target_revfn, &ret), | 1065 | rev.revision, 1, &ret), |
1249 | "arpt_%s", rev.name); | 1066 | "arpt_%s", rev.name); |
1250 | break; | 1067 | break; |
1251 | } | 1068 | } |
@@ -1258,38 +1075,16 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len | |||
1258 | return ret; | 1075 | return ret; |
1259 | } | 1076 | } |
1260 | 1077 | ||
1261 | /* Registration hooks for targets. */ | ||
1262 | int arpt_register_target(struct arpt_target *target) | ||
1263 | { | ||
1264 | int ret; | ||
1265 | |||
1266 | ret = down_interruptible(&arpt_mutex); | ||
1267 | if (ret != 0) | ||
1268 | return ret; | ||
1269 | |||
1270 | list_add(&target->list, &arpt_target); | ||
1271 | up(&arpt_mutex); | ||
1272 | |||
1273 | return ret; | ||
1274 | } | ||
1275 | |||
1276 | void arpt_unregister_target(struct arpt_target *target) | ||
1277 | { | ||
1278 | down(&arpt_mutex); | ||
1279 | LIST_DELETE(&arpt_target, target); | ||
1280 | up(&arpt_mutex); | ||
1281 | } | ||
1282 | |||
1283 | int arpt_register_table(struct arpt_table *table, | 1078 | int arpt_register_table(struct arpt_table *table, |
1284 | const struct arpt_replace *repl) | 1079 | const struct arpt_replace *repl) |
1285 | { | 1080 | { |
1286 | int ret; | 1081 | int ret; |
1287 | struct arpt_table_info *newinfo; | 1082 | struct xt_table_info *newinfo; |
1288 | static struct arpt_table_info bootstrap | 1083 | static struct xt_table_info bootstrap |
1289 | = { 0, 0, 0, { 0 }, { 0 }, { } }; | 1084 | = { 0, 0, 0, { 0 }, { 0 }, { } }; |
1290 | void *loc_cpu_entry; | 1085 | void *loc_cpu_entry; |
1291 | 1086 | ||
1292 | newinfo = alloc_table_info(repl->size); | 1087 | newinfo = xt_alloc_table_info(repl->size); |
1293 | if (!newinfo) { | 1088 | if (!newinfo) { |
1294 | ret = -ENOMEM; | 1089 | ret = -ENOMEM; |
1295 | return ret; | 1090 | return ret; |
@@ -1304,60 +1099,33 @@ int arpt_register_table(struct arpt_table *table, | |||
1304 | repl->num_entries, | 1099 | repl->num_entries, |
1305 | repl->hook_entry, | 1100 | repl->hook_entry, |
1306 | repl->underflow); | 1101 | repl->underflow); |
1102 | |||
1307 | duprintf("arpt_register_table: translate table gives %d\n", ret); | 1103 | duprintf("arpt_register_table: translate table gives %d\n", ret); |
1308 | if (ret != 0) { | 1104 | if (ret != 0) { |
1309 | free_table_info(newinfo); | 1105 | xt_free_table_info(newinfo); |
1310 | return ret; | 1106 | return ret; |
1311 | } | 1107 | } |
1312 | 1108 | ||
1313 | ret = down_interruptible(&arpt_mutex); | 1109 | if (xt_register_table(table, &bootstrap, newinfo) != 0) { |
1314 | if (ret != 0) { | 1110 | xt_free_table_info(newinfo); |
1315 | free_table_info(newinfo); | ||
1316 | return ret; | 1111 | return ret; |
1317 | } | 1112 | } |
1318 | 1113 | ||
1319 | /* Don't autoload: we'd eat our tail... */ | 1114 | return 0; |
1320 | if (list_named_find(&arpt_tables, table->name)) { | ||
1321 | ret = -EEXIST; | ||
1322 | goto free_unlock; | ||
1323 | } | ||
1324 | |||
1325 | /* Simplifies replace_table code. */ | ||
1326 | table->private = &bootstrap; | ||
1327 | if (!replace_table(table, 0, newinfo, &ret)) | ||
1328 | goto free_unlock; | ||
1329 | |||
1330 | duprintf("table->private->number = %u\n", | ||
1331 | table->private->number); | ||
1332 | |||
1333 | /* save number of initial entries */ | ||
1334 | table->private->initial_entries = table->private->number; | ||
1335 | |||
1336 | rwlock_init(&table->lock); | ||
1337 | list_prepend(&arpt_tables, table); | ||
1338 | |||
1339 | unlock: | ||
1340 | up(&arpt_mutex); | ||
1341 | return ret; | ||
1342 | |||
1343 | free_unlock: | ||
1344 | free_table_info(newinfo); | ||
1345 | goto unlock; | ||
1346 | } | 1115 | } |
1347 | 1116 | ||
1348 | void arpt_unregister_table(struct arpt_table *table) | 1117 | void arpt_unregister_table(struct arpt_table *table) |
1349 | { | 1118 | { |
1119 | struct xt_table_info *private; | ||
1350 | void *loc_cpu_entry; | 1120 | void *loc_cpu_entry; |
1351 | 1121 | ||
1352 | down(&arpt_mutex); | 1122 | private = xt_unregister_table(table); |
1353 | LIST_DELETE(&arpt_tables, table); | ||
1354 | up(&arpt_mutex); | ||
1355 | 1123 | ||
1356 | /* Decrease module usage counts and free resources */ | 1124 | /* Decrease module usage counts and free resources */ |
1357 | loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; | 1125 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; |
1358 | ARPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size, | 1126 | ARPT_ENTRY_ITERATE(loc_cpu_entry, private->size, |
1359 | cleanup_entry, NULL); | 1127 | cleanup_entry, NULL); |
1360 | free_table_info(table->private); | 1128 | xt_free_table_info(private); |
1361 | } | 1129 | } |
1362 | 1130 | ||
1363 | /* The built-in targets: standard (NULL) and error. */ | 1131 | /* The built-in targets: standard (NULL) and error. */ |
@@ -1380,52 +1148,15 @@ static struct nf_sockopt_ops arpt_sockopts = { | |||
1380 | .get = do_arpt_get_ctl, | 1148 | .get = do_arpt_get_ctl, |
1381 | }; | 1149 | }; |
1382 | 1150 | ||
1383 | #ifdef CONFIG_PROC_FS | ||
1384 | static inline int print_name(const struct arpt_table *t, | ||
1385 | off_t start_offset, char *buffer, int length, | ||
1386 | off_t *pos, unsigned int *count) | ||
1387 | { | ||
1388 | if ((*count)++ >= start_offset) { | ||
1389 | unsigned int namelen; | ||
1390 | |||
1391 | namelen = sprintf(buffer + *pos, "%s\n", t->name); | ||
1392 | if (*pos + namelen > length) { | ||
1393 | /* Stop iterating */ | ||
1394 | return 1; | ||
1395 | } | ||
1396 | *pos += namelen; | ||
1397 | } | ||
1398 | return 0; | ||
1399 | } | ||
1400 | |||
1401 | static int arpt_get_tables(char *buffer, char **start, off_t offset, int length) | ||
1402 | { | ||
1403 | off_t pos = 0; | ||
1404 | unsigned int count = 0; | ||
1405 | |||
1406 | if (down_interruptible(&arpt_mutex) != 0) | ||
1407 | return 0; | ||
1408 | |||
1409 | LIST_FIND(&arpt_tables, print_name, struct arpt_table *, | ||
1410 | offset, buffer, length, &pos, &count); | ||
1411 | |||
1412 | up(&arpt_mutex); | ||
1413 | |||
1414 | /* `start' hack - see fs/proc/generic.c line ~105 */ | ||
1415 | *start=(char *)((unsigned long)count-offset); | ||
1416 | return pos; | ||
1417 | } | ||
1418 | #endif /*CONFIG_PROC_FS*/ | ||
1419 | |||
1420 | static int __init init(void) | 1151 | static int __init init(void) |
1421 | { | 1152 | { |
1422 | int ret; | 1153 | int ret; |
1423 | 1154 | ||
1155 | xt_proto_init(NF_ARP); | ||
1156 | |||
1424 | /* Noone else will be downing sem now, so we won't sleep */ | 1157 | /* Noone else will be downing sem now, so we won't sleep */ |
1425 | down(&arpt_mutex); | 1158 | xt_register_target(NF_ARP, &arpt_standard_target); |
1426 | list_append(&arpt_target, &arpt_standard_target); | 1159 | xt_register_target(NF_ARP, &arpt_error_target); |
1427 | list_append(&arpt_target, &arpt_error_target); | ||
1428 | up(&arpt_mutex); | ||
1429 | 1160 | ||
1430 | /* Register setsockopt */ | 1161 | /* Register setsockopt */ |
1431 | ret = nf_register_sockopt(&arpt_sockopts); | 1162 | ret = nf_register_sockopt(&arpt_sockopts); |
@@ -1434,19 +1165,6 @@ static int __init init(void) | |||
1434 | return ret; | 1165 | return ret; |
1435 | } | 1166 | } |
1436 | 1167 | ||
1437 | #ifdef CONFIG_PROC_FS | ||
1438 | { | ||
1439 | struct proc_dir_entry *proc; | ||
1440 | |||
1441 | proc = proc_net_create("arp_tables_names", 0, arpt_get_tables); | ||
1442 | if (!proc) { | ||
1443 | nf_unregister_sockopt(&arpt_sockopts); | ||
1444 | return -ENOMEM; | ||
1445 | } | ||
1446 | proc->owner = THIS_MODULE; | ||
1447 | } | ||
1448 | #endif | ||
1449 | |||
1450 | printk("arp_tables: (C) 2002 David S. Miller\n"); | 1168 | printk("arp_tables: (C) 2002 David S. Miller\n"); |
1451 | return 0; | 1169 | return 0; |
1452 | } | 1170 | } |
@@ -1454,16 +1172,12 @@ static int __init init(void) | |||
1454 | static void __exit fini(void) | 1172 | static void __exit fini(void) |
1455 | { | 1173 | { |
1456 | nf_unregister_sockopt(&arpt_sockopts); | 1174 | nf_unregister_sockopt(&arpt_sockopts); |
1457 | #ifdef CONFIG_PROC_FS | 1175 | xt_proto_fini(NF_ARP); |
1458 | proc_net_remove("arp_tables_names"); | ||
1459 | #endif | ||
1460 | } | 1176 | } |
1461 | 1177 | ||
1462 | EXPORT_SYMBOL(arpt_register_table); | 1178 | EXPORT_SYMBOL(arpt_register_table); |
1463 | EXPORT_SYMBOL(arpt_unregister_table); | 1179 | EXPORT_SYMBOL(arpt_unregister_table); |
1464 | EXPORT_SYMBOL(arpt_do_table); | 1180 | EXPORT_SYMBOL(arpt_do_table); |
1465 | EXPORT_SYMBOL(arpt_register_target); | ||
1466 | EXPORT_SYMBOL(arpt_unregister_target); | ||
1467 | 1181 | ||
1468 | module_init(init); | 1182 | module_init(init); |
1469 | module_exit(fini); | 1183 | module_exit(fini); |
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c index 3e592ec86482..c97650a16a5b 100644 --- a/net/ipv4/netfilter/arpt_mangle.c +++ b/net/ipv4/netfilter/arpt_mangle.c | |||
@@ -8,8 +8,9 @@ MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); | |||
8 | MODULE_DESCRIPTION("arptables arp payload mangle target"); | 8 | MODULE_DESCRIPTION("arptables arp payload mangle target"); |
9 | 9 | ||
10 | static unsigned int | 10 | static unsigned int |
11 | target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, | 11 | target(struct sk_buff **pskb, const struct net_device *in, |
12 | const struct net_device *out, const void *targinfo, void *userinfo) | 12 | const struct net_device *out, unsigned int hooknum, const void *targinfo, |
13 | void *userinfo) | ||
13 | { | 14 | { |
14 | const struct arpt_mangle *mangle = targinfo; | 15 | const struct arpt_mangle *mangle = targinfo; |
15 | struct arphdr *arp; | 16 | struct arphdr *arp; |
@@ -64,7 +65,7 @@ target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, | |||
64 | } | 65 | } |
65 | 66 | ||
66 | static int | 67 | static int |
67 | checkentry(const char *tablename, const struct arpt_entry *e, void *targinfo, | 68 | checkentry(const char *tablename, const void *e, void *targinfo, |
68 | unsigned int targinfosize, unsigned int hook_mask) | 69 | unsigned int targinfosize, unsigned int hook_mask) |
69 | { | 70 | { |
70 | const struct arpt_mangle *mangle = targinfo; | 71 | const struct arpt_mangle *mangle = targinfo; |
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c index 0d759f5a4ef0..f6ab45f48681 100644 --- a/net/ipv4/netfilter/arptable_filter.c +++ b/net/ipv4/netfilter/arptable_filter.c | |||
@@ -145,6 +145,7 @@ static struct arpt_table packet_filter = { | |||
145 | .lock = RW_LOCK_UNLOCKED, | 145 | .lock = RW_LOCK_UNLOCKED, |
146 | .private = NULL, | 146 | .private = NULL, |
147 | .me = THIS_MODULE, | 147 | .me = THIS_MODULE, |
148 | .af = NF_ARP, | ||
148 | }; | 149 | }; |
149 | 150 | ||
150 | /* The work comes in here from netfilter.c */ | 151 | /* The work comes in here from netfilter.c */ |
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index 9dec1293f67a..833fcb4be5e7 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c | |||
@@ -944,7 +944,7 @@ module_exit(fini); | |||
944 | 944 | ||
945 | /* Some modules need us, but don't depend directly on any symbol. | 945 | /* Some modules need us, but don't depend directly on any symbol. |
946 | They should call this. */ | 946 | They should call this. */ |
947 | void need_ip_conntrack(void) | 947 | void need_conntrack(void) |
948 | { | 948 | { |
949 | } | 949 | } |
950 | 950 | ||
@@ -962,7 +962,7 @@ EXPORT_SYMBOL(ip_ct_get_tuple); | |||
962 | EXPORT_SYMBOL(invert_tuplepr); | 962 | EXPORT_SYMBOL(invert_tuplepr); |
963 | EXPORT_SYMBOL(ip_conntrack_alter_reply); | 963 | EXPORT_SYMBOL(ip_conntrack_alter_reply); |
964 | EXPORT_SYMBOL(ip_conntrack_destroyed); | 964 | EXPORT_SYMBOL(ip_conntrack_destroyed); |
965 | EXPORT_SYMBOL(need_ip_conntrack); | 965 | EXPORT_SYMBOL(need_conntrack); |
966 | EXPORT_SYMBOL(ip_conntrack_helper_register); | 966 | EXPORT_SYMBOL(ip_conntrack_helper_register); |
967 | EXPORT_SYMBOL(ip_conntrack_helper_unregister); | 967 | EXPORT_SYMBOL(ip_conntrack_helper_unregister); |
968 | EXPORT_SYMBOL(ip_ct_iterate_cleanup); | 968 | EXPORT_SYMBOL(ip_ct_iterate_cleanup); |
diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c index cb66b8bddeb3..1de86282d232 100644 --- a/net/ipv4/netfilter/ip_nat_rule.c +++ b/net/ipv4/netfilter/ip_nat_rule.c | |||
@@ -95,6 +95,7 @@ static struct ipt_table nat_table = { | |||
95 | .valid_hooks = NAT_VALID_HOOKS, | 95 | .valid_hooks = NAT_VALID_HOOKS, |
96 | .lock = RW_LOCK_UNLOCKED, | 96 | .lock = RW_LOCK_UNLOCKED, |
97 | .me = THIS_MODULE, | 97 | .me = THIS_MODULE, |
98 | .af = AF_INET, | ||
98 | }; | 99 | }; |
99 | 100 | ||
100 | /* Source NAT */ | 101 | /* Source NAT */ |
@@ -168,7 +169,7 @@ static unsigned int ipt_dnat_target(struct sk_buff **pskb, | |||
168 | } | 169 | } |
169 | 170 | ||
170 | static int ipt_snat_checkentry(const char *tablename, | 171 | static int ipt_snat_checkentry(const char *tablename, |
171 | const struct ipt_entry *e, | 172 | const void *entry, |
172 | void *targinfo, | 173 | void *targinfo, |
173 | unsigned int targinfosize, | 174 | unsigned int targinfosize, |
174 | unsigned int hook_mask) | 175 | unsigned int hook_mask) |
@@ -201,7 +202,7 @@ static int ipt_snat_checkentry(const char *tablename, | |||
201 | } | 202 | } |
202 | 203 | ||
203 | static int ipt_dnat_checkentry(const char *tablename, | 204 | static int ipt_dnat_checkentry(const char *tablename, |
204 | const struct ipt_entry *e, | 205 | const void *entry, |
205 | void *targinfo, | 206 | void *targinfo, |
206 | unsigned int targinfosize, | 207 | unsigned int targinfosize, |
207 | unsigned int hook_mask) | 208 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 8b8a1f00bbf4..ad438fb185b8 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c | |||
@@ -364,7 +364,7 @@ static int init_or_cleanup(int init) | |||
364 | { | 364 | { |
365 | int ret = 0; | 365 | int ret = 0; |
366 | 366 | ||
367 | need_ip_conntrack(); | 367 | need_conntrack(); |
368 | 368 | ||
369 | if (!init) goto cleanup; | 369 | if (!init) goto cleanup; |
370 | 370 | ||
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 877bc96d3336..2371b2062c2d 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Packet matching code. | 2 | * Packet matching code. |
3 | * | 3 | * |
4 | * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling | 4 | * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling |
5 | * Copyright (C) 2000-2004 Netfilter Core Team <coreteam@netfilter.org> | 5 | * Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -11,6 +11,8 @@ | |||
11 | * 19 Jan 2002 Harald Welte <laforge@gnumonks.org> | 11 | * 19 Jan 2002 Harald Welte <laforge@gnumonks.org> |
12 | * - increase module usage count as soon as we have rules inside | 12 | * - increase module usage count as soon as we have rules inside |
13 | * a table | 13 | * a table |
14 | * 08 Oct 2005 Harald Welte <lafore@netfilter.org> | ||
15 | * - Generalize into "x_tables" layer and "{ip,ip6,arp}_tables" | ||
14 | */ | 16 | */ |
15 | #include <linux/config.h> | 17 | #include <linux/config.h> |
16 | #include <linux/cache.h> | 18 | #include <linux/cache.h> |
@@ -20,8 +22,6 @@ | |||
20 | #include <linux/vmalloc.h> | 22 | #include <linux/vmalloc.h> |
21 | #include <linux/netdevice.h> | 23 | #include <linux/netdevice.h> |
22 | #include <linux/module.h> | 24 | #include <linux/module.h> |
23 | #include <linux/tcp.h> | ||
24 | #include <linux/udp.h> | ||
25 | #include <linux/icmp.h> | 25 | #include <linux/icmp.h> |
26 | #include <net/ip.h> | 26 | #include <net/ip.h> |
27 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/err.h> | 30 | #include <linux/err.h> |
31 | #include <linux/cpumask.h> | 31 | #include <linux/cpumask.h> |
32 | 32 | ||
33 | #include <linux/netfilter/x_tables.h> | ||
33 | #include <linux/netfilter_ipv4/ip_tables.h> | 34 | #include <linux/netfilter_ipv4/ip_tables.h> |
34 | 35 | ||
35 | MODULE_LICENSE("GPL"); | 36 | MODULE_LICENSE("GPL"); |
@@ -62,14 +63,6 @@ do { \ | |||
62 | #else | 63 | #else |
63 | #define IP_NF_ASSERT(x) | 64 | #define IP_NF_ASSERT(x) |
64 | #endif | 65 | #endif |
65 | #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) | ||
66 | |||
67 | static DECLARE_MUTEX(ipt_mutex); | ||
68 | |||
69 | /* Must have mutex */ | ||
70 | #define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0) | ||
71 | #define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0) | ||
72 | #include <linux/netfilter_ipv4/listhelp.h> | ||
73 | 66 | ||
74 | #if 0 | 67 | #if 0 |
75 | /* All the better to debug you with... */ | 68 | /* All the better to debug you with... */ |
@@ -86,36 +79,6 @@ static DECLARE_MUTEX(ipt_mutex); | |||
86 | 79 | ||
87 | Hence the start of any table is given by get_table() below. */ | 80 | Hence the start of any table is given by get_table() below. */ |
88 | 81 | ||
89 | /* The table itself */ | ||
90 | struct ipt_table_info | ||
91 | { | ||
92 | /* Size per table */ | ||
93 | unsigned int size; | ||
94 | /* Number of entries: FIXME. --RR */ | ||
95 | unsigned int number; | ||
96 | /* Initial number of entries. Needed for module usage count */ | ||
97 | unsigned int initial_entries; | ||
98 | |||
99 | /* Entry points and underflows */ | ||
100 | unsigned int hook_entry[NF_IP_NUMHOOKS]; | ||
101 | unsigned int underflow[NF_IP_NUMHOOKS]; | ||
102 | |||
103 | /* ipt_entry tables: one per CPU */ | ||
104 | void *entries[NR_CPUS]; | ||
105 | }; | ||
106 | |||
107 | static LIST_HEAD(ipt_target); | ||
108 | static LIST_HEAD(ipt_match); | ||
109 | static LIST_HEAD(ipt_tables); | ||
110 | #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) | ||
111 | #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) | ||
112 | |||
113 | #if 0 | ||
114 | #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) | ||
115 | #define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; }) | ||
116 | #define up(x) do { printk("UP:%u:" #x "\n", __LINE__); up(x); } while(0) | ||
117 | #endif | ||
118 | |||
119 | /* Returns whether matches rule or not. */ | 82 | /* Returns whether matches rule or not. */ |
120 | static inline int | 83 | static inline int |
121 | ip_packet_match(const struct iphdr *ip, | 84 | ip_packet_match(const struct iphdr *ip, |
@@ -234,7 +197,8 @@ int do_match(struct ipt_entry_match *m, | |||
234 | int *hotdrop) | 197 | int *hotdrop) |
235 | { | 198 | { |
236 | /* Stop iteration if it doesn't match */ | 199 | /* Stop iteration if it doesn't match */ |
237 | if (!m->u.kernel.match->match(skb, in, out, m->data, offset, hotdrop)) | 200 | if (!m->u.kernel.match->match(skb, in, out, m->data, offset, |
201 | skb->nh.iph->ihl*4, hotdrop)) | ||
238 | return 1; | 202 | return 1; |
239 | else | 203 | else |
240 | return 0; | 204 | return 0; |
@@ -265,6 +229,7 @@ ipt_do_table(struct sk_buff **pskb, | |||
265 | const char *indev, *outdev; | 229 | const char *indev, *outdev; |
266 | void *table_base; | 230 | void *table_base; |
267 | struct ipt_entry *e, *back; | 231 | struct ipt_entry *e, *back; |
232 | struct xt_table_info *private = table->private; | ||
268 | 233 | ||
269 | /* Initialization */ | 234 | /* Initialization */ |
270 | ip = (*pskb)->nh.iph; | 235 | ip = (*pskb)->nh.iph; |
@@ -281,24 +246,11 @@ ipt_do_table(struct sk_buff **pskb, | |||
281 | 246 | ||
282 | read_lock_bh(&table->lock); | 247 | read_lock_bh(&table->lock); |
283 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); | 248 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); |
284 | table_base = (void *)table->private->entries[smp_processor_id()]; | 249 | table_base = (void *)private->entries[smp_processor_id()]; |
285 | e = get_entry(table_base, table->private->hook_entry[hook]); | 250 | e = get_entry(table_base, private->hook_entry[hook]); |
286 | |||
287 | #ifdef CONFIG_NETFILTER_DEBUG | ||
288 | /* Check noone else using our table */ | ||
289 | if (((struct ipt_entry *)table_base)->comefrom != 0xdead57ac | ||
290 | && ((struct ipt_entry *)table_base)->comefrom != 0xeeeeeeec) { | ||
291 | printk("ASSERT: CPU #%u, %s comefrom(%p) = %X\n", | ||
292 | smp_processor_id(), | ||
293 | table->name, | ||
294 | &((struct ipt_entry *)table_base)->comefrom, | ||
295 | ((struct ipt_entry *)table_base)->comefrom); | ||
296 | } | ||
297 | ((struct ipt_entry *)table_base)->comefrom = 0x57acc001; | ||
298 | #endif | ||
299 | 251 | ||
300 | /* For return from builtin chain */ | 252 | /* For return from builtin chain */ |
301 | back = get_entry(table_base, table->private->underflow[hook]); | 253 | back = get_entry(table_base, private->underflow[hook]); |
302 | 254 | ||
303 | do { | 255 | do { |
304 | IP_NF_ASSERT(e); | 256 | IP_NF_ASSERT(e); |
@@ -384,9 +336,6 @@ ipt_do_table(struct sk_buff **pskb, | |||
384 | } | 336 | } |
385 | } while (!hotdrop); | 337 | } while (!hotdrop); |
386 | 338 | ||
387 | #ifdef CONFIG_NETFILTER_DEBUG | ||
388 | ((struct ipt_entry *)table_base)->comefrom = 0xdead57ac; | ||
389 | #endif | ||
390 | read_unlock_bh(&table->lock); | 339 | read_unlock_bh(&table->lock); |
391 | 340 | ||
392 | #ifdef DEBUG_ALLOW_ALL | 341 | #ifdef DEBUG_ALLOW_ALL |
@@ -398,145 +347,6 @@ ipt_do_table(struct sk_buff **pskb, | |||
398 | #endif | 347 | #endif |
399 | } | 348 | } |
400 | 349 | ||
401 | /* | ||
402 | * These are weird, but module loading must not be done with mutex | ||
403 | * held (since they will register), and we have to have a single | ||
404 | * function to use try_then_request_module(). | ||
405 | */ | ||
406 | |||
407 | /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ | ||
408 | static inline struct ipt_table *find_table_lock(const char *name) | ||
409 | { | ||
410 | struct ipt_table *t; | ||
411 | |||
412 | if (down_interruptible(&ipt_mutex) != 0) | ||
413 | return ERR_PTR(-EINTR); | ||
414 | |||
415 | list_for_each_entry(t, &ipt_tables, list) | ||
416 | if (strcmp(t->name, name) == 0 && try_module_get(t->me)) | ||
417 | return t; | ||
418 | up(&ipt_mutex); | ||
419 | return NULL; | ||
420 | } | ||
421 | |||
422 | /* Find match, grabs ref. Returns ERR_PTR() on error. */ | ||
423 | static inline struct ipt_match *find_match(const char *name, u8 revision) | ||
424 | { | ||
425 | struct ipt_match *m; | ||
426 | int err = 0; | ||
427 | |||
428 | if (down_interruptible(&ipt_mutex) != 0) | ||
429 | return ERR_PTR(-EINTR); | ||
430 | |||
431 | list_for_each_entry(m, &ipt_match, list) { | ||
432 | if (strcmp(m->name, name) == 0) { | ||
433 | if (m->revision == revision) { | ||
434 | if (try_module_get(m->me)) { | ||
435 | up(&ipt_mutex); | ||
436 | return m; | ||
437 | } | ||
438 | } else | ||
439 | err = -EPROTOTYPE; /* Found something. */ | ||
440 | } | ||
441 | } | ||
442 | up(&ipt_mutex); | ||
443 | return ERR_PTR(err); | ||
444 | } | ||
445 | |||
446 | /* Find target, grabs ref. Returns ERR_PTR() on error. */ | ||
447 | static inline struct ipt_target *find_target(const char *name, u8 revision) | ||
448 | { | ||
449 | struct ipt_target *t; | ||
450 | int err = 0; | ||
451 | |||
452 | if (down_interruptible(&ipt_mutex) != 0) | ||
453 | return ERR_PTR(-EINTR); | ||
454 | |||
455 | list_for_each_entry(t, &ipt_target, list) { | ||
456 | if (strcmp(t->name, name) == 0) { | ||
457 | if (t->revision == revision) { | ||
458 | if (try_module_get(t->me)) { | ||
459 | up(&ipt_mutex); | ||
460 | return t; | ||
461 | } | ||
462 | } else | ||
463 | err = -EPROTOTYPE; /* Found something. */ | ||
464 | } | ||
465 | } | ||
466 | up(&ipt_mutex); | ||
467 | return ERR_PTR(err); | ||
468 | } | ||
469 | |||
470 | struct ipt_target *ipt_find_target(const char *name, u8 revision) | ||
471 | { | ||
472 | struct ipt_target *target; | ||
473 | |||
474 | target = try_then_request_module(find_target(name, revision), | ||
475 | "ipt_%s", name); | ||
476 | if (IS_ERR(target) || !target) | ||
477 | return NULL; | ||
478 | return target; | ||
479 | } | ||
480 | |||
481 | static int match_revfn(const char *name, u8 revision, int *bestp) | ||
482 | { | ||
483 | struct ipt_match *m; | ||
484 | int have_rev = 0; | ||
485 | |||
486 | list_for_each_entry(m, &ipt_match, list) { | ||
487 | if (strcmp(m->name, name) == 0) { | ||
488 | if (m->revision > *bestp) | ||
489 | *bestp = m->revision; | ||
490 | if (m->revision == revision) | ||
491 | have_rev = 1; | ||
492 | } | ||
493 | } | ||
494 | return have_rev; | ||
495 | } | ||
496 | |||
497 | static int target_revfn(const char *name, u8 revision, int *bestp) | ||
498 | { | ||
499 | struct ipt_target *t; | ||
500 | int have_rev = 0; | ||
501 | |||
502 | list_for_each_entry(t, &ipt_target, list) { | ||
503 | if (strcmp(t->name, name) == 0) { | ||
504 | if (t->revision > *bestp) | ||
505 | *bestp = t->revision; | ||
506 | if (t->revision == revision) | ||
507 | have_rev = 1; | ||
508 | } | ||
509 | } | ||
510 | return have_rev; | ||
511 | } | ||
512 | |||
513 | /* Returns true or false (if no such extension at all) */ | ||
514 | static inline int find_revision(const char *name, u8 revision, | ||
515 | int (*revfn)(const char *, u8, int *), | ||
516 | int *err) | ||
517 | { | ||
518 | int have_rev, best = -1; | ||
519 | |||
520 | if (down_interruptible(&ipt_mutex) != 0) { | ||
521 | *err = -EINTR; | ||
522 | return 1; | ||
523 | } | ||
524 | have_rev = revfn(name, revision, &best); | ||
525 | up(&ipt_mutex); | ||
526 | |||
527 | /* Nothing at all? Return 0 to try loading module. */ | ||
528 | if (best == -1) { | ||
529 | *err = -ENOENT; | ||
530 | return 0; | ||
531 | } | ||
532 | |||
533 | *err = best; | ||
534 | if (!have_rev) | ||
535 | *err = -EPROTONOSUPPORT; | ||
536 | return 1; | ||
537 | } | ||
538 | |||
539 | |||
540 | /* All zeroes == unconditional rule. */ | 350 | /* All zeroes == unconditional rule. */ |
541 | static inline int | 351 | static inline int |
542 | unconditional(const struct ipt_ip *ip) | 352 | unconditional(const struct ipt_ip *ip) |
@@ -553,7 +363,7 @@ unconditional(const struct ipt_ip *ip) | |||
553 | /* Figures out from what hook each rule can be called: returns 0 if | 363 | /* Figures out from what hook each rule can be called: returns 0 if |
554 | there are loops. Puts hook bitmask in comefrom. */ | 364 | there are loops. Puts hook bitmask in comefrom. */ |
555 | static int | 365 | static int |
556 | mark_source_chains(struct ipt_table_info *newinfo, | 366 | mark_source_chains(struct xt_table_info *newinfo, |
557 | unsigned int valid_hooks, void *entry0) | 367 | unsigned int valid_hooks, void *entry0) |
558 | { | 368 | { |
559 | unsigned int hook; | 369 | unsigned int hook; |
@@ -699,7 +509,7 @@ check_match(struct ipt_entry_match *m, | |||
699 | { | 509 | { |
700 | struct ipt_match *match; | 510 | struct ipt_match *match; |
701 | 511 | ||
702 | match = try_then_request_module(find_match(m->u.user.name, | 512 | match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name, |
703 | m->u.user.revision), | 513 | m->u.user.revision), |
704 | "ipt_%s", m->u.user.name); | 514 | "ipt_%s", m->u.user.name); |
705 | if (IS_ERR(match) || !match) { | 515 | if (IS_ERR(match) || !match) { |
@@ -744,7 +554,8 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size, | |||
744 | goto cleanup_matches; | 554 | goto cleanup_matches; |
745 | 555 | ||
746 | t = ipt_get_target(e); | 556 | t = ipt_get_target(e); |
747 | target = try_then_request_module(find_target(t->u.user.name, | 557 | target = try_then_request_module(xt_find_target(AF_INET, |
558 | t->u.user.name, | ||
748 | t->u.user.revision), | 559 | t->u.user.revision), |
749 | "ipt_%s", t->u.user.name); | 560 | "ipt_%s", t->u.user.name); |
750 | if (IS_ERR(target) || !target) { | 561 | if (IS_ERR(target) || !target) { |
@@ -781,7 +592,7 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size, | |||
781 | 592 | ||
782 | static inline int | 593 | static inline int |
783 | check_entry_size_and_hooks(struct ipt_entry *e, | 594 | check_entry_size_and_hooks(struct ipt_entry *e, |
784 | struct ipt_table_info *newinfo, | 595 | struct xt_table_info *newinfo, |
785 | unsigned char *base, | 596 | unsigned char *base, |
786 | unsigned char *limit, | 597 | unsigned char *limit, |
787 | const unsigned int *hook_entries, | 598 | const unsigned int *hook_entries, |
@@ -815,7 +626,7 @@ check_entry_size_and_hooks(struct ipt_entry *e, | |||
815 | < 0 (not IPT_RETURN). --RR */ | 626 | < 0 (not IPT_RETURN). --RR */ |
816 | 627 | ||
817 | /* Clear counters and comefrom */ | 628 | /* Clear counters and comefrom */ |
818 | e->counters = ((struct ipt_counters) { 0, 0 }); | 629 | e->counters = ((struct xt_counters) { 0, 0 }); |
819 | e->comefrom = 0; | 630 | e->comefrom = 0; |
820 | 631 | ||
821 | (*i)++; | 632 | (*i)++; |
@@ -845,7 +656,7 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i) | |||
845 | static int | 656 | static int |
846 | translate_table(const char *name, | 657 | translate_table(const char *name, |
847 | unsigned int valid_hooks, | 658 | unsigned int valid_hooks, |
848 | struct ipt_table_info *newinfo, | 659 | struct xt_table_info *newinfo, |
849 | void *entry0, | 660 | void *entry0, |
850 | unsigned int size, | 661 | unsigned int size, |
851 | unsigned int number, | 662 | unsigned int number, |
@@ -922,48 +733,10 @@ translate_table(const char *name, | |||
922 | return ret; | 733 | return ret; |
923 | } | 734 | } |
924 | 735 | ||
925 | static struct ipt_table_info * | ||
926 | replace_table(struct ipt_table *table, | ||
927 | unsigned int num_counters, | ||
928 | struct ipt_table_info *newinfo, | ||
929 | int *error) | ||
930 | { | ||
931 | struct ipt_table_info *oldinfo; | ||
932 | |||
933 | #ifdef CONFIG_NETFILTER_DEBUG | ||
934 | { | ||
935 | int cpu; | ||
936 | |||
937 | for_each_cpu(cpu) { | ||
938 | struct ipt_entry *table_base = newinfo->entries[cpu]; | ||
939 | if (table_base) | ||
940 | table_base->comefrom = 0xdead57ac; | ||
941 | } | ||
942 | } | ||
943 | #endif | ||
944 | |||
945 | /* Do the substitution. */ | ||
946 | write_lock_bh(&table->lock); | ||
947 | /* Check inside lock: is the old number correct? */ | ||
948 | if (num_counters != table->private->number) { | ||
949 | duprintf("num_counters != table->private->number (%u/%u)\n", | ||
950 | num_counters, table->private->number); | ||
951 | write_unlock_bh(&table->lock); | ||
952 | *error = -EAGAIN; | ||
953 | return NULL; | ||
954 | } | ||
955 | oldinfo = table->private; | ||
956 | table->private = newinfo; | ||
957 | newinfo->initial_entries = oldinfo->initial_entries; | ||
958 | write_unlock_bh(&table->lock); | ||
959 | |||
960 | return oldinfo; | ||
961 | } | ||
962 | |||
963 | /* Gets counters. */ | 736 | /* Gets counters. */ |
964 | static inline int | 737 | static inline int |
965 | add_entry_to_counter(const struct ipt_entry *e, | 738 | add_entry_to_counter(const struct ipt_entry *e, |
966 | struct ipt_counters total[], | 739 | struct xt_counters total[], |
967 | unsigned int *i) | 740 | unsigned int *i) |
968 | { | 741 | { |
969 | ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); | 742 | ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); |
@@ -984,8 +757,8 @@ set_entry_to_counter(const struct ipt_entry *e, | |||
984 | } | 757 | } |
985 | 758 | ||
986 | static void | 759 | static void |
987 | get_counters(const struct ipt_table_info *t, | 760 | get_counters(const struct xt_table_info *t, |
988 | struct ipt_counters counters[]) | 761 | struct xt_counters counters[]) |
989 | { | 762 | { |
990 | unsigned int cpu; | 763 | unsigned int cpu; |
991 | unsigned int i; | 764 | unsigned int i; |
@@ -1024,14 +797,15 @@ copy_entries_to_user(unsigned int total_size, | |||
1024 | { | 797 | { |
1025 | unsigned int off, num, countersize; | 798 | unsigned int off, num, countersize; |
1026 | struct ipt_entry *e; | 799 | struct ipt_entry *e; |
1027 | struct ipt_counters *counters; | 800 | struct xt_counters *counters; |
801 | struct xt_table_info *private = table->private; | ||
1028 | int ret = 0; | 802 | int ret = 0; |
1029 | void *loc_cpu_entry; | 803 | void *loc_cpu_entry; |
1030 | 804 | ||
1031 | /* We need atomic snapshot of counters: rest doesn't change | 805 | /* We need atomic snapshot of counters: rest doesn't change |
1032 | (other than comefrom, which userspace doesn't care | 806 | (other than comefrom, which userspace doesn't care |
1033 | about). */ | 807 | about). */ |
1034 | countersize = sizeof(struct ipt_counters) * table->private->number; | 808 | countersize = sizeof(struct xt_counters) * private->number; |
1035 | counters = vmalloc_node(countersize, numa_node_id()); | 809 | counters = vmalloc_node(countersize, numa_node_id()); |
1036 | 810 | ||
1037 | if (counters == NULL) | 811 | if (counters == NULL) |
@@ -1039,14 +813,14 @@ copy_entries_to_user(unsigned int total_size, | |||
1039 | 813 | ||
1040 | /* First, sum counters... */ | 814 | /* First, sum counters... */ |
1041 | write_lock_bh(&table->lock); | 815 | write_lock_bh(&table->lock); |
1042 | get_counters(table->private, counters); | 816 | get_counters(private, counters); |
1043 | write_unlock_bh(&table->lock); | 817 | write_unlock_bh(&table->lock); |
1044 | 818 | ||
1045 | /* choose the copy that is on our node/cpu, ... | 819 | /* choose the copy that is on our node/cpu, ... |
1046 | * This choice is lazy (because current thread is | 820 | * This choice is lazy (because current thread is |
1047 | * allowed to migrate to another cpu) | 821 | * allowed to migrate to another cpu) |
1048 | */ | 822 | */ |
1049 | loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; | 823 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; |
1050 | /* ... then copy entire thing ... */ | 824 | /* ... then copy entire thing ... */ |
1051 | if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { | 825 | if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { |
1052 | ret = -EFAULT; | 826 | ret = -EFAULT; |
@@ -1108,74 +882,36 @@ get_entries(const struct ipt_get_entries *entries, | |||
1108 | int ret; | 882 | int ret; |
1109 | struct ipt_table *t; | 883 | struct ipt_table *t; |
1110 | 884 | ||
1111 | t = find_table_lock(entries->name); | 885 | t = xt_find_table_lock(AF_INET, entries->name); |
1112 | if (t && !IS_ERR(t)) { | 886 | if (t && !IS_ERR(t)) { |
887 | struct xt_table_info *private = t->private; | ||
1113 | duprintf("t->private->number = %u\n", | 888 | duprintf("t->private->number = %u\n", |
1114 | t->private->number); | 889 | private->number); |
1115 | if (entries->size == t->private->size) | 890 | if (entries->size == private->size) |
1116 | ret = copy_entries_to_user(t->private->size, | 891 | ret = copy_entries_to_user(private->size, |
1117 | t, uptr->entrytable); | 892 | t, uptr->entrytable); |
1118 | else { | 893 | else { |
1119 | duprintf("get_entries: I've got %u not %u!\n", | 894 | duprintf("get_entries: I've got %u not %u!\n", |
1120 | t->private->size, | 895 | private->size, |
1121 | entries->size); | 896 | entries->size); |
1122 | ret = -EINVAL; | 897 | ret = -EINVAL; |
1123 | } | 898 | } |
1124 | module_put(t->me); | 899 | module_put(t->me); |
1125 | up(&ipt_mutex); | 900 | xt_table_unlock(t); |
1126 | } else | 901 | } else |
1127 | ret = t ? PTR_ERR(t) : -ENOENT; | 902 | ret = t ? PTR_ERR(t) : -ENOENT; |
1128 | 903 | ||
1129 | return ret; | 904 | return ret; |
1130 | } | 905 | } |
1131 | 906 | ||
1132 | static void free_table_info(struct ipt_table_info *info) | ||
1133 | { | ||
1134 | int cpu; | ||
1135 | for_each_cpu(cpu) { | ||
1136 | if (info->size <= PAGE_SIZE) | ||
1137 | kfree(info->entries[cpu]); | ||
1138 | else | ||
1139 | vfree(info->entries[cpu]); | ||
1140 | } | ||
1141 | kfree(info); | ||
1142 | } | ||
1143 | |||
1144 | static struct ipt_table_info *alloc_table_info(unsigned int size) | ||
1145 | { | ||
1146 | struct ipt_table_info *newinfo; | ||
1147 | int cpu; | ||
1148 | |||
1149 | newinfo = kzalloc(sizeof(struct ipt_table_info), GFP_KERNEL); | ||
1150 | if (!newinfo) | ||
1151 | return NULL; | ||
1152 | |||
1153 | newinfo->size = size; | ||
1154 | |||
1155 | for_each_cpu(cpu) { | ||
1156 | if (size <= PAGE_SIZE) | ||
1157 | newinfo->entries[cpu] = kmalloc_node(size, | ||
1158 | GFP_KERNEL, | ||
1159 | cpu_to_node(cpu)); | ||
1160 | else | ||
1161 | newinfo->entries[cpu] = vmalloc_node(size, cpu_to_node(cpu)); | ||
1162 | if (newinfo->entries[cpu] == 0) { | ||
1163 | free_table_info(newinfo); | ||
1164 | return NULL; | ||
1165 | } | ||
1166 | } | ||
1167 | |||
1168 | return newinfo; | ||
1169 | } | ||
1170 | |||
1171 | static int | 907 | static int |
1172 | do_replace(void __user *user, unsigned int len) | 908 | do_replace(void __user *user, unsigned int len) |
1173 | { | 909 | { |
1174 | int ret; | 910 | int ret; |
1175 | struct ipt_replace tmp; | 911 | struct ipt_replace tmp; |
1176 | struct ipt_table *t; | 912 | struct ipt_table *t; |
1177 | struct ipt_table_info *newinfo, *oldinfo; | 913 | struct xt_table_info *newinfo, *oldinfo; |
1178 | struct ipt_counters *counters; | 914 | struct xt_counters *counters; |
1179 | void *loc_cpu_entry, *loc_cpu_old_entry; | 915 | void *loc_cpu_entry, *loc_cpu_old_entry; |
1180 | 916 | ||
1181 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 917 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
@@ -1185,11 +921,7 @@ do_replace(void __user *user, unsigned int len) | |||
1185 | if (len != sizeof(tmp) + tmp.size) | 921 | if (len != sizeof(tmp) + tmp.size) |
1186 | return -ENOPROTOOPT; | 922 | return -ENOPROTOOPT; |
1187 | 923 | ||
1188 | /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ | 924 | newinfo = xt_alloc_table_info(tmp.size); |
1189 | if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) | ||
1190 | return -ENOMEM; | ||
1191 | |||
1192 | newinfo = alloc_table_info(tmp.size); | ||
1193 | if (!newinfo) | 925 | if (!newinfo) |
1194 | return -ENOMEM; | 926 | return -ENOMEM; |
1195 | 927 | ||
@@ -1201,7 +933,7 @@ do_replace(void __user *user, unsigned int len) | |||
1201 | goto free_newinfo; | 933 | goto free_newinfo; |
1202 | } | 934 | } |
1203 | 935 | ||
1204 | counters = vmalloc(tmp.num_counters * sizeof(struct ipt_counters)); | 936 | counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters)); |
1205 | if (!counters) { | 937 | if (!counters) { |
1206 | ret = -ENOMEM; | 938 | ret = -ENOMEM; |
1207 | goto free_newinfo; | 939 | goto free_newinfo; |
@@ -1215,7 +947,7 @@ do_replace(void __user *user, unsigned int len) | |||
1215 | 947 | ||
1216 | duprintf("ip_tables: Translated table\n"); | 948 | duprintf("ip_tables: Translated table\n"); |
1217 | 949 | ||
1218 | t = try_then_request_module(find_table_lock(tmp.name), | 950 | t = try_then_request_module(xt_find_table_lock(AF_INET, tmp.name), |
1219 | "iptable_%s", tmp.name); | 951 | "iptable_%s", tmp.name); |
1220 | if (!t || IS_ERR(t)) { | 952 | if (!t || IS_ERR(t)) { |
1221 | ret = t ? PTR_ERR(t) : -ENOENT; | 953 | ret = t ? PTR_ERR(t) : -ENOENT; |
@@ -1230,7 +962,7 @@ do_replace(void __user *user, unsigned int len) | |||
1230 | goto put_module; | 962 | goto put_module; |
1231 | } | 963 | } |
1232 | 964 | ||
1233 | oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); | 965 | oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret); |
1234 | if (!oldinfo) | 966 | if (!oldinfo) |
1235 | goto put_module; | 967 | goto put_module; |
1236 | 968 | ||
@@ -1249,23 +981,23 @@ do_replace(void __user *user, unsigned int len) | |||
1249 | /* Decrease module usage counts and free resource */ | 981 | /* Decrease module usage counts and free resource */ |
1250 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; | 982 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; |
1251 | IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); | 983 | IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); |
1252 | free_table_info(oldinfo); | 984 | xt_free_table_info(oldinfo); |
1253 | if (copy_to_user(tmp.counters, counters, | 985 | if (copy_to_user(tmp.counters, counters, |
1254 | sizeof(struct ipt_counters) * tmp.num_counters) != 0) | 986 | sizeof(struct xt_counters) * tmp.num_counters) != 0) |
1255 | ret = -EFAULT; | 987 | ret = -EFAULT; |
1256 | vfree(counters); | 988 | vfree(counters); |
1257 | up(&ipt_mutex); | 989 | xt_table_unlock(t); |
1258 | return ret; | 990 | return ret; |
1259 | 991 | ||
1260 | put_module: | 992 | put_module: |
1261 | module_put(t->me); | 993 | module_put(t->me); |
1262 | up(&ipt_mutex); | 994 | xt_table_unlock(t); |
1263 | free_newinfo_counters_untrans: | 995 | free_newinfo_counters_untrans: |
1264 | IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); | 996 | IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); |
1265 | free_newinfo_counters: | 997 | free_newinfo_counters: |
1266 | vfree(counters); | 998 | vfree(counters); |
1267 | free_newinfo: | 999 | free_newinfo: |
1268 | free_table_info(newinfo); | 1000 | xt_free_table_info(newinfo); |
1269 | return ret; | 1001 | return ret; |
1270 | } | 1002 | } |
1271 | 1003 | ||
@@ -1273,7 +1005,7 @@ do_replace(void __user *user, unsigned int len) | |||
1273 | * and everything is OK. */ | 1005 | * and everything is OK. */ |
1274 | static inline int | 1006 | static inline int |
1275 | add_counter_to_entry(struct ipt_entry *e, | 1007 | add_counter_to_entry(struct ipt_entry *e, |
1276 | const struct ipt_counters addme[], | 1008 | const struct xt_counters addme[], |
1277 | unsigned int *i) | 1009 | unsigned int *i) |
1278 | { | 1010 | { |
1279 | #if 0 | 1011 | #if 0 |
@@ -1295,15 +1027,16 @@ static int | |||
1295 | do_add_counters(void __user *user, unsigned int len) | 1027 | do_add_counters(void __user *user, unsigned int len) |
1296 | { | 1028 | { |
1297 | unsigned int i; | 1029 | unsigned int i; |
1298 | struct ipt_counters_info tmp, *paddc; | 1030 | struct xt_counters_info tmp, *paddc; |
1299 | struct ipt_table *t; | 1031 | struct ipt_table *t; |
1032 | struct xt_table_info *private; | ||
1300 | int ret = 0; | 1033 | int ret = 0; |
1301 | void *loc_cpu_entry; | 1034 | void *loc_cpu_entry; |
1302 | 1035 | ||
1303 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 1036 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
1304 | return -EFAULT; | 1037 | return -EFAULT; |
1305 | 1038 | ||
1306 | if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct ipt_counters)) | 1039 | if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters)) |
1307 | return -EINVAL; | 1040 | return -EINVAL; |
1308 | 1041 | ||
1309 | paddc = vmalloc_node(len, numa_node_id()); | 1042 | paddc = vmalloc_node(len, numa_node_id()); |
@@ -1315,29 +1048,30 @@ do_add_counters(void __user *user, unsigned int len) | |||
1315 | goto free; | 1048 | goto free; |
1316 | } | 1049 | } |
1317 | 1050 | ||
1318 | t = find_table_lock(tmp.name); | 1051 | t = xt_find_table_lock(AF_INET, tmp.name); |
1319 | if (!t || IS_ERR(t)) { | 1052 | if (!t || IS_ERR(t)) { |
1320 | ret = t ? PTR_ERR(t) : -ENOENT; | 1053 | ret = t ? PTR_ERR(t) : -ENOENT; |
1321 | goto free; | 1054 | goto free; |
1322 | } | 1055 | } |
1323 | 1056 | ||
1324 | write_lock_bh(&t->lock); | 1057 | write_lock_bh(&t->lock); |
1325 | if (t->private->number != paddc->num_counters) { | 1058 | private = t->private; |
1059 | if (private->number != paddc->num_counters) { | ||
1326 | ret = -EINVAL; | 1060 | ret = -EINVAL; |
1327 | goto unlock_up_free; | 1061 | goto unlock_up_free; |
1328 | } | 1062 | } |
1329 | 1063 | ||
1330 | i = 0; | 1064 | i = 0; |
1331 | /* Choose the copy that is on our node */ | 1065 | /* Choose the copy that is on our node */ |
1332 | loc_cpu_entry = t->private->entries[raw_smp_processor_id()]; | 1066 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; |
1333 | IPT_ENTRY_ITERATE(loc_cpu_entry, | 1067 | IPT_ENTRY_ITERATE(loc_cpu_entry, |
1334 | t->private->size, | 1068 | private->size, |
1335 | add_counter_to_entry, | 1069 | add_counter_to_entry, |
1336 | paddc->counters, | 1070 | paddc->counters, |
1337 | &i); | 1071 | &i); |
1338 | unlock_up_free: | 1072 | unlock_up_free: |
1339 | write_unlock_bh(&t->lock); | 1073 | write_unlock_bh(&t->lock); |
1340 | up(&ipt_mutex); | 1074 | xt_table_unlock(t); |
1341 | module_put(t->me); | 1075 | module_put(t->me); |
1342 | free: | 1076 | free: |
1343 | vfree(paddc); | 1077 | vfree(paddc); |
@@ -1396,25 +1130,26 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1396 | } | 1130 | } |
1397 | name[IPT_TABLE_MAXNAMELEN-1] = '\0'; | 1131 | name[IPT_TABLE_MAXNAMELEN-1] = '\0'; |
1398 | 1132 | ||
1399 | t = try_then_request_module(find_table_lock(name), | 1133 | t = try_then_request_module(xt_find_table_lock(AF_INET, name), |
1400 | "iptable_%s", name); | 1134 | "iptable_%s", name); |
1401 | if (t && !IS_ERR(t)) { | 1135 | if (t && !IS_ERR(t)) { |
1402 | struct ipt_getinfo info; | 1136 | struct ipt_getinfo info; |
1137 | struct xt_table_info *private = t->private; | ||
1403 | 1138 | ||
1404 | info.valid_hooks = t->valid_hooks; | 1139 | info.valid_hooks = t->valid_hooks; |
1405 | memcpy(info.hook_entry, t->private->hook_entry, | 1140 | memcpy(info.hook_entry, private->hook_entry, |
1406 | sizeof(info.hook_entry)); | 1141 | sizeof(info.hook_entry)); |
1407 | memcpy(info.underflow, t->private->underflow, | 1142 | memcpy(info.underflow, private->underflow, |
1408 | sizeof(info.underflow)); | 1143 | sizeof(info.underflow)); |
1409 | info.num_entries = t->private->number; | 1144 | info.num_entries = private->number; |
1410 | info.size = t->private->size; | 1145 | info.size = private->size; |
1411 | memcpy(info.name, name, sizeof(info.name)); | 1146 | memcpy(info.name, name, sizeof(info.name)); |
1412 | 1147 | ||
1413 | if (copy_to_user(user, &info, *len) != 0) | 1148 | if (copy_to_user(user, &info, *len) != 0) |
1414 | ret = -EFAULT; | 1149 | ret = -EFAULT; |
1415 | else | 1150 | else |
1416 | ret = 0; | 1151 | ret = 0; |
1417 | up(&ipt_mutex); | 1152 | xt_table_unlock(t); |
1418 | module_put(t->me); | 1153 | module_put(t->me); |
1419 | } else | 1154 | } else |
1420 | ret = t ? PTR_ERR(t) : -ENOENT; | 1155 | ret = t ? PTR_ERR(t) : -ENOENT; |
@@ -1441,7 +1176,7 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1441 | case IPT_SO_GET_REVISION_MATCH: | 1176 | case IPT_SO_GET_REVISION_MATCH: |
1442 | case IPT_SO_GET_REVISION_TARGET: { | 1177 | case IPT_SO_GET_REVISION_TARGET: { |
1443 | struct ipt_get_revision rev; | 1178 | struct ipt_get_revision rev; |
1444 | int (*revfn)(const char *, u8, int *); | 1179 | int target; |
1445 | 1180 | ||
1446 | if (*len != sizeof(rev)) { | 1181 | if (*len != sizeof(rev)) { |
1447 | ret = -EINVAL; | 1182 | ret = -EINVAL; |
@@ -1453,12 +1188,13 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1453 | } | 1188 | } |
1454 | 1189 | ||
1455 | if (cmd == IPT_SO_GET_REVISION_TARGET) | 1190 | if (cmd == IPT_SO_GET_REVISION_TARGET) |
1456 | revfn = target_revfn; | 1191 | target = 1; |
1457 | else | 1192 | else |
1458 | revfn = match_revfn; | 1193 | target = 0; |
1459 | 1194 | ||
1460 | try_then_request_module(find_revision(rev.name, rev.revision, | 1195 | try_then_request_module(xt_find_revision(AF_INET, rev.name, |
1461 | revfn, &ret), | 1196 | rev.revision, |
1197 | target, &ret), | ||
1462 | "ipt_%s", rev.name); | 1198 | "ipt_%s", rev.name); |
1463 | break; | 1199 | break; |
1464 | } | 1200 | } |
@@ -1471,60 +1207,15 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1471 | return ret; | 1207 | return ret; |
1472 | } | 1208 | } |
1473 | 1209 | ||
1474 | /* Registration hooks for targets. */ | 1210 | int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl) |
1475 | int | ||
1476 | ipt_register_target(struct ipt_target *target) | ||
1477 | { | 1211 | { |
1478 | int ret; | 1212 | int ret; |
1479 | 1213 | struct xt_table_info *newinfo; | |
1480 | ret = down_interruptible(&ipt_mutex); | 1214 | static struct xt_table_info bootstrap |
1481 | if (ret != 0) | ||
1482 | return ret; | ||
1483 | list_add(&target->list, &ipt_target); | ||
1484 | up(&ipt_mutex); | ||
1485 | return ret; | ||
1486 | } | ||
1487 | |||
1488 | void | ||
1489 | ipt_unregister_target(struct ipt_target *target) | ||
1490 | { | ||
1491 | down(&ipt_mutex); | ||
1492 | LIST_DELETE(&ipt_target, target); | ||
1493 | up(&ipt_mutex); | ||
1494 | } | ||
1495 | |||
1496 | int | ||
1497 | ipt_register_match(struct ipt_match *match) | ||
1498 | { | ||
1499 | int ret; | ||
1500 | |||
1501 | ret = down_interruptible(&ipt_mutex); | ||
1502 | if (ret != 0) | ||
1503 | return ret; | ||
1504 | |||
1505 | list_add(&match->list, &ipt_match); | ||
1506 | up(&ipt_mutex); | ||
1507 | |||
1508 | return ret; | ||
1509 | } | ||
1510 | |||
1511 | void | ||
1512 | ipt_unregister_match(struct ipt_match *match) | ||
1513 | { | ||
1514 | down(&ipt_mutex); | ||
1515 | LIST_DELETE(&ipt_match, match); | ||
1516 | up(&ipt_mutex); | ||
1517 | } | ||
1518 | |||
1519 | int ipt_register_table(struct ipt_table *table, const struct ipt_replace *repl) | ||
1520 | { | ||
1521 | int ret; | ||
1522 | struct ipt_table_info *newinfo; | ||
1523 | static struct ipt_table_info bootstrap | ||
1524 | = { 0, 0, 0, { 0 }, { 0 }, { } }; | 1215 | = { 0, 0, 0, { 0 }, { 0 }, { } }; |
1525 | void *loc_cpu_entry; | 1216 | void *loc_cpu_entry; |
1526 | 1217 | ||
1527 | newinfo = alloc_table_info(repl->size); | 1218 | newinfo = xt_alloc_table_info(repl->size); |
1528 | if (!newinfo) | 1219 | if (!newinfo) |
1529 | return -ENOMEM; | 1220 | return -ENOMEM; |
1530 | 1221 | ||
@@ -1540,246 +1231,29 @@ int ipt_register_table(struct ipt_table *table, const struct ipt_replace *repl) | |||
1540 | repl->hook_entry, | 1231 | repl->hook_entry, |
1541 | repl->underflow); | 1232 | repl->underflow); |
1542 | if (ret != 0) { | 1233 | if (ret != 0) { |
1543 | free_table_info(newinfo); | 1234 | xt_free_table_info(newinfo); |
1544 | return ret; | 1235 | return ret; |
1545 | } | 1236 | } |
1546 | 1237 | ||
1547 | ret = down_interruptible(&ipt_mutex); | 1238 | if (xt_register_table(table, &bootstrap, newinfo) != 0) { |
1548 | if (ret != 0) { | 1239 | xt_free_table_info(newinfo); |
1549 | free_table_info(newinfo); | ||
1550 | return ret; | 1240 | return ret; |
1551 | } | 1241 | } |
1552 | 1242 | ||
1553 | /* Don't autoload: we'd eat our tail... */ | 1243 | return 0; |
1554 | if (list_named_find(&ipt_tables, table->name)) { | ||
1555 | ret = -EEXIST; | ||
1556 | goto free_unlock; | ||
1557 | } | ||
1558 | |||
1559 | /* Simplifies replace_table code. */ | ||
1560 | table->private = &bootstrap; | ||
1561 | if (!replace_table(table, 0, newinfo, &ret)) | ||
1562 | goto free_unlock; | ||
1563 | |||
1564 | duprintf("table->private->number = %u\n", | ||
1565 | table->private->number); | ||
1566 | |||
1567 | /* save number of initial entries */ | ||
1568 | table->private->initial_entries = table->private->number; | ||
1569 | |||
1570 | rwlock_init(&table->lock); | ||
1571 | list_prepend(&ipt_tables, table); | ||
1572 | |||
1573 | unlock: | ||
1574 | up(&ipt_mutex); | ||
1575 | return ret; | ||
1576 | |||
1577 | free_unlock: | ||
1578 | free_table_info(newinfo); | ||
1579 | goto unlock; | ||
1580 | } | 1244 | } |
1581 | 1245 | ||
1582 | void ipt_unregister_table(struct ipt_table *table) | 1246 | void ipt_unregister_table(struct ipt_table *table) |
1583 | { | 1247 | { |
1248 | struct xt_table_info *private; | ||
1584 | void *loc_cpu_entry; | 1249 | void *loc_cpu_entry; |
1585 | 1250 | ||
1586 | down(&ipt_mutex); | 1251 | private = xt_unregister_table(table); |
1587 | LIST_DELETE(&ipt_tables, table); | ||
1588 | up(&ipt_mutex); | ||
1589 | 1252 | ||
1590 | /* Decrease module usage counts and free resources */ | 1253 | /* Decrease module usage counts and free resources */ |
1591 | loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; | 1254 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; |
1592 | IPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size, | 1255 | IPT_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL); |
1593 | cleanup_entry, NULL); | 1256 | xt_free_table_info(private); |
1594 | free_table_info(table->private); | ||
1595 | } | ||
1596 | |||
1597 | /* Returns 1 if the port is matched by the range, 0 otherwise */ | ||
1598 | static inline int | ||
1599 | port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert) | ||
1600 | { | ||
1601 | int ret; | ||
1602 | |||
1603 | ret = (port >= min && port <= max) ^ invert; | ||
1604 | return ret; | ||
1605 | } | ||
1606 | |||
1607 | static int | ||
1608 | tcp_find_option(u_int8_t option, | ||
1609 | const struct sk_buff *skb, | ||
1610 | unsigned int optlen, | ||
1611 | int invert, | ||
1612 | int *hotdrop) | ||
1613 | { | ||
1614 | /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ | ||
1615 | u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; | ||
1616 | unsigned int i; | ||
1617 | |||
1618 | duprintf("tcp_match: finding option\n"); | ||
1619 | |||
1620 | if (!optlen) | ||
1621 | return invert; | ||
1622 | |||
1623 | /* If we don't have the whole header, drop packet. */ | ||
1624 | op = skb_header_pointer(skb, | ||
1625 | skb->nh.iph->ihl*4 + sizeof(struct tcphdr), | ||
1626 | optlen, _opt); | ||
1627 | if (op == NULL) { | ||
1628 | *hotdrop = 1; | ||
1629 | return 0; | ||
1630 | } | ||
1631 | |||
1632 | for (i = 0; i < optlen; ) { | ||
1633 | if (op[i] == option) return !invert; | ||
1634 | if (op[i] < 2) i++; | ||
1635 | else i += op[i+1]?:1; | ||
1636 | } | ||
1637 | |||
1638 | return invert; | ||
1639 | } | ||
1640 | |||
1641 | static int | ||
1642 | tcp_match(const struct sk_buff *skb, | ||
1643 | const struct net_device *in, | ||
1644 | const struct net_device *out, | ||
1645 | const void *matchinfo, | ||
1646 | int offset, | ||
1647 | int *hotdrop) | ||
1648 | { | ||
1649 | struct tcphdr _tcph, *th; | ||
1650 | const struct ipt_tcp *tcpinfo = matchinfo; | ||
1651 | |||
1652 | if (offset) { | ||
1653 | /* To quote Alan: | ||
1654 | |||
1655 | Don't allow a fragment of TCP 8 bytes in. Nobody normal | ||
1656 | causes this. Its a cracker trying to break in by doing a | ||
1657 | flag overwrite to pass the direction checks. | ||
1658 | */ | ||
1659 | if (offset == 1) { | ||
1660 | duprintf("Dropping evil TCP offset=1 frag.\n"); | ||
1661 | *hotdrop = 1; | ||
1662 | } | ||
1663 | /* Must not be a fragment. */ | ||
1664 | return 0; | ||
1665 | } | ||
1666 | |||
1667 | #define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) | ||
1668 | |||
1669 | th = skb_header_pointer(skb, skb->nh.iph->ihl*4, | ||
1670 | sizeof(_tcph), &_tcph); | ||
1671 | if (th == NULL) { | ||
1672 | /* We've been asked to examine this packet, and we | ||
1673 | can't. Hence, no choice but to drop. */ | ||
1674 | duprintf("Dropping evil TCP offset=0 tinygram.\n"); | ||
1675 | *hotdrop = 1; | ||
1676 | return 0; | ||
1677 | } | ||
1678 | |||
1679 | if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1], | ||
1680 | ntohs(th->source), | ||
1681 | !!(tcpinfo->invflags & IPT_TCP_INV_SRCPT))) | ||
1682 | return 0; | ||
1683 | if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1], | ||
1684 | ntohs(th->dest), | ||
1685 | !!(tcpinfo->invflags & IPT_TCP_INV_DSTPT))) | ||
1686 | return 0; | ||
1687 | if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask) | ||
1688 | == tcpinfo->flg_cmp, | ||
1689 | IPT_TCP_INV_FLAGS)) | ||
1690 | return 0; | ||
1691 | if (tcpinfo->option) { | ||
1692 | if (th->doff * 4 < sizeof(_tcph)) { | ||
1693 | *hotdrop = 1; | ||
1694 | return 0; | ||
1695 | } | ||
1696 | if (!tcp_find_option(tcpinfo->option, skb, | ||
1697 | th->doff*4 - sizeof(_tcph), | ||
1698 | tcpinfo->invflags & IPT_TCP_INV_OPTION, | ||
1699 | hotdrop)) | ||
1700 | return 0; | ||
1701 | } | ||
1702 | return 1; | ||
1703 | } | ||
1704 | |||
1705 | /* Called when user tries to insert an entry of this type. */ | ||
1706 | static int | ||
1707 | tcp_checkentry(const char *tablename, | ||
1708 | const struct ipt_ip *ip, | ||
1709 | void *matchinfo, | ||
1710 | unsigned int matchsize, | ||
1711 | unsigned int hook_mask) | ||
1712 | { | ||
1713 | const struct ipt_tcp *tcpinfo = matchinfo; | ||
1714 | |||
1715 | /* Must specify proto == TCP, and no unknown invflags */ | ||
1716 | return ip->proto == IPPROTO_TCP | ||
1717 | && !(ip->invflags & IPT_INV_PROTO) | ||
1718 | && matchsize == IPT_ALIGN(sizeof(struct ipt_tcp)) | ||
1719 | && !(tcpinfo->invflags & ~IPT_TCP_INV_MASK); | ||
1720 | } | ||
1721 | |||
1722 | static int | ||
1723 | udp_match(const struct sk_buff *skb, | ||
1724 | const struct net_device *in, | ||
1725 | const struct net_device *out, | ||
1726 | const void *matchinfo, | ||
1727 | int offset, | ||
1728 | int *hotdrop) | ||
1729 | { | ||
1730 | struct udphdr _udph, *uh; | ||
1731 | const struct ipt_udp *udpinfo = matchinfo; | ||
1732 | |||
1733 | /* Must not be a fragment. */ | ||
1734 | if (offset) | ||
1735 | return 0; | ||
1736 | |||
1737 | uh = skb_header_pointer(skb, skb->nh.iph->ihl*4, | ||
1738 | sizeof(_udph), &_udph); | ||
1739 | if (uh == NULL) { | ||
1740 | /* We've been asked to examine this packet, and we | ||
1741 | can't. Hence, no choice but to drop. */ | ||
1742 | duprintf("Dropping evil UDP tinygram.\n"); | ||
1743 | *hotdrop = 1; | ||
1744 | return 0; | ||
1745 | } | ||
1746 | |||
1747 | return port_match(udpinfo->spts[0], udpinfo->spts[1], | ||
1748 | ntohs(uh->source), | ||
1749 | !!(udpinfo->invflags & IPT_UDP_INV_SRCPT)) | ||
1750 | && port_match(udpinfo->dpts[0], udpinfo->dpts[1], | ||
1751 | ntohs(uh->dest), | ||
1752 | !!(udpinfo->invflags & IPT_UDP_INV_DSTPT)); | ||
1753 | } | ||
1754 | |||
1755 | /* Called when user tries to insert an entry of this type. */ | ||
1756 | static int | ||
1757 | udp_checkentry(const char *tablename, | ||
1758 | const struct ipt_ip *ip, | ||
1759 | void *matchinfo, | ||
1760 | unsigned int matchinfosize, | ||
1761 | unsigned int hook_mask) | ||
1762 | { | ||
1763 | const struct ipt_udp *udpinfo = matchinfo; | ||
1764 | |||
1765 | /* Must specify proto == UDP, and no unknown invflags */ | ||
1766 | if (ip->proto != IPPROTO_UDP || (ip->invflags & IPT_INV_PROTO)) { | ||
1767 | duprintf("ipt_udp: Protocol %u != %u\n", ip->proto, | ||
1768 | IPPROTO_UDP); | ||
1769 | return 0; | ||
1770 | } | ||
1771 | if (matchinfosize != IPT_ALIGN(sizeof(struct ipt_udp))) { | ||
1772 | duprintf("ipt_udp: matchsize %u != %u\n", | ||
1773 | matchinfosize, IPT_ALIGN(sizeof(struct ipt_udp))); | ||
1774 | return 0; | ||
1775 | } | ||
1776 | if (udpinfo->invflags & ~IPT_UDP_INV_MASK) { | ||
1777 | duprintf("ipt_udp: unknown flags %X\n", | ||
1778 | udpinfo->invflags); | ||
1779 | return 0; | ||
1780 | } | ||
1781 | |||
1782 | return 1; | ||
1783 | } | 1257 | } |
1784 | 1258 | ||
1785 | /* Returns 1 if the type and code is matched by the range, 0 otherwise */ | 1259 | /* Returns 1 if the type and code is matched by the range, 0 otherwise */ |
@@ -1798,6 +1272,7 @@ icmp_match(const struct sk_buff *skb, | |||
1798 | const struct net_device *out, | 1272 | const struct net_device *out, |
1799 | const void *matchinfo, | 1273 | const void *matchinfo, |
1800 | int offset, | 1274 | int offset, |
1275 | unsigned int protoff, | ||
1801 | int *hotdrop) | 1276 | int *hotdrop) |
1802 | { | 1277 | { |
1803 | struct icmphdr _icmph, *ic; | 1278 | struct icmphdr _icmph, *ic; |
@@ -1807,8 +1282,7 @@ icmp_match(const struct sk_buff *skb, | |||
1807 | if (offset) | 1282 | if (offset) |
1808 | return 0; | 1283 | return 0; |
1809 | 1284 | ||
1810 | ic = skb_header_pointer(skb, skb->nh.iph->ihl*4, | 1285 | ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph); |
1811 | sizeof(_icmph), &_icmph); | ||
1812 | if (ic == NULL) { | 1286 | if (ic == NULL) { |
1813 | /* We've been asked to examine this packet, and we | 1287 | /* We've been asked to examine this packet, and we |
1814 | * can't. Hence, no choice but to drop. | 1288 | * can't. Hence, no choice but to drop. |
@@ -1828,11 +1302,12 @@ icmp_match(const struct sk_buff *skb, | |||
1828 | /* Called when user tries to insert an entry of this type. */ | 1302 | /* Called when user tries to insert an entry of this type. */ |
1829 | static int | 1303 | static int |
1830 | icmp_checkentry(const char *tablename, | 1304 | icmp_checkentry(const char *tablename, |
1831 | const struct ipt_ip *ip, | 1305 | const void *info, |
1832 | void *matchinfo, | 1306 | void *matchinfo, |
1833 | unsigned int matchsize, | 1307 | unsigned int matchsize, |
1834 | unsigned int hook_mask) | 1308 | unsigned int hook_mask) |
1835 | { | 1309 | { |
1310 | const struct ipt_ip *ip = info; | ||
1836 | const struct ipt_icmp *icmpinfo = matchinfo; | 1311 | const struct ipt_icmp *icmpinfo = matchinfo; |
1837 | 1312 | ||
1838 | /* Must specify proto == ICMP, and no unknown invflags */ | 1313 | /* Must specify proto == ICMP, and no unknown invflags */ |
@@ -1862,123 +1337,22 @@ static struct nf_sockopt_ops ipt_sockopts = { | |||
1862 | .get = do_ipt_get_ctl, | 1337 | .get = do_ipt_get_ctl, |
1863 | }; | 1338 | }; |
1864 | 1339 | ||
1865 | static struct ipt_match tcp_matchstruct = { | ||
1866 | .name = "tcp", | ||
1867 | .match = &tcp_match, | ||
1868 | .checkentry = &tcp_checkentry, | ||
1869 | }; | ||
1870 | |||
1871 | static struct ipt_match udp_matchstruct = { | ||
1872 | .name = "udp", | ||
1873 | .match = &udp_match, | ||
1874 | .checkentry = &udp_checkentry, | ||
1875 | }; | ||
1876 | |||
1877 | static struct ipt_match icmp_matchstruct = { | 1340 | static struct ipt_match icmp_matchstruct = { |
1878 | .name = "icmp", | 1341 | .name = "icmp", |
1879 | .match = &icmp_match, | 1342 | .match = &icmp_match, |
1880 | .checkentry = &icmp_checkentry, | 1343 | .checkentry = &icmp_checkentry, |
1881 | }; | 1344 | }; |
1882 | 1345 | ||
1883 | #ifdef CONFIG_PROC_FS | ||
1884 | static inline int print_name(const char *i, | ||
1885 | off_t start_offset, char *buffer, int length, | ||
1886 | off_t *pos, unsigned int *count) | ||
1887 | { | ||
1888 | if ((*count)++ >= start_offset) { | ||
1889 | unsigned int namelen; | ||
1890 | |||
1891 | namelen = sprintf(buffer + *pos, "%s\n", | ||
1892 | i + sizeof(struct list_head)); | ||
1893 | if (*pos + namelen > length) { | ||
1894 | /* Stop iterating */ | ||
1895 | return 1; | ||
1896 | } | ||
1897 | *pos += namelen; | ||
1898 | } | ||
1899 | return 0; | ||
1900 | } | ||
1901 | |||
1902 | static inline int print_target(const struct ipt_target *t, | ||
1903 | off_t start_offset, char *buffer, int length, | ||
1904 | off_t *pos, unsigned int *count) | ||
1905 | { | ||
1906 | if (t == &ipt_standard_target || t == &ipt_error_target) | ||
1907 | return 0; | ||
1908 | return print_name((char *)t, start_offset, buffer, length, pos, count); | ||
1909 | } | ||
1910 | |||
1911 | static int ipt_get_tables(char *buffer, char **start, off_t offset, int length) | ||
1912 | { | ||
1913 | off_t pos = 0; | ||
1914 | unsigned int count = 0; | ||
1915 | |||
1916 | if (down_interruptible(&ipt_mutex) != 0) | ||
1917 | return 0; | ||
1918 | |||
1919 | LIST_FIND(&ipt_tables, print_name, void *, | ||
1920 | offset, buffer, length, &pos, &count); | ||
1921 | |||
1922 | up(&ipt_mutex); | ||
1923 | |||
1924 | /* `start' hack - see fs/proc/generic.c line ~105 */ | ||
1925 | *start=(char *)((unsigned long)count-offset); | ||
1926 | return pos; | ||
1927 | } | ||
1928 | |||
1929 | static int ipt_get_targets(char *buffer, char **start, off_t offset, int length) | ||
1930 | { | ||
1931 | off_t pos = 0; | ||
1932 | unsigned int count = 0; | ||
1933 | |||
1934 | if (down_interruptible(&ipt_mutex) != 0) | ||
1935 | return 0; | ||
1936 | |||
1937 | LIST_FIND(&ipt_target, print_target, struct ipt_target *, | ||
1938 | offset, buffer, length, &pos, &count); | ||
1939 | |||
1940 | up(&ipt_mutex); | ||
1941 | |||
1942 | *start = (char *)((unsigned long)count - offset); | ||
1943 | return pos; | ||
1944 | } | ||
1945 | |||
1946 | static int ipt_get_matches(char *buffer, char **start, off_t offset, int length) | ||
1947 | { | ||
1948 | off_t pos = 0; | ||
1949 | unsigned int count = 0; | ||
1950 | |||
1951 | if (down_interruptible(&ipt_mutex) != 0) | ||
1952 | return 0; | ||
1953 | |||
1954 | LIST_FIND(&ipt_match, print_name, void *, | ||
1955 | offset, buffer, length, &pos, &count); | ||
1956 | |||
1957 | up(&ipt_mutex); | ||
1958 | |||
1959 | *start = (char *)((unsigned long)count - offset); | ||
1960 | return pos; | ||
1961 | } | ||
1962 | |||
1963 | static const struct { char *name; get_info_t *get_info; } ipt_proc_entry[] = | ||
1964 | { { "ip_tables_names", ipt_get_tables }, | ||
1965 | { "ip_tables_targets", ipt_get_targets }, | ||
1966 | { "ip_tables_matches", ipt_get_matches }, | ||
1967 | { NULL, NULL} }; | ||
1968 | #endif /*CONFIG_PROC_FS*/ | ||
1969 | |||
1970 | static int __init init(void) | 1346 | static int __init init(void) |
1971 | { | 1347 | { |
1972 | int ret; | 1348 | int ret; |
1973 | 1349 | ||
1350 | xt_proto_init(AF_INET); | ||
1351 | |||
1974 | /* Noone else will be downing sem now, so we won't sleep */ | 1352 | /* Noone else will be downing sem now, so we won't sleep */ |
1975 | down(&ipt_mutex); | 1353 | xt_register_target(AF_INET, &ipt_standard_target); |
1976 | list_append(&ipt_target, &ipt_standard_target); | 1354 | xt_register_target(AF_INET, &ipt_error_target); |
1977 | list_append(&ipt_target, &ipt_error_target); | 1355 | xt_register_match(AF_INET, &icmp_matchstruct); |
1978 | list_append(&ipt_match, &tcp_matchstruct); | ||
1979 | list_append(&ipt_match, &udp_matchstruct); | ||
1980 | list_append(&ipt_match, &icmp_matchstruct); | ||
1981 | up(&ipt_mutex); | ||
1982 | 1356 | ||
1983 | /* Register setsockopt */ | 1357 | /* Register setsockopt */ |
1984 | ret = nf_register_sockopt(&ipt_sockopts); | 1358 | ret = nf_register_sockopt(&ipt_sockopts); |
@@ -1987,49 +1361,23 @@ static int __init init(void) | |||
1987 | return ret; | 1361 | return ret; |
1988 | } | 1362 | } |
1989 | 1363 | ||
1990 | #ifdef CONFIG_PROC_FS | 1364 | printk("ip_tables: (C) 2000-2006 Netfilter Core Team\n"); |
1991 | { | ||
1992 | struct proc_dir_entry *proc; | ||
1993 | int i; | ||
1994 | |||
1995 | for (i = 0; ipt_proc_entry[i].name; i++) { | ||
1996 | proc = proc_net_create(ipt_proc_entry[i].name, 0, | ||
1997 | ipt_proc_entry[i].get_info); | ||
1998 | if (!proc) { | ||
1999 | while (--i >= 0) | ||
2000 | proc_net_remove(ipt_proc_entry[i].name); | ||
2001 | nf_unregister_sockopt(&ipt_sockopts); | ||
2002 | return -ENOMEM; | ||
2003 | } | ||
2004 | proc->owner = THIS_MODULE; | ||
2005 | } | ||
2006 | } | ||
2007 | #endif | ||
2008 | |||
2009 | printk("ip_tables: (C) 2000-2002 Netfilter core team\n"); | ||
2010 | return 0; | 1365 | return 0; |
2011 | } | 1366 | } |
2012 | 1367 | ||
2013 | static void __exit fini(void) | 1368 | static void __exit fini(void) |
2014 | { | 1369 | { |
2015 | nf_unregister_sockopt(&ipt_sockopts); | 1370 | nf_unregister_sockopt(&ipt_sockopts); |
2016 | #ifdef CONFIG_PROC_FS | 1371 | |
2017 | { | 1372 | xt_unregister_match(AF_INET, &icmp_matchstruct); |
2018 | int i; | 1373 | xt_unregister_target(AF_INET, &ipt_error_target); |
2019 | for (i = 0; ipt_proc_entry[i].name; i++) | 1374 | xt_unregister_target(AF_INET, &ipt_standard_target); |
2020 | proc_net_remove(ipt_proc_entry[i].name); | 1375 | |
2021 | } | 1376 | xt_proto_fini(AF_INET); |
2022 | #endif | ||
2023 | } | 1377 | } |
2024 | 1378 | ||
2025 | EXPORT_SYMBOL(ipt_register_table); | 1379 | EXPORT_SYMBOL(ipt_register_table); |
2026 | EXPORT_SYMBOL(ipt_unregister_table); | 1380 | EXPORT_SYMBOL(ipt_unregister_table); |
2027 | EXPORT_SYMBOL(ipt_register_match); | ||
2028 | EXPORT_SYMBOL(ipt_unregister_match); | ||
2029 | EXPORT_SYMBOL(ipt_do_table); | 1381 | EXPORT_SYMBOL(ipt_do_table); |
2030 | EXPORT_SYMBOL(ipt_register_target); | ||
2031 | EXPORT_SYMBOL(ipt_unregister_target); | ||
2032 | EXPORT_SYMBOL(ipt_find_target); | ||
2033 | |||
2034 | module_init(init); | 1382 | module_init(init); |
2035 | module_exit(fini); | 1383 | module_exit(fini); |
diff --git a/net/ipv4/netfilter/ipt_CLASSIFY.c b/net/ipv4/netfilter/ipt_CLASSIFY.c deleted file mode 100644 index dab78d8bd494..000000000000 --- a/net/ipv4/netfilter/ipt_CLASSIFY.c +++ /dev/null | |||
@@ -1,90 +0,0 @@ | |||
1 | /* | ||
2 | * This is a module which is used for setting the skb->priority field | ||
3 | * of an skb for qdisc classification. | ||
4 | */ | ||
5 | |||
6 | /* (C) 2001-2002 Patrick McHardy <kaber@trash.net> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/skbuff.h> | ||
15 | #include <linux/ip.h> | ||
16 | #include <net/checksum.h> | ||
17 | |||
18 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
19 | #include <linux/netfilter_ipv4/ipt_CLASSIFY.h> | ||
20 | |||
21 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
22 | MODULE_LICENSE("GPL"); | ||
23 | MODULE_DESCRIPTION("iptables qdisc classification target module"); | ||
24 | |||
25 | static unsigned int | ||
26 | target(struct sk_buff **pskb, | ||
27 | const struct net_device *in, | ||
28 | const struct net_device *out, | ||
29 | unsigned int hooknum, | ||
30 | const void *targinfo, | ||
31 | void *userinfo) | ||
32 | { | ||
33 | const struct ipt_classify_target_info *clinfo = targinfo; | ||
34 | |||
35 | if((*pskb)->priority != clinfo->priority) | ||
36 | (*pskb)->priority = clinfo->priority; | ||
37 | |||
38 | return IPT_CONTINUE; | ||
39 | } | ||
40 | |||
41 | static int | ||
42 | checkentry(const char *tablename, | ||
43 | const struct ipt_entry *e, | ||
44 | void *targinfo, | ||
45 | unsigned int targinfosize, | ||
46 | unsigned int hook_mask) | ||
47 | { | ||
48 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_classify_target_info))){ | ||
49 | printk(KERN_ERR "CLASSIFY: invalid size (%u != %Zu).\n", | ||
50 | targinfosize, | ||
51 | IPT_ALIGN(sizeof(struct ipt_classify_target_info))); | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | if (hook_mask & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) | | ||
56 | (1 << NF_IP_POST_ROUTING))) { | ||
57 | printk(KERN_ERR "CLASSIFY: only valid in LOCAL_OUT, FORWARD " | ||
58 | "and POST_ROUTING.\n"); | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | if (strcmp(tablename, "mangle") != 0) { | ||
63 | printk(KERN_ERR "CLASSIFY: can only be called from " | ||
64 | "\"mangle\" table, not \"%s\".\n", | ||
65 | tablename); | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | return 1; | ||
70 | } | ||
71 | |||
72 | static struct ipt_target ipt_classify_reg = { | ||
73 | .name = "CLASSIFY", | ||
74 | .target = target, | ||
75 | .checkentry = checkentry, | ||
76 | .me = THIS_MODULE, | ||
77 | }; | ||
78 | |||
79 | static int __init init(void) | ||
80 | { | ||
81 | return ipt_register_target(&ipt_classify_reg); | ||
82 | } | ||
83 | |||
84 | static void __exit fini(void) | ||
85 | { | ||
86 | ipt_unregister_target(&ipt_classify_reg); | ||
87 | } | ||
88 | |||
89 | module_init(init); | ||
90 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 45c52d8f4d99..d9bc971f03af 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -379,12 +379,13 @@ target(struct sk_buff **pskb, | |||
379 | 379 | ||
380 | static int | 380 | static int |
381 | checkentry(const char *tablename, | 381 | checkentry(const char *tablename, |
382 | const struct ipt_entry *e, | 382 | const void *e_void, |
383 | void *targinfo, | 383 | void *targinfo, |
384 | unsigned int targinfosize, | 384 | unsigned int targinfosize, |
385 | unsigned int hook_mask) | 385 | unsigned int hook_mask) |
386 | { | 386 | { |
387 | struct ipt_clusterip_tgt_info *cipinfo = targinfo; | 387 | struct ipt_clusterip_tgt_info *cipinfo = targinfo; |
388 | const struct ipt_entry *e = e_void; | ||
388 | 389 | ||
389 | struct clusterip_config *config; | 390 | struct clusterip_config *config; |
390 | 391 | ||
diff --git a/net/ipv4/netfilter/ipt_CONNMARK.c b/net/ipv4/netfilter/ipt_CONNMARK.c deleted file mode 100644 index 8acac5a40a92..000000000000 --- a/net/ipv4/netfilter/ipt_CONNMARK.c +++ /dev/null | |||
@@ -1,122 +0,0 @@ | |||
1 | /* This kernel module is used to modify the connection mark values, or | ||
2 | * to optionally restore the skb nfmark from the connection mark | ||
3 | * | ||
4 | * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> | ||
5 | * by Henrik Nordstrom <hno@marasystems.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/skbuff.h> | ||
23 | #include <linux/ip.h> | ||
24 | #include <net/checksum.h> | ||
25 | |||
26 | MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>"); | ||
27 | MODULE_DESCRIPTION("IP tables CONNMARK matching module"); | ||
28 | MODULE_LICENSE("GPL"); | ||
29 | |||
30 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
31 | #include <linux/netfilter_ipv4/ipt_CONNMARK.h> | ||
32 | #include <net/netfilter/nf_conntrack_compat.h> | ||
33 | |||
34 | static unsigned int | ||
35 | target(struct sk_buff **pskb, | ||
36 | const struct net_device *in, | ||
37 | const struct net_device *out, | ||
38 | unsigned int hooknum, | ||
39 | const void *targinfo, | ||
40 | void *userinfo) | ||
41 | { | ||
42 | const struct ipt_connmark_target_info *markinfo = targinfo; | ||
43 | u_int32_t diff; | ||
44 | u_int32_t nfmark; | ||
45 | u_int32_t newmark; | ||
46 | u_int32_t ctinfo; | ||
47 | u_int32_t *ctmark = nf_ct_get_mark(*pskb, &ctinfo); | ||
48 | |||
49 | if (ctmark) { | ||
50 | switch(markinfo->mode) { | ||
51 | case IPT_CONNMARK_SET: | ||
52 | newmark = (*ctmark & ~markinfo->mask) | markinfo->mark; | ||
53 | if (newmark != *ctmark) | ||
54 | *ctmark = newmark; | ||
55 | break; | ||
56 | case IPT_CONNMARK_SAVE: | ||
57 | newmark = (*ctmark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask); | ||
58 | if (*ctmark != newmark) | ||
59 | *ctmark = newmark; | ||
60 | break; | ||
61 | case IPT_CONNMARK_RESTORE: | ||
62 | nfmark = (*pskb)->nfmark; | ||
63 | diff = (*ctmark ^ nfmark) & markinfo->mask; | ||
64 | if (diff != 0) | ||
65 | (*pskb)->nfmark = nfmark ^ diff; | ||
66 | break; | ||
67 | } | ||
68 | } | ||
69 | |||
70 | return IPT_CONTINUE; | ||
71 | } | ||
72 | |||
73 | static int | ||
74 | checkentry(const char *tablename, | ||
75 | const struct ipt_entry *e, | ||
76 | void *targinfo, | ||
77 | unsigned int targinfosize, | ||
78 | unsigned int hook_mask) | ||
79 | { | ||
80 | struct ipt_connmark_target_info *matchinfo = targinfo; | ||
81 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_connmark_target_info))) { | ||
82 | printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n", | ||
83 | targinfosize, | ||
84 | IPT_ALIGN(sizeof(struct ipt_connmark_target_info))); | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | if (matchinfo->mode == IPT_CONNMARK_RESTORE) { | ||
89 | if (strcmp(tablename, "mangle") != 0) { | ||
90 | printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename); | ||
91 | return 0; | ||
92 | } | ||
93 | } | ||
94 | |||
95 | if (matchinfo->mark > 0xffffffff || matchinfo->mask > 0xffffffff) { | ||
96 | printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n"); | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | return 1; | ||
101 | } | ||
102 | |||
103 | static struct ipt_target ipt_connmark_reg = { | ||
104 | .name = "CONNMARK", | ||
105 | .target = &target, | ||
106 | .checkentry = &checkentry, | ||
107 | .me = THIS_MODULE | ||
108 | }; | ||
109 | |||
110 | static int __init init(void) | ||
111 | { | ||
112 | need_ip_conntrack(); | ||
113 | return ipt_register_target(&ipt_connmark_reg); | ||
114 | } | ||
115 | |||
116 | static void __exit fini(void) | ||
117 | { | ||
118 | ipt_unregister_target(&ipt_connmark_reg); | ||
119 | } | ||
120 | |||
121 | module_init(init); | ||
122 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_DSCP.c b/net/ipv4/netfilter/ipt_DSCP.c index 6e319570a28c..898cdf79ce18 100644 --- a/net/ipv4/netfilter/ipt_DSCP.c +++ b/net/ipv4/netfilter/ipt_DSCP.c | |||
@@ -57,7 +57,7 @@ target(struct sk_buff **pskb, | |||
57 | 57 | ||
58 | static int | 58 | static int |
59 | checkentry(const char *tablename, | 59 | checkentry(const char *tablename, |
60 | const struct ipt_entry *e, | 60 | const void *e_void, |
61 | void *targinfo, | 61 | void *targinfo, |
62 | unsigned int targinfosize, | 62 | unsigned int targinfosize, |
63 | unsigned int hook_mask) | 63 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c index a1319693f648..706445426a6d 100644 --- a/net/ipv4/netfilter/ipt_ECN.c +++ b/net/ipv4/netfilter/ipt_ECN.c | |||
@@ -113,12 +113,13 @@ target(struct sk_buff **pskb, | |||
113 | 113 | ||
114 | static int | 114 | static int |
115 | checkentry(const char *tablename, | 115 | checkentry(const char *tablename, |
116 | const struct ipt_entry *e, | 116 | const void *e_void, |
117 | void *targinfo, | 117 | void *targinfo, |
118 | unsigned int targinfosize, | 118 | unsigned int targinfosize, |
119 | unsigned int hook_mask) | 119 | unsigned int hook_mask) |
120 | { | 120 | { |
121 | const struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)targinfo; | 121 | const struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)targinfo; |
122 | const struct ipt_entry *e = e_void; | ||
122 | 123 | ||
123 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ECN_info))) { | 124 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ECN_info))) { |
124 | printk(KERN_WARNING "ECN: targinfosize %u != %Zu\n", | 125 | printk(KERN_WARNING "ECN: targinfosize %u != %Zu\n", |
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index 30be0f1dae37..6606ddb66a29 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c | |||
@@ -431,7 +431,7 @@ ipt_log_target(struct sk_buff **pskb, | |||
431 | } | 431 | } |
432 | 432 | ||
433 | static int ipt_log_checkentry(const char *tablename, | 433 | static int ipt_log_checkentry(const char *tablename, |
434 | const struct ipt_entry *e, | 434 | const void *e, |
435 | void *targinfo, | 435 | void *targinfo, |
436 | unsigned int targinfosize, | 436 | unsigned int targinfosize, |
437 | unsigned int hook_mask) | 437 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_MARK.c b/net/ipv4/netfilter/ipt_MARK.c deleted file mode 100644 index 52b4f2c296bf..000000000000 --- a/net/ipv4/netfilter/ipt_MARK.c +++ /dev/null | |||
@@ -1,172 +0,0 @@ | |||
1 | /* This is a module which is used for setting the NFMARK field of an skb. */ | ||
2 | |||
3 | /* (C) 1999-2001 Marc Boucher <marc@mbsi.ca> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/skbuff.h> | ||
12 | #include <linux/ip.h> | ||
13 | #include <net/checksum.h> | ||
14 | |||
15 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
16 | #include <linux/netfilter_ipv4/ipt_MARK.h> | ||
17 | |||
18 | MODULE_LICENSE("GPL"); | ||
19 | MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); | ||
20 | MODULE_DESCRIPTION("iptables MARK modification module"); | ||
21 | |||
22 | static unsigned int | ||
23 | target_v0(struct sk_buff **pskb, | ||
24 | const struct net_device *in, | ||
25 | const struct net_device *out, | ||
26 | unsigned int hooknum, | ||
27 | const void *targinfo, | ||
28 | void *userinfo) | ||
29 | { | ||
30 | const struct ipt_mark_target_info *markinfo = targinfo; | ||
31 | |||
32 | if((*pskb)->nfmark != markinfo->mark) | ||
33 | (*pskb)->nfmark = markinfo->mark; | ||
34 | |||
35 | return IPT_CONTINUE; | ||
36 | } | ||
37 | |||
38 | static unsigned int | ||
39 | target_v1(struct sk_buff **pskb, | ||
40 | const struct net_device *in, | ||
41 | const struct net_device *out, | ||
42 | unsigned int hooknum, | ||
43 | const void *targinfo, | ||
44 | void *userinfo) | ||
45 | { | ||
46 | const struct ipt_mark_target_info_v1 *markinfo = targinfo; | ||
47 | int mark = 0; | ||
48 | |||
49 | switch (markinfo->mode) { | ||
50 | case IPT_MARK_SET: | ||
51 | mark = markinfo->mark; | ||
52 | break; | ||
53 | |||
54 | case IPT_MARK_AND: | ||
55 | mark = (*pskb)->nfmark & markinfo->mark; | ||
56 | break; | ||
57 | |||
58 | case IPT_MARK_OR: | ||
59 | mark = (*pskb)->nfmark | markinfo->mark; | ||
60 | break; | ||
61 | } | ||
62 | |||
63 | if((*pskb)->nfmark != mark) | ||
64 | (*pskb)->nfmark = mark; | ||
65 | |||
66 | return IPT_CONTINUE; | ||
67 | } | ||
68 | |||
69 | |||
70 | static int | ||
71 | checkentry_v0(const char *tablename, | ||
72 | const struct ipt_entry *e, | ||
73 | void *targinfo, | ||
74 | unsigned int targinfosize, | ||
75 | unsigned int hook_mask) | ||
76 | { | ||
77 | struct ipt_mark_target_info *markinfo = targinfo; | ||
78 | |||
79 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info))) { | ||
80 | printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", | ||
81 | targinfosize, | ||
82 | IPT_ALIGN(sizeof(struct ipt_mark_target_info))); | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | if (strcmp(tablename, "mangle") != 0) { | ||
87 | printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename); | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | if (markinfo->mark > 0xffffffff) { | ||
92 | printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | return 1; | ||
97 | } | ||
98 | |||
99 | static int | ||
100 | checkentry_v1(const char *tablename, | ||
101 | const struct ipt_entry *e, | ||
102 | void *targinfo, | ||
103 | unsigned int targinfosize, | ||
104 | unsigned int hook_mask) | ||
105 | { | ||
106 | struct ipt_mark_target_info_v1 *markinfo = targinfo; | ||
107 | |||
108 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1))){ | ||
109 | printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", | ||
110 | targinfosize, | ||
111 | IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1))); | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | if (strcmp(tablename, "mangle") != 0) { | ||
116 | printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename); | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | if (markinfo->mode != IPT_MARK_SET | ||
121 | && markinfo->mode != IPT_MARK_AND | ||
122 | && markinfo->mode != IPT_MARK_OR) { | ||
123 | printk(KERN_WARNING "MARK: unknown mode %u\n", | ||
124 | markinfo->mode); | ||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | if (markinfo->mark > 0xffffffff) { | ||
129 | printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | return 1; | ||
134 | } | ||
135 | |||
136 | static struct ipt_target ipt_mark_reg_v0 = { | ||
137 | .name = "MARK", | ||
138 | .target = target_v0, | ||
139 | .checkentry = checkentry_v0, | ||
140 | .me = THIS_MODULE, | ||
141 | .revision = 0, | ||
142 | }; | ||
143 | |||
144 | static struct ipt_target ipt_mark_reg_v1 = { | ||
145 | .name = "MARK", | ||
146 | .target = target_v1, | ||
147 | .checkentry = checkentry_v1, | ||
148 | .me = THIS_MODULE, | ||
149 | .revision = 1, | ||
150 | }; | ||
151 | |||
152 | static int __init init(void) | ||
153 | { | ||
154 | int err; | ||
155 | |||
156 | err = ipt_register_target(&ipt_mark_reg_v0); | ||
157 | if (!err) { | ||
158 | err = ipt_register_target(&ipt_mark_reg_v1); | ||
159 | if (err) | ||
160 | ipt_unregister_target(&ipt_mark_reg_v0); | ||
161 | } | ||
162 | return err; | ||
163 | } | ||
164 | |||
165 | static void __exit fini(void) | ||
166 | { | ||
167 | ipt_unregister_target(&ipt_mark_reg_v0); | ||
168 | ipt_unregister_target(&ipt_mark_reg_v1); | ||
169 | } | ||
170 | |||
171 | module_init(init); | ||
172 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c index 27860510ca6d..12c56d3343ca 100644 --- a/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c | |||
@@ -40,7 +40,7 @@ static DEFINE_RWLOCK(masq_lock); | |||
40 | /* FIXME: Multiple targets. --RR */ | 40 | /* FIXME: Multiple targets. --RR */ |
41 | static int | 41 | static int |
42 | masquerade_check(const char *tablename, | 42 | masquerade_check(const char *tablename, |
43 | const struct ipt_entry *e, | 43 | const void *e, |
44 | void *targinfo, | 44 | void *targinfo, |
45 | unsigned int targinfosize, | 45 | unsigned int targinfosize, |
46 | unsigned int hook_mask) | 46 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c index e6e7b6095363..b074467fe67b 100644 --- a/net/ipv4/netfilter/ipt_NETMAP.c +++ b/net/ipv4/netfilter/ipt_NETMAP.c | |||
@@ -31,7 +31,7 @@ MODULE_DESCRIPTION("iptables 1:1 NAT mapping of IP networks target"); | |||
31 | 31 | ||
32 | static int | 32 | static int |
33 | check(const char *tablename, | 33 | check(const char *tablename, |
34 | const struct ipt_entry *e, | 34 | const void *e, |
35 | void *targinfo, | 35 | void *targinfo, |
36 | unsigned int targinfosize, | 36 | unsigned int targinfosize, |
37 | unsigned int hook_mask) | 37 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_NFQUEUE.c b/net/ipv4/netfilter/ipt_NFQUEUE.c deleted file mode 100644 index 3cedc9be8807..000000000000 --- a/net/ipv4/netfilter/ipt_NFQUEUE.c +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
1 | /* iptables module for using new netfilter netlink queue | ||
2 | * | ||
3 | * (C) 2005 by Harald Welte <laforge@netfilter.org> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/skbuff.h> | ||
13 | |||
14 | #include <linux/netfilter.h> | ||
15 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
16 | #include <linux/netfilter_ipv4/ipt_NFQUEUE.h> | ||
17 | |||
18 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | ||
19 | MODULE_DESCRIPTION("iptables NFQUEUE target"); | ||
20 | MODULE_LICENSE("GPL"); | ||
21 | |||
22 | static unsigned int | ||
23 | target(struct sk_buff **pskb, | ||
24 | const struct net_device *in, | ||
25 | const struct net_device *out, | ||
26 | unsigned int hooknum, | ||
27 | const void *targinfo, | ||
28 | void *userinfo) | ||
29 | { | ||
30 | const struct ipt_NFQ_info *tinfo = targinfo; | ||
31 | |||
32 | return NF_QUEUE_NR(tinfo->queuenum); | ||
33 | } | ||
34 | |||
35 | static int | ||
36 | checkentry(const char *tablename, | ||
37 | const struct ipt_entry *e, | ||
38 | void *targinfo, | ||
39 | unsigned int targinfosize, | ||
40 | unsigned int hook_mask) | ||
41 | { | ||
42 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_NFQ_info))) { | ||
43 | printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n", | ||
44 | targinfosize, | ||
45 | IPT_ALIGN(sizeof(struct ipt_NFQ_info))); | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | return 1; | ||
50 | } | ||
51 | |||
52 | static struct ipt_target ipt_NFQ_reg = { | ||
53 | .name = "NFQUEUE", | ||
54 | .target = target, | ||
55 | .checkentry = checkentry, | ||
56 | .me = THIS_MODULE, | ||
57 | }; | ||
58 | |||
59 | static int __init init(void) | ||
60 | { | ||
61 | return ipt_register_target(&ipt_NFQ_reg); | ||
62 | } | ||
63 | |||
64 | static void __exit fini(void) | ||
65 | { | ||
66 | ipt_unregister_target(&ipt_NFQ_reg); | ||
67 | } | ||
68 | |||
69 | module_init(init); | ||
70 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_NOTRACK.c b/net/ipv4/netfilter/ipt_NOTRACK.c deleted file mode 100644 index e3c69d072c6e..000000000000 --- a/net/ipv4/netfilter/ipt_NOTRACK.c +++ /dev/null | |||
@@ -1,76 +0,0 @@ | |||
1 | /* This is a module which is used for setting up fake conntracks | ||
2 | * on packets so that they are not seen by the conntrack/NAT code. | ||
3 | */ | ||
4 | #include <linux/module.h> | ||
5 | #include <linux/skbuff.h> | ||
6 | |||
7 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
8 | #include <net/netfilter/nf_conntrack_compat.h> | ||
9 | |||
10 | static unsigned int | ||
11 | target(struct sk_buff **pskb, | ||
12 | const struct net_device *in, | ||
13 | const struct net_device *out, | ||
14 | unsigned int hooknum, | ||
15 | const void *targinfo, | ||
16 | void *userinfo) | ||
17 | { | ||
18 | /* Previously seen (loopback)? Ignore. */ | ||
19 | if ((*pskb)->nfct != NULL) | ||
20 | return IPT_CONTINUE; | ||
21 | |||
22 | /* Attach fake conntrack entry. | ||
23 | If there is a real ct entry correspondig to this packet, | ||
24 | it'll hang aroun till timing out. We don't deal with it | ||
25 | for performance reasons. JK */ | ||
26 | nf_ct_untrack(*pskb); | ||
27 | (*pskb)->nfctinfo = IP_CT_NEW; | ||
28 | nf_conntrack_get((*pskb)->nfct); | ||
29 | |||
30 | return IPT_CONTINUE; | ||
31 | } | ||
32 | |||
33 | static int | ||
34 | checkentry(const char *tablename, | ||
35 | const struct ipt_entry *e, | ||
36 | void *targinfo, | ||
37 | unsigned int targinfosize, | ||
38 | unsigned int hook_mask) | ||
39 | { | ||
40 | if (targinfosize != 0) { | ||
41 | printk(KERN_WARNING "NOTRACK: targinfosize %u != 0\n", | ||
42 | targinfosize); | ||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | if (strcmp(tablename, "raw") != 0) { | ||
47 | printk(KERN_WARNING "NOTRACK: can only be called from \"raw\" table, not \"%s\"\n", tablename); | ||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | return 1; | ||
52 | } | ||
53 | |||
54 | static struct ipt_target ipt_notrack_reg = { | ||
55 | .name = "NOTRACK", | ||
56 | .target = target, | ||
57 | .checkentry = checkentry, | ||
58 | .me = THIS_MODULE | ||
59 | }; | ||
60 | |||
61 | static int __init init(void) | ||
62 | { | ||
63 | if (ipt_register_target(&ipt_notrack_reg)) | ||
64 | return -EINVAL; | ||
65 | |||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static void __exit fini(void) | ||
70 | { | ||
71 | ipt_unregister_target(&ipt_notrack_reg); | ||
72 | } | ||
73 | |||
74 | module_init(init); | ||
75 | module_exit(fini); | ||
76 | MODULE_LICENSE("GPL"); | ||
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c index 5245bfd33d52..140be51f2f01 100644 --- a/net/ipv4/netfilter/ipt_REDIRECT.c +++ b/net/ipv4/netfilter/ipt_REDIRECT.c | |||
@@ -33,7 +33,7 @@ MODULE_DESCRIPTION("iptables REDIRECT target module"); | |||
33 | /* FIXME: Take multiple ranges --RR */ | 33 | /* FIXME: Take multiple ranges --RR */ |
34 | static int | 34 | static int |
35 | redirect_check(const char *tablename, | 35 | redirect_check(const char *tablename, |
36 | const struct ipt_entry *e, | 36 | const void *e, |
37 | void *targinfo, | 37 | void *targinfo, |
38 | unsigned int targinfosize, | 38 | unsigned int targinfosize, |
39 | unsigned int hook_mask) | 39 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 6693526ae128..3eb47aae78c5 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -282,12 +282,13 @@ static unsigned int reject(struct sk_buff **pskb, | |||
282 | } | 282 | } |
283 | 283 | ||
284 | static int check(const char *tablename, | 284 | static int check(const char *tablename, |
285 | const struct ipt_entry *e, | 285 | const void *e_void, |
286 | void *targinfo, | 286 | void *targinfo, |
287 | unsigned int targinfosize, | 287 | unsigned int targinfosize, |
288 | unsigned int hook_mask) | 288 | unsigned int hook_mask) |
289 | { | 289 | { |
290 | const struct ipt_reject_info *rejinfo = targinfo; | 290 | const struct ipt_reject_info *rejinfo = targinfo; |
291 | const struct ipt_entry *e = e_void; | ||
291 | 292 | ||
292 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_reject_info))) { | 293 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_reject_info))) { |
293 | DEBUGP("REJECT: targinfosize %u != 0\n", targinfosize); | 294 | DEBUGP("REJECT: targinfosize %u != 0\n", targinfosize); |
diff --git a/net/ipv4/netfilter/ipt_SAME.c b/net/ipv4/netfilter/ipt_SAME.c index 7a0536d864ac..a22de59bba0e 100644 --- a/net/ipv4/netfilter/ipt_SAME.c +++ b/net/ipv4/netfilter/ipt_SAME.c | |||
@@ -49,7 +49,7 @@ MODULE_DESCRIPTION("iptables special SNAT module for consistent sourceip"); | |||
49 | 49 | ||
50 | static int | 50 | static int |
51 | same_check(const char *tablename, | 51 | same_check(const char *tablename, |
52 | const struct ipt_entry *e, | 52 | const void *e, |
53 | void *targinfo, | 53 | void *targinfo, |
54 | unsigned int targinfosize, | 54 | unsigned int targinfosize, |
55 | unsigned int hook_mask) | 55 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_TCPMSS.c b/net/ipv4/netfilter/ipt_TCPMSS.c index 8db70d6908c3..c122841e182c 100644 --- a/net/ipv4/netfilter/ipt_TCPMSS.c +++ b/net/ipv4/netfilter/ipt_TCPMSS.c | |||
@@ -210,12 +210,13 @@ static inline int find_syn_match(const struct ipt_entry_match *m) | |||
210 | /* Must specify -p tcp --syn/--tcp-flags SYN */ | 210 | /* Must specify -p tcp --syn/--tcp-flags SYN */ |
211 | static int | 211 | static int |
212 | ipt_tcpmss_checkentry(const char *tablename, | 212 | ipt_tcpmss_checkentry(const char *tablename, |
213 | const struct ipt_entry *e, | 213 | const void *e_void, |
214 | void *targinfo, | 214 | void *targinfo, |
215 | unsigned int targinfosize, | 215 | unsigned int targinfosize, |
216 | unsigned int hook_mask) | 216 | unsigned int hook_mask) |
217 | { | 217 | { |
218 | const struct ipt_tcpmss_info *tcpmssinfo = targinfo; | 218 | const struct ipt_tcpmss_info *tcpmssinfo = targinfo; |
219 | const struct ipt_entry *e = e_void; | ||
219 | 220 | ||
220 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_tcpmss_info))) { | 221 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_tcpmss_info))) { |
221 | DEBUGP("ipt_tcpmss_checkentry: targinfosize %u != %u\n", | 222 | DEBUGP("ipt_tcpmss_checkentry: targinfosize %u != %u\n", |
diff --git a/net/ipv4/netfilter/ipt_TOS.c b/net/ipv4/netfilter/ipt_TOS.c index deadb36d4428..3a44a56db239 100644 --- a/net/ipv4/netfilter/ipt_TOS.c +++ b/net/ipv4/netfilter/ipt_TOS.c | |||
@@ -52,7 +52,7 @@ target(struct sk_buff **pskb, | |||
52 | 52 | ||
53 | static int | 53 | static int |
54 | checkentry(const char *tablename, | 54 | checkentry(const char *tablename, |
55 | const struct ipt_entry *e, | 55 | const void *e_void, |
56 | void *targinfo, | 56 | void *targinfo, |
57 | unsigned int targinfosize, | 57 | unsigned int targinfosize, |
58 | unsigned int hook_mask) | 58 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_TTL.c b/net/ipv4/netfilter/ipt_TTL.c index b9ae6a9382f3..b769eb231970 100644 --- a/net/ipv4/netfilter/ipt_TTL.c +++ b/net/ipv4/netfilter/ipt_TTL.c | |||
@@ -66,7 +66,7 @@ ipt_ttl_target(struct sk_buff **pskb, const struct net_device *in, | |||
66 | } | 66 | } |
67 | 67 | ||
68 | static int ipt_ttl_checkentry(const char *tablename, | 68 | static int ipt_ttl_checkentry(const char *tablename, |
69 | const struct ipt_entry *e, | 69 | const void *e, |
70 | void *targinfo, | 70 | void *targinfo, |
71 | unsigned int targinfosize, | 71 | unsigned int targinfosize, |
72 | unsigned int hook_mask) | 72 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index 38641cd06123..641dbc477650 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c | |||
@@ -330,7 +330,7 @@ static void ipt_logfn(unsigned int pf, | |||
330 | } | 330 | } |
331 | 331 | ||
332 | static int ipt_ulog_checkentry(const char *tablename, | 332 | static int ipt_ulog_checkentry(const char *tablename, |
333 | const struct ipt_entry *e, | 333 | const void *e, |
334 | void *targinfo, | 334 | void *targinfo, |
335 | unsigned int targinfosize, | 335 | unsigned int targinfosize, |
336 | unsigned int hookmask) | 336 | unsigned int hookmask) |
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c index e19c2a52d00c..d6b83a976518 100644 --- a/net/ipv4/netfilter/ipt_addrtype.c +++ b/net/ipv4/netfilter/ipt_addrtype.c | |||
@@ -29,7 +29,7 @@ static inline int match_type(u_int32_t addr, u_int16_t mask) | |||
29 | 29 | ||
30 | static int match(const struct sk_buff *skb, const struct net_device *in, | 30 | static int match(const struct sk_buff *skb, const struct net_device *in, |
31 | const struct net_device *out, const void *matchinfo, | 31 | const struct net_device *out, const void *matchinfo, |
32 | int offset, int *hotdrop) | 32 | int offset, unsigned int protoff, int *hotdrop) |
33 | { | 33 | { |
34 | const struct ipt_addrtype_info *info = matchinfo; | 34 | const struct ipt_addrtype_info *info = matchinfo; |
35 | const struct iphdr *iph = skb->nh.iph; | 35 | const struct iphdr *iph = skb->nh.iph; |
@@ -43,7 +43,7 @@ static int match(const struct sk_buff *skb, const struct net_device *in, | |||
43 | return ret; | 43 | return ret; |
44 | } | 44 | } |
45 | 45 | ||
46 | static int checkentry(const char *tablename, const struct ipt_ip *ip, | 46 | static int checkentry(const char *tablename, const void *ip, |
47 | void *matchinfo, unsigned int matchsize, | 47 | void *matchinfo, unsigned int matchsize, |
48 | unsigned int hook_mask) | 48 | unsigned int hook_mask) |
49 | { | 49 | { |
diff --git a/net/ipv4/netfilter/ipt_ah.c b/net/ipv4/netfilter/ipt_ah.c index a0fea847cb72..144adfec13cc 100644 --- a/net/ipv4/netfilter/ipt_ah.c +++ b/net/ipv4/netfilter/ipt_ah.c | |||
@@ -41,6 +41,7 @@ match(const struct sk_buff *skb, | |||
41 | const struct net_device *out, | 41 | const struct net_device *out, |
42 | const void *matchinfo, | 42 | const void *matchinfo, |
43 | int offset, | 43 | int offset, |
44 | unsigned int protoff, | ||
44 | int *hotdrop) | 45 | int *hotdrop) |
45 | { | 46 | { |
46 | struct ip_auth_hdr _ahdr, *ah; | 47 | struct ip_auth_hdr _ahdr, *ah; |
@@ -50,7 +51,7 @@ match(const struct sk_buff *skb, | |||
50 | if (offset) | 51 | if (offset) |
51 | return 0; | 52 | return 0; |
52 | 53 | ||
53 | ah = skb_header_pointer(skb, skb->nh.iph->ihl * 4, | 54 | ah = skb_header_pointer(skb, protoff, |
54 | sizeof(_ahdr), &_ahdr); | 55 | sizeof(_ahdr), &_ahdr); |
55 | if (ah == NULL) { | 56 | if (ah == NULL) { |
56 | /* We've been asked to examine this packet, and we | 57 | /* We've been asked to examine this packet, and we |
@@ -69,12 +70,13 @@ match(const struct sk_buff *skb, | |||
69 | /* Called when user tries to insert an entry of this type. */ | 70 | /* Called when user tries to insert an entry of this type. */ |
70 | static int | 71 | static int |
71 | checkentry(const char *tablename, | 72 | checkentry(const char *tablename, |
72 | const struct ipt_ip *ip, | 73 | const void *ip_void, |
73 | void *matchinfo, | 74 | void *matchinfo, |
74 | unsigned int matchinfosize, | 75 | unsigned int matchinfosize, |
75 | unsigned int hook_mask) | 76 | unsigned int hook_mask) |
76 | { | 77 | { |
77 | const struct ipt_ah *ahinfo = matchinfo; | 78 | const struct ipt_ah *ahinfo = matchinfo; |
79 | const struct ipt_ip *ip = ip_void; | ||
78 | 80 | ||
79 | /* Must specify proto == AH, and no unknown invflags */ | 81 | /* Must specify proto == AH, and no unknown invflags */ |
80 | if (ip->proto != IPPROTO_AH || (ip->invflags & IPT_INV_PROTO)) { | 82 | if (ip->proto != IPPROTO_AH || (ip->invflags & IPT_INV_PROTO)) { |
diff --git a/net/ipv4/netfilter/ipt_comment.c b/net/ipv4/netfilter/ipt_comment.c deleted file mode 100644 index 6b76a1ea5245..000000000000 --- a/net/ipv4/netfilter/ipt_comment.c +++ /dev/null | |||
@@ -1,59 +0,0 @@ | |||
1 | /* | ||
2 | * Implements a dummy match to allow attaching comments to rules | ||
3 | * | ||
4 | * 2003-05-13 Brad Fisher (brad@info-link.net) | ||
5 | */ | ||
6 | |||
7 | #include <linux/module.h> | ||
8 | #include <linux/skbuff.h> | ||
9 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
10 | #include <linux/netfilter_ipv4/ipt_comment.h> | ||
11 | |||
12 | MODULE_AUTHOR("Brad Fisher <brad@info-link.net>"); | ||
13 | MODULE_DESCRIPTION("iptables comment match module"); | ||
14 | MODULE_LICENSE("GPL"); | ||
15 | |||
16 | static int | ||
17 | match(const struct sk_buff *skb, | ||
18 | const struct net_device *in, | ||
19 | const struct net_device *out, | ||
20 | const void *matchinfo, | ||
21 | int offset, | ||
22 | int *hotdrop) | ||
23 | { | ||
24 | /* We always match */ | ||
25 | return 1; | ||
26 | } | ||
27 | |||
28 | static int | ||
29 | checkentry(const char *tablename, | ||
30 | const struct ipt_ip *ip, | ||
31 | void *matchinfo, | ||
32 | unsigned int matchsize, | ||
33 | unsigned int hook_mask) | ||
34 | { | ||
35 | /* Check the size */ | ||
36 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_comment_info))) | ||
37 | return 0; | ||
38 | return 1; | ||
39 | } | ||
40 | |||
41 | static struct ipt_match comment_match = { | ||
42 | .name = "comment", | ||
43 | .match = match, | ||
44 | .checkentry = checkentry, | ||
45 | .me = THIS_MODULE | ||
46 | }; | ||
47 | |||
48 | static int __init init(void) | ||
49 | { | ||
50 | return ipt_register_match(&comment_match); | ||
51 | } | ||
52 | |||
53 | static void __exit fini(void) | ||
54 | { | ||
55 | ipt_unregister_match(&comment_match); | ||
56 | } | ||
57 | |||
58 | module_init(init); | ||
59 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_connbytes.c b/net/ipv4/netfilter/ipt_connbytes.c deleted file mode 100644 index d68a048b7176..000000000000 --- a/net/ipv4/netfilter/ipt_connbytes.c +++ /dev/null | |||
@@ -1,161 +0,0 @@ | |||
1 | /* Kernel module to match connection tracking byte counter. | ||
2 | * GPL (C) 2002 Martin Devera (devik@cdi.cz). | ||
3 | * | ||
4 | * 2004-07-20 Harald Welte <laforge@netfilter.org> | ||
5 | * - reimplemented to use per-connection accounting counters | ||
6 | * - add functionality to match number of packets | ||
7 | * - add functionality to match average packet size | ||
8 | * - add support to match directions seperately | ||
9 | * | ||
10 | */ | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/skbuff.h> | ||
13 | #include <net/netfilter/nf_conntrack_compat.h> | ||
14 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
15 | #include <linux/netfilter_ipv4/ipt_connbytes.h> | ||
16 | |||
17 | #include <asm/div64.h> | ||
18 | #include <asm/bitops.h> | ||
19 | |||
20 | MODULE_LICENSE("GPL"); | ||
21 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | ||
22 | MODULE_DESCRIPTION("iptables match for matching number of pkts/bytes per connection"); | ||
23 | |||
24 | /* 64bit divisor, dividend and result. dynamic precision */ | ||
25 | static u_int64_t div64_64(u_int64_t dividend, u_int64_t divisor) | ||
26 | { | ||
27 | u_int32_t d = divisor; | ||
28 | |||
29 | if (divisor > 0xffffffffULL) { | ||
30 | unsigned int shift = fls(divisor >> 32); | ||
31 | |||
32 | d = divisor >> shift; | ||
33 | dividend >>= shift; | ||
34 | } | ||
35 | |||
36 | do_div(dividend, d); | ||
37 | return dividend; | ||
38 | } | ||
39 | |||
40 | static int | ||
41 | match(const struct sk_buff *skb, | ||
42 | const struct net_device *in, | ||
43 | const struct net_device *out, | ||
44 | const void *matchinfo, | ||
45 | int offset, | ||
46 | int *hotdrop) | ||
47 | { | ||
48 | const struct ipt_connbytes_info *sinfo = matchinfo; | ||
49 | u_int64_t what = 0; /* initialize to make gcc happy */ | ||
50 | const struct ip_conntrack_counter *counters; | ||
51 | |||
52 | if (!(counters = nf_ct_get_counters(skb))) | ||
53 | return 0; /* no match */ | ||
54 | |||
55 | switch (sinfo->what) { | ||
56 | case IPT_CONNBYTES_PKTS: | ||
57 | switch (sinfo->direction) { | ||
58 | case IPT_CONNBYTES_DIR_ORIGINAL: | ||
59 | what = counters[IP_CT_DIR_ORIGINAL].packets; | ||
60 | break; | ||
61 | case IPT_CONNBYTES_DIR_REPLY: | ||
62 | what = counters[IP_CT_DIR_REPLY].packets; | ||
63 | break; | ||
64 | case IPT_CONNBYTES_DIR_BOTH: | ||
65 | what = counters[IP_CT_DIR_ORIGINAL].packets; | ||
66 | what += counters[IP_CT_DIR_REPLY].packets; | ||
67 | break; | ||
68 | } | ||
69 | break; | ||
70 | case IPT_CONNBYTES_BYTES: | ||
71 | switch (sinfo->direction) { | ||
72 | case IPT_CONNBYTES_DIR_ORIGINAL: | ||
73 | what = counters[IP_CT_DIR_ORIGINAL].bytes; | ||
74 | break; | ||
75 | case IPT_CONNBYTES_DIR_REPLY: | ||
76 | what = counters[IP_CT_DIR_REPLY].bytes; | ||
77 | break; | ||
78 | case IPT_CONNBYTES_DIR_BOTH: | ||
79 | what = counters[IP_CT_DIR_ORIGINAL].bytes; | ||
80 | what += counters[IP_CT_DIR_REPLY].bytes; | ||
81 | break; | ||
82 | } | ||
83 | break; | ||
84 | case IPT_CONNBYTES_AVGPKT: | ||
85 | switch (sinfo->direction) { | ||
86 | case IPT_CONNBYTES_DIR_ORIGINAL: | ||
87 | what = div64_64(counters[IP_CT_DIR_ORIGINAL].bytes, | ||
88 | counters[IP_CT_DIR_ORIGINAL].packets); | ||
89 | break; | ||
90 | case IPT_CONNBYTES_DIR_REPLY: | ||
91 | what = div64_64(counters[IP_CT_DIR_REPLY].bytes, | ||
92 | counters[IP_CT_DIR_REPLY].packets); | ||
93 | break; | ||
94 | case IPT_CONNBYTES_DIR_BOTH: | ||
95 | { | ||
96 | u_int64_t bytes; | ||
97 | u_int64_t pkts; | ||
98 | bytes = counters[IP_CT_DIR_ORIGINAL].bytes + | ||
99 | counters[IP_CT_DIR_REPLY].bytes; | ||
100 | pkts = counters[IP_CT_DIR_ORIGINAL].packets+ | ||
101 | counters[IP_CT_DIR_REPLY].packets; | ||
102 | |||
103 | /* FIXME_THEORETICAL: what to do if sum | ||
104 | * overflows ? */ | ||
105 | |||
106 | what = div64_64(bytes, pkts); | ||
107 | } | ||
108 | break; | ||
109 | } | ||
110 | break; | ||
111 | } | ||
112 | |||
113 | if (sinfo->count.to) | ||
114 | return (what <= sinfo->count.to && what >= sinfo->count.from); | ||
115 | else | ||
116 | return (what >= sinfo->count.from); | ||
117 | } | ||
118 | |||
119 | static int check(const char *tablename, | ||
120 | const struct ipt_ip *ip, | ||
121 | void *matchinfo, | ||
122 | unsigned int matchsize, | ||
123 | unsigned int hook_mask) | ||
124 | { | ||
125 | const struct ipt_connbytes_info *sinfo = matchinfo; | ||
126 | |||
127 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_connbytes_info))) | ||
128 | return 0; | ||
129 | |||
130 | if (sinfo->what != IPT_CONNBYTES_PKTS && | ||
131 | sinfo->what != IPT_CONNBYTES_BYTES && | ||
132 | sinfo->what != IPT_CONNBYTES_AVGPKT) | ||
133 | return 0; | ||
134 | |||
135 | if (sinfo->direction != IPT_CONNBYTES_DIR_ORIGINAL && | ||
136 | sinfo->direction != IPT_CONNBYTES_DIR_REPLY && | ||
137 | sinfo->direction != IPT_CONNBYTES_DIR_BOTH) | ||
138 | return 0; | ||
139 | |||
140 | return 1; | ||
141 | } | ||
142 | |||
143 | static struct ipt_match state_match = { | ||
144 | .name = "connbytes", | ||
145 | .match = &match, | ||
146 | .checkentry = &check, | ||
147 | .me = THIS_MODULE | ||
148 | }; | ||
149 | |||
150 | static int __init init(void) | ||
151 | { | ||
152 | return ipt_register_match(&state_match); | ||
153 | } | ||
154 | |||
155 | static void __exit fini(void) | ||
156 | { | ||
157 | ipt_unregister_match(&state_match); | ||
158 | } | ||
159 | |||
160 | module_init(init); | ||
161 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_connmark.c b/net/ipv4/netfilter/ipt_connmark.c deleted file mode 100644 index 5306ef293b92..000000000000 --- a/net/ipv4/netfilter/ipt_connmark.c +++ /dev/null | |||
@@ -1,88 +0,0 @@ | |||
1 | /* This kernel module matches connection mark values set by the | ||
2 | * CONNMARK target | ||
3 | * | ||
4 | * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> | ||
5 | * by Henrik Nordstrom <hno@marasystems.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/skbuff.h> | ||
24 | |||
25 | MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>"); | ||
26 | MODULE_DESCRIPTION("IP tables connmark match module"); | ||
27 | MODULE_LICENSE("GPL"); | ||
28 | |||
29 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
30 | #include <linux/netfilter_ipv4/ipt_connmark.h> | ||
31 | #include <net/netfilter/nf_conntrack_compat.h> | ||
32 | |||
33 | static int | ||
34 | match(const struct sk_buff *skb, | ||
35 | const struct net_device *in, | ||
36 | const struct net_device *out, | ||
37 | const void *matchinfo, | ||
38 | int offset, | ||
39 | int *hotdrop) | ||
40 | { | ||
41 | const struct ipt_connmark_info *info = matchinfo; | ||
42 | u_int32_t ctinfo; | ||
43 | const u_int32_t *ctmark = nf_ct_get_mark(skb, &ctinfo); | ||
44 | if (!ctmark) | ||
45 | return 0; | ||
46 | |||
47 | return (((*ctmark) & info->mask) == info->mark) ^ info->invert; | ||
48 | } | ||
49 | |||
50 | static int | ||
51 | checkentry(const char *tablename, | ||
52 | const struct ipt_ip *ip, | ||
53 | void *matchinfo, | ||
54 | unsigned int matchsize, | ||
55 | unsigned int hook_mask) | ||
56 | { | ||
57 | struct ipt_connmark_info *cm = | ||
58 | (struct ipt_connmark_info *)matchinfo; | ||
59 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_connmark_info))) | ||
60 | return 0; | ||
61 | |||
62 | if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) { | ||
63 | printk(KERN_WARNING "connmark: only support 32bit mark\n"); | ||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | return 1; | ||
68 | } | ||
69 | |||
70 | static struct ipt_match connmark_match = { | ||
71 | .name = "connmark", | ||
72 | .match = &match, | ||
73 | .checkentry = &checkentry, | ||
74 | .me = THIS_MODULE | ||
75 | }; | ||
76 | |||
77 | static int __init init(void) | ||
78 | { | ||
79 | return ipt_register_match(&connmark_match); | ||
80 | } | ||
81 | |||
82 | static void __exit fini(void) | ||
83 | { | ||
84 | ipt_unregister_match(&connmark_match); | ||
85 | } | ||
86 | |||
87 | module_init(init); | ||
88 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_conntrack.c b/net/ipv4/netfilter/ipt_conntrack.c deleted file mode 100644 index c8d18705469b..000000000000 --- a/net/ipv4/netfilter/ipt_conntrack.c +++ /dev/null | |||
@@ -1,232 +0,0 @@ | |||
1 | /* Kernel module to match connection tracking information. | ||
2 | * Superset of Rusty's minimalistic state match. | ||
3 | * | ||
4 | * (C) 2001 Marc Boucher (marc@mbsi.ca). | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/skbuff.h> | ||
13 | |||
14 | #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) | ||
15 | #include <linux/netfilter_ipv4/ip_conntrack.h> | ||
16 | #include <linux/netfilter_ipv4/ip_conntrack_tuple.h> | ||
17 | #else | ||
18 | #include <net/netfilter/nf_conntrack.h> | ||
19 | #endif | ||
20 | |||
21 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
22 | #include <linux/netfilter_ipv4/ipt_conntrack.h> | ||
23 | |||
24 | MODULE_LICENSE("GPL"); | ||
25 | MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); | ||
26 | MODULE_DESCRIPTION("iptables connection tracking match module"); | ||
27 | |||
28 | #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) | ||
29 | |||
30 | static int | ||
31 | match(const struct sk_buff *skb, | ||
32 | const struct net_device *in, | ||
33 | const struct net_device *out, | ||
34 | const void *matchinfo, | ||
35 | int offset, | ||
36 | int *hotdrop) | ||
37 | { | ||
38 | const struct ipt_conntrack_info *sinfo = matchinfo; | ||
39 | struct ip_conntrack *ct; | ||
40 | enum ip_conntrack_info ctinfo; | ||
41 | unsigned int statebit; | ||
42 | |||
43 | ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); | ||
44 | |||
45 | #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) | ||
46 | |||
47 | if (ct == &ip_conntrack_untracked) | ||
48 | statebit = IPT_CONNTRACK_STATE_UNTRACKED; | ||
49 | else if (ct) | ||
50 | statebit = IPT_CONNTRACK_STATE_BIT(ctinfo); | ||
51 | else | ||
52 | statebit = IPT_CONNTRACK_STATE_INVALID; | ||
53 | |||
54 | if(sinfo->flags & IPT_CONNTRACK_STATE) { | ||
55 | if (ct) { | ||
56 | if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip != | ||
57 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip) | ||
58 | statebit |= IPT_CONNTRACK_STATE_SNAT; | ||
59 | |||
60 | if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip != | ||
61 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip) | ||
62 | statebit |= IPT_CONNTRACK_STATE_DNAT; | ||
63 | } | ||
64 | |||
65 | if (FWINV((statebit & sinfo->statemask) == 0, IPT_CONNTRACK_STATE)) | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | if(sinfo->flags & IPT_CONNTRACK_PROTO) { | ||
70 | if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, IPT_CONNTRACK_PROTO)) | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) { | ||
75 | if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, IPT_CONNTRACK_ORIGSRC)) | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | if(sinfo->flags & IPT_CONNTRACK_ORIGDST) { | ||
80 | if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, IPT_CONNTRACK_ORIGDST)) | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | if(sinfo->flags & IPT_CONNTRACK_REPLSRC) { | ||
85 | if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, IPT_CONNTRACK_REPLSRC)) | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | if(sinfo->flags & IPT_CONNTRACK_REPLDST) { | ||
90 | if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, IPT_CONNTRACK_REPLDST)) | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | if(sinfo->flags & IPT_CONNTRACK_STATUS) { | ||
95 | if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, IPT_CONNTRACK_STATUS)) | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | if(sinfo->flags & IPT_CONNTRACK_EXPIRES) { | ||
100 | unsigned long expires; | ||
101 | |||
102 | if(!ct) | ||
103 | return 0; | ||
104 | |||
105 | expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0; | ||
106 | |||
107 | if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), IPT_CONNTRACK_EXPIRES)) | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | return 1; | ||
112 | } | ||
113 | |||
114 | #else /* CONFIG_IP_NF_CONNTRACK */ | ||
115 | static int | ||
116 | match(const struct sk_buff *skb, | ||
117 | const struct net_device *in, | ||
118 | const struct net_device *out, | ||
119 | const void *matchinfo, | ||
120 | int offset, | ||
121 | int *hotdrop) | ||
122 | { | ||
123 | const struct ipt_conntrack_info *sinfo = matchinfo; | ||
124 | struct nf_conn *ct; | ||
125 | enum ip_conntrack_info ctinfo; | ||
126 | unsigned int statebit; | ||
127 | |||
128 | ct = nf_ct_get((struct sk_buff *)skb, &ctinfo); | ||
129 | |||
130 | #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) | ||
131 | |||
132 | if (ct == &nf_conntrack_untracked) | ||
133 | statebit = IPT_CONNTRACK_STATE_UNTRACKED; | ||
134 | else if (ct) | ||
135 | statebit = IPT_CONNTRACK_STATE_BIT(ctinfo); | ||
136 | else | ||
137 | statebit = IPT_CONNTRACK_STATE_INVALID; | ||
138 | |||
139 | if(sinfo->flags & IPT_CONNTRACK_STATE) { | ||
140 | if (ct) { | ||
141 | if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip != | ||
142 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip) | ||
143 | statebit |= IPT_CONNTRACK_STATE_SNAT; | ||
144 | |||
145 | if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip != | ||
146 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip) | ||
147 | statebit |= IPT_CONNTRACK_STATE_DNAT; | ||
148 | } | ||
149 | |||
150 | if (FWINV((statebit & sinfo->statemask) == 0, IPT_CONNTRACK_STATE)) | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | if(sinfo->flags & IPT_CONNTRACK_PROTO) { | ||
155 | if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, IPT_CONNTRACK_PROTO)) | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) { | ||
160 | if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, IPT_CONNTRACK_ORIGSRC)) | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | if(sinfo->flags & IPT_CONNTRACK_ORIGDST) { | ||
165 | if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, IPT_CONNTRACK_ORIGDST)) | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | if(sinfo->flags & IPT_CONNTRACK_REPLSRC) { | ||
170 | if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, IPT_CONNTRACK_REPLSRC)) | ||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | if(sinfo->flags & IPT_CONNTRACK_REPLDST) { | ||
175 | if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, IPT_CONNTRACK_REPLDST)) | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | if(sinfo->flags & IPT_CONNTRACK_STATUS) { | ||
180 | if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, IPT_CONNTRACK_STATUS)) | ||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | if(sinfo->flags & IPT_CONNTRACK_EXPIRES) { | ||
185 | unsigned long expires; | ||
186 | |||
187 | if(!ct) | ||
188 | return 0; | ||
189 | |||
190 | expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0; | ||
191 | |||
192 | if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), IPT_CONNTRACK_EXPIRES)) | ||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | return 1; | ||
197 | } | ||
198 | |||
199 | #endif /* CONFIG_NF_IP_CONNTRACK */ | ||
200 | |||
201 | static int check(const char *tablename, | ||
202 | const struct ipt_ip *ip, | ||
203 | void *matchinfo, | ||
204 | unsigned int matchsize, | ||
205 | unsigned int hook_mask) | ||
206 | { | ||
207 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_conntrack_info))) | ||
208 | return 0; | ||
209 | |||
210 | return 1; | ||
211 | } | ||
212 | |||
213 | static struct ipt_match conntrack_match = { | ||
214 | .name = "conntrack", | ||
215 | .match = &match, | ||
216 | .checkentry = &check, | ||
217 | .me = THIS_MODULE, | ||
218 | }; | ||
219 | |||
220 | static int __init init(void) | ||
221 | { | ||
222 | need_ip_conntrack(); | ||
223 | return ipt_register_match(&conntrack_match); | ||
224 | } | ||
225 | |||
226 | static void __exit fini(void) | ||
227 | { | ||
228 | ipt_unregister_match(&conntrack_match); | ||
229 | } | ||
230 | |||
231 | module_init(init); | ||
232 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_dccp.c b/net/ipv4/netfilter/ipt_dccp.c deleted file mode 100644 index ad3278bba6c1..000000000000 --- a/net/ipv4/netfilter/ipt_dccp.c +++ /dev/null | |||
@@ -1,176 +0,0 @@ | |||
1 | /* | ||
2 | * iptables module for DCCP protocol header matching | ||
3 | * | ||
4 | * (C) 2005 by Harald Welte <laforge@netfilter.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/skbuff.h> | ||
13 | #include <linux/spinlock.h> | ||
14 | #include <net/ip.h> | ||
15 | #include <linux/dccp.h> | ||
16 | |||
17 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
18 | #include <linux/netfilter_ipv4/ipt_dccp.h> | ||
19 | |||
20 | #define DCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \ | ||
21 | || (!!((invflag) & (option)) ^ (cond))) | ||
22 | |||
23 | static unsigned char *dccp_optbuf; | ||
24 | static DEFINE_SPINLOCK(dccp_buflock); | ||
25 | |||
26 | static inline int | ||
27 | dccp_find_option(u_int8_t option, | ||
28 | const struct sk_buff *skb, | ||
29 | const struct dccp_hdr *dh, | ||
30 | int *hotdrop) | ||
31 | { | ||
32 | /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ | ||
33 | unsigned char *op; | ||
34 | unsigned int optoff = __dccp_hdr_len(dh); | ||
35 | unsigned int optlen = dh->dccph_doff*4 - __dccp_hdr_len(dh); | ||
36 | unsigned int i; | ||
37 | |||
38 | if (dh->dccph_doff * 4 < __dccp_hdr_len(dh)) { | ||
39 | *hotdrop = 1; | ||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | if (!optlen) | ||
44 | return 0; | ||
45 | |||
46 | spin_lock_bh(&dccp_buflock); | ||
47 | op = skb_header_pointer(skb, | ||
48 | skb->nh.iph->ihl*4 + optoff, | ||
49 | optlen, dccp_optbuf); | ||
50 | if (op == NULL) { | ||
51 | /* If we don't have the whole header, drop packet. */ | ||
52 | spin_unlock_bh(&dccp_buflock); | ||
53 | *hotdrop = 1; | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | for (i = 0; i < optlen; ) { | ||
58 | if (op[i] == option) { | ||
59 | spin_unlock_bh(&dccp_buflock); | ||
60 | return 1; | ||
61 | } | ||
62 | |||
63 | if (op[i] < 2) | ||
64 | i++; | ||
65 | else | ||
66 | i += op[i+1]?:1; | ||
67 | } | ||
68 | |||
69 | spin_unlock_bh(&dccp_buflock); | ||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | |||
74 | static inline int | ||
75 | match_types(const struct dccp_hdr *dh, u_int16_t typemask) | ||
76 | { | ||
77 | return (typemask & (1 << dh->dccph_type)); | ||
78 | } | ||
79 | |||
80 | static inline int | ||
81 | match_option(u_int8_t option, const struct sk_buff *skb, | ||
82 | const struct dccp_hdr *dh, int *hotdrop) | ||
83 | { | ||
84 | return dccp_find_option(option, skb, dh, hotdrop); | ||
85 | } | ||
86 | |||
87 | static int | ||
88 | match(const struct sk_buff *skb, | ||
89 | const struct net_device *in, | ||
90 | const struct net_device *out, | ||
91 | const void *matchinfo, | ||
92 | int offset, | ||
93 | int *hotdrop) | ||
94 | { | ||
95 | const struct ipt_dccp_info *info = | ||
96 | (const struct ipt_dccp_info *)matchinfo; | ||
97 | struct dccp_hdr _dh, *dh; | ||
98 | |||
99 | if (offset) | ||
100 | return 0; | ||
101 | |||
102 | dh = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_dh), &_dh); | ||
103 | if (dh == NULL) { | ||
104 | *hotdrop = 1; | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | return DCCHECK(((ntohs(dh->dccph_sport) >= info->spts[0]) | ||
109 | && (ntohs(dh->dccph_sport) <= info->spts[1])), | ||
110 | IPT_DCCP_SRC_PORTS, info->flags, info->invflags) | ||
111 | && DCCHECK(((ntohs(dh->dccph_dport) >= info->dpts[0]) | ||
112 | && (ntohs(dh->dccph_dport) <= info->dpts[1])), | ||
113 | IPT_DCCP_DEST_PORTS, info->flags, info->invflags) | ||
114 | && DCCHECK(match_types(dh, info->typemask), | ||
115 | IPT_DCCP_TYPE, info->flags, info->invflags) | ||
116 | && DCCHECK(match_option(info->option, skb, dh, hotdrop), | ||
117 | IPT_DCCP_OPTION, info->flags, info->invflags); | ||
118 | } | ||
119 | |||
120 | static int | ||
121 | checkentry(const char *tablename, | ||
122 | const struct ipt_ip *ip, | ||
123 | void *matchinfo, | ||
124 | unsigned int matchsize, | ||
125 | unsigned int hook_mask) | ||
126 | { | ||
127 | const struct ipt_dccp_info *info; | ||
128 | |||
129 | info = (const struct ipt_dccp_info *)matchinfo; | ||
130 | |||
131 | return ip->proto == IPPROTO_DCCP | ||
132 | && !(ip->invflags & IPT_INV_PROTO) | ||
133 | && matchsize == IPT_ALIGN(sizeof(struct ipt_dccp_info)) | ||
134 | && !(info->flags & ~IPT_DCCP_VALID_FLAGS) | ||
135 | && !(info->invflags & ~IPT_DCCP_VALID_FLAGS) | ||
136 | && !(info->invflags & ~info->flags); | ||
137 | } | ||
138 | |||
139 | static struct ipt_match dccp_match = | ||
140 | { | ||
141 | .name = "dccp", | ||
142 | .match = &match, | ||
143 | .checkentry = &checkentry, | ||
144 | .me = THIS_MODULE, | ||
145 | }; | ||
146 | |||
147 | static int __init init(void) | ||
148 | { | ||
149 | int ret; | ||
150 | |||
151 | /* doff is 8 bits, so the maximum option size is (4*256). Don't put | ||
152 | * this in BSS since DaveM is worried about locked TLB's for kernel | ||
153 | * BSS. */ | ||
154 | dccp_optbuf = kmalloc(256 * 4, GFP_KERNEL); | ||
155 | if (!dccp_optbuf) | ||
156 | return -ENOMEM; | ||
157 | ret = ipt_register_match(&dccp_match); | ||
158 | if (ret) | ||
159 | kfree(dccp_optbuf); | ||
160 | |||
161 | return ret; | ||
162 | } | ||
163 | |||
164 | static void __exit fini(void) | ||
165 | { | ||
166 | ipt_unregister_match(&dccp_match); | ||
167 | kfree(dccp_optbuf); | ||
168 | } | ||
169 | |||
170 | module_init(init); | ||
171 | module_exit(fini); | ||
172 | |||
173 | MODULE_LICENSE("GPL"); | ||
174 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | ||
175 | MODULE_DESCRIPTION("Match for DCCP protocol packets"); | ||
176 | |||
diff --git a/net/ipv4/netfilter/ipt_dscp.c b/net/ipv4/netfilter/ipt_dscp.c index 5df52a64a5d4..92063b4f8602 100644 --- a/net/ipv4/netfilter/ipt_dscp.c +++ b/net/ipv4/netfilter/ipt_dscp.c | |||
@@ -21,7 +21,7 @@ MODULE_LICENSE("GPL"); | |||
21 | 21 | ||
22 | static int match(const struct sk_buff *skb, const struct net_device *in, | 22 | static int match(const struct sk_buff *skb, const struct net_device *in, |
23 | const struct net_device *out, const void *matchinfo, | 23 | const struct net_device *out, const void *matchinfo, |
24 | int offset, int *hotdrop) | 24 | int offset, unsigned int protoff, int *hotdrop) |
25 | { | 25 | { |
26 | const struct ipt_dscp_info *info = matchinfo; | 26 | const struct ipt_dscp_info *info = matchinfo; |
27 | const struct iphdr *iph = skb->nh.iph; | 27 | const struct iphdr *iph = skb->nh.iph; |
@@ -31,7 +31,7 @@ static int match(const struct sk_buff *skb, const struct net_device *in, | |||
31 | return ((iph->tos&IPT_DSCP_MASK) == sh_dscp) ^ info->invert; | 31 | return ((iph->tos&IPT_DSCP_MASK) == sh_dscp) ^ info->invert; |
32 | } | 32 | } |
33 | 33 | ||
34 | static int checkentry(const char *tablename, const struct ipt_ip *ip, | 34 | static int checkentry(const char *tablename, const void *ip, |
35 | void *matchinfo, unsigned int matchsize, | 35 | void *matchinfo, unsigned int matchsize, |
36 | unsigned int hook_mask) | 36 | unsigned int hook_mask) |
37 | { | 37 | { |
diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c index b6f7181e89cc..e68b0c7981f0 100644 --- a/net/ipv4/netfilter/ipt_ecn.c +++ b/net/ipv4/netfilter/ipt_ecn.c | |||
@@ -67,7 +67,7 @@ static inline int match_tcp(const struct sk_buff *skb, | |||
67 | 67 | ||
68 | static int match(const struct sk_buff *skb, const struct net_device *in, | 68 | static int match(const struct sk_buff *skb, const struct net_device *in, |
69 | const struct net_device *out, const void *matchinfo, | 69 | const struct net_device *out, const void *matchinfo, |
70 | int offset, int *hotdrop) | 70 | int offset, unsigned int protoff, int *hotdrop) |
71 | { | 71 | { |
72 | const struct ipt_ecn_info *info = matchinfo; | 72 | const struct ipt_ecn_info *info = matchinfo; |
73 | 73 | ||
@@ -85,11 +85,12 @@ static int match(const struct sk_buff *skb, const struct net_device *in, | |||
85 | return 1; | 85 | return 1; |
86 | } | 86 | } |
87 | 87 | ||
88 | static int checkentry(const char *tablename, const struct ipt_ip *ip, | 88 | static int checkentry(const char *tablename, const void *ip_void, |
89 | void *matchinfo, unsigned int matchsize, | 89 | void *matchinfo, unsigned int matchsize, |
90 | unsigned int hook_mask) | 90 | unsigned int hook_mask) |
91 | { | 91 | { |
92 | const struct ipt_ecn_info *info = matchinfo; | 92 | const struct ipt_ecn_info *info = matchinfo; |
93 | const struct ipt_ip *ip = ip_void; | ||
93 | 94 | ||
94 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_ecn_info))) | 95 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_ecn_info))) |
95 | return 0; | 96 | return 0; |
diff --git a/net/ipv4/netfilter/ipt_esp.c b/net/ipv4/netfilter/ipt_esp.c index e1d0dd31e117..9de191a8162d 100644 --- a/net/ipv4/netfilter/ipt_esp.c +++ b/net/ipv4/netfilter/ipt_esp.c | |||
@@ -42,6 +42,7 @@ match(const struct sk_buff *skb, | |||
42 | const struct net_device *out, | 42 | const struct net_device *out, |
43 | const void *matchinfo, | 43 | const void *matchinfo, |
44 | int offset, | 44 | int offset, |
45 | unsigned int protoff, | ||
45 | int *hotdrop) | 46 | int *hotdrop) |
46 | { | 47 | { |
47 | struct ip_esp_hdr _esp, *eh; | 48 | struct ip_esp_hdr _esp, *eh; |
@@ -51,7 +52,7 @@ match(const struct sk_buff *skb, | |||
51 | if (offset) | 52 | if (offset) |
52 | return 0; | 53 | return 0; |
53 | 54 | ||
54 | eh = skb_header_pointer(skb, skb->nh.iph->ihl * 4, | 55 | eh = skb_header_pointer(skb, protoff, |
55 | sizeof(_esp), &_esp); | 56 | sizeof(_esp), &_esp); |
56 | if (eh == NULL) { | 57 | if (eh == NULL) { |
57 | /* We've been asked to examine this packet, and we | 58 | /* We've been asked to examine this packet, and we |
@@ -70,12 +71,13 @@ match(const struct sk_buff *skb, | |||
70 | /* Called when user tries to insert an entry of this type. */ | 71 | /* Called when user tries to insert an entry of this type. */ |
71 | static int | 72 | static int |
72 | checkentry(const char *tablename, | 73 | checkentry(const char *tablename, |
73 | const struct ipt_ip *ip, | 74 | const void *ip_void, |
74 | void *matchinfo, | 75 | void *matchinfo, |
75 | unsigned int matchinfosize, | 76 | unsigned int matchinfosize, |
76 | unsigned int hook_mask) | 77 | unsigned int hook_mask) |
77 | { | 78 | { |
78 | const struct ipt_esp *espinfo = matchinfo; | 79 | const struct ipt_esp *espinfo = matchinfo; |
80 | const struct ipt_ip *ip = ip_void; | ||
79 | 81 | ||
80 | /* Must specify proto == ESP, and no unknown invflags */ | 82 | /* Must specify proto == ESP, and no unknown invflags */ |
81 | if (ip->proto != IPPROTO_ESP || (ip->invflags & IPT_INV_PROTO)) { | 83 | if (ip->proto != IPPROTO_ESP || (ip->invflags & IPT_INV_PROTO)) { |
diff --git a/net/ipv4/netfilter/ipt_hashlimit.c b/net/ipv4/netfilter/ipt_hashlimit.c index 2dd1cccbdab9..4fe48c1bd5f3 100644 --- a/net/ipv4/netfilter/ipt_hashlimit.c +++ b/net/ipv4/netfilter/ipt_hashlimit.c | |||
@@ -429,6 +429,7 @@ hashlimit_match(const struct sk_buff *skb, | |||
429 | const struct net_device *out, | 429 | const struct net_device *out, |
430 | const void *matchinfo, | 430 | const void *matchinfo, |
431 | int offset, | 431 | int offset, |
432 | unsigned int protoff, | ||
432 | int *hotdrop) | 433 | int *hotdrop) |
433 | { | 434 | { |
434 | struct ipt_hashlimit_info *r = | 435 | struct ipt_hashlimit_info *r = |
@@ -504,7 +505,7 @@ hashlimit_match(const struct sk_buff *skb, | |||
504 | 505 | ||
505 | static int | 506 | static int |
506 | hashlimit_checkentry(const char *tablename, | 507 | hashlimit_checkentry(const char *tablename, |
507 | const struct ipt_ip *ip, | 508 | const void *inf, |
508 | void *matchinfo, | 509 | void *matchinfo, |
509 | unsigned int matchsize, | 510 | unsigned int matchsize, |
510 | unsigned int hook_mask) | 511 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_helper.c b/net/ipv4/netfilter/ipt_helper.c deleted file mode 100644 index aef649e393af..000000000000 --- a/net/ipv4/netfilter/ipt_helper.c +++ /dev/null | |||
@@ -1,168 +0,0 @@ | |||
1 | /* iptables module to match on related connections */ | ||
2 | /* | ||
3 | * (C) 2001 Martin Josefsson <gandalf@wlug.westbo.se> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * 19 Mar 2002 Harald Welte <laforge@gnumonks.org>: | ||
10 | * - Port to newnat infrastructure | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/skbuff.h> | ||
15 | #include <linux/netfilter.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) | ||
18 | #include <linux/netfilter_ipv4/ip_conntrack.h> | ||
19 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> | ||
20 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> | ||
21 | #else | ||
22 | #include <net/netfilter/nf_conntrack.h> | ||
23 | #include <net/netfilter/nf_conntrack_core.h> | ||
24 | #include <net/netfilter/nf_conntrack_helper.h> | ||
25 | #endif | ||
26 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
27 | #include <linux/netfilter_ipv4/ipt_helper.h> | ||
28 | |||
29 | MODULE_LICENSE("GPL"); | ||
30 | MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>"); | ||
31 | MODULE_DESCRIPTION("iptables helper match module"); | ||
32 | |||
33 | #if 0 | ||
34 | #define DEBUGP printk | ||
35 | #else | ||
36 | #define DEBUGP(format, args...) | ||
37 | #endif | ||
38 | |||
39 | #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) | ||
40 | static int | ||
41 | match(const struct sk_buff *skb, | ||
42 | const struct net_device *in, | ||
43 | const struct net_device *out, | ||
44 | const void *matchinfo, | ||
45 | int offset, | ||
46 | int *hotdrop) | ||
47 | { | ||
48 | const struct ipt_helper_info *info = matchinfo; | ||
49 | struct ip_conntrack *ct; | ||
50 | enum ip_conntrack_info ctinfo; | ||
51 | int ret = info->invert; | ||
52 | |||
53 | ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); | ||
54 | if (!ct) { | ||
55 | DEBUGP("ipt_helper: Eek! invalid conntrack?\n"); | ||
56 | return ret; | ||
57 | } | ||
58 | |||
59 | if (!ct->master) { | ||
60 | DEBUGP("ipt_helper: conntrack %p has no master\n", ct); | ||
61 | return ret; | ||
62 | } | ||
63 | |||
64 | read_lock_bh(&ip_conntrack_lock); | ||
65 | if (!ct->master->helper) { | ||
66 | DEBUGP("ipt_helper: master ct %p has no helper\n", | ||
67 | exp->expectant); | ||
68 | goto out_unlock; | ||
69 | } | ||
70 | |||
71 | DEBUGP("master's name = %s , info->name = %s\n", | ||
72 | ct->master->helper->name, info->name); | ||
73 | |||
74 | if (info->name[0] == '\0') | ||
75 | ret ^= 1; | ||
76 | else | ||
77 | ret ^= !strncmp(ct->master->helper->name, info->name, | ||
78 | strlen(ct->master->helper->name)); | ||
79 | out_unlock: | ||
80 | read_unlock_bh(&ip_conntrack_lock); | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | #else /* CONFIG_IP_NF_CONNTRACK */ | ||
85 | |||
86 | static int | ||
87 | match(const struct sk_buff *skb, | ||
88 | const struct net_device *in, | ||
89 | const struct net_device *out, | ||
90 | const void *matchinfo, | ||
91 | int offset, | ||
92 | int *hotdrop) | ||
93 | { | ||
94 | const struct ipt_helper_info *info = matchinfo; | ||
95 | struct nf_conn *ct; | ||
96 | enum ip_conntrack_info ctinfo; | ||
97 | int ret = info->invert; | ||
98 | |||
99 | ct = nf_ct_get((struct sk_buff *)skb, &ctinfo); | ||
100 | if (!ct) { | ||
101 | DEBUGP("ipt_helper: Eek! invalid conntrack?\n"); | ||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | if (!ct->master) { | ||
106 | DEBUGP("ipt_helper: conntrack %p has no master\n", ct); | ||
107 | return ret; | ||
108 | } | ||
109 | |||
110 | read_lock_bh(&nf_conntrack_lock); | ||
111 | if (!ct->master->helper) { | ||
112 | DEBUGP("ipt_helper: master ct %p has no helper\n", | ||
113 | exp->expectant); | ||
114 | goto out_unlock; | ||
115 | } | ||
116 | |||
117 | DEBUGP("master's name = %s , info->name = %s\n", | ||
118 | ct->master->helper->name, info->name); | ||
119 | |||
120 | if (info->name[0] == '\0') | ||
121 | ret ^= 1; | ||
122 | else | ||
123 | ret ^= !strncmp(ct->master->helper->name, info->name, | ||
124 | strlen(ct->master->helper->name)); | ||
125 | out_unlock: | ||
126 | read_unlock_bh(&nf_conntrack_lock); | ||
127 | return ret; | ||
128 | } | ||
129 | #endif | ||
130 | |||
131 | static int check(const char *tablename, | ||
132 | const struct ipt_ip *ip, | ||
133 | void *matchinfo, | ||
134 | unsigned int matchsize, | ||
135 | unsigned int hook_mask) | ||
136 | { | ||
137 | struct ipt_helper_info *info = matchinfo; | ||
138 | |||
139 | info->name[29] = '\0'; | ||
140 | |||
141 | /* verify size */ | ||
142 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_helper_info))) | ||
143 | return 0; | ||
144 | |||
145 | return 1; | ||
146 | } | ||
147 | |||
148 | static struct ipt_match helper_match = { | ||
149 | .name = "helper", | ||
150 | .match = &match, | ||
151 | .checkentry = &check, | ||
152 | .me = THIS_MODULE, | ||
153 | }; | ||
154 | |||
155 | static int __init init(void) | ||
156 | { | ||
157 | need_ip_conntrack(); | ||
158 | return ipt_register_match(&helper_match); | ||
159 | } | ||
160 | |||
161 | static void __exit fini(void) | ||
162 | { | ||
163 | ipt_unregister_match(&helper_match); | ||
164 | } | ||
165 | |||
166 | module_init(init); | ||
167 | module_exit(fini); | ||
168 | |||
diff --git a/net/ipv4/netfilter/ipt_iprange.c b/net/ipv4/netfilter/ipt_iprange.c index b835b7b2e560..13fb16fb7892 100644 --- a/net/ipv4/netfilter/ipt_iprange.c +++ b/net/ipv4/netfilter/ipt_iprange.c | |||
@@ -28,7 +28,7 @@ match(const struct sk_buff *skb, | |||
28 | const struct net_device *in, | 28 | const struct net_device *in, |
29 | const struct net_device *out, | 29 | const struct net_device *out, |
30 | const void *matchinfo, | 30 | const void *matchinfo, |
31 | int offset, int *hotdrop) | 31 | int offset, unsigned int protoff, int *hotdrop) |
32 | { | 32 | { |
33 | const struct ipt_iprange_info *info = matchinfo; | 33 | const struct ipt_iprange_info *info = matchinfo; |
34 | const struct iphdr *iph = skb->nh.iph; | 34 | const struct iphdr *iph = skb->nh.iph; |
@@ -63,7 +63,7 @@ match(const struct sk_buff *skb, | |||
63 | } | 63 | } |
64 | 64 | ||
65 | static int check(const char *tablename, | 65 | static int check(const char *tablename, |
66 | const struct ipt_ip *ip, | 66 | const void *inf, |
67 | void *matchinfo, | 67 | void *matchinfo, |
68 | unsigned int matchsize, | 68 | unsigned int matchsize, |
69 | unsigned int hook_mask) | 69 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_length.c b/net/ipv4/netfilter/ipt_length.c deleted file mode 100644 index 4eabcfbda9d1..000000000000 --- a/net/ipv4/netfilter/ipt_length.c +++ /dev/null | |||
@@ -1,64 +0,0 @@ | |||
1 | /* Kernel module to match packet length. */ | ||
2 | /* (C) 1999-2001 James Morris <jmorros@intercode.com.au> | ||
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/module.h> | ||
10 | #include <linux/skbuff.h> | ||
11 | |||
12 | #include <linux/netfilter_ipv4/ipt_length.h> | ||
13 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
14 | |||
15 | MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); | ||
16 | MODULE_DESCRIPTION("IP tables packet length matching module"); | ||
17 | MODULE_LICENSE("GPL"); | ||
18 | |||
19 | static int | ||
20 | match(const struct sk_buff *skb, | ||
21 | const struct net_device *in, | ||
22 | const struct net_device *out, | ||
23 | const void *matchinfo, | ||
24 | int offset, | ||
25 | int *hotdrop) | ||
26 | { | ||
27 | const struct ipt_length_info *info = matchinfo; | ||
28 | u_int16_t pktlen = ntohs(skb->nh.iph->tot_len); | ||
29 | |||
30 | return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; | ||
31 | } | ||
32 | |||
33 | static int | ||
34 | checkentry(const char *tablename, | ||
35 | const struct ipt_ip *ip, | ||
36 | void *matchinfo, | ||
37 | unsigned int matchsize, | ||
38 | unsigned int hook_mask) | ||
39 | { | ||
40 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_length_info))) | ||
41 | return 0; | ||
42 | |||
43 | return 1; | ||
44 | } | ||
45 | |||
46 | static struct ipt_match length_match = { | ||
47 | .name = "length", | ||
48 | .match = &match, | ||
49 | .checkentry = &checkentry, | ||
50 | .me = THIS_MODULE, | ||
51 | }; | ||
52 | |||
53 | static int __init init(void) | ||
54 | { | ||
55 | return ipt_register_match(&length_match); | ||
56 | } | ||
57 | |||
58 | static void __exit fini(void) | ||
59 | { | ||
60 | ipt_unregister_match(&length_match); | ||
61 | } | ||
62 | |||
63 | module_init(init); | ||
64 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_limit.c b/net/ipv4/netfilter/ipt_limit.c deleted file mode 100644 index 0c24dcc703a5..000000000000 --- a/net/ipv4/netfilter/ipt_limit.c +++ /dev/null | |||
@@ -1,157 +0,0 @@ | |||
1 | /* Kernel module to control the rate | ||
2 | * | ||
3 | * 2 September 1999: Changed from the target RATE to the match | ||
4 | * `limit', removed logging. Did I mention that | ||
5 | * Alexey is a fucking genius? | ||
6 | * Rusty Russell (rusty@rustcorp.com.au). */ | ||
7 | |||
8 | /* (C) 1999 Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr> | ||
9 | * (C) 1999 Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/skbuff.h> | ||
18 | #include <linux/spinlock.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | |||
21 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
22 | #include <linux/netfilter_ipv4/ipt_limit.h> | ||
23 | |||
24 | MODULE_LICENSE("GPL"); | ||
25 | MODULE_AUTHOR("Herve Eychenne <rv@wallfire.org>"); | ||
26 | MODULE_DESCRIPTION("iptables rate limit match"); | ||
27 | |||
28 | /* The algorithm used is the Simple Token Bucket Filter (TBF) | ||
29 | * see net/sched/sch_tbf.c in the linux source tree | ||
30 | */ | ||
31 | |||
32 | static DEFINE_SPINLOCK(limit_lock); | ||
33 | |||
34 | /* Rusty: This is my (non-mathematically-inclined) understanding of | ||
35 | this algorithm. The `average rate' in jiffies becomes your initial | ||
36 | amount of credit `credit' and the most credit you can ever have | ||
37 | `credit_cap'. The `peak rate' becomes the cost of passing the | ||
38 | test, `cost'. | ||
39 | |||
40 | `prev' tracks the last packet hit: you gain one credit per jiffy. | ||
41 | If you get credit balance more than this, the extra credit is | ||
42 | discarded. Every time the match passes, you lose `cost' credits; | ||
43 | if you don't have that many, the test fails. | ||
44 | |||
45 | See Alexey's formal explanation in net/sched/sch_tbf.c. | ||
46 | |||
47 | To get the maxmum range, we multiply by this factor (ie. you get N | ||
48 | credits per jiffy). We want to allow a rate as low as 1 per day | ||
49 | (slowest userspace tool allows), which means | ||
50 | CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32. ie. */ | ||
51 | #define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24)) | ||
52 | |||
53 | /* Repeated shift and or gives us all 1s, final shift and add 1 gives | ||
54 | * us the power of 2 below the theoretical max, so GCC simply does a | ||
55 | * shift. */ | ||
56 | #define _POW2_BELOW2(x) ((x)|((x)>>1)) | ||
57 | #define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2)) | ||
58 | #define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4)) | ||
59 | #define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8)) | ||
60 | #define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16)) | ||
61 | #define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1) | ||
62 | |||
63 | #define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ) | ||
64 | |||
65 | static int | ||
66 | ipt_limit_match(const struct sk_buff *skb, | ||
67 | const struct net_device *in, | ||
68 | const struct net_device *out, | ||
69 | const void *matchinfo, | ||
70 | int offset, | ||
71 | int *hotdrop) | ||
72 | { | ||
73 | struct ipt_rateinfo *r = ((struct ipt_rateinfo *)matchinfo)->master; | ||
74 | unsigned long now = jiffies; | ||
75 | |||
76 | spin_lock_bh(&limit_lock); | ||
77 | r->credit += (now - xchg(&r->prev, now)) * CREDITS_PER_JIFFY; | ||
78 | if (r->credit > r->credit_cap) | ||
79 | r->credit = r->credit_cap; | ||
80 | |||
81 | if (r->credit >= r->cost) { | ||
82 | /* We're not limited. */ | ||
83 | r->credit -= r->cost; | ||
84 | spin_unlock_bh(&limit_lock); | ||
85 | return 1; | ||
86 | } | ||
87 | |||
88 | spin_unlock_bh(&limit_lock); | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | /* Precision saver. */ | ||
93 | static u_int32_t | ||
94 | user2credits(u_int32_t user) | ||
95 | { | ||
96 | /* If multiplying would overflow... */ | ||
97 | if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) | ||
98 | /* Divide first. */ | ||
99 | return (user / IPT_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY; | ||
100 | |||
101 | return (user * HZ * CREDITS_PER_JIFFY) / IPT_LIMIT_SCALE; | ||
102 | } | ||
103 | |||
104 | static int | ||
105 | ipt_limit_checkentry(const char *tablename, | ||
106 | const struct ipt_ip *ip, | ||
107 | void *matchinfo, | ||
108 | unsigned int matchsize, | ||
109 | unsigned int hook_mask) | ||
110 | { | ||
111 | struct ipt_rateinfo *r = matchinfo; | ||
112 | |||
113 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_rateinfo))) | ||
114 | return 0; | ||
115 | |||
116 | /* Check for overflow. */ | ||
117 | if (r->burst == 0 | ||
118 | || user2credits(r->avg * r->burst) < user2credits(r->avg)) { | ||
119 | printk("Overflow in ipt_limit, try lower: %u/%u\n", | ||
120 | r->avg, r->burst); | ||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | /* User avg in seconds * IPT_LIMIT_SCALE: convert to jiffies * | ||
125 | 128. */ | ||
126 | r->prev = jiffies; | ||
127 | r->credit = user2credits(r->avg * r->burst); /* Credits full. */ | ||
128 | r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */ | ||
129 | r->cost = user2credits(r->avg); | ||
130 | |||
131 | /* For SMP, we only want to use one set of counters. */ | ||
132 | r->master = r; | ||
133 | |||
134 | return 1; | ||
135 | } | ||
136 | |||
137 | static struct ipt_match ipt_limit_reg = { | ||
138 | .name = "limit", | ||
139 | .match = ipt_limit_match, | ||
140 | .checkentry = ipt_limit_checkentry, | ||
141 | .me = THIS_MODULE, | ||
142 | }; | ||
143 | |||
144 | static int __init init(void) | ||
145 | { | ||
146 | if (ipt_register_match(&ipt_limit_reg)) | ||
147 | return -EINVAL; | ||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static void __exit fini(void) | ||
152 | { | ||
153 | ipt_unregister_match(&ipt_limit_reg); | ||
154 | } | ||
155 | |||
156 | module_init(init); | ||
157 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_mac.c b/net/ipv4/netfilter/ipt_mac.c deleted file mode 100644 index 1b9bb4559f80..000000000000 --- a/net/ipv4/netfilter/ipt_mac.c +++ /dev/null | |||
@@ -1,80 +0,0 @@ | |||
1 | /* Kernel module to match MAC address parameters. */ | ||
2 | |||
3 | /* (C) 1999-2001 Paul `Rusty' Russell | ||
4 | * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/skbuff.h> | ||
13 | #include <linux/if_ether.h> | ||
14 | #include <linux/etherdevice.h> | ||
15 | |||
16 | #include <linux/netfilter_ipv4/ipt_mac.h> | ||
17 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
18 | |||
19 | MODULE_LICENSE("GPL"); | ||
20 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); | ||
21 | MODULE_DESCRIPTION("iptables mac matching module"); | ||
22 | |||
23 | static int | ||
24 | match(const struct sk_buff *skb, | ||
25 | const struct net_device *in, | ||
26 | const struct net_device *out, | ||
27 | const void *matchinfo, | ||
28 | int offset, | ||
29 | int *hotdrop) | ||
30 | { | ||
31 | const struct ipt_mac_info *info = matchinfo; | ||
32 | |||
33 | /* Is mac pointer valid? */ | ||
34 | return (skb->mac.raw >= skb->head | ||
35 | && (skb->mac.raw + ETH_HLEN) <= skb->data | ||
36 | /* If so, compare... */ | ||
37 | && ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr)) | ||
38 | ^ info->invert)); | ||
39 | } | ||
40 | |||
41 | static int | ||
42 | ipt_mac_checkentry(const char *tablename, | ||
43 | const struct ipt_ip *ip, | ||
44 | void *matchinfo, | ||
45 | unsigned int matchsize, | ||
46 | unsigned int hook_mask) | ||
47 | { | ||
48 | /* FORWARD isn't always valid, but it's nice to be able to do --RR */ | ||
49 | if (hook_mask | ||
50 | & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | ||
51 | | (1 << NF_IP_FORWARD))) { | ||
52 | printk("ipt_mac: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n"); | ||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_mac_info))) | ||
57 | return 0; | ||
58 | |||
59 | return 1; | ||
60 | } | ||
61 | |||
62 | static struct ipt_match mac_match = { | ||
63 | .name = "mac", | ||
64 | .match = &match, | ||
65 | .checkentry = &ipt_mac_checkentry, | ||
66 | .me = THIS_MODULE, | ||
67 | }; | ||
68 | |||
69 | static int __init init(void) | ||
70 | { | ||
71 | return ipt_register_match(&mac_match); | ||
72 | } | ||
73 | |||
74 | static void __exit fini(void) | ||
75 | { | ||
76 | ipt_unregister_match(&mac_match); | ||
77 | } | ||
78 | |||
79 | module_init(init); | ||
80 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_mark.c b/net/ipv4/netfilter/ipt_mark.c deleted file mode 100644 index 00bef6cdd3f8..000000000000 --- a/net/ipv4/netfilter/ipt_mark.c +++ /dev/null | |||
@@ -1,71 +0,0 @@ | |||
1 | /* Kernel module to match NFMARK values. */ | ||
2 | |||
3 | /* (C) 1999-2001 Marc Boucher <marc@mbsi.ca> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/skbuff.h> | ||
12 | |||
13 | #include <linux/netfilter_ipv4/ipt_mark.h> | ||
14 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
15 | |||
16 | MODULE_LICENSE("GPL"); | ||
17 | MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); | ||
18 | MODULE_DESCRIPTION("iptables mark matching module"); | ||
19 | |||
20 | static int | ||
21 | match(const struct sk_buff *skb, | ||
22 | const struct net_device *in, | ||
23 | const struct net_device *out, | ||
24 | const void *matchinfo, | ||
25 | int offset, | ||
26 | int *hotdrop) | ||
27 | { | ||
28 | const struct ipt_mark_info *info = matchinfo; | ||
29 | |||
30 | return ((skb->nfmark & info->mask) == info->mark) ^ info->invert; | ||
31 | } | ||
32 | |||
33 | static int | ||
34 | checkentry(const char *tablename, | ||
35 | const struct ipt_ip *ip, | ||
36 | void *matchinfo, | ||
37 | unsigned int matchsize, | ||
38 | unsigned int hook_mask) | ||
39 | { | ||
40 | struct ipt_mark_info *minfo = (struct ipt_mark_info *) matchinfo; | ||
41 | |||
42 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_mark_info))) | ||
43 | return 0; | ||
44 | |||
45 | if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) { | ||
46 | printk(KERN_WARNING "mark: only supports 32bit mark\n"); | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | return 1; | ||
51 | } | ||
52 | |||
53 | static struct ipt_match mark_match = { | ||
54 | .name = "mark", | ||
55 | .match = &match, | ||
56 | .checkentry = &checkentry, | ||
57 | .me = THIS_MODULE, | ||
58 | }; | ||
59 | |||
60 | static int __init init(void) | ||
61 | { | ||
62 | return ipt_register_match(&mark_match); | ||
63 | } | ||
64 | |||
65 | static void __exit fini(void) | ||
66 | { | ||
67 | ipt_unregister_match(&mark_match); | ||
68 | } | ||
69 | |||
70 | module_init(init); | ||
71 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_multiport.c b/net/ipv4/netfilter/ipt_multiport.c index 99e8188162e2..2d52326553f1 100644 --- a/net/ipv4/netfilter/ipt_multiport.c +++ b/net/ipv4/netfilter/ipt_multiport.c | |||
@@ -97,6 +97,7 @@ match(const struct sk_buff *skb, | |||
97 | const struct net_device *out, | 97 | const struct net_device *out, |
98 | const void *matchinfo, | 98 | const void *matchinfo, |
99 | int offset, | 99 | int offset, |
100 | unsigned int protoff, | ||
100 | int *hotdrop) | 101 | int *hotdrop) |
101 | { | 102 | { |
102 | u16 _ports[2], *pptr; | 103 | u16 _ports[2], *pptr; |
@@ -105,7 +106,7 @@ match(const struct sk_buff *skb, | |||
105 | if (offset) | 106 | if (offset) |
106 | return 0; | 107 | return 0; |
107 | 108 | ||
108 | pptr = skb_header_pointer(skb, skb->nh.iph->ihl * 4, | 109 | pptr = skb_header_pointer(skb, protoff, |
109 | sizeof(_ports), _ports); | 110 | sizeof(_ports), _ports); |
110 | if (pptr == NULL) { | 111 | if (pptr == NULL) { |
111 | /* We've been asked to examine this packet, and we | 112 | /* We've been asked to examine this packet, and we |
@@ -128,6 +129,7 @@ match_v1(const struct sk_buff *skb, | |||
128 | const struct net_device *out, | 129 | const struct net_device *out, |
129 | const void *matchinfo, | 130 | const void *matchinfo, |
130 | int offset, | 131 | int offset, |
132 | unsigned int protoff, | ||
131 | int *hotdrop) | 133 | int *hotdrop) |
132 | { | 134 | { |
133 | u16 _ports[2], *pptr; | 135 | u16 _ports[2], *pptr; |
@@ -136,7 +138,7 @@ match_v1(const struct sk_buff *skb, | |||
136 | if (offset) | 138 | if (offset) |
137 | return 0; | 139 | return 0; |
138 | 140 | ||
139 | pptr = skb_header_pointer(skb, skb->nh.iph->ihl * 4, | 141 | pptr = skb_header_pointer(skb, protoff, |
140 | sizeof(_ports), _ports); | 142 | sizeof(_ports), _ports); |
141 | if (pptr == NULL) { | 143 | if (pptr == NULL) { |
142 | /* We've been asked to examine this packet, and we | 144 | /* We've been asked to examine this packet, and we |
@@ -154,7 +156,7 @@ match_v1(const struct sk_buff *skb, | |||
154 | /* Called when user tries to insert an entry of this type. */ | 156 | /* Called when user tries to insert an entry of this type. */ |
155 | static int | 157 | static int |
156 | checkentry(const char *tablename, | 158 | checkentry(const char *tablename, |
157 | const struct ipt_ip *ip, | 159 | const void *ip, |
158 | void *matchinfo, | 160 | void *matchinfo, |
159 | unsigned int matchsize, | 161 | unsigned int matchsize, |
160 | unsigned int hook_mask) | 162 | unsigned int hook_mask) |
@@ -164,7 +166,7 @@ checkentry(const char *tablename, | |||
164 | 166 | ||
165 | static int | 167 | static int |
166 | checkentry_v1(const char *tablename, | 168 | checkentry_v1(const char *tablename, |
167 | const struct ipt_ip *ip, | 169 | const void *ip, |
168 | void *matchinfo, | 170 | void *matchinfo, |
169 | unsigned int matchsize, | 171 | unsigned int matchsize, |
170 | unsigned int hook_mask) | 172 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c index 0cee2862ed85..4843d0c9734f 100644 --- a/net/ipv4/netfilter/ipt_owner.c +++ b/net/ipv4/netfilter/ipt_owner.c | |||
@@ -27,6 +27,7 @@ match(const struct sk_buff *skb, | |||
27 | const struct net_device *out, | 27 | const struct net_device *out, |
28 | const void *matchinfo, | 28 | const void *matchinfo, |
29 | int offset, | 29 | int offset, |
30 | unsigned int protoff, | ||
30 | int *hotdrop) | 31 | int *hotdrop) |
31 | { | 32 | { |
32 | const struct ipt_owner_info *info = matchinfo; | 33 | const struct ipt_owner_info *info = matchinfo; |
@@ -51,7 +52,7 @@ match(const struct sk_buff *skb, | |||
51 | 52 | ||
52 | static int | 53 | static int |
53 | checkentry(const char *tablename, | 54 | checkentry(const char *tablename, |
54 | const struct ipt_ip *ip, | 55 | const void *ip, |
55 | void *matchinfo, | 56 | void *matchinfo, |
56 | unsigned int matchsize, | 57 | unsigned int matchsize, |
57 | unsigned int hook_mask) | 58 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_physdev.c b/net/ipv4/netfilter/ipt_physdev.c deleted file mode 100644 index 03f554857a4d..000000000000 --- a/net/ipv4/netfilter/ipt_physdev.c +++ /dev/null | |||
@@ -1,135 +0,0 @@ | |||
1 | /* Kernel module to match the bridge port in and | ||
2 | * out device for IP packets coming into contact with a bridge. */ | ||
3 | |||
4 | /* (C) 2001-2003 Bart De Schuymer <bdschuym@pandora.be> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/netdevice.h> | ||
13 | #include <linux/skbuff.h> | ||
14 | #include <linux/netfilter_ipv4/ipt_physdev.h> | ||
15 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
16 | #include <linux/netfilter_bridge.h> | ||
17 | #define MATCH 1 | ||
18 | #define NOMATCH 0 | ||
19 | |||
20 | MODULE_LICENSE("GPL"); | ||
21 | MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); | ||
22 | MODULE_DESCRIPTION("iptables bridge physical device match module"); | ||
23 | |||
24 | static int | ||
25 | match(const struct sk_buff *skb, | ||
26 | const struct net_device *in, | ||
27 | const struct net_device *out, | ||
28 | const void *matchinfo, | ||
29 | int offset, | ||
30 | int *hotdrop) | ||
31 | { | ||
32 | int i; | ||
33 | static const char nulldevname[IFNAMSIZ]; | ||
34 | const struct ipt_physdev_info *info = matchinfo; | ||
35 | unsigned int ret; | ||
36 | const char *indev, *outdev; | ||
37 | struct nf_bridge_info *nf_bridge; | ||
38 | |||
39 | /* Not a bridged IP packet or no info available yet: | ||
40 | * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if | ||
41 | * the destination device will be a bridge. */ | ||
42 | if (!(nf_bridge = skb->nf_bridge)) { | ||
43 | /* Return MATCH if the invert flags of the used options are on */ | ||
44 | if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) && | ||
45 | !(info->invert & IPT_PHYSDEV_OP_BRIDGED)) | ||
46 | return NOMATCH; | ||
47 | if ((info->bitmask & IPT_PHYSDEV_OP_ISIN) && | ||
48 | !(info->invert & IPT_PHYSDEV_OP_ISIN)) | ||
49 | return NOMATCH; | ||
50 | if ((info->bitmask & IPT_PHYSDEV_OP_ISOUT) && | ||
51 | !(info->invert & IPT_PHYSDEV_OP_ISOUT)) | ||
52 | return NOMATCH; | ||
53 | if ((info->bitmask & IPT_PHYSDEV_OP_IN) && | ||
54 | !(info->invert & IPT_PHYSDEV_OP_IN)) | ||
55 | return NOMATCH; | ||
56 | if ((info->bitmask & IPT_PHYSDEV_OP_OUT) && | ||
57 | !(info->invert & IPT_PHYSDEV_OP_OUT)) | ||
58 | return NOMATCH; | ||
59 | return MATCH; | ||
60 | } | ||
61 | |||
62 | /* This only makes sense in the FORWARD and POSTROUTING chains */ | ||
63 | if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) && | ||
64 | (!!(nf_bridge->mask & BRNF_BRIDGED) ^ | ||
65 | !(info->invert & IPT_PHYSDEV_OP_BRIDGED))) | ||
66 | return NOMATCH; | ||
67 | |||
68 | if ((info->bitmask & IPT_PHYSDEV_OP_ISIN && | ||
69 | (!nf_bridge->physindev ^ !!(info->invert & IPT_PHYSDEV_OP_ISIN))) || | ||
70 | (info->bitmask & IPT_PHYSDEV_OP_ISOUT && | ||
71 | (!nf_bridge->physoutdev ^ !!(info->invert & IPT_PHYSDEV_OP_ISOUT)))) | ||
72 | return NOMATCH; | ||
73 | |||
74 | if (!(info->bitmask & IPT_PHYSDEV_OP_IN)) | ||
75 | goto match_outdev; | ||
76 | indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; | ||
77 | for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { | ||
78 | ret |= (((const unsigned int *)indev)[i] | ||
79 | ^ ((const unsigned int *)info->physindev)[i]) | ||
80 | & ((const unsigned int *)info->in_mask)[i]; | ||
81 | } | ||
82 | |||
83 | if ((ret == 0) ^ !(info->invert & IPT_PHYSDEV_OP_IN)) | ||
84 | return NOMATCH; | ||
85 | |||
86 | match_outdev: | ||
87 | if (!(info->bitmask & IPT_PHYSDEV_OP_OUT)) | ||
88 | return MATCH; | ||
89 | outdev = nf_bridge->physoutdev ? | ||
90 | nf_bridge->physoutdev->name : nulldevname; | ||
91 | for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { | ||
92 | ret |= (((const unsigned int *)outdev)[i] | ||
93 | ^ ((const unsigned int *)info->physoutdev)[i]) | ||
94 | & ((const unsigned int *)info->out_mask)[i]; | ||
95 | } | ||
96 | |||
97 | return (ret != 0) ^ !(info->invert & IPT_PHYSDEV_OP_OUT); | ||
98 | } | ||
99 | |||
100 | static int | ||
101 | checkentry(const char *tablename, | ||
102 | const struct ipt_ip *ip, | ||
103 | void *matchinfo, | ||
104 | unsigned int matchsize, | ||
105 | unsigned int hook_mask) | ||
106 | { | ||
107 | const struct ipt_physdev_info *info = matchinfo; | ||
108 | |||
109 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_physdev_info))) | ||
110 | return 0; | ||
111 | if (!(info->bitmask & IPT_PHYSDEV_OP_MASK) || | ||
112 | info->bitmask & ~IPT_PHYSDEV_OP_MASK) | ||
113 | return 0; | ||
114 | return 1; | ||
115 | } | ||
116 | |||
117 | static struct ipt_match physdev_match = { | ||
118 | .name = "physdev", | ||
119 | .match = &match, | ||
120 | .checkentry = &checkentry, | ||
121 | .me = THIS_MODULE, | ||
122 | }; | ||
123 | |||
124 | static int __init init(void) | ||
125 | { | ||
126 | return ipt_register_match(&physdev_match); | ||
127 | } | ||
128 | |||
129 | static void __exit fini(void) | ||
130 | { | ||
131 | ipt_unregister_match(&physdev_match); | ||
132 | } | ||
133 | |||
134 | module_init(init); | ||
135 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_pkttype.c b/net/ipv4/netfilter/ipt_pkttype.c deleted file mode 100644 index 8ddb1dc5e5ae..000000000000 --- a/net/ipv4/netfilter/ipt_pkttype.c +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
1 | /* (C) 1999-2001 Michal Ludvig <michal@logix.cz> | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or modify | ||
4 | * it under the terms of the GNU General Public License version 2 as | ||
5 | * published by the Free Software Foundation. | ||
6 | */ | ||
7 | |||
8 | #include <linux/module.h> | ||
9 | #include <linux/skbuff.h> | ||
10 | #include <linux/if_ether.h> | ||
11 | #include <linux/if_packet.h> | ||
12 | |||
13 | #include <linux/netfilter_ipv4/ipt_pkttype.h> | ||
14 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
15 | |||
16 | MODULE_LICENSE("GPL"); | ||
17 | MODULE_AUTHOR("Michal Ludvig <michal@logix.cz>"); | ||
18 | MODULE_DESCRIPTION("IP tables match to match on linklayer packet type"); | ||
19 | |||
20 | static int match(const struct sk_buff *skb, | ||
21 | const struct net_device *in, | ||
22 | const struct net_device *out, | ||
23 | const void *matchinfo, | ||
24 | int offset, | ||
25 | int *hotdrop) | ||
26 | { | ||
27 | const struct ipt_pkttype_info *info = matchinfo; | ||
28 | |||
29 | return (skb->pkt_type == info->pkttype) ^ info->invert; | ||
30 | } | ||
31 | |||
32 | static int checkentry(const char *tablename, | ||
33 | const struct ipt_ip *ip, | ||
34 | void *matchinfo, | ||
35 | unsigned int matchsize, | ||
36 | unsigned int hook_mask) | ||
37 | { | ||
38 | /* | ||
39 | if (hook_mask | ||
40 | & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | ||
41 | | (1 << NF_IP_FORWARD))) { | ||
42 | printk("ipt_pkttype: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n"); | ||
43 | return 0; | ||
44 | } | ||
45 | */ | ||
46 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_pkttype_info))) | ||
47 | return 0; | ||
48 | |||
49 | return 1; | ||
50 | } | ||
51 | |||
52 | static struct ipt_match pkttype_match = { | ||
53 | .name = "pkttype", | ||
54 | .match = &match, | ||
55 | .checkentry = &checkentry, | ||
56 | .me = THIS_MODULE, | ||
57 | }; | ||
58 | |||
59 | static int __init init(void) | ||
60 | { | ||
61 | return ipt_register_match(&pkttype_match); | ||
62 | } | ||
63 | |||
64 | static void __exit fini(void) | ||
65 | { | ||
66 | ipt_unregister_match(&pkttype_match); | ||
67 | } | ||
68 | |||
69 | module_init(init); | ||
70 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_realm.c b/net/ipv4/netfilter/ipt_realm.c deleted file mode 100644 index 54a6897ebaa6..000000000000 --- a/net/ipv4/netfilter/ipt_realm.c +++ /dev/null | |||
@@ -1,76 +0,0 @@ | |||
1 | /* IP tables module for matching the routing realm | ||
2 | * | ||
3 | * $Id: ipt_realm.c,v 1.3 2004/03/05 13:25:40 laforge Exp $ | ||
4 | * | ||
5 | * (C) 2003 by Sampsa Ranta <sampsa@netsonic.fi> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/skbuff.h> | ||
14 | #include <linux/netdevice.h> | ||
15 | #include <net/route.h> | ||
16 | |||
17 | #include <linux/netfilter_ipv4/ipt_realm.h> | ||
18 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
19 | |||
20 | MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>"); | ||
21 | MODULE_LICENSE("GPL"); | ||
22 | MODULE_DESCRIPTION("iptables realm match"); | ||
23 | |||
24 | static int | ||
25 | match(const struct sk_buff *skb, | ||
26 | const struct net_device *in, | ||
27 | const struct net_device *out, | ||
28 | const void *matchinfo, | ||
29 | int offset, | ||
30 | int *hotdrop) | ||
31 | { | ||
32 | const struct ipt_realm_info *info = matchinfo; | ||
33 | struct dst_entry *dst = skb->dst; | ||
34 | |||
35 | return (info->id == (dst->tclassid & info->mask)) ^ info->invert; | ||
36 | } | ||
37 | |||
38 | static int check(const char *tablename, | ||
39 | const struct ipt_ip *ip, | ||
40 | void *matchinfo, | ||
41 | unsigned int matchsize, | ||
42 | unsigned int hook_mask) | ||
43 | { | ||
44 | if (hook_mask | ||
45 | & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) | | ||
46 | (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN))) { | ||
47 | printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, " | ||
48 | "LOCAL_IN or FORWARD.\n"); | ||
49 | return 0; | ||
50 | } | ||
51 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info))) { | ||
52 | printk("ipt_realm: invalid matchsize.\n"); | ||
53 | return 0; | ||
54 | } | ||
55 | return 1; | ||
56 | } | ||
57 | |||
58 | static struct ipt_match realm_match = { | ||
59 | .name = "realm", | ||
60 | .match = match, | ||
61 | .checkentry = check, | ||
62 | .me = THIS_MODULE | ||
63 | }; | ||
64 | |||
65 | static int __init init(void) | ||
66 | { | ||
67 | return ipt_register_match(&realm_match); | ||
68 | } | ||
69 | |||
70 | static void __exit fini(void) | ||
71 | { | ||
72 | ipt_unregister_match(&realm_match); | ||
73 | } | ||
74 | |||
75 | module_init(init); | ||
76 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c index 5ddccb18c65e..44611d6d14f5 100644 --- a/net/ipv4/netfilter/ipt_recent.c +++ b/net/ipv4/netfilter/ipt_recent.c | |||
@@ -104,6 +104,7 @@ match(const struct sk_buff *skb, | |||
104 | const struct net_device *out, | 104 | const struct net_device *out, |
105 | const void *matchinfo, | 105 | const void *matchinfo, |
106 | int offset, | 106 | int offset, |
107 | unsigned int protoff, | ||
107 | int *hotdrop); | 108 | int *hotdrop); |
108 | 109 | ||
109 | /* Function to hash a given address into the hash table of table_size size */ | 110 | /* Function to hash a given address into the hash table of table_size size */ |
@@ -317,7 +318,7 @@ static int ip_recent_ctrl(struct file *file, const char __user *input, unsigned | |||
317 | skb->nh.iph->daddr = 0; | 318 | skb->nh.iph->daddr = 0; |
318 | /* Clear ttl since we have no way of knowing it */ | 319 | /* Clear ttl since we have no way of knowing it */ |
319 | skb->nh.iph->ttl = 0; | 320 | skb->nh.iph->ttl = 0; |
320 | match(skb,NULL,NULL,info,0,NULL); | 321 | match(skb,NULL,NULL,info,0,0,NULL); |
321 | 322 | ||
322 | kfree(skb->nh.iph); | 323 | kfree(skb->nh.iph); |
323 | out_free_skb: | 324 | out_free_skb: |
@@ -357,6 +358,7 @@ match(const struct sk_buff *skb, | |||
357 | const struct net_device *out, | 358 | const struct net_device *out, |
358 | const void *matchinfo, | 359 | const void *matchinfo, |
359 | int offset, | 360 | int offset, |
361 | unsigned int protoff, | ||
360 | int *hotdrop) | 362 | int *hotdrop) |
361 | { | 363 | { |
362 | int pkt_count, hits_found, ans; | 364 | int pkt_count, hits_found, ans; |
@@ -654,7 +656,7 @@ match(const struct sk_buff *skb, | |||
654 | */ | 656 | */ |
655 | static int | 657 | static int |
656 | checkentry(const char *tablename, | 658 | checkentry(const char *tablename, |
657 | const struct ipt_ip *ip, | 659 | const void *ip, |
658 | void *matchinfo, | 660 | void *matchinfo, |
659 | unsigned int matchsize, | 661 | unsigned int matchsize, |
660 | unsigned int hook_mask) | 662 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_sctp.c b/net/ipv4/netfilter/ipt_sctp.c deleted file mode 100644 index fe2b327bcaa4..000000000000 --- a/net/ipv4/netfilter/ipt_sctp.c +++ /dev/null | |||
@@ -1,203 +0,0 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/skbuff.h> | ||
3 | #include <net/ip.h> | ||
4 | #include <linux/sctp.h> | ||
5 | |||
6 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
7 | #include <linux/netfilter_ipv4/ipt_sctp.h> | ||
8 | |||
9 | #ifdef DEBUG_SCTP | ||
10 | #define duprintf(format, args...) printk(format , ## args) | ||
11 | #else | ||
12 | #define duprintf(format, args...) | ||
13 | #endif | ||
14 | |||
15 | #define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \ | ||
16 | || (!!((invflag) & (option)) ^ (cond))) | ||
17 | |||
18 | static int | ||
19 | match_flags(const struct ipt_sctp_flag_info *flag_info, | ||
20 | const int flag_count, | ||
21 | u_int8_t chunktype, | ||
22 | u_int8_t chunkflags) | ||
23 | { | ||
24 | int i; | ||
25 | |||
26 | for (i = 0; i < flag_count; i++) { | ||
27 | if (flag_info[i].chunktype == chunktype) { | ||
28 | return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag; | ||
29 | } | ||
30 | } | ||
31 | |||
32 | return 1; | ||
33 | } | ||
34 | |||
35 | static int | ||
36 | match_packet(const struct sk_buff *skb, | ||
37 | const u_int32_t *chunkmap, | ||
38 | int chunk_match_type, | ||
39 | const struct ipt_sctp_flag_info *flag_info, | ||
40 | const int flag_count, | ||
41 | int *hotdrop) | ||
42 | { | ||
43 | int offset; | ||
44 | u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)]; | ||
45 | sctp_chunkhdr_t _sch, *sch; | ||
46 | |||
47 | #ifdef DEBUG_SCTP | ||
48 | int i = 0; | ||
49 | #endif | ||
50 | |||
51 | if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) { | ||
52 | SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap); | ||
53 | } | ||
54 | |||
55 | offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t); | ||
56 | do { | ||
57 | sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch); | ||
58 | if (sch == NULL) { | ||
59 | duprintf("Dropping invalid SCTP packet.\n"); | ||
60 | *hotdrop = 1; | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n", | ||
65 | ++i, offset, sch->type, htons(sch->length), sch->flags); | ||
66 | |||
67 | offset += (htons(sch->length) + 3) & ~3; | ||
68 | |||
69 | duprintf("skb->len: %d\toffset: %d\n", skb->len, offset); | ||
70 | |||
71 | if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch->type)) { | ||
72 | switch (chunk_match_type) { | ||
73 | case SCTP_CHUNK_MATCH_ANY: | ||
74 | if (match_flags(flag_info, flag_count, | ||
75 | sch->type, sch->flags)) { | ||
76 | return 1; | ||
77 | } | ||
78 | break; | ||
79 | |||
80 | case SCTP_CHUNK_MATCH_ALL: | ||
81 | if (match_flags(flag_info, flag_count, | ||
82 | sch->type, sch->flags)) { | ||
83 | SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch->type); | ||
84 | } | ||
85 | break; | ||
86 | |||
87 | case SCTP_CHUNK_MATCH_ONLY: | ||
88 | if (!match_flags(flag_info, flag_count, | ||
89 | sch->type, sch->flags)) { | ||
90 | return 0; | ||
91 | } | ||
92 | break; | ||
93 | } | ||
94 | } else { | ||
95 | switch (chunk_match_type) { | ||
96 | case SCTP_CHUNK_MATCH_ONLY: | ||
97 | return 0; | ||
98 | } | ||
99 | } | ||
100 | } while (offset < skb->len); | ||
101 | |||
102 | switch (chunk_match_type) { | ||
103 | case SCTP_CHUNK_MATCH_ALL: | ||
104 | return SCTP_CHUNKMAP_IS_CLEAR(chunkmap); | ||
105 | case SCTP_CHUNK_MATCH_ANY: | ||
106 | return 0; | ||
107 | case SCTP_CHUNK_MATCH_ONLY: | ||
108 | return 1; | ||
109 | } | ||
110 | |||
111 | /* This will never be reached, but required to stop compiler whine */ | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static int | ||
116 | match(const struct sk_buff *skb, | ||
117 | const struct net_device *in, | ||
118 | const struct net_device *out, | ||
119 | const void *matchinfo, | ||
120 | int offset, | ||
121 | int *hotdrop) | ||
122 | { | ||
123 | const struct ipt_sctp_info *info; | ||
124 | sctp_sctphdr_t _sh, *sh; | ||
125 | |||
126 | info = (const struct ipt_sctp_info *)matchinfo; | ||
127 | |||
128 | if (offset) { | ||
129 | duprintf("Dropping non-first fragment.. FIXME\n"); | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | sh = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_sh), &_sh); | ||
134 | if (sh == NULL) { | ||
135 | duprintf("Dropping evil TCP offset=0 tinygram.\n"); | ||
136 | *hotdrop = 1; | ||
137 | return 0; | ||
138 | } | ||
139 | duprintf("spt: %d\tdpt: %d\n", ntohs(sh->source), ntohs(sh->dest)); | ||
140 | |||
141 | return SCCHECK(((ntohs(sh->source) >= info->spts[0]) | ||
142 | && (ntohs(sh->source) <= info->spts[1])), | ||
143 | IPT_SCTP_SRC_PORTS, info->flags, info->invflags) | ||
144 | && SCCHECK(((ntohs(sh->dest) >= info->dpts[0]) | ||
145 | && (ntohs(sh->dest) <= info->dpts[1])), | ||
146 | IPT_SCTP_DEST_PORTS, info->flags, info->invflags) | ||
147 | && SCCHECK(match_packet(skb, info->chunkmap, info->chunk_match_type, | ||
148 | info->flag_info, info->flag_count, | ||
149 | hotdrop), | ||
150 | IPT_SCTP_CHUNK_TYPES, info->flags, info->invflags); | ||
151 | } | ||
152 | |||
153 | static int | ||
154 | checkentry(const char *tablename, | ||
155 | const struct ipt_ip *ip, | ||
156 | void *matchinfo, | ||
157 | unsigned int matchsize, | ||
158 | unsigned int hook_mask) | ||
159 | { | ||
160 | const struct ipt_sctp_info *info; | ||
161 | |||
162 | info = (const struct ipt_sctp_info *)matchinfo; | ||
163 | |||
164 | return ip->proto == IPPROTO_SCTP | ||
165 | && !(ip->invflags & IPT_INV_PROTO) | ||
166 | && matchsize == IPT_ALIGN(sizeof(struct ipt_sctp_info)) | ||
167 | && !(info->flags & ~IPT_SCTP_VALID_FLAGS) | ||
168 | && !(info->invflags & ~IPT_SCTP_VALID_FLAGS) | ||
169 | && !(info->invflags & ~info->flags) | ||
170 | && ((!(info->flags & IPT_SCTP_CHUNK_TYPES)) || | ||
171 | (info->chunk_match_type & | ||
172 | (SCTP_CHUNK_MATCH_ALL | ||
173 | | SCTP_CHUNK_MATCH_ANY | ||
174 | | SCTP_CHUNK_MATCH_ONLY))); | ||
175 | } | ||
176 | |||
177 | static struct ipt_match sctp_match = | ||
178 | { | ||
179 | .list = { NULL, NULL}, | ||
180 | .name = "sctp", | ||
181 | .match = &match, | ||
182 | .checkentry = &checkentry, | ||
183 | .destroy = NULL, | ||
184 | .me = THIS_MODULE | ||
185 | }; | ||
186 | |||
187 | static int __init init(void) | ||
188 | { | ||
189 | return ipt_register_match(&sctp_match); | ||
190 | } | ||
191 | |||
192 | static void __exit fini(void) | ||
193 | { | ||
194 | ipt_unregister_match(&sctp_match); | ||
195 | } | ||
196 | |||
197 | module_init(init); | ||
198 | module_exit(fini); | ||
199 | |||
200 | MODULE_LICENSE("GPL"); | ||
201 | MODULE_AUTHOR("Kiran Kumar Immidi"); | ||
202 | MODULE_DESCRIPTION("Match for SCTP protocol packets"); | ||
203 | |||
diff --git a/net/ipv4/netfilter/ipt_state.c b/net/ipv4/netfilter/ipt_state.c deleted file mode 100644 index 4d7f16b70cec..000000000000 --- a/net/ipv4/netfilter/ipt_state.c +++ /dev/null | |||
@@ -1,74 +0,0 @@ | |||
1 | /* Kernel module to match connection tracking information. */ | ||
2 | |||
3 | /* (C) 1999-2001 Paul `Rusty' Russell | ||
4 | * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/skbuff.h> | ||
13 | #include <net/netfilter/nf_conntrack_compat.h> | ||
14 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
15 | #include <linux/netfilter_ipv4/ipt_state.h> | ||
16 | |||
17 | MODULE_LICENSE("GPL"); | ||
18 | MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>"); | ||
19 | MODULE_DESCRIPTION("iptables connection tracking state match module"); | ||
20 | |||
21 | static int | ||
22 | match(const struct sk_buff *skb, | ||
23 | const struct net_device *in, | ||
24 | const struct net_device *out, | ||
25 | const void *matchinfo, | ||
26 | int offset, | ||
27 | int *hotdrop) | ||
28 | { | ||
29 | const struct ipt_state_info *sinfo = matchinfo; | ||
30 | enum ip_conntrack_info ctinfo; | ||
31 | unsigned int statebit; | ||
32 | |||
33 | if (nf_ct_is_untracked(skb)) | ||
34 | statebit = IPT_STATE_UNTRACKED; | ||
35 | else if (!nf_ct_get_ctinfo(skb, &ctinfo)) | ||
36 | statebit = IPT_STATE_INVALID; | ||
37 | else | ||
38 | statebit = IPT_STATE_BIT(ctinfo); | ||
39 | |||
40 | return (sinfo->statemask & statebit); | ||
41 | } | ||
42 | |||
43 | static int check(const char *tablename, | ||
44 | const struct ipt_ip *ip, | ||
45 | void *matchinfo, | ||
46 | unsigned int matchsize, | ||
47 | unsigned int hook_mask) | ||
48 | { | ||
49 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_state_info))) | ||
50 | return 0; | ||
51 | |||
52 | return 1; | ||
53 | } | ||
54 | |||
55 | static struct ipt_match state_match = { | ||
56 | .name = "state", | ||
57 | .match = &match, | ||
58 | .checkentry = &check, | ||
59 | .me = THIS_MODULE, | ||
60 | }; | ||
61 | |||
62 | static int __init init(void) | ||
63 | { | ||
64 | need_ip_conntrack(); | ||
65 | return ipt_register_match(&state_match); | ||
66 | } | ||
67 | |||
68 | static void __exit fini(void) | ||
69 | { | ||
70 | ipt_unregister_match(&state_match); | ||
71 | } | ||
72 | |||
73 | module_init(init); | ||
74 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_string.c b/net/ipv4/netfilter/ipt_string.c deleted file mode 100644 index b5def204d798..000000000000 --- a/net/ipv4/netfilter/ipt_string.c +++ /dev/null | |||
@@ -1,91 +0,0 @@ | |||
1 | /* String matching match for iptables | ||
2 | * | ||
3 | * (C) 2005 Pablo Neira Ayuso <pablo@eurodev.net> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #include <linux/init.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/skbuff.h> | ||
14 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
15 | #include <linux/netfilter_ipv4/ipt_string.h> | ||
16 | #include <linux/textsearch.h> | ||
17 | |||
18 | MODULE_AUTHOR("Pablo Neira Ayuso <pablo@eurodev.net>"); | ||
19 | MODULE_DESCRIPTION("IP tables string match module"); | ||
20 | MODULE_LICENSE("GPL"); | ||
21 | |||
22 | static int match(const struct sk_buff *skb, | ||
23 | const struct net_device *in, | ||
24 | const struct net_device *out, | ||
25 | const void *matchinfo, | ||
26 | int offset, | ||
27 | int *hotdrop) | ||
28 | { | ||
29 | struct ts_state state; | ||
30 | struct ipt_string_info *conf = (struct ipt_string_info *) matchinfo; | ||
31 | |||
32 | memset(&state, 0, sizeof(struct ts_state)); | ||
33 | |||
34 | return (skb_find_text((struct sk_buff *)skb, conf->from_offset, | ||
35 | conf->to_offset, conf->config, &state) | ||
36 | != UINT_MAX) && !conf->invert; | ||
37 | } | ||
38 | |||
39 | #define STRING_TEXT_PRIV(m) ((struct ipt_string_info *) m) | ||
40 | |||
41 | static int checkentry(const char *tablename, | ||
42 | const struct ipt_ip *ip, | ||
43 | void *matchinfo, | ||
44 | unsigned int matchsize, | ||
45 | unsigned int hook_mask) | ||
46 | { | ||
47 | struct ipt_string_info *conf = matchinfo; | ||
48 | struct ts_config *ts_conf; | ||
49 | |||
50 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_string_info))) | ||
51 | return 0; | ||
52 | |||
53 | /* Damn, can't handle this case properly with iptables... */ | ||
54 | if (conf->from_offset > conf->to_offset) | ||
55 | return 0; | ||
56 | |||
57 | ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen, | ||
58 | GFP_KERNEL, TS_AUTOLOAD); | ||
59 | if (IS_ERR(ts_conf)) | ||
60 | return 0; | ||
61 | |||
62 | conf->config = ts_conf; | ||
63 | |||
64 | return 1; | ||
65 | } | ||
66 | |||
67 | static void destroy(void *matchinfo, unsigned int matchsize) | ||
68 | { | ||
69 | textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config); | ||
70 | } | ||
71 | |||
72 | static struct ipt_match string_match = { | ||
73 | .name = "string", | ||
74 | .match = match, | ||
75 | .checkentry = checkentry, | ||
76 | .destroy = destroy, | ||
77 | .me = THIS_MODULE | ||
78 | }; | ||
79 | |||
80 | static int __init init(void) | ||
81 | { | ||
82 | return ipt_register_match(&string_match); | ||
83 | } | ||
84 | |||
85 | static void __exit fini(void) | ||
86 | { | ||
87 | ipt_unregister_match(&string_match); | ||
88 | } | ||
89 | |||
90 | module_init(init); | ||
91 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_tcpmss.c b/net/ipv4/netfilter/ipt_tcpmss.c deleted file mode 100644 index 4dc9b16ab4a3..000000000000 --- a/net/ipv4/netfilter/ipt_tcpmss.c +++ /dev/null | |||
@@ -1,127 +0,0 @@ | |||
1 | /* Kernel module to match TCP MSS values. */ | ||
2 | |||
3 | /* Copyright (C) 2000 Marc Boucher <marc@mbsi.ca> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/skbuff.h> | ||
12 | #include <net/tcp.h> | ||
13 | |||
14 | #include <linux/netfilter_ipv4/ipt_tcpmss.h> | ||
15 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
16 | |||
17 | #define TH_SYN 0x02 | ||
18 | |||
19 | MODULE_LICENSE("GPL"); | ||
20 | MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); | ||
21 | MODULE_DESCRIPTION("iptables TCP MSS match module"); | ||
22 | |||
23 | /* Returns 1 if the mss option is set and matched by the range, 0 otherwise */ | ||
24 | static inline int | ||
25 | mssoption_match(u_int16_t min, u_int16_t max, | ||
26 | const struct sk_buff *skb, | ||
27 | int invert, | ||
28 | int *hotdrop) | ||
29 | { | ||
30 | struct tcphdr _tcph, *th; | ||
31 | /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ | ||
32 | u8 _opt[15 * 4 - sizeof(_tcph)], *op; | ||
33 | unsigned int i, optlen; | ||
34 | |||
35 | /* If we don't have the whole header, drop packet. */ | ||
36 | th = skb_header_pointer(skb, skb->nh.iph->ihl * 4, | ||
37 | sizeof(_tcph), &_tcph); | ||
38 | if (th == NULL) | ||
39 | goto dropit; | ||
40 | |||
41 | /* Malformed. */ | ||
42 | if (th->doff*4 < sizeof(*th)) | ||
43 | goto dropit; | ||
44 | |||
45 | optlen = th->doff*4 - sizeof(*th); | ||
46 | if (!optlen) | ||
47 | goto out; | ||
48 | |||
49 | /* Truncated options. */ | ||
50 | op = skb_header_pointer(skb, skb->nh.iph->ihl * 4 + sizeof(*th), | ||
51 | optlen, _opt); | ||
52 | if (op == NULL) | ||
53 | goto dropit; | ||
54 | |||
55 | for (i = 0; i < optlen; ) { | ||
56 | if (op[i] == TCPOPT_MSS | ||
57 | && (optlen - i) >= TCPOLEN_MSS | ||
58 | && op[i+1] == TCPOLEN_MSS) { | ||
59 | u_int16_t mssval; | ||
60 | |||
61 | mssval = (op[i+2] << 8) | op[i+3]; | ||
62 | |||
63 | return (mssval >= min && mssval <= max) ^ invert; | ||
64 | } | ||
65 | if (op[i] < 2) i++; | ||
66 | else i += op[i+1]?:1; | ||
67 | } | ||
68 | out: | ||
69 | return invert; | ||
70 | |||
71 | dropit: | ||
72 | *hotdrop = 1; | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static int | ||
77 | match(const struct sk_buff *skb, | ||
78 | const struct net_device *in, | ||
79 | const struct net_device *out, | ||
80 | const void *matchinfo, | ||
81 | int offset, | ||
82 | int *hotdrop) | ||
83 | { | ||
84 | const struct ipt_tcpmss_match_info *info = matchinfo; | ||
85 | |||
86 | return mssoption_match(info->mss_min, info->mss_max, skb, | ||
87 | info->invert, hotdrop); | ||
88 | } | ||
89 | |||
90 | static int | ||
91 | checkentry(const char *tablename, | ||
92 | const struct ipt_ip *ip, | ||
93 | void *matchinfo, | ||
94 | unsigned int matchsize, | ||
95 | unsigned int hook_mask) | ||
96 | { | ||
97 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_tcpmss_match_info))) | ||
98 | return 0; | ||
99 | |||
100 | /* Must specify -p tcp */ | ||
101 | if (ip->proto != IPPROTO_TCP || (ip->invflags & IPT_INV_PROTO)) { | ||
102 | printk("tcpmss: Only works on TCP packets\n"); | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | return 1; | ||
107 | } | ||
108 | |||
109 | static struct ipt_match tcpmss_match = { | ||
110 | .name = "tcpmss", | ||
111 | .match = &match, | ||
112 | .checkentry = &checkentry, | ||
113 | .me = THIS_MODULE, | ||
114 | }; | ||
115 | |||
116 | static int __init init(void) | ||
117 | { | ||
118 | return ipt_register_match(&tcpmss_match); | ||
119 | } | ||
120 | |||
121 | static void __exit fini(void) | ||
122 | { | ||
123 | ipt_unregister_match(&tcpmss_match); | ||
124 | } | ||
125 | |||
126 | module_init(init); | ||
127 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_tos.c b/net/ipv4/netfilter/ipt_tos.c index 086a1bb61e3e..9ab765e126f2 100644 --- a/net/ipv4/netfilter/ipt_tos.c +++ b/net/ipv4/netfilter/ipt_tos.c | |||
@@ -23,6 +23,7 @@ match(const struct sk_buff *skb, | |||
23 | const struct net_device *out, | 23 | const struct net_device *out, |
24 | const void *matchinfo, | 24 | const void *matchinfo, |
25 | int offset, | 25 | int offset, |
26 | unsigned int protoff, | ||
26 | int *hotdrop) | 27 | int *hotdrop) |
27 | { | 28 | { |
28 | const struct ipt_tos_info *info = matchinfo; | 29 | const struct ipt_tos_info *info = matchinfo; |
@@ -32,7 +33,7 @@ match(const struct sk_buff *skb, | |||
32 | 33 | ||
33 | static int | 34 | static int |
34 | checkentry(const char *tablename, | 35 | checkentry(const char *tablename, |
35 | const struct ipt_ip *ip, | 36 | const void *ip, |
36 | void *matchinfo, | 37 | void *matchinfo, |
37 | unsigned int matchsize, | 38 | unsigned int matchsize, |
38 | unsigned int hook_mask) | 39 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_ttl.c b/net/ipv4/netfilter/ipt_ttl.c index 219aa9de88cc..82da53f430ab 100644 --- a/net/ipv4/netfilter/ipt_ttl.c +++ b/net/ipv4/netfilter/ipt_ttl.c | |||
@@ -21,7 +21,7 @@ MODULE_LICENSE("GPL"); | |||
21 | 21 | ||
22 | static int match(const struct sk_buff *skb, const struct net_device *in, | 22 | static int match(const struct sk_buff *skb, const struct net_device *in, |
23 | const struct net_device *out, const void *matchinfo, | 23 | const struct net_device *out, const void *matchinfo, |
24 | int offset, int *hotdrop) | 24 | int offset, unsigned int protoff, int *hotdrop) |
25 | { | 25 | { |
26 | const struct ipt_ttl_info *info = matchinfo; | 26 | const struct ipt_ttl_info *info = matchinfo; |
27 | 27 | ||
@@ -47,7 +47,7 @@ static int match(const struct sk_buff *skb, const struct net_device *in, | |||
47 | return 0; | 47 | return 0; |
48 | } | 48 | } |
49 | 49 | ||
50 | static int checkentry(const char *tablename, const struct ipt_ip *ip, | 50 | static int checkentry(const char *tablename, const void *ip, |
51 | void *matchinfo, unsigned int matchsize, | 51 | void *matchinfo, unsigned int matchsize, |
52 | unsigned int hook_mask) | 52 | unsigned int hook_mask) |
53 | { | 53 | { |
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 260a4f0a2a90..212a3079085b 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c | |||
@@ -78,7 +78,8 @@ static struct ipt_table packet_filter = { | |||
78 | .name = "filter", | 78 | .name = "filter", |
79 | .valid_hooks = FILTER_VALID_HOOKS, | 79 | .valid_hooks = FILTER_VALID_HOOKS, |
80 | .lock = RW_LOCK_UNLOCKED, | 80 | .lock = RW_LOCK_UNLOCKED, |
81 | .me = THIS_MODULE | 81 | .me = THIS_MODULE, |
82 | .af = AF_INET, | ||
82 | }; | 83 | }; |
83 | 84 | ||
84 | /* The work comes in here from netfilter.c. */ | 85 | /* The work comes in here from netfilter.c. */ |
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index 160eb11b6e2f..3212a5cc4b6b 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c | |||
@@ -109,6 +109,7 @@ static struct ipt_table packet_mangler = { | |||
109 | .valid_hooks = MANGLE_VALID_HOOKS, | 109 | .valid_hooks = MANGLE_VALID_HOOKS, |
110 | .lock = RW_LOCK_UNLOCKED, | 110 | .lock = RW_LOCK_UNLOCKED, |
111 | .me = THIS_MODULE, | 111 | .me = THIS_MODULE, |
112 | .af = AF_INET, | ||
112 | }; | 113 | }; |
113 | 114 | ||
114 | /* The work comes in here from netfilter.c. */ | 115 | /* The work comes in here from netfilter.c. */ |
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index 47449ba83eb9..fdb9e9c81e81 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c | |||
@@ -83,7 +83,8 @@ static struct ipt_table packet_raw = { | |||
83 | .name = "raw", | 83 | .name = "raw", |
84 | .valid_hooks = RAW_VALID_HOOKS, | 84 | .valid_hooks = RAW_VALID_HOOKS, |
85 | .lock = RW_LOCK_UNLOCKED, | 85 | .lock = RW_LOCK_UNLOCKED, |
86 | .me = THIS_MODULE | 86 | .me = THIS_MODULE, |
87 | .af = AF_INET, | ||
87 | }; | 88 | }; |
88 | 89 | ||
89 | /* The work comes in here from netfilter.c. */ | 90 | /* The work comes in here from netfilter.c. */ |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 0c56c52a3831..167619f638c6 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
@@ -575,7 +575,7 @@ MODULE_LICENSE("GPL"); | |||
575 | 575 | ||
576 | static int __init init(void) | 576 | static int __init init(void) |
577 | { | 577 | { |
578 | need_nf_conntrack(); | 578 | need_conntrack(); |
579 | return init_or_cleanup(1); | 579 | return init_or_cleanup(1); |
580 | } | 580 | } |
581 | 581 | ||
@@ -587,9 +587,4 @@ static void __exit fini(void) | |||
587 | module_init(init); | 587 | module_init(init); |
588 | module_exit(fini); | 588 | module_exit(fini); |
589 | 589 | ||
590 | void need_ip_conntrack(void) | ||
591 | { | ||
592 | } | ||
593 | |||
594 | EXPORT_SYMBOL(need_ip_conntrack); | ||
595 | EXPORT_SYMBOL(nf_ct_ipv4_gather_frags); | 590 | EXPORT_SYMBOL(nf_ct_ipv4_gather_frags); |