aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorHarald Welte <laforge@netfilter.org>2006-01-12 16:30:04 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-01-12 17:06:43 -0500
commit2e4e6a17af35be359cc8f1c924f8f198fbd478cc (patch)
treecb4b5438dcf9ff9d57518a26124308bcbfffd214 /net/ipv4
parent880b005f294454d989783d0984dc554dfe3c8214 (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')
-rw-r--r--net/ipv4/netfilter/Kconfig250
-rw-r--r--net/ipv4/netfilter/Makefile21
-rw-r--r--net/ipv4/netfilter/arp_tables.c444
-rw-r--r--net/ipv4/netfilter/arpt_mangle.c7
-rw-r--r--net/ipv4/netfilter/arptable_filter.c1
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c4
-rw-r--r--net/ipv4/netfilter/ip_nat_rule.c5
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c2
-rw-r--r--net/ipv4/netfilter/ip_tables.c842
-rw-r--r--net/ipv4/netfilter/ipt_CLASSIFY.c90
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c3
-rw-r--r--net/ipv4/netfilter/ipt_CONNMARK.c122
-rw-r--r--net/ipv4/netfilter/ipt_DSCP.c2
-rw-r--r--net/ipv4/netfilter/ipt_ECN.c3
-rw-r--r--net/ipv4/netfilter/ipt_LOG.c2
-rw-r--r--net/ipv4/netfilter/ipt_MARK.c172
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c2
-rw-r--r--net/ipv4/netfilter/ipt_NETMAP.c2
-rw-r--r--net/ipv4/netfilter/ipt_NFQUEUE.c70
-rw-r--r--net/ipv4/netfilter/ipt_NOTRACK.c76
-rw-r--r--net/ipv4/netfilter/ipt_REDIRECT.c2
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c3
-rw-r--r--net/ipv4/netfilter/ipt_SAME.c2
-rw-r--r--net/ipv4/netfilter/ipt_TCPMSS.c3
-rw-r--r--net/ipv4/netfilter/ipt_TOS.c2
-rw-r--r--net/ipv4/netfilter/ipt_TTL.c2
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c2
-rw-r--r--net/ipv4/netfilter/ipt_addrtype.c4
-rw-r--r--net/ipv4/netfilter/ipt_ah.c6
-rw-r--r--net/ipv4/netfilter/ipt_comment.c59
-rw-r--r--net/ipv4/netfilter/ipt_connbytes.c161
-rw-r--r--net/ipv4/netfilter/ipt_connmark.c88
-rw-r--r--net/ipv4/netfilter/ipt_conntrack.c232
-rw-r--r--net/ipv4/netfilter/ipt_dccp.c176
-rw-r--r--net/ipv4/netfilter/ipt_dscp.c4
-rw-r--r--net/ipv4/netfilter/ipt_ecn.c5
-rw-r--r--net/ipv4/netfilter/ipt_esp.c6
-rw-r--r--net/ipv4/netfilter/ipt_hashlimit.c3
-rw-r--r--net/ipv4/netfilter/ipt_helper.c168
-rw-r--r--net/ipv4/netfilter/ipt_iprange.c4
-rw-r--r--net/ipv4/netfilter/ipt_length.c64
-rw-r--r--net/ipv4/netfilter/ipt_limit.c157
-rw-r--r--net/ipv4/netfilter/ipt_mac.c80
-rw-r--r--net/ipv4/netfilter/ipt_mark.c71
-rw-r--r--net/ipv4/netfilter/ipt_multiport.c10
-rw-r--r--net/ipv4/netfilter/ipt_owner.c3
-rw-r--r--net/ipv4/netfilter/ipt_physdev.c135
-rw-r--r--net/ipv4/netfilter/ipt_pkttype.c70
-rw-r--r--net/ipv4/netfilter/ipt_realm.c76
-rw-r--r--net/ipv4/netfilter/ipt_recent.c6
-rw-r--r--net/ipv4/netfilter/ipt_sctp.c203
-rw-r--r--net/ipv4/netfilter/ipt_state.c74
-rw-r--r--net/ipv4/netfilter/ipt_string.c91
-rw-r--r--net/ipv4/netfilter/ipt_tcpmss.c127
-rw-r--r--net/ipv4/netfilter/ipt_tos.c3
-rw-r--r--net/ipv4/netfilter/ipt_ttl.c4
-rw-r--r--net/ipv4/netfilter/iptable_filter.c3
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c1
-rw-r--r--net/ipv4/netfilter/iptable_raw.c3
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c7
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
183config IP_NF_IPTABLES 183config 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.
194config 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
204config IP_NF_MATCH_IPRANGE 195config 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
213config 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
222config 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
234config 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
244config IP_NF_MATCH_MULTIPORT 204config 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
304config 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
313config IP_NF_MATCH_TTL 264config 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
322config 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
332config 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
342config 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
353config 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
366config IP_NF_MATCH_OWNER 273config 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
375config 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
384config IP_NF_MATCH_ADDRTYPE 282config 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
394config 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
408config 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
419config 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
430config 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
440config 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
452config 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
463config IP_NF_MATCH_HASHLIMIT 292config 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
477config 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
490config IP_NF_MATCH_POLICY 306config 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
575config 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
587config IP_NF_NAT 392config 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
738config 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
751config 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
763config IP_NF_TARGET_TTL 543config 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
777config 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
790config IP_NF_TARGET_CLUSTERIP 557config 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
813config 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
828config IP_NF_ARPTABLES 581config 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
49obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o 49obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
50obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
51obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o 50obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o
52obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o
53obj-$(CONFIG_IP_NF_MATCH_DCCP) += ipt_dccp.o
54obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
55obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
56obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o 51obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
57obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
58obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o 52obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
59obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o 53obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
60obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o 54obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
@@ -62,40 +56,25 @@ obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
62obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o 56obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
63obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o 57obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o
64obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o 58obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o
65obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o
66obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o 59obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
67obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
68obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o
69obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
70obj-$(CONFIG_IP_NF_MATCH_CONNBYTES) += ipt_connbytes.o
71obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
72obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
73obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o 60obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
74obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
75obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o 61obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o
76obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o
77obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o
78 62
79# targets 63# targets
80obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o 64obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
81obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o 65obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o
82obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o 66obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
83obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o 67obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o
84obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o
85obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o 68obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
86obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o 69obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
87obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o 70obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
88obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o 71obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o
89obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
90obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o 72obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
91obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o 73obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
92obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK.o
93obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o 74obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
94obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o 75obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
95obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o
96obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o 76obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
97obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o 77obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
98obj-$(CONFIG_IP_NF_TARGET_NFQUEUE) += ipt_NFQUEUE.o
99 78
100# generic ARP tables 79# generic ARP tables
101obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o 80obj-$(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
29MODULE_LICENSE("GPL"); 30MODULE_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
60static 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
66struct 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
75static LIST_HEAD(arpt_target);
76static 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
80static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, 62static 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
225static unsigned int arpt_error(struct sk_buff **pskb, 207static 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. */
351static 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. */
367static 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
390struct 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
401static 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) */
418static 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. */
445static inline int unconditional(const struct arpt_arp *arp) 328static 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 */
459static int mark_source_chains(struct arpt_table_info *newinfo, 342static 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
624static inline int check_entry_size_and_hooks(struct arpt_entry *e, 507static 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 */
684static int translate_table(const char *name, 567static 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
767static 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. */
793static inline int add_entry_to_counter(const struct arpt_entry *e, 651static 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
803static inline int set_entry_to_counter(const struct arpt_entry *e, 661static 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
813static void get_counters(const struct arpt_table_info *t, 671static 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
935static 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
947static 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
976static int do_replace(void __user *user, unsigned int len) 794static 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 */
1080static inline int add_counter_to_entry(struct arpt_entry *e, 894static 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,
1091static int do_add_counters(void __user *user, unsigned int len) 905static 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. */
1262int 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
1276void arpt_unregister_target(struct arpt_target *target)
1277{
1278 down(&arpt_mutex);
1279 LIST_DELETE(&arpt_target, target);
1280 up(&arpt_mutex);
1281}
1282
1283int arpt_register_table(struct arpt_table *table, 1078int 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
1348void arpt_unregister_table(struct arpt_table *table) 1117void 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
1384static 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
1401static 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
1420static int __init init(void) 1151static 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)
1454static void __exit fini(void) 1172static 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
1462EXPORT_SYMBOL(arpt_register_table); 1178EXPORT_SYMBOL(arpt_register_table);
1463EXPORT_SYMBOL(arpt_unregister_table); 1179EXPORT_SYMBOL(arpt_unregister_table);
1464EXPORT_SYMBOL(arpt_do_table); 1180EXPORT_SYMBOL(arpt_do_table);
1465EXPORT_SYMBOL(arpt_register_target);
1466EXPORT_SYMBOL(arpt_unregister_target);
1467 1181
1468module_init(init); 1182module_init(init);
1469module_exit(fini); 1183module_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>");
8MODULE_DESCRIPTION("arptables arp payload mangle target"); 8MODULE_DESCRIPTION("arptables arp payload mangle target");
9 9
10static unsigned int 10static unsigned int
11target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, 11target(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
66static int 67static int
67checkentry(const char *tablename, const struct arpt_entry *e, void *targinfo, 68checkentry(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. */
947void need_ip_conntrack(void) 947void need_conntrack(void)
948{ 948{
949} 949}
950 950
@@ -962,7 +962,7 @@ EXPORT_SYMBOL(ip_ct_get_tuple);
962EXPORT_SYMBOL(invert_tuplepr); 962EXPORT_SYMBOL(invert_tuplepr);
963EXPORT_SYMBOL(ip_conntrack_alter_reply); 963EXPORT_SYMBOL(ip_conntrack_alter_reply);
964EXPORT_SYMBOL(ip_conntrack_destroyed); 964EXPORT_SYMBOL(ip_conntrack_destroyed);
965EXPORT_SYMBOL(need_ip_conntrack); 965EXPORT_SYMBOL(need_conntrack);
966EXPORT_SYMBOL(ip_conntrack_helper_register); 966EXPORT_SYMBOL(ip_conntrack_helper_register);
967EXPORT_SYMBOL(ip_conntrack_helper_unregister); 967EXPORT_SYMBOL(ip_conntrack_helper_unregister);
968EXPORT_SYMBOL(ip_ct_iterate_cleanup); 968EXPORT_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
170static int ipt_snat_checkentry(const char *tablename, 171static 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
203static int ipt_dnat_checkentry(const char *tablename, 204static 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
35MODULE_LICENSE("GPL"); 36MODULE_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
67static 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 */
90struct 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
107static LIST_HEAD(ipt_target);
108static LIST_HEAD(ipt_match);
109static 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. */
120static inline int 83static inline int
121ip_packet_match(const struct iphdr *ip, 84ip_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. */
408static 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. */
423static 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. */
447static 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
470struct 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
481static 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
497static 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) */
514static 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. */
541static inline int 351static inline int
542unconditional(const struct ipt_ip *ip) 352unconditional(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. */
555static int 365static int
556mark_source_chains(struct ipt_table_info *newinfo, 366mark_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
782static inline int 593static inline int
783check_entry_size_and_hooks(struct ipt_entry *e, 594check_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)
845static int 656static int
846translate_table(const char *name, 657translate_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
925static struct ipt_table_info *
926replace_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. */
964static inline int 737static inline int
965add_entry_to_counter(const struct ipt_entry *e, 738add_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
986static void 759static void
987get_counters(const struct ipt_table_info *t, 760get_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
1132static 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
1144static 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
1171static int 907static int
1172do_replace(void __user *user, unsigned int len) 908do_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. */
1274static inline int 1006static inline int
1275add_counter_to_entry(struct ipt_entry *e, 1007add_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
1295do_add_counters(void __user *user, unsigned int len) 1027do_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. */ 1210int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl)
1475int
1476ipt_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
1488void
1489ipt_unregister_target(struct ipt_target *target)
1490{
1491 down(&ipt_mutex);
1492 LIST_DELETE(&ipt_target, target);
1493 up(&ipt_mutex);
1494}
1495
1496int
1497ipt_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
1511void
1512ipt_unregister_match(struct ipt_match *match)
1513{
1514 down(&ipt_mutex);
1515 LIST_DELETE(&ipt_match, match);
1516 up(&ipt_mutex);
1517}
1518
1519int 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
1582void ipt_unregister_table(struct ipt_table *table) 1246void 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 */
1598static inline int
1599port_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
1607static int
1608tcp_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
1641static int
1642tcp_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. */
1706static int
1707tcp_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
1722static int
1723udp_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. */
1756static int
1757udp_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. */
1829static int 1303static int
1830icmp_checkentry(const char *tablename, 1304icmp_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
1865static struct ipt_match tcp_matchstruct = {
1866 .name = "tcp",
1867 .match = &tcp_match,
1868 .checkentry = &tcp_checkentry,
1869};
1870
1871static struct ipt_match udp_matchstruct = {
1872 .name = "udp",
1873 .match = &udp_match,
1874 .checkentry = &udp_checkentry,
1875};
1876
1877static struct ipt_match icmp_matchstruct = { 1340static 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
1884static 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
1902static 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
1911static 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
1929static 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
1946static 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
1963static 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
1970static int __init init(void) 1346static 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
2013static void __exit fini(void) 1368static 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
2025EXPORT_SYMBOL(ipt_register_table); 1379EXPORT_SYMBOL(ipt_register_table);
2026EXPORT_SYMBOL(ipt_unregister_table); 1380EXPORT_SYMBOL(ipt_unregister_table);
2027EXPORT_SYMBOL(ipt_register_match);
2028EXPORT_SYMBOL(ipt_unregister_match);
2029EXPORT_SYMBOL(ipt_do_table); 1381EXPORT_SYMBOL(ipt_do_table);
2030EXPORT_SYMBOL(ipt_register_target);
2031EXPORT_SYMBOL(ipt_unregister_target);
2032EXPORT_SYMBOL(ipt_find_target);
2033
2034module_init(init); 1382module_init(init);
2035module_exit(fini); 1383module_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
21MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
22MODULE_LICENSE("GPL");
23MODULE_DESCRIPTION("iptables qdisc classification target module");
24
25static unsigned int
26target(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
41static int
42checkentry(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
72static struct ipt_target ipt_classify_reg = {
73 .name = "CLASSIFY",
74 .target = target,
75 .checkentry = checkentry,
76 .me = THIS_MODULE,
77};
78
79static int __init init(void)
80{
81 return ipt_register_target(&ipt_classify_reg);
82}
83
84static void __exit fini(void)
85{
86 ipt_unregister_target(&ipt_classify_reg);
87}
88
89module_init(init);
90module_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
380static int 380static int
381checkentry(const char *tablename, 381checkentry(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
26MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
27MODULE_DESCRIPTION("IP tables CONNMARK matching module");
28MODULE_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
34static unsigned int
35target(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
73static int
74checkentry(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
103static struct ipt_target ipt_connmark_reg = {
104 .name = "CONNMARK",
105 .target = &target,
106 .checkentry = &checkentry,
107 .me = THIS_MODULE
108};
109
110static int __init init(void)
111{
112 need_ip_conntrack();
113 return ipt_register_target(&ipt_connmark_reg);
114}
115
116static void __exit fini(void)
117{
118 ipt_unregister_target(&ipt_connmark_reg);
119}
120
121module_init(init);
122module_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
58static int 58static int
59checkentry(const char *tablename, 59checkentry(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
114static int 114static int
115checkentry(const char *tablename, 115checkentry(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
433static int ipt_log_checkentry(const char *tablename, 433static 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
18MODULE_LICENSE("GPL");
19MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
20MODULE_DESCRIPTION("iptables MARK modification module");
21
22static unsigned int
23target_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
38static unsigned int
39target_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
70static int
71checkentry_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
99static int
100checkentry_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
136static 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
144static 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
152static 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
165static void __exit fini(void)
166{
167 ipt_unregister_target(&ipt_mark_reg_v0);
168 ipt_unregister_target(&ipt_mark_reg_v1);
169}
170
171module_init(init);
172module_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 */
41static int 41static int
42masquerade_check(const char *tablename, 42masquerade_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
32static int 32static int
33check(const char *tablename, 33check(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
18MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
19MODULE_DESCRIPTION("iptables NFQUEUE target");
20MODULE_LICENSE("GPL");
21
22static unsigned int
23target(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
35static int
36checkentry(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
52static struct ipt_target ipt_NFQ_reg = {
53 .name = "NFQUEUE",
54 .target = target,
55 .checkentry = checkentry,
56 .me = THIS_MODULE,
57};
58
59static int __init init(void)
60{
61 return ipt_register_target(&ipt_NFQ_reg);
62}
63
64static void __exit fini(void)
65{
66 ipt_unregister_target(&ipt_NFQ_reg);
67}
68
69module_init(init);
70module_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
10static unsigned int
11target(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
33static int
34checkentry(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
54static struct ipt_target ipt_notrack_reg = {
55 .name = "NOTRACK",
56 .target = target,
57 .checkentry = checkentry,
58 .me = THIS_MODULE
59};
60
61static int __init init(void)
62{
63 if (ipt_register_target(&ipt_notrack_reg))
64 return -EINVAL;
65
66 return 0;
67}
68
69static void __exit fini(void)
70{
71 ipt_unregister_target(&ipt_notrack_reg);
72}
73
74module_init(init);
75module_exit(fini);
76MODULE_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 */
34static int 34static int
35redirect_check(const char *tablename, 35redirect_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
284static int check(const char *tablename, 284static 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
50static int 50static int
51same_check(const char *tablename, 51same_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 */
211static int 211static int
212ipt_tcpmss_checkentry(const char *tablename, 212ipt_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
53static int 53static int
54checkentry(const char *tablename, 54checkentry(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
68static int ipt_ttl_checkentry(const char *tablename, 68static 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
332static int ipt_ulog_checkentry(const char *tablename, 332static 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
30static int match(const struct sk_buff *skb, const struct net_device *in, 30static 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
46static int checkentry(const char *tablename, const struct ipt_ip *ip, 46static 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. */
70static int 71static int
71checkentry(const char *tablename, 72checkentry(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
12MODULE_AUTHOR("Brad Fisher <brad@info-link.net>");
13MODULE_DESCRIPTION("iptables comment match module");
14MODULE_LICENSE("GPL");
15
16static int
17match(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
28static int
29checkentry(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
41static struct ipt_match comment_match = {
42 .name = "comment",
43 .match = match,
44 .checkentry = checkentry,
45 .me = THIS_MODULE
46};
47
48static int __init init(void)
49{
50 return ipt_register_match(&comment_match);
51}
52
53static void __exit fini(void)
54{
55 ipt_unregister_match(&comment_match);
56}
57
58module_init(init);
59module_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
20MODULE_LICENSE("GPL");
21MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
22MODULE_DESCRIPTION("iptables match for matching number of pkts/bytes per connection");
23
24/* 64bit divisor, dividend and result. dynamic precision */
25static 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
40static int
41match(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
119static 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
143static struct ipt_match state_match = {
144 .name = "connbytes",
145 .match = &match,
146 .checkentry = &check,
147 .me = THIS_MODULE
148};
149
150static int __init init(void)
151{
152 return ipt_register_match(&state_match);
153}
154
155static void __exit fini(void)
156{
157 ipt_unregister_match(&state_match);
158}
159
160module_init(init);
161module_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
25MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
26MODULE_DESCRIPTION("IP tables connmark match module");
27MODULE_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
33static int
34match(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
50static int
51checkentry(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
70static struct ipt_match connmark_match = {
71 .name = "connmark",
72 .match = &match,
73 .checkentry = &checkentry,
74 .me = THIS_MODULE
75};
76
77static int __init init(void)
78{
79 return ipt_register_match(&connmark_match);
80}
81
82static void __exit fini(void)
83{
84 ipt_unregister_match(&connmark_match);
85}
86
87module_init(init);
88module_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
24MODULE_LICENSE("GPL");
25MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
26MODULE_DESCRIPTION("iptables connection tracking match module");
27
28#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
29
30static int
31match(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 */
115static int
116match(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
201static 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
213static struct ipt_match conntrack_match = {
214 .name = "conntrack",
215 .match = &match,
216 .checkentry = &check,
217 .me = THIS_MODULE,
218};
219
220static int __init init(void)
221{
222 need_ip_conntrack();
223 return ipt_register_match(&conntrack_match);
224}
225
226static void __exit fini(void)
227{
228 ipt_unregister_match(&conntrack_match);
229}
230
231module_init(init);
232module_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
23static unsigned char *dccp_optbuf;
24static DEFINE_SPINLOCK(dccp_buflock);
25
26static inline int
27dccp_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
74static inline int
75match_types(const struct dccp_hdr *dh, u_int16_t typemask)
76{
77 return (typemask & (1 << dh->dccph_type));
78}
79
80static inline int
81match_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
87static int
88match(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
120static int
121checkentry(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
139static struct ipt_match dccp_match =
140{
141 .name = "dccp",
142 .match = &match,
143 .checkentry = &checkentry,
144 .me = THIS_MODULE,
145};
146
147static 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
164static void __exit fini(void)
165{
166 ipt_unregister_match(&dccp_match);
167 kfree(dccp_optbuf);
168}
169
170module_init(init);
171module_exit(fini);
172
173MODULE_LICENSE("GPL");
174MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
175MODULE_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
22static int match(const struct sk_buff *skb, const struct net_device *in, 22static 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
34static int checkentry(const char *tablename, const struct ipt_ip *ip, 34static 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
68static int match(const struct sk_buff *skb, const struct net_device *in, 68static 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
88static int checkentry(const char *tablename, const struct ipt_ip *ip, 88static 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. */
71static int 72static int
72checkentry(const char *tablename, 73checkentry(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
505static int 506static int
506hashlimit_checkentry(const char *tablename, 507hashlimit_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
29MODULE_LICENSE("GPL");
30MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>");
31MODULE_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)
40static int
41match(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));
79out_unlock:
80 read_unlock_bh(&ip_conntrack_lock);
81 return ret;
82}
83
84#else /* CONFIG_IP_NF_CONNTRACK */
85
86static int
87match(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));
125out_unlock:
126 read_unlock_bh(&nf_conntrack_lock);
127 return ret;
128}
129#endif
130
131static 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
148static struct ipt_match helper_match = {
149 .name = "helper",
150 .match = &match,
151 .checkentry = &check,
152 .me = THIS_MODULE,
153};
154
155static int __init init(void)
156{
157 need_ip_conntrack();
158 return ipt_register_match(&helper_match);
159}
160
161static void __exit fini(void)
162{
163 ipt_unregister_match(&helper_match);
164}
165
166module_init(init);
167module_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
65static int check(const char *tablename, 65static 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
15MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
16MODULE_DESCRIPTION("IP tables packet length matching module");
17MODULE_LICENSE("GPL");
18
19static int
20match(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
33static int
34checkentry(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
46static struct ipt_match length_match = {
47 .name = "length",
48 .match = &match,
49 .checkentry = &checkentry,
50 .me = THIS_MODULE,
51};
52
53static int __init init(void)
54{
55 return ipt_register_match(&length_match);
56}
57
58static void __exit fini(void)
59{
60 ipt_unregister_match(&length_match);
61}
62
63module_init(init);
64module_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
24MODULE_LICENSE("GPL");
25MODULE_AUTHOR("Herve Eychenne <rv@wallfire.org>");
26MODULE_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
32static 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
65static int
66ipt_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. */
93static u_int32_t
94user2credits(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
104static int
105ipt_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
137static 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
144static int __init init(void)
145{
146 if (ipt_register_match(&ipt_limit_reg))
147 return -EINVAL;
148 return 0;
149}
150
151static void __exit fini(void)
152{
153 ipt_unregister_match(&ipt_limit_reg);
154}
155
156module_init(init);
157module_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
19MODULE_LICENSE("GPL");
20MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
21MODULE_DESCRIPTION("iptables mac matching module");
22
23static int
24match(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
41static int
42ipt_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
62static struct ipt_match mac_match = {
63 .name = "mac",
64 .match = &match,
65 .checkentry = &ipt_mac_checkentry,
66 .me = THIS_MODULE,
67};
68
69static int __init init(void)
70{
71 return ipt_register_match(&mac_match);
72}
73
74static void __exit fini(void)
75{
76 ipt_unregister_match(&mac_match);
77}
78
79module_init(init);
80module_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
16MODULE_LICENSE("GPL");
17MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
18MODULE_DESCRIPTION("iptables mark matching module");
19
20static int
21match(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
33static int
34checkentry(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
53static struct ipt_match mark_match = {
54 .name = "mark",
55 .match = &match,
56 .checkentry = &checkentry,
57 .me = THIS_MODULE,
58};
59
60static int __init init(void)
61{
62 return ipt_register_match(&mark_match);
63}
64
65static void __exit fini(void)
66{
67 ipt_unregister_match(&mark_match);
68}
69
70module_init(init);
71module_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. */
155static int 157static int
156checkentry(const char *tablename, 158checkentry(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
165static int 167static int
166checkentry_v1(const char *tablename, 168checkentry_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
52static int 53static int
53checkentry(const char *tablename, 54checkentry(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
20MODULE_LICENSE("GPL");
21MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
22MODULE_DESCRIPTION("iptables bridge physical device match module");
23
24static int
25match(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
86match_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
100static int
101checkentry(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
117static struct ipt_match physdev_match = {
118 .name = "physdev",
119 .match = &match,
120 .checkentry = &checkentry,
121 .me = THIS_MODULE,
122};
123
124static int __init init(void)
125{
126 return ipt_register_match(&physdev_match);
127}
128
129static void __exit fini(void)
130{
131 ipt_unregister_match(&physdev_match);
132}
133
134module_init(init);
135module_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
16MODULE_LICENSE("GPL");
17MODULE_AUTHOR("Michal Ludvig <michal@logix.cz>");
18MODULE_DESCRIPTION("IP tables match to match on linklayer packet type");
19
20static 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
32static 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
52static struct ipt_match pkttype_match = {
53 .name = "pkttype",
54 .match = &match,
55 .checkentry = &checkentry,
56 .me = THIS_MODULE,
57};
58
59static int __init init(void)
60{
61 return ipt_register_match(&pkttype_match);
62}
63
64static void __exit fini(void)
65{
66 ipt_unregister_match(&pkttype_match);
67}
68
69module_init(init);
70module_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
20MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>");
21MODULE_LICENSE("GPL");
22MODULE_DESCRIPTION("iptables realm match");
23
24static int
25match(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
38static 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
58static struct ipt_match realm_match = {
59 .name = "realm",
60 .match = match,
61 .checkentry = check,
62 .me = THIS_MODULE
63};
64
65static int __init init(void)
66{
67 return ipt_register_match(&realm_match);
68}
69
70static void __exit fini(void)
71{
72 ipt_unregister_match(&realm_match);
73}
74
75module_init(init);
76module_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);
323out_free_skb: 324out_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 */
655static int 657static int
656checkentry(const char *tablename, 658checkentry(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
18static int
19match_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
35static int
36match_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
115static int
116match(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
153static int
154checkentry(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
177static 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
187static int __init init(void)
188{
189 return ipt_register_match(&sctp_match);
190}
191
192static void __exit fini(void)
193{
194 ipt_unregister_match(&sctp_match);
195}
196
197module_init(init);
198module_exit(fini);
199
200MODULE_LICENSE("GPL");
201MODULE_AUTHOR("Kiran Kumar Immidi");
202MODULE_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
17MODULE_LICENSE("GPL");
18MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
19MODULE_DESCRIPTION("iptables connection tracking state match module");
20
21static int
22match(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
43static 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
55static struct ipt_match state_match = {
56 .name = "state",
57 .match = &match,
58 .checkentry = &check,
59 .me = THIS_MODULE,
60};
61
62static int __init init(void)
63{
64 need_ip_conntrack();
65 return ipt_register_match(&state_match);
66}
67
68static void __exit fini(void)
69{
70 ipt_unregister_match(&state_match);
71}
72
73module_init(init);
74module_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
18MODULE_AUTHOR("Pablo Neira Ayuso <pablo@eurodev.net>");
19MODULE_DESCRIPTION("IP tables string match module");
20MODULE_LICENSE("GPL");
21
22static 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
41static 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
67static void destroy(void *matchinfo, unsigned int matchsize)
68{
69 textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config);
70}
71
72static struct ipt_match string_match = {
73 .name = "string",
74 .match = match,
75 .checkentry = checkentry,
76 .destroy = destroy,
77 .me = THIS_MODULE
78};
79
80static int __init init(void)
81{
82 return ipt_register_match(&string_match);
83}
84
85static void __exit fini(void)
86{
87 ipt_unregister_match(&string_match);
88}
89
90module_init(init);
91module_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
19MODULE_LICENSE("GPL");
20MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
21MODULE_DESCRIPTION("iptables TCP MSS match module");
22
23/* Returns 1 if the mss option is set and matched by the range, 0 otherwise */
24static inline int
25mssoption_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 }
68out:
69 return invert;
70
71 dropit:
72 *hotdrop = 1;
73 return 0;
74}
75
76static int
77match(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
90static int
91checkentry(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
109static struct ipt_match tcpmss_match = {
110 .name = "tcpmss",
111 .match = &match,
112 .checkentry = &checkentry,
113 .me = THIS_MODULE,
114};
115
116static int __init init(void)
117{
118 return ipt_register_match(&tcpmss_match);
119}
120
121static void __exit fini(void)
122{
123 ipt_unregister_match(&tcpmss_match);
124}
125
126module_init(init);
127module_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
33static int 34static int
34checkentry(const char *tablename, 35checkentry(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
22static int match(const struct sk_buff *skb, const struct net_device *in, 22static 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
50static int checkentry(const char *tablename, const struct ipt_ip *ip, 50static 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
576static int __init init(void) 576static 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)
587module_init(init); 587module_init(init);
588module_exit(fini); 588module_exit(fini);
589 589
590void need_ip_conntrack(void)
591{
592}
593
594EXPORT_SYMBOL(need_ip_conntrack);
595EXPORT_SYMBOL(nf_ct_ipv4_gather_frags); 590EXPORT_SYMBOL(nf_ct_ipv4_gather_frags);