diff options
author | Harald Welte <laforge@netfilter.org> | 2006-01-12 16:30:04 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-01-12 17:06:43 -0500 |
commit | 2e4e6a17af35be359cc8f1c924f8f198fbd478cc (patch) | |
tree | cb4b5438dcf9ff9d57518a26124308bcbfffd214 /net | |
parent | 880b005f294454d989783d0984dc554dfe3c8214 (diff) |
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
98 files changed, 2646 insertions, 3446 deletions
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index 9f6e0193ae10..a29c1232c420 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/netfilter.h> | 15 | #include <linux/netfilter.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/ip.h> | 17 | #include <linux/ip.h> |
18 | #include <linux/in.h> | ||
18 | #include <linux/if_arp.h> | 19 | #include <linux/if_arp.h> |
19 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
20 | 21 | ||
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index a9893ec03e02..db783036e4d8 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -182,6 +182,7 @@ config IP_NF_QUEUE | |||
182 | 182 | ||
183 | config IP_NF_IPTABLES | 183 | config IP_NF_IPTABLES |
184 | tristate "IP tables support (required for filtering/masq/NAT)" | 184 | tristate "IP tables support (required for filtering/masq/NAT)" |
185 | depends on NETFILTER_XTABLES | ||
185 | help | 186 | help |
186 | iptables is a general, extensible packet identification framework. | 187 | iptables is a general, extensible packet identification framework. |
187 | The packet filtering and full NAT (masquerading, port forwarding, | 188 | The packet filtering and full NAT (masquerading, port forwarding, |
@@ -191,16 +192,6 @@ config IP_NF_IPTABLES | |||
191 | To compile it as a module, choose M here. If unsure, say N. | 192 | To compile it as a module, choose M here. If unsure, say N. |
192 | 193 | ||
193 | # The matches. | 194 | # The matches. |
194 | config IP_NF_MATCH_LIMIT | ||
195 | tristate "limit match support" | ||
196 | depends on IP_NF_IPTABLES | ||
197 | help | ||
198 | limit matching allows you to control the rate at which a rule can be | ||
199 | matched: mainly useful in combination with the LOG target ("LOG | ||
200 | target support", below) and to avoid some Denial of Service attacks. | ||
201 | |||
202 | To compile it as a module, choose M here. If unsure, say N. | ||
203 | |||
204 | config IP_NF_MATCH_IPRANGE | 195 | config IP_NF_MATCH_IPRANGE |
205 | tristate "IP range match support" | 196 | tristate "IP range match support" |
206 | depends on IP_NF_IPTABLES | 197 | depends on IP_NF_IPTABLES |
@@ -210,37 +201,6 @@ config IP_NF_MATCH_IPRANGE | |||
210 | 201 | ||
211 | To compile it as a module, choose M here. If unsure, say N. | 202 | To compile it as a module, choose M here. If unsure, say N. |
212 | 203 | ||
213 | config IP_NF_MATCH_MAC | ||
214 | tristate "MAC address match support" | ||
215 | depends on IP_NF_IPTABLES | ||
216 | help | ||
217 | MAC matching allows you to match packets based on the source | ||
218 | Ethernet address of the packet. | ||
219 | |||
220 | To compile it as a module, choose M here. If unsure, say N. | ||
221 | |||
222 | config IP_NF_MATCH_PKTTYPE | ||
223 | tristate "Packet type match support" | ||
224 | depends on IP_NF_IPTABLES | ||
225 | help | ||
226 | Packet type matching allows you to match a packet by | ||
227 | its "class", eg. BROADCAST, MULTICAST, ... | ||
228 | |||
229 | Typical usage: | ||
230 | iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG | ||
231 | |||
232 | To compile it as a module, choose M here. If unsure, say N. | ||
233 | |||
234 | config IP_NF_MATCH_MARK | ||
235 | tristate "netfilter MARK match support" | ||
236 | depends on IP_NF_IPTABLES | ||
237 | help | ||
238 | Netfilter mark matching allows you to match packets based on the | ||
239 | `nfmark' value in the packet. This can be set by the MARK target | ||
240 | (see below). | ||
241 | |||
242 | To compile it as a module, choose M here. If unsure, say N. | ||
243 | |||
244 | config IP_NF_MATCH_MULTIPORT | 204 | config IP_NF_MATCH_MULTIPORT |
245 | tristate "Multiple port match support" | 205 | tristate "Multiple port match support" |
246 | depends on IP_NF_IPTABLES | 206 | depends on IP_NF_IPTABLES |
@@ -301,15 +261,6 @@ config IP_NF_MATCH_AH_ESP | |||
301 | 261 | ||
302 | To compile it as a module, choose M here. If unsure, say N. | 262 | To compile it as a module, choose M here. If unsure, say N. |
303 | 263 | ||
304 | config IP_NF_MATCH_LENGTH | ||
305 | tristate "LENGTH match support" | ||
306 | depends on IP_NF_IPTABLES | ||
307 | help | ||
308 | This option allows you to match the length of a packet against a | ||
309 | specific value or range of values. | ||
310 | |||
311 | To compile it as a module, choose M here. If unsure, say N. | ||
312 | |||
313 | config IP_NF_MATCH_TTL | 264 | config IP_NF_MATCH_TTL |
314 | tristate "TTL match support" | 265 | tristate "TTL match support" |
315 | depends on IP_NF_IPTABLES | 266 | depends on IP_NF_IPTABLES |
@@ -319,50 +270,6 @@ config IP_NF_MATCH_TTL | |||
319 | 270 | ||
320 | To compile it as a module, choose M here. If unsure, say N. | 271 | To compile it as a module, choose M here. If unsure, say N. |
321 | 272 | ||
322 | config IP_NF_MATCH_TCPMSS | ||
323 | tristate "tcpmss match support" | ||
324 | depends on IP_NF_IPTABLES | ||
325 | help | ||
326 | This option adds a `tcpmss' match, which allows you to examine the | ||
327 | MSS value of TCP SYN packets, which control the maximum packet size | ||
328 | for that connection. | ||
329 | |||
330 | To compile it as a module, choose M here. If unsure, say N. | ||
331 | |||
332 | config IP_NF_MATCH_HELPER | ||
333 | tristate "Helper match support" | ||
334 | depends on IP_NF_IPTABLES | ||
335 | depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 | ||
336 | help | ||
337 | Helper matching allows you to match packets in dynamic connections | ||
338 | tracked by a conntrack-helper, ie. ip_conntrack_ftp | ||
339 | |||
340 | To compile it as a module, choose M here. If unsure, say Y. | ||
341 | |||
342 | config IP_NF_MATCH_STATE | ||
343 | tristate "Connection state match support" | ||
344 | depends on IP_NF_IPTABLES | ||
345 | depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 | ||
346 | help | ||
347 | Connection state matching allows you to match packets based on their | ||
348 | relationship to a tracked connection (ie. previous packets). This | ||
349 | is a powerful tool for packet classification. | ||
350 | |||
351 | To compile it as a module, choose M here. If unsure, say N. | ||
352 | |||
353 | config IP_NF_MATCH_CONNTRACK | ||
354 | tristate "Connection tracking match support" | ||
355 | depends on IP_NF_IPTABLES | ||
356 | depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 | ||
357 | help | ||
358 | This is a general conntrack match module, a superset of the state match. | ||
359 | |||
360 | It allows matching on additional conntrack information, which is | ||
361 | useful in complex configurations, such as NAT gateways with multiple | ||
362 | internet links or tunnels. | ||
363 | |||
364 | To compile it as a module, choose M here. If unsure, say N. | ||
365 | |||
366 | config IP_NF_MATCH_OWNER | 273 | config IP_NF_MATCH_OWNER |
367 | tristate "Owner match support" | 274 | tristate "Owner match support" |
368 | depends on IP_NF_IPTABLES | 275 | depends on IP_NF_IPTABLES |
@@ -372,15 +279,6 @@ config IP_NF_MATCH_OWNER | |||
372 | 279 | ||
373 | To compile it as a module, choose M here. If unsure, say N. | 280 | To compile it as a module, choose M here. If unsure, say N. |
374 | 281 | ||
375 | config IP_NF_MATCH_PHYSDEV | ||
376 | tristate "Physdev match support" | ||
377 | depends on IP_NF_IPTABLES && BRIDGE_NETFILTER | ||
378 | help | ||
379 | Physdev packet matching matches against the physical bridge ports | ||
380 | the IP packet arrived on or will leave by. | ||
381 | |||
382 | To compile it as a module, choose M here. If unsure, say N. | ||
383 | |||
384 | config IP_NF_MATCH_ADDRTYPE | 282 | config IP_NF_MATCH_ADDRTYPE |
385 | tristate 'address type match support' | 283 | tristate 'address type match support' |
386 | depends on IP_NF_IPTABLES | 284 | depends on IP_NF_IPTABLES |
@@ -391,75 +289,6 @@ config IP_NF_MATCH_ADDRTYPE | |||
391 | If you want to compile it as a module, say M here and read | 289 | If you want to compile it as a module, say M here and read |
392 | <file:Documentation/modules.txt>. If unsure, say `N'. | 290 | <file:Documentation/modules.txt>. If unsure, say `N'. |
393 | 291 | ||
394 | config IP_NF_MATCH_REALM | ||
395 | tristate 'realm match support' | ||
396 | depends on IP_NF_IPTABLES | ||
397 | select NET_CLS_ROUTE | ||
398 | help | ||
399 | This option adds a `realm' match, which allows you to use the realm | ||
400 | key from the routing subsystem inside iptables. | ||
401 | |||
402 | This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option | ||
403 | in tc world. | ||
404 | |||
405 | If you want to compile it as a module, say M here and read | ||
406 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
407 | |||
408 | config IP_NF_MATCH_SCTP | ||
409 | tristate 'SCTP protocol match support' | ||
410 | depends on IP_NF_IPTABLES | ||
411 | help | ||
412 | With this option enabled, you will be able to use the iptables | ||
413 | `sctp' match in order to match on SCTP source/destination ports | ||
414 | and SCTP chunk types. | ||
415 | |||
416 | If you want to compile it as a module, say M here and read | ||
417 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
418 | |||
419 | config IP_NF_MATCH_DCCP | ||
420 | tristate 'DCCP protocol match support' | ||
421 | depends on IP_NF_IPTABLES | ||
422 | help | ||
423 | With this option enabled, you will be able to use the iptables | ||
424 | `dccp' match in order to match on DCCP source/destination ports | ||
425 | and DCCP flags. | ||
426 | |||
427 | If you want to compile it as a module, say M here and read | ||
428 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
429 | |||
430 | config IP_NF_MATCH_COMMENT | ||
431 | tristate 'comment match support' | ||
432 | depends on IP_NF_IPTABLES | ||
433 | help | ||
434 | This option adds a `comment' dummy-match, which allows you to put | ||
435 | comments in your iptables ruleset. | ||
436 | |||
437 | If you want to compile it as a module, say M here and read | ||
438 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
439 | |||
440 | config IP_NF_MATCH_CONNMARK | ||
441 | tristate 'Connection mark match support' | ||
442 | depends on IP_NF_IPTABLES | ||
443 | depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4) | ||
444 | help | ||
445 | This option adds a `connmark' match, which allows you to match the | ||
446 | connection mark value previously set for the session by `CONNMARK'. | ||
447 | |||
448 | If you want to compile it as a module, say M here and read | ||
449 | <file:Documentation/modules.txt>. The module will be called | ||
450 | ipt_connmark.o. If unsure, say `N'. | ||
451 | |||
452 | config IP_NF_MATCH_CONNBYTES | ||
453 | tristate 'Connection byte/packet counter match support' | ||
454 | depends on IP_NF_IPTABLES | ||
455 | depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || (NF_CT_ACCT && NF_CONNTRACK_IPV4) | ||
456 | help | ||
457 | This option adds a `connbytes' match, which allows you to match the | ||
458 | number of bytes and/or packets for each direction within a connection. | ||
459 | |||
460 | If you want to compile it as a module, say M here and read | ||
461 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
462 | |||
463 | config IP_NF_MATCH_HASHLIMIT | 292 | config IP_NF_MATCH_HASHLIMIT |
464 | tristate 'hashlimit match support' | 293 | tristate 'hashlimit match support' |
465 | depends on IP_NF_IPTABLES | 294 | depends on IP_NF_IPTABLES |
@@ -474,19 +303,6 @@ config IP_NF_MATCH_HASHLIMIT | |||
474 | destination IP' or `500pps from any given source IP' with a single | 303 | destination IP' or `500pps from any given source IP' with a single |
475 | IPtables rule. | 304 | IPtables rule. |
476 | 305 | ||
477 | config IP_NF_MATCH_STRING | ||
478 | tristate 'string match support' | ||
479 | depends on IP_NF_IPTABLES | ||
480 | select TEXTSEARCH | ||
481 | select TEXTSEARCH_KMP | ||
482 | select TEXTSEARCH_BM | ||
483 | select TEXTSEARCH_FSM | ||
484 | help | ||
485 | This option adds a `string' match, which allows you to look for | ||
486 | pattern matchings in packets. | ||
487 | |||
488 | To compile it as a module, choose M here. If unsure, say N. | ||
489 | |||
490 | config IP_NF_MATCH_POLICY | 306 | config IP_NF_MATCH_POLICY |
491 | tristate "IPsec policy match support" | 307 | tristate "IPsec policy match support" |
492 | depends on IP_NF_IPTABLES && XFRM | 308 | depends on IP_NF_IPTABLES && XFRM |
@@ -572,17 +388,6 @@ config IP_NF_TARGET_TCPMSS | |||
572 | 388 | ||
573 | To compile it as a module, choose M here. If unsure, say N. | 389 | To compile it as a module, choose M here. If unsure, say N. |
574 | 390 | ||
575 | config IP_NF_TARGET_NFQUEUE | ||
576 | tristate "NFQUEUE Target Support" | ||
577 | depends on IP_NF_IPTABLES | ||
578 | help | ||
579 | This Target replaced the old obsolete QUEUE target. | ||
580 | |||
581 | As opposed to QUEUE, it supports 65535 different queues, | ||
582 | not just one. | ||
583 | |||
584 | To compile it as a module, choose M here. If unsure, say N. | ||
585 | |||
586 | # NAT + specific targets | 391 | # NAT + specific targets |
587 | config IP_NF_NAT | 392 | config IP_NF_NAT |
588 | tristate "Full NAT" | 393 | tristate "Full NAT" |
@@ -735,31 +540,6 @@ config IP_NF_TARGET_DSCP | |||
735 | 540 | ||
736 | To compile it as a module, choose M here. If unsure, say N. | 541 | To compile it as a module, choose M here. If unsure, say N. |
737 | 542 | ||
738 | config IP_NF_TARGET_MARK | ||
739 | tristate "MARK target support" | ||
740 | depends on IP_NF_MANGLE | ||
741 | help | ||
742 | This option adds a `MARK' target, which allows you to create rules | ||
743 | in the `mangle' table which alter the netfilter mark (nfmark) field | ||
744 | associated with the packet prior to routing. This can change | ||
745 | the routing method (see `Use netfilter MARK value as routing | ||
746 | key') and can also be used by other subsystems to change their | ||
747 | behavior. | ||
748 | |||
749 | To compile it as a module, choose M here. If unsure, say N. | ||
750 | |||
751 | config IP_NF_TARGET_CLASSIFY | ||
752 | tristate "CLASSIFY target support" | ||
753 | depends on IP_NF_MANGLE | ||
754 | help | ||
755 | This option adds a `CLASSIFY' target, which enables the user to set | ||
756 | the priority of a packet. Some qdiscs can use this value for | ||
757 | classification, among these are: | ||
758 | |||
759 | atm, cbq, dsmark, pfifo_fast, htb, prio | ||
760 | |||
761 | To compile it as a module, choose M here. If unsure, say N. | ||
762 | |||
763 | config IP_NF_TARGET_TTL | 543 | config IP_NF_TARGET_TTL |
764 | tristate 'TTL target support' | 544 | tristate 'TTL target support' |
765 | depends on IP_NF_MANGLE | 545 | depends on IP_NF_MANGLE |
@@ -774,19 +554,6 @@ config IP_NF_TARGET_TTL | |||
774 | 554 | ||
775 | To compile it as a module, choose M here. If unsure, say N. | 555 | To compile it as a module, choose M here. If unsure, say N. |
776 | 556 | ||
777 | config IP_NF_TARGET_CONNMARK | ||
778 | tristate 'CONNMARK target support' | ||
779 | depends on IP_NF_MANGLE | ||
780 | depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4) | ||
781 | help | ||
782 | This option adds a `CONNMARK' target, which allows one to manipulate | ||
783 | the connection mark value. Similar to the MARK target, but | ||
784 | affects the connection mark value rather than the packet mark value. | ||
785 | |||
786 | If you want to compile it as a module, say M here and read | ||
787 | <file:Documentation/modules.txt>. The module will be called | ||
788 | ipt_CONNMARK.o. If unsure, say `N'. | ||
789 | |||
790 | config IP_NF_TARGET_CLUSTERIP | 557 | config IP_NF_TARGET_CLUSTERIP |
791 | tristate "CLUSTERIP target support (EXPERIMENTAL)" | 558 | tristate "CLUSTERIP target support (EXPERIMENTAL)" |
792 | depends on IP_NF_MANGLE && EXPERIMENTAL | 559 | depends on IP_NF_MANGLE && EXPERIMENTAL |
@@ -810,23 +577,10 @@ config IP_NF_RAW | |||
810 | If you want to compile it as a module, say M here and read | 577 | If you want to compile it as a module, say M here and read |
811 | <file:Documentation/modules.txt>. If unsure, say `N'. | 578 | <file:Documentation/modules.txt>. If unsure, say `N'. |
812 | 579 | ||
813 | config IP_NF_TARGET_NOTRACK | ||
814 | tristate 'NOTRACK target support' | ||
815 | depends on IP_NF_RAW | ||
816 | depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 | ||
817 | help | ||
818 | The NOTRACK target allows a select rule to specify | ||
819 | which packets *not* to enter the conntrack/NAT | ||
820 | subsystem with all the consequences (no ICMP error tracking, | ||
821 | no protocol helpers for the selected packets). | ||
822 | |||
823 | If you want to compile it as a module, say M here and read | ||
824 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
825 | |||
826 | |||
827 | # ARP tables | 580 | # ARP tables |
828 | config IP_NF_ARPTABLES | 581 | config IP_NF_ARPTABLES |
829 | tristate "ARP tables support" | 582 | tristate "ARP tables support" |
583 | depends on NETFILTER_XTABLES | ||
830 | help | 584 | help |
831 | arptables is a general, extensible packet identification framework. | 585 | arptables is a general, extensible packet identification framework. |
832 | The ARP packet filtering and mangling (manipulation)subsystems | 586 | The ARP packet filtering and mangling (manipulation)subsystems |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 549b01a648b3..bcefe64b9317 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
@@ -47,14 +47,8 @@ obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o | |||
47 | 47 | ||
48 | # matches | 48 | # matches |
49 | obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o | 49 | obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o |
50 | obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o | ||
51 | obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o | 50 | obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o |
52 | obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o | ||
53 | obj-$(CONFIG_IP_NF_MATCH_DCCP) += ipt_dccp.o | ||
54 | obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o | ||
55 | obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o | ||
56 | obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o | 51 | obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o |
57 | obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o | ||
58 | obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o | 52 | obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o |
59 | obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o | 53 | obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o |
60 | obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o | 54 | obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o |
@@ -62,40 +56,25 @@ obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o | |||
62 | obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o | 56 | obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o |
63 | obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o | 57 | obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o |
64 | obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o | 58 | obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o |
65 | obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o | ||
66 | obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o | 59 | obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o |
67 | obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o | ||
68 | obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o | ||
69 | obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o | ||
70 | obj-$(CONFIG_IP_NF_MATCH_CONNBYTES) += ipt_connbytes.o | ||
71 | obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o | ||
72 | obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o | ||
73 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o | 60 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o |
74 | obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o | ||
75 | obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o | 61 | obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o |
76 | obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o | ||
77 | obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o | ||
78 | 62 | ||
79 | # targets | 63 | # targets |
80 | obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o | 64 | obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o |
81 | obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o | 65 | obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o |
82 | obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o | 66 | obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o |
83 | obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o | 67 | obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o |
84 | obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o | ||
85 | obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o | 68 | obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o |
86 | obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o | 69 | obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o |
87 | obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o | 70 | obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o |
88 | obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o | 71 | obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o |
89 | obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o | ||
90 | obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o | 72 | obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o |
91 | obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o | 73 | obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o |
92 | obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK.o | ||
93 | obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o | 74 | obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o |
94 | obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o | 75 | obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o |
95 | obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o | ||
96 | obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o | 76 | obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o |
97 | obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o | 77 | obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o |
98 | obj-$(CONFIG_IP_NF_TARGET_NFQUEUE) += ipt_NFQUEUE.o | ||
99 | 78 | ||
100 | # generic ARP tables | 79 | # generic ARP tables |
101 | obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o | 80 | obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index b6d5284c8020..afe3d8f8177d 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
25 | #include <asm/semaphore.h> | 25 | #include <asm/semaphore.h> |
26 | 26 | ||
27 | #include <linux/netfilter/x_tables.h> | ||
27 | #include <linux/netfilter_arp/arp_tables.h> | 28 | #include <linux/netfilter_arp/arp_tables.h> |
28 | 29 | ||
29 | MODULE_LICENSE("GPL"); | 30 | MODULE_LICENSE("GPL"); |
@@ -55,28 +56,9 @@ do { \ | |||
55 | #else | 56 | #else |
56 | #define ARP_NF_ASSERT(x) | 57 | #define ARP_NF_ASSERT(x) |
57 | #endif | 58 | #endif |
58 | #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) | ||
59 | 59 | ||
60 | static DECLARE_MUTEX(arpt_mutex); | ||
61 | |||
62 | #define ASSERT_READ_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0) | ||
63 | #define ASSERT_WRITE_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0) | ||
64 | #include <linux/netfilter_ipv4/listhelp.h> | 60 | #include <linux/netfilter_ipv4/listhelp.h> |
65 | 61 | ||
66 | struct arpt_table_info { | ||
67 | unsigned int size; | ||
68 | unsigned int number; | ||
69 | unsigned int initial_entries; | ||
70 | unsigned int hook_entry[NF_ARP_NUMHOOKS]; | ||
71 | unsigned int underflow[NF_ARP_NUMHOOKS]; | ||
72 | void *entries[NR_CPUS]; | ||
73 | }; | ||
74 | |||
75 | static LIST_HEAD(arpt_target); | ||
76 | static LIST_HEAD(arpt_tables); | ||
77 | #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) | ||
78 | #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) | ||
79 | |||
80 | static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, | 62 | static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, |
81 | char *hdr_addr, int len) | 63 | char *hdr_addr, int len) |
82 | { | 64 | { |
@@ -223,9 +205,9 @@ static inline int arp_checkentry(const struct arpt_arp *arp) | |||
223 | } | 205 | } |
224 | 206 | ||
225 | static unsigned int arpt_error(struct sk_buff **pskb, | 207 | static unsigned int arpt_error(struct sk_buff **pskb, |
226 | unsigned int hooknum, | ||
227 | const struct net_device *in, | 208 | const struct net_device *in, |
228 | const struct net_device *out, | 209 | const struct net_device *out, |
210 | unsigned int hooknum, | ||
229 | const void *targinfo, | 211 | const void *targinfo, |
230 | void *userinfo) | 212 | void *userinfo) |
231 | { | 213 | { |
@@ -254,6 +236,7 @@ unsigned int arpt_do_table(struct sk_buff **pskb, | |||
254 | struct arpt_entry *e, *back; | 236 | struct arpt_entry *e, *back; |
255 | const char *indev, *outdev; | 237 | const char *indev, *outdev; |
256 | void *table_base; | 238 | void *table_base; |
239 | struct xt_table_info *private = table->private; | ||
257 | 240 | ||
258 | /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ | 241 | /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ |
259 | if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) + | 242 | if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) + |
@@ -265,9 +248,9 @@ unsigned int arpt_do_table(struct sk_buff **pskb, | |||
265 | outdev = out ? out->name : nulldevname; | 248 | outdev = out ? out->name : nulldevname; |
266 | 249 | ||
267 | read_lock_bh(&table->lock); | 250 | read_lock_bh(&table->lock); |
268 | table_base = (void *)table->private->entries[smp_processor_id()]; | 251 | table_base = (void *)private->entries[smp_processor_id()]; |
269 | e = get_entry(table_base, table->private->hook_entry[hook]); | 252 | e = get_entry(table_base, private->hook_entry[hook]); |
270 | back = get_entry(table_base, table->private->underflow[hook]); | 253 | back = get_entry(table_base, private->underflow[hook]); |
271 | 254 | ||
272 | arp = (*pskb)->nh.arph; | 255 | arp = (*pskb)->nh.arph; |
273 | do { | 256 | do { |
@@ -315,8 +298,8 @@ unsigned int arpt_do_table(struct sk_buff **pskb, | |||
315 | * abs. verdicts | 298 | * abs. verdicts |
316 | */ | 299 | */ |
317 | verdict = t->u.kernel.target->target(pskb, | 300 | verdict = t->u.kernel.target->target(pskb, |
318 | hook, | ||
319 | in, out, | 301 | in, out, |
302 | hook, | ||
320 | t->data, | 303 | t->data, |
321 | userdata); | 304 | userdata); |
322 | 305 | ||
@@ -341,106 +324,6 @@ unsigned int arpt_do_table(struct sk_buff **pskb, | |||
341 | return verdict; | 324 | return verdict; |
342 | } | 325 | } |
343 | 326 | ||
344 | /* | ||
345 | * These are weird, but module loading must not be done with mutex | ||
346 | * held (since they will register), and we have to have a single | ||
347 | * function to use try_then_request_module(). | ||
348 | */ | ||
349 | |||
350 | /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ | ||
351 | static inline struct arpt_table *find_table_lock(const char *name) | ||
352 | { | ||
353 | struct arpt_table *t; | ||
354 | |||
355 | if (down_interruptible(&arpt_mutex) != 0) | ||
356 | return ERR_PTR(-EINTR); | ||
357 | |||
358 | list_for_each_entry(t, &arpt_tables, list) | ||
359 | if (strcmp(t->name, name) == 0 && try_module_get(t->me)) | ||
360 | return t; | ||
361 | up(&arpt_mutex); | ||
362 | return NULL; | ||
363 | } | ||
364 | |||
365 | |||
366 | /* Find target, grabs ref. Returns ERR_PTR() on error. */ | ||
367 | static inline struct arpt_target *find_target(const char *name, u8 revision) | ||
368 | { | ||
369 | struct arpt_target *t; | ||
370 | int err = 0; | ||
371 | |||
372 | if (down_interruptible(&arpt_mutex) != 0) | ||
373 | return ERR_PTR(-EINTR); | ||
374 | |||
375 | list_for_each_entry(t, &arpt_target, list) { | ||
376 | if (strcmp(t->name, name) == 0) { | ||
377 | if (t->revision == revision) { | ||
378 | if (try_module_get(t->me)) { | ||
379 | up(&arpt_mutex); | ||
380 | return t; | ||
381 | } | ||
382 | } else | ||
383 | err = -EPROTOTYPE; /* Found something. */ | ||
384 | } | ||
385 | } | ||
386 | up(&arpt_mutex); | ||
387 | return ERR_PTR(err); | ||
388 | } | ||
389 | |||
390 | struct arpt_target *arpt_find_target(const char *name, u8 revision) | ||
391 | { | ||
392 | struct arpt_target *target; | ||
393 | |||
394 | target = try_then_request_module(find_target(name, revision), | ||
395 | "arpt_%s", name); | ||
396 | if (IS_ERR(target) || !target) | ||
397 | return NULL; | ||
398 | return target; | ||
399 | } | ||
400 | |||
401 | static int target_revfn(const char *name, u8 revision, int *bestp) | ||
402 | { | ||
403 | struct arpt_target *t; | ||
404 | int have_rev = 0; | ||
405 | |||
406 | list_for_each_entry(t, &arpt_target, list) { | ||
407 | if (strcmp(t->name, name) == 0) { | ||
408 | if (t->revision > *bestp) | ||
409 | *bestp = t->revision; | ||
410 | if (t->revision == revision) | ||
411 | have_rev =1; | ||
412 | } | ||
413 | } | ||
414 | return have_rev; | ||
415 | } | ||
416 | |||
417 | /* Returns true or false (if no such extension at all) */ | ||
418 | static inline int find_revision(const char *name, u8 revision, | ||
419 | int (*revfn)(const char *, u8, int *), | ||
420 | int *err) | ||
421 | { | ||
422 | int have_rev, best = -1; | ||
423 | |||
424 | if (down_interruptible(&arpt_mutex) != 0) { | ||
425 | *err = -EINTR; | ||
426 | return 1; | ||
427 | } | ||
428 | have_rev = revfn(name, revision, &best); | ||
429 | up(&arpt_mutex); | ||
430 | |||
431 | /* Nothing at all? Return 0 to try loading module. */ | ||
432 | if (best == -1) { | ||
433 | *err = -ENOENT; | ||
434 | return 0; | ||
435 | } | ||
436 | |||
437 | *err = best; | ||
438 | if (!have_rev) | ||
439 | *err = -EPROTONOSUPPORT; | ||
440 | return 1; | ||
441 | } | ||
442 | |||
443 | |||
444 | /* All zeroes == unconditional rule. */ | 327 | /* All zeroes == unconditional rule. */ |
445 | static inline int unconditional(const struct arpt_arp *arp) | 328 | static inline int unconditional(const struct arpt_arp *arp) |
446 | { | 329 | { |
@@ -456,7 +339,7 @@ static inline int unconditional(const struct arpt_arp *arp) | |||
456 | /* Figures out from what hook each rule can be called: returns 0 if | 339 | /* Figures out from what hook each rule can be called: returns 0 if |
457 | * there are loops. Puts hook bitmask in comefrom. | 340 | * there are loops. Puts hook bitmask in comefrom. |
458 | */ | 341 | */ |
459 | static int mark_source_chains(struct arpt_table_info *newinfo, | 342 | static int mark_source_chains(struct xt_table_info *newinfo, |
460 | unsigned int valid_hooks, void *entry0) | 343 | unsigned int valid_hooks, void *entry0) |
461 | { | 344 | { |
462 | unsigned int hook; | 345 | unsigned int hook; |
@@ -587,8 +470,8 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i | |||
587 | } | 470 | } |
588 | 471 | ||
589 | t = arpt_get_target(e); | 472 | t = arpt_get_target(e); |
590 | target = try_then_request_module(find_target(t->u.user.name, | 473 | target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, |
591 | t->u.user.revision), | 474 | t->u.user.revision), |
592 | "arpt_%s", t->u.user.name); | 475 | "arpt_%s", t->u.user.name); |
593 | if (IS_ERR(target) || !target) { | 476 | if (IS_ERR(target) || !target) { |
594 | duprintf("check_entry: `%s' not found\n", t->u.user.name); | 477 | duprintf("check_entry: `%s' not found\n", t->u.user.name); |
@@ -622,7 +505,7 @@ out: | |||
622 | } | 505 | } |
623 | 506 | ||
624 | static inline int check_entry_size_and_hooks(struct arpt_entry *e, | 507 | static inline int check_entry_size_and_hooks(struct arpt_entry *e, |
625 | struct arpt_table_info *newinfo, | 508 | struct xt_table_info *newinfo, |
626 | unsigned char *base, | 509 | unsigned char *base, |
627 | unsigned char *limit, | 510 | unsigned char *limit, |
628 | const unsigned int *hook_entries, | 511 | const unsigned int *hook_entries, |
@@ -656,7 +539,7 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, | |||
656 | < 0 (not ARPT_RETURN). --RR */ | 539 | < 0 (not ARPT_RETURN). --RR */ |
657 | 540 | ||
658 | /* Clear counters and comefrom */ | 541 | /* Clear counters and comefrom */ |
659 | e->counters = ((struct arpt_counters) { 0, 0 }); | 542 | e->counters = ((struct xt_counters) { 0, 0 }); |
660 | e->comefrom = 0; | 543 | e->comefrom = 0; |
661 | 544 | ||
662 | (*i)++; | 545 | (*i)++; |
@@ -683,7 +566,7 @@ static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i) | |||
683 | */ | 566 | */ |
684 | static int translate_table(const char *name, | 567 | static int translate_table(const char *name, |
685 | unsigned int valid_hooks, | 568 | unsigned int valid_hooks, |
686 | struct arpt_table_info *newinfo, | 569 | struct xt_table_info *newinfo, |
687 | void *entry0, | 570 | void *entry0, |
688 | unsigned int size, | 571 | unsigned int size, |
689 | unsigned int number, | 572 | unsigned int number, |
@@ -764,34 +647,9 @@ static int translate_table(const char *name, | |||
764 | return ret; | 647 | return ret; |
765 | } | 648 | } |
766 | 649 | ||
767 | static struct arpt_table_info *replace_table(struct arpt_table *table, | ||
768 | unsigned int num_counters, | ||
769 | struct arpt_table_info *newinfo, | ||
770 | int *error) | ||
771 | { | ||
772 | struct arpt_table_info *oldinfo; | ||
773 | |||
774 | /* Do the substitution. */ | ||
775 | write_lock_bh(&table->lock); | ||
776 | /* Check inside lock: is the old number correct? */ | ||
777 | if (num_counters != table->private->number) { | ||
778 | duprintf("num_counters != table->private->number (%u/%u)\n", | ||
779 | num_counters, table->private->number); | ||
780 | write_unlock_bh(&table->lock); | ||
781 | *error = -EAGAIN; | ||
782 | return NULL; | ||
783 | } | ||
784 | oldinfo = table->private; | ||
785 | table->private = newinfo; | ||
786 | newinfo->initial_entries = oldinfo->initial_entries; | ||
787 | write_unlock_bh(&table->lock); | ||
788 | |||
789 | return oldinfo; | ||
790 | } | ||
791 | |||
792 | /* Gets counters. */ | 650 | /* Gets counters. */ |
793 | static inline int add_entry_to_counter(const struct arpt_entry *e, | 651 | static inline int add_entry_to_counter(const struct arpt_entry *e, |
794 | struct arpt_counters total[], | 652 | struct xt_counters total[], |
795 | unsigned int *i) | 653 | unsigned int *i) |
796 | { | 654 | { |
797 | ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); | 655 | ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); |
@@ -801,7 +659,7 @@ static inline int add_entry_to_counter(const struct arpt_entry *e, | |||
801 | } | 659 | } |
802 | 660 | ||
803 | static inline int set_entry_to_counter(const struct arpt_entry *e, | 661 | static inline int set_entry_to_counter(const struct arpt_entry *e, |
804 | struct arpt_counters total[], | 662 | struct xt_counters total[], |
805 | unsigned int *i) | 663 | unsigned int *i) |
806 | { | 664 | { |
807 | SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); | 665 | SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); |
@@ -810,8 +668,8 @@ static inline int set_entry_to_counter(const struct arpt_entry *e, | |||
810 | return 0; | 668 | return 0; |
811 | } | 669 | } |
812 | 670 | ||
813 | static void get_counters(const struct arpt_table_info *t, | 671 | static void get_counters(const struct xt_table_info *t, |
814 | struct arpt_counters counters[]) | 672 | struct xt_counters counters[]) |
815 | { | 673 | { |
816 | unsigned int cpu; | 674 | unsigned int cpu; |
817 | unsigned int i; | 675 | unsigned int i; |
@@ -849,7 +707,8 @@ static int copy_entries_to_user(unsigned int total_size, | |||
849 | { | 707 | { |
850 | unsigned int off, num, countersize; | 708 | unsigned int off, num, countersize; |
851 | struct arpt_entry *e; | 709 | struct arpt_entry *e; |
852 | struct arpt_counters *counters; | 710 | struct xt_counters *counters; |
711 | struct xt_table_info *private = table->private; | ||
853 | int ret = 0; | 712 | int ret = 0; |
854 | void *loc_cpu_entry; | 713 | void *loc_cpu_entry; |
855 | 714 | ||
@@ -857,18 +716,18 @@ static int copy_entries_to_user(unsigned int total_size, | |||
857 | * (other than comefrom, which userspace doesn't care | 716 | * (other than comefrom, which userspace doesn't care |
858 | * about). | 717 | * about). |
859 | */ | 718 | */ |
860 | countersize = sizeof(struct arpt_counters) * table->private->number; | 719 | countersize = sizeof(struct xt_counters) * private->number; |
861 | counters = vmalloc(countersize); | 720 | counters = vmalloc_node(countersize, numa_node_id()); |
862 | 721 | ||
863 | if (counters == NULL) | 722 | if (counters == NULL) |
864 | return -ENOMEM; | 723 | return -ENOMEM; |
865 | 724 | ||
866 | /* First, sum counters... */ | 725 | /* First, sum counters... */ |
867 | write_lock_bh(&table->lock); | 726 | write_lock_bh(&table->lock); |
868 | get_counters(table->private, counters); | 727 | get_counters(private, counters); |
869 | write_unlock_bh(&table->lock); | 728 | write_unlock_bh(&table->lock); |
870 | 729 | ||
871 | loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; | 730 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; |
872 | /* ... then copy entire thing ... */ | 731 | /* ... then copy entire thing ... */ |
873 | if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { | 732 | if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { |
874 | ret = -EFAULT; | 733 | ret = -EFAULT; |
@@ -911,75 +770,34 @@ static int get_entries(const struct arpt_get_entries *entries, | |||
911 | int ret; | 770 | int ret; |
912 | struct arpt_table *t; | 771 | struct arpt_table *t; |
913 | 772 | ||
914 | t = find_table_lock(entries->name); | 773 | t = xt_find_table_lock(NF_ARP, entries->name); |
915 | if (t || !IS_ERR(t)) { | 774 | if (t || !IS_ERR(t)) { |
775 | struct xt_table_info *private = t->private; | ||
916 | duprintf("t->private->number = %u\n", | 776 | duprintf("t->private->number = %u\n", |
917 | t->private->number); | 777 | private->number); |
918 | if (entries->size == t->private->size) | 778 | if (entries->size == private->size) |
919 | ret = copy_entries_to_user(t->private->size, | 779 | ret = copy_entries_to_user(private->size, |
920 | t, uptr->entrytable); | 780 | t, uptr->entrytable); |
921 | else { | 781 | else { |
922 | duprintf("get_entries: I've got %u not %u!\n", | 782 | duprintf("get_entries: I've got %u not %u!\n", |
923 | t->private->size, | 783 | private->size, entries->size); |
924 | entries->size); | ||
925 | ret = -EINVAL; | 784 | ret = -EINVAL; |
926 | } | 785 | } |
927 | module_put(t->me); | 786 | module_put(t->me); |
928 | up(&arpt_mutex); | 787 | xt_table_unlock(t); |
929 | } else | 788 | } else |
930 | ret = t ? PTR_ERR(t) : -ENOENT; | 789 | ret = t ? PTR_ERR(t) : -ENOENT; |
931 | 790 | ||
932 | return ret; | 791 | return ret; |
933 | } | 792 | } |
934 | 793 | ||
935 | static void free_table_info(struct arpt_table_info *info) | ||
936 | { | ||
937 | int cpu; | ||
938 | for_each_cpu(cpu) { | ||
939 | if (info->size <= PAGE_SIZE) | ||
940 | kfree(info->entries[cpu]); | ||
941 | else | ||
942 | vfree(info->entries[cpu]); | ||
943 | } | ||
944 | kfree(info); | ||
945 | } | ||
946 | |||
947 | static struct arpt_table_info *alloc_table_info(unsigned int size) | ||
948 | { | ||
949 | struct arpt_table_info *newinfo; | ||
950 | int cpu; | ||
951 | |||
952 | newinfo = kzalloc(sizeof(struct arpt_table_info), GFP_KERNEL); | ||
953 | if (!newinfo) | ||
954 | return NULL; | ||
955 | |||
956 | newinfo->size = size; | ||
957 | |||
958 | for_each_cpu(cpu) { | ||
959 | if (size <= PAGE_SIZE) | ||
960 | newinfo->entries[cpu] = kmalloc_node(size, | ||
961 | GFP_KERNEL, | ||
962 | cpu_to_node(cpu)); | ||
963 | else | ||
964 | newinfo->entries[cpu] = vmalloc_node(size, | ||
965 | cpu_to_node(cpu)); | ||
966 | |||
967 | if (newinfo->entries[cpu] == NULL) { | ||
968 | free_table_info(newinfo); | ||
969 | return NULL; | ||
970 | } | ||
971 | } | ||
972 | |||
973 | return newinfo; | ||
974 | } | ||
975 | |||
976 | static int do_replace(void __user *user, unsigned int len) | 794 | static int do_replace(void __user *user, unsigned int len) |
977 | { | 795 | { |
978 | int ret; | 796 | int ret; |
979 | struct arpt_replace tmp; | 797 | struct arpt_replace tmp; |
980 | struct arpt_table *t; | 798 | struct arpt_table *t; |
981 | struct arpt_table_info *newinfo, *oldinfo; | 799 | struct xt_table_info *newinfo, *oldinfo; |
982 | struct arpt_counters *counters; | 800 | struct xt_counters *counters; |
983 | void *loc_cpu_entry, *loc_cpu_old_entry; | 801 | void *loc_cpu_entry, *loc_cpu_old_entry; |
984 | 802 | ||
985 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 803 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
@@ -989,11 +807,7 @@ static int do_replace(void __user *user, unsigned int len) | |||
989 | if (len != sizeof(tmp) + tmp.size) | 807 | if (len != sizeof(tmp) + tmp.size) |
990 | return -ENOPROTOOPT; | 808 | return -ENOPROTOOPT; |
991 | 809 | ||
992 | /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ | 810 | newinfo = xt_alloc_table_info(tmp.size); |
993 | if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) | ||
994 | return -ENOMEM; | ||
995 | |||
996 | newinfo = alloc_table_info(tmp.size); | ||
997 | if (!newinfo) | 811 | if (!newinfo) |
998 | return -ENOMEM; | 812 | return -ENOMEM; |
999 | 813 | ||
@@ -1005,7 +819,7 @@ static int do_replace(void __user *user, unsigned int len) | |||
1005 | goto free_newinfo; | 819 | goto free_newinfo; |
1006 | } | 820 | } |
1007 | 821 | ||
1008 | counters = vmalloc(tmp.num_counters * sizeof(struct arpt_counters)); | 822 | counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters)); |
1009 | if (!counters) { | 823 | if (!counters) { |
1010 | ret = -ENOMEM; | 824 | ret = -ENOMEM; |
1011 | goto free_newinfo; | 825 | goto free_newinfo; |
@@ -1019,7 +833,7 @@ static int do_replace(void __user *user, unsigned int len) | |||
1019 | 833 | ||
1020 | duprintf("arp_tables: Translated table\n"); | 834 | duprintf("arp_tables: Translated table\n"); |
1021 | 835 | ||
1022 | t = try_then_request_module(find_table_lock(tmp.name), | 836 | t = try_then_request_module(xt_find_table_lock(NF_ARP, tmp.name), |
1023 | "arptable_%s", tmp.name); | 837 | "arptable_%s", tmp.name); |
1024 | if (!t || IS_ERR(t)) { | 838 | if (!t || IS_ERR(t)) { |
1025 | ret = t ? PTR_ERR(t) : -ENOENT; | 839 | ret = t ? PTR_ERR(t) : -ENOENT; |
@@ -1034,7 +848,7 @@ static int do_replace(void __user *user, unsigned int len) | |||
1034 | goto put_module; | 848 | goto put_module; |
1035 | } | 849 | } |
1036 | 850 | ||
1037 | oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); | 851 | oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret); |
1038 | if (!oldinfo) | 852 | if (!oldinfo) |
1039 | goto put_module; | 853 | goto put_module; |
1040 | 854 | ||
@@ -1054,23 +868,23 @@ static int do_replace(void __user *user, unsigned int len) | |||
1054 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; | 868 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; |
1055 | ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); | 869 | ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); |
1056 | 870 | ||
1057 | free_table_info(oldinfo); | 871 | xt_free_table_info(oldinfo); |
1058 | if (copy_to_user(tmp.counters, counters, | 872 | if (copy_to_user(tmp.counters, counters, |
1059 | sizeof(struct arpt_counters) * tmp.num_counters) != 0) | 873 | sizeof(struct xt_counters) * tmp.num_counters) != 0) |
1060 | ret = -EFAULT; | 874 | ret = -EFAULT; |
1061 | vfree(counters); | 875 | vfree(counters); |
1062 | up(&arpt_mutex); | 876 | xt_table_unlock(t); |
1063 | return ret; | 877 | return ret; |
1064 | 878 | ||
1065 | put_module: | 879 | put_module: |
1066 | module_put(t->me); | 880 | module_put(t->me); |
1067 | up(&arpt_mutex); | 881 | xt_table_unlock(t); |
1068 | free_newinfo_counters_untrans: | 882 | free_newinfo_counters_untrans: |
1069 | ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); | 883 | ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); |
1070 | free_newinfo_counters: | 884 | free_newinfo_counters: |
1071 | vfree(counters); | 885 | vfree(counters); |
1072 | free_newinfo: | 886 | free_newinfo: |
1073 | free_table_info(newinfo); | 887 | xt_free_table_info(newinfo); |
1074 | return ret; | 888 | return ret; |
1075 | } | 889 | } |
1076 | 890 | ||
@@ -1078,7 +892,7 @@ static int do_replace(void __user *user, unsigned int len) | |||
1078 | * and everything is OK. | 892 | * and everything is OK. |
1079 | */ | 893 | */ |
1080 | static inline int add_counter_to_entry(struct arpt_entry *e, | 894 | static inline int add_counter_to_entry(struct arpt_entry *e, |
1081 | const struct arpt_counters addme[], | 895 | const struct xt_counters addme[], |
1082 | unsigned int *i) | 896 | unsigned int *i) |
1083 | { | 897 | { |
1084 | 898 | ||
@@ -1091,15 +905,16 @@ static inline int add_counter_to_entry(struct arpt_entry *e, | |||
1091 | static int do_add_counters(void __user *user, unsigned int len) | 905 | static int do_add_counters(void __user *user, unsigned int len) |
1092 | { | 906 | { |
1093 | unsigned int i; | 907 | unsigned int i; |
1094 | struct arpt_counters_info tmp, *paddc; | 908 | struct xt_counters_info tmp, *paddc; |
1095 | struct arpt_table *t; | 909 | struct arpt_table *t; |
910 | struct xt_table_info *private; | ||
1096 | int ret = 0; | 911 | int ret = 0; |
1097 | void *loc_cpu_entry; | 912 | void *loc_cpu_entry; |
1098 | 913 | ||
1099 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 914 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
1100 | return -EFAULT; | 915 | return -EFAULT; |
1101 | 916 | ||
1102 | if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct arpt_counters)) | 917 | if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters)) |
1103 | return -EINVAL; | 918 | return -EINVAL; |
1104 | 919 | ||
1105 | paddc = vmalloc(len); | 920 | paddc = vmalloc(len); |
@@ -1111,29 +926,30 @@ static int do_add_counters(void __user *user, unsigned int len) | |||
1111 | goto free; | 926 | goto free; |
1112 | } | 927 | } |
1113 | 928 | ||
1114 | t = find_table_lock(tmp.name); | 929 | t = xt_find_table_lock(NF_ARP, tmp.name); |
1115 | if (!t || IS_ERR(t)) { | 930 | if (!t || IS_ERR(t)) { |
1116 | ret = t ? PTR_ERR(t) : -ENOENT; | 931 | ret = t ? PTR_ERR(t) : -ENOENT; |
1117 | goto free; | 932 | goto free; |
1118 | } | 933 | } |
1119 | 934 | ||
1120 | write_lock_bh(&t->lock); | 935 | write_lock_bh(&t->lock); |
1121 | if (t->private->number != paddc->num_counters) { | 936 | private = t->private; |
937 | if (private->number != paddc->num_counters) { | ||
1122 | ret = -EINVAL; | 938 | ret = -EINVAL; |
1123 | goto unlock_up_free; | 939 | goto unlock_up_free; |
1124 | } | 940 | } |
1125 | 941 | ||
1126 | i = 0; | 942 | i = 0; |
1127 | /* Choose the copy that is on our node */ | 943 | /* Choose the copy that is on our node */ |
1128 | loc_cpu_entry = t->private->entries[smp_processor_id()]; | 944 | loc_cpu_entry = private->entries[smp_processor_id()]; |
1129 | ARPT_ENTRY_ITERATE(loc_cpu_entry, | 945 | ARPT_ENTRY_ITERATE(loc_cpu_entry, |
1130 | t->private->size, | 946 | private->size, |
1131 | add_counter_to_entry, | 947 | add_counter_to_entry, |
1132 | paddc->counters, | 948 | paddc->counters, |
1133 | &i); | 949 | &i); |
1134 | unlock_up_free: | 950 | unlock_up_free: |
1135 | write_unlock_bh(&t->lock); | 951 | write_unlock_bh(&t->lock); |
1136 | up(&arpt_mutex); | 952 | xt_table_unlock(t); |
1137 | module_put(t->me); | 953 | module_put(t->me); |
1138 | free: | 954 | free: |
1139 | vfree(paddc); | 955 | vfree(paddc); |
@@ -1190,25 +1006,26 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len | |||
1190 | } | 1006 | } |
1191 | name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; | 1007 | name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; |
1192 | 1008 | ||
1193 | t = try_then_request_module(find_table_lock(name), | 1009 | t = try_then_request_module(xt_find_table_lock(NF_ARP, name), |
1194 | "arptable_%s", name); | 1010 | "arptable_%s", name); |
1195 | if (t && !IS_ERR(t)) { | 1011 | if (t && !IS_ERR(t)) { |
1196 | struct arpt_getinfo info; | 1012 | struct arpt_getinfo info; |
1013 | struct xt_table_info *private = t->private; | ||
1197 | 1014 | ||
1198 | info.valid_hooks = t->valid_hooks; | 1015 | info.valid_hooks = t->valid_hooks; |
1199 | memcpy(info.hook_entry, t->private->hook_entry, | 1016 | memcpy(info.hook_entry, private->hook_entry, |
1200 | sizeof(info.hook_entry)); | 1017 | sizeof(info.hook_entry)); |
1201 | memcpy(info.underflow, t->private->underflow, | 1018 | memcpy(info.underflow, private->underflow, |
1202 | sizeof(info.underflow)); | 1019 | sizeof(info.underflow)); |
1203 | info.num_entries = t->private->number; | 1020 | info.num_entries = private->number; |
1204 | info.size = t->private->size; | 1021 | info.size = private->size; |
1205 | strcpy(info.name, name); | 1022 | strcpy(info.name, name); |
1206 | 1023 | ||
1207 | if (copy_to_user(user, &info, *len) != 0) | 1024 | if (copy_to_user(user, &info, *len) != 0) |
1208 | ret = -EFAULT; | 1025 | ret = -EFAULT; |
1209 | else | 1026 | else |
1210 | ret = 0; | 1027 | ret = 0; |
1211 | up(&arpt_mutex); | 1028 | xt_table_unlock(t); |
1212 | module_put(t->me); | 1029 | module_put(t->me); |
1213 | } else | 1030 | } else |
1214 | ret = t ? PTR_ERR(t) : -ENOENT; | 1031 | ret = t ? PTR_ERR(t) : -ENOENT; |
@@ -1233,7 +1050,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len | |||
1233 | } | 1050 | } |
1234 | 1051 | ||
1235 | case ARPT_SO_GET_REVISION_TARGET: { | 1052 | case ARPT_SO_GET_REVISION_TARGET: { |
1236 | struct arpt_get_revision rev; | 1053 | struct xt_get_revision rev; |
1237 | 1054 | ||
1238 | if (*len != sizeof(rev)) { | 1055 | if (*len != sizeof(rev)) { |
1239 | ret = -EINVAL; | 1056 | ret = -EINVAL; |
@@ -1244,8 +1061,8 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len | |||
1244 | break; | 1061 | break; |
1245 | } | 1062 | } |
1246 | 1063 | ||
1247 | try_then_request_module(find_revision(rev.name, rev.revision, | 1064 | try_then_request_module(xt_find_revision(NF_ARP, rev.name, |
1248 | target_revfn, &ret), | 1065 | rev.revision, 1, &ret), |
1249 | "arpt_%s", rev.name); | 1066 | "arpt_%s", rev.name); |
1250 | break; | 1067 | break; |
1251 | } | 1068 | } |
@@ -1258,38 +1075,16 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len | |||
1258 | return ret; | 1075 | return ret; |
1259 | } | 1076 | } |
1260 | 1077 | ||
1261 | /* Registration hooks for targets. */ | ||
1262 | int arpt_register_target(struct arpt_target *target) | ||
1263 | { | ||
1264 | int ret; | ||
1265 | |||
1266 | ret = down_interruptible(&arpt_mutex); | ||
1267 | if (ret != 0) | ||
1268 | return ret; | ||
1269 | |||
1270 | list_add(&target->list, &arpt_target); | ||
1271 | up(&arpt_mutex); | ||
1272 | |||
1273 | return ret; | ||
1274 | } | ||
1275 | |||
1276 | void arpt_unregister_target(struct arpt_target *target) | ||
1277 | { | ||
1278 | down(&arpt_mutex); | ||
1279 | LIST_DELETE(&arpt_target, target); | ||
1280 | up(&arpt_mutex); | ||
1281 | } | ||
1282 | |||
1283 | int arpt_register_table(struct arpt_table *table, | 1078 | int arpt_register_table(struct arpt_table *table, |
1284 | const struct arpt_replace *repl) | 1079 | const struct arpt_replace *repl) |
1285 | { | 1080 | { |
1286 | int ret; | 1081 | int ret; |
1287 | struct arpt_table_info *newinfo; | 1082 | struct xt_table_info *newinfo; |
1288 | static struct arpt_table_info bootstrap | 1083 | static struct xt_table_info bootstrap |
1289 | = { 0, 0, 0, { 0 }, { 0 }, { } }; | 1084 | = { 0, 0, 0, { 0 }, { 0 }, { } }; |
1290 | void *loc_cpu_entry; | 1085 | void *loc_cpu_entry; |
1291 | 1086 | ||
1292 | newinfo = alloc_table_info(repl->size); | 1087 | newinfo = xt_alloc_table_info(repl->size); |
1293 | if (!newinfo) { | 1088 | if (!newinfo) { |
1294 | ret = -ENOMEM; | 1089 | ret = -ENOMEM; |
1295 | return ret; | 1090 | return ret; |
@@ -1304,60 +1099,33 @@ int arpt_register_table(struct arpt_table *table, | |||
1304 | repl->num_entries, | 1099 | repl->num_entries, |
1305 | repl->hook_entry, | 1100 | repl->hook_entry, |
1306 | repl->underflow); | 1101 | repl->underflow); |
1102 | |||
1307 | duprintf("arpt_register_table: translate table gives %d\n", ret); | 1103 | duprintf("arpt_register_table: translate table gives %d\n", ret); |
1308 | if (ret != 0) { | 1104 | if (ret != 0) { |
1309 | free_table_info(newinfo); | 1105 | xt_free_table_info(newinfo); |
1310 | return ret; | 1106 | return ret; |
1311 | } | 1107 | } |
1312 | 1108 | ||
1313 | ret = down_interruptible(&arpt_mutex); | 1109 | if (xt_register_table(table, &bootstrap, newinfo) != 0) { |
1314 | if (ret != 0) { | 1110 | xt_free_table_info(newinfo); |
1315 | free_table_info(newinfo); | ||
1316 | return ret; | 1111 | return ret; |
1317 | } | 1112 | } |
1318 | 1113 | ||
1319 | /* Don't autoload: we'd eat our tail... */ | 1114 | return 0; |
1320 | if (list_named_find(&arpt_tables, table->name)) { | ||
1321 | ret = -EEXIST; | ||
1322 | goto free_unlock; | ||
1323 | } | ||
1324 | |||
1325 | /* Simplifies replace_table code. */ | ||
1326 | table->private = &bootstrap; | ||
1327 | if (!replace_table(table, 0, newinfo, &ret)) | ||
1328 | goto free_unlock; | ||
1329 | |||
1330 | duprintf("table->private->number = %u\n", | ||
1331 | table->private->number); | ||
1332 | |||
1333 | /* save number of initial entries */ | ||
1334 | table->private->initial_entries = table->private->number; | ||
1335 | |||
1336 | rwlock_init(&table->lock); | ||
1337 | list_prepend(&arpt_tables, table); | ||
1338 | |||
1339 | unlock: | ||
1340 | up(&arpt_mutex); | ||
1341 | return ret; | ||
1342 | |||
1343 | free_unlock: | ||
1344 | free_table_info(newinfo); | ||
1345 | goto unlock; | ||
1346 | } | 1115 | } |
1347 | 1116 | ||
1348 | void arpt_unregister_table(struct arpt_table *table) | 1117 | void arpt_unregister_table(struct arpt_table *table) |
1349 | { | 1118 | { |
1119 | struct xt_table_info *private; | ||
1350 | void *loc_cpu_entry; | 1120 | void *loc_cpu_entry; |
1351 | 1121 | ||
1352 | down(&arpt_mutex); | 1122 | private = xt_unregister_table(table); |
1353 | LIST_DELETE(&arpt_tables, table); | ||
1354 | up(&arpt_mutex); | ||
1355 | 1123 | ||
1356 | /* Decrease module usage counts and free resources */ | 1124 | /* Decrease module usage counts and free resources */ |
1357 | loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; | 1125 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; |
1358 | ARPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size, | 1126 | ARPT_ENTRY_ITERATE(loc_cpu_entry, private->size, |
1359 | cleanup_entry, NULL); | 1127 | cleanup_entry, NULL); |
1360 | free_table_info(table->private); | 1128 | xt_free_table_info(private); |
1361 | } | 1129 | } |
1362 | 1130 | ||
1363 | /* The built-in targets: standard (NULL) and error. */ | 1131 | /* The built-in targets: standard (NULL) and error. */ |
@@ -1380,52 +1148,15 @@ static struct nf_sockopt_ops arpt_sockopts = { | |||
1380 | .get = do_arpt_get_ctl, | 1148 | .get = do_arpt_get_ctl, |
1381 | }; | 1149 | }; |
1382 | 1150 | ||
1383 | #ifdef CONFIG_PROC_FS | ||
1384 | static inline int print_name(const struct arpt_table *t, | ||
1385 | off_t start_offset, char *buffer, int length, | ||
1386 | off_t *pos, unsigned int *count) | ||
1387 | { | ||
1388 | if ((*count)++ >= start_offset) { | ||
1389 | unsigned int namelen; | ||
1390 | |||
1391 | namelen = sprintf(buffer + *pos, "%s\n", t->name); | ||
1392 | if (*pos + namelen > length) { | ||
1393 | /* Stop iterating */ | ||
1394 | return 1; | ||
1395 | } | ||
1396 | *pos += namelen; | ||
1397 | } | ||
1398 | return 0; | ||
1399 | } | ||
1400 | |||
1401 | static int arpt_get_tables(char *buffer, char **start, off_t offset, int length) | ||
1402 | { | ||
1403 | off_t pos = 0; | ||
1404 | unsigned int count = 0; | ||
1405 | |||
1406 | if (down_interruptible(&arpt_mutex) != 0) | ||
1407 | return 0; | ||
1408 | |||
1409 | LIST_FIND(&arpt_tables, print_name, struct arpt_table *, | ||
1410 | offset, buffer, length, &pos, &count); | ||
1411 | |||
1412 | up(&arpt_mutex); | ||
1413 | |||
1414 | /* `start' hack - see fs/proc/generic.c line ~105 */ | ||
1415 | *start=(char *)((unsigned long)count-offset); | ||
1416 | return pos; | ||
1417 | } | ||
1418 | #endif /*CONFIG_PROC_FS*/ | ||
1419 | |||
1420 | static int __init init(void) | 1151 | static int __init init(void) |
1421 | { | 1152 | { |
1422 | int ret; | 1153 | int ret; |
1423 | 1154 | ||
1155 | xt_proto_init(NF_ARP); | ||
1156 | |||
1424 | /* Noone else will be downing sem now, so we won't sleep */ | 1157 | /* Noone else will be downing sem now, so we won't sleep */ |
1425 | down(&arpt_mutex); | 1158 | xt_register_target(NF_ARP, &arpt_standard_target); |
1426 | list_append(&arpt_target, &arpt_standard_target); | 1159 | xt_register_target(NF_ARP, &arpt_error_target); |
1427 | list_append(&arpt_target, &arpt_error_target); | ||
1428 | up(&arpt_mutex); | ||
1429 | 1160 | ||
1430 | /* Register setsockopt */ | 1161 | /* Register setsockopt */ |
1431 | ret = nf_register_sockopt(&arpt_sockopts); | 1162 | ret = nf_register_sockopt(&arpt_sockopts); |
@@ -1434,19 +1165,6 @@ static int __init init(void) | |||
1434 | return ret; | 1165 | return ret; |
1435 | } | 1166 | } |
1436 | 1167 | ||
1437 | #ifdef CONFIG_PROC_FS | ||
1438 | { | ||
1439 | struct proc_dir_entry *proc; | ||
1440 | |||
1441 | proc = proc_net_create("arp_tables_names", 0, arpt_get_tables); | ||
1442 | if (!proc) { | ||
1443 | nf_unregister_sockopt(&arpt_sockopts); | ||
1444 | return -ENOMEM; | ||
1445 | } | ||
1446 | proc->owner = THIS_MODULE; | ||
1447 | } | ||
1448 | #endif | ||
1449 | |||
1450 | printk("arp_tables: (C) 2002 David S. Miller\n"); | 1168 | printk("arp_tables: (C) 2002 David S. Miller\n"); |
1451 | return 0; | 1169 | return 0; |
1452 | } | 1170 | } |
@@ -1454,16 +1172,12 @@ static int __init init(void) | |||
1454 | static void __exit fini(void) | 1172 | static void __exit fini(void) |
1455 | { | 1173 | { |
1456 | nf_unregister_sockopt(&arpt_sockopts); | 1174 | nf_unregister_sockopt(&arpt_sockopts); |
1457 | #ifdef CONFIG_PROC_FS | 1175 | xt_proto_fini(NF_ARP); |
1458 | proc_net_remove("arp_tables_names"); | ||
1459 | #endif | ||
1460 | } | 1176 | } |
1461 | 1177 | ||
1462 | EXPORT_SYMBOL(arpt_register_table); | 1178 | EXPORT_SYMBOL(arpt_register_table); |
1463 | EXPORT_SYMBOL(arpt_unregister_table); | 1179 | EXPORT_SYMBOL(arpt_unregister_table); |
1464 | EXPORT_SYMBOL(arpt_do_table); | 1180 | EXPORT_SYMBOL(arpt_do_table); |
1465 | EXPORT_SYMBOL(arpt_register_target); | ||
1466 | EXPORT_SYMBOL(arpt_unregister_target); | ||
1467 | 1181 | ||
1468 | module_init(init); | 1182 | module_init(init); |
1469 | module_exit(fini); | 1183 | module_exit(fini); |
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c index 3e592ec86482..c97650a16a5b 100644 --- a/net/ipv4/netfilter/arpt_mangle.c +++ b/net/ipv4/netfilter/arpt_mangle.c | |||
@@ -8,8 +8,9 @@ MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); | |||
8 | MODULE_DESCRIPTION("arptables arp payload mangle target"); | 8 | MODULE_DESCRIPTION("arptables arp payload mangle target"); |
9 | 9 | ||
10 | static unsigned int | 10 | static unsigned int |
11 | target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, | 11 | target(struct sk_buff **pskb, const struct net_device *in, |
12 | const struct net_device *out, const void *targinfo, void *userinfo) | 12 | const struct net_device *out, unsigned int hooknum, const void *targinfo, |
13 | void *userinfo) | ||
13 | { | 14 | { |
14 | const struct arpt_mangle *mangle = targinfo; | 15 | const struct arpt_mangle *mangle = targinfo; |
15 | struct arphdr *arp; | 16 | struct arphdr *arp; |
@@ -64,7 +65,7 @@ target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, | |||
64 | } | 65 | } |
65 | 66 | ||
66 | static int | 67 | static int |
67 | checkentry(const char *tablename, const struct arpt_entry *e, void *targinfo, | 68 | checkentry(const char *tablename, const void *e, void *targinfo, |
68 | unsigned int targinfosize, unsigned int hook_mask) | 69 | unsigned int targinfosize, unsigned int hook_mask) |
69 | { | 70 | { |
70 | const struct arpt_mangle *mangle = targinfo; | 71 | const struct arpt_mangle *mangle = targinfo; |
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c index 0d759f5a4ef0..f6ab45f48681 100644 --- a/net/ipv4/netfilter/arptable_filter.c +++ b/net/ipv4/netfilter/arptable_filter.c | |||
@@ -145,6 +145,7 @@ static struct arpt_table packet_filter = { | |||
145 | .lock = RW_LOCK_UNLOCKED, | 145 | .lock = RW_LOCK_UNLOCKED, |
146 | .private = NULL, | 146 | .private = NULL, |
147 | .me = THIS_MODULE, | 147 | .me = THIS_MODULE, |
148 | .af = NF_ARP, | ||
148 | }; | 149 | }; |
149 | 150 | ||
150 | /* The work comes in here from netfilter.c */ | 151 | /* The work comes in here from netfilter.c */ |
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index 9dec1293f67a..833fcb4be5e7 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c | |||
@@ -944,7 +944,7 @@ module_exit(fini); | |||
944 | 944 | ||
945 | /* Some modules need us, but don't depend directly on any symbol. | 945 | /* Some modules need us, but don't depend directly on any symbol. |
946 | They should call this. */ | 946 | They should call this. */ |
947 | void need_ip_conntrack(void) | 947 | void need_conntrack(void) |
948 | { | 948 | { |
949 | } | 949 | } |
950 | 950 | ||
@@ -962,7 +962,7 @@ EXPORT_SYMBOL(ip_ct_get_tuple); | |||
962 | EXPORT_SYMBOL(invert_tuplepr); | 962 | EXPORT_SYMBOL(invert_tuplepr); |
963 | EXPORT_SYMBOL(ip_conntrack_alter_reply); | 963 | EXPORT_SYMBOL(ip_conntrack_alter_reply); |
964 | EXPORT_SYMBOL(ip_conntrack_destroyed); | 964 | EXPORT_SYMBOL(ip_conntrack_destroyed); |
965 | EXPORT_SYMBOL(need_ip_conntrack); | 965 | EXPORT_SYMBOL(need_conntrack); |
966 | EXPORT_SYMBOL(ip_conntrack_helper_register); | 966 | EXPORT_SYMBOL(ip_conntrack_helper_register); |
967 | EXPORT_SYMBOL(ip_conntrack_helper_unregister); | 967 | EXPORT_SYMBOL(ip_conntrack_helper_unregister); |
968 | EXPORT_SYMBOL(ip_ct_iterate_cleanup); | 968 | EXPORT_SYMBOL(ip_ct_iterate_cleanup); |
diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c index cb66b8bddeb3..1de86282d232 100644 --- a/net/ipv4/netfilter/ip_nat_rule.c +++ b/net/ipv4/netfilter/ip_nat_rule.c | |||
@@ -95,6 +95,7 @@ static struct ipt_table nat_table = { | |||
95 | .valid_hooks = NAT_VALID_HOOKS, | 95 | .valid_hooks = NAT_VALID_HOOKS, |
96 | .lock = RW_LOCK_UNLOCKED, | 96 | .lock = RW_LOCK_UNLOCKED, |
97 | .me = THIS_MODULE, | 97 | .me = THIS_MODULE, |
98 | .af = AF_INET, | ||
98 | }; | 99 | }; |
99 | 100 | ||
100 | /* Source NAT */ | 101 | /* Source NAT */ |
@@ -168,7 +169,7 @@ static unsigned int ipt_dnat_target(struct sk_buff **pskb, | |||
168 | } | 169 | } |
169 | 170 | ||
170 | static int ipt_snat_checkentry(const char *tablename, | 171 | static int ipt_snat_checkentry(const char *tablename, |
171 | const struct ipt_entry *e, | 172 | const void *entry, |
172 | void *targinfo, | 173 | void *targinfo, |
173 | unsigned int targinfosize, | 174 | unsigned int targinfosize, |
174 | unsigned int hook_mask) | 175 | unsigned int hook_mask) |
@@ -201,7 +202,7 @@ static int ipt_snat_checkentry(const char *tablename, | |||
201 | } | 202 | } |
202 | 203 | ||
203 | static int ipt_dnat_checkentry(const char *tablename, | 204 | static int ipt_dnat_checkentry(const char *tablename, |
204 | const struct ipt_entry *e, | 205 | const void *entry, |
205 | void *targinfo, | 206 | void *targinfo, |
206 | unsigned int targinfosize, | 207 | unsigned int targinfosize, |
207 | unsigned int hook_mask) | 208 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 8b8a1f00bbf4..ad438fb185b8 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c | |||
@@ -364,7 +364,7 @@ static int init_or_cleanup(int init) | |||
364 | { | 364 | { |
365 | int ret = 0; | 365 | int ret = 0; |
366 | 366 | ||
367 | need_ip_conntrack(); | 367 | need_conntrack(); |
368 | 368 | ||
369 | if (!init) goto cleanup; | 369 | if (!init) goto cleanup; |
370 | 370 | ||
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 877bc96d3336..2371b2062c2d 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Packet matching code. | 2 | * Packet matching code. |
3 | * | 3 | * |
4 | * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling | 4 | * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling |
5 | * Copyright (C) 2000-2004 Netfilter Core Team <coreteam@netfilter.org> | 5 | * Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -11,6 +11,8 @@ | |||
11 | * 19 Jan 2002 Harald Welte <laforge@gnumonks.org> | 11 | * 19 Jan 2002 Harald Welte <laforge@gnumonks.org> |
12 | * - increase module usage count as soon as we have rules inside | 12 | * - increase module usage count as soon as we have rules inside |
13 | * a table | 13 | * a table |
14 | * 08 Oct 2005 Harald Welte <lafore@netfilter.org> | ||
15 | * - Generalize into "x_tables" layer and "{ip,ip6,arp}_tables" | ||
14 | */ | 16 | */ |
15 | #include <linux/config.h> | 17 | #include <linux/config.h> |
16 | #include <linux/cache.h> | 18 | #include <linux/cache.h> |
@@ -20,8 +22,6 @@ | |||
20 | #include <linux/vmalloc.h> | 22 | #include <linux/vmalloc.h> |
21 | #include <linux/netdevice.h> | 23 | #include <linux/netdevice.h> |
22 | #include <linux/module.h> | 24 | #include <linux/module.h> |
23 | #include <linux/tcp.h> | ||
24 | #include <linux/udp.h> | ||
25 | #include <linux/icmp.h> | 25 | #include <linux/icmp.h> |
26 | #include <net/ip.h> | 26 | #include <net/ip.h> |
27 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/err.h> | 30 | #include <linux/err.h> |
31 | #include <linux/cpumask.h> | 31 | #include <linux/cpumask.h> |
32 | 32 | ||
33 | #include <linux/netfilter/x_tables.h> | ||
33 | #include <linux/netfilter_ipv4/ip_tables.h> | 34 | #include <linux/netfilter_ipv4/ip_tables.h> |
34 | 35 | ||
35 | MODULE_LICENSE("GPL"); | 36 | MODULE_LICENSE("GPL"); |
@@ -62,14 +63,6 @@ do { \ | |||
62 | #else | 63 | #else |
63 | #define IP_NF_ASSERT(x) | 64 | #define IP_NF_ASSERT(x) |
64 | #endif | 65 | #endif |
65 | #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) | ||
66 | |||
67 | static DECLARE_MUTEX(ipt_mutex); | ||
68 | |||
69 | /* Must have mutex */ | ||
70 | #define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0) | ||
71 | #define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0) | ||
72 | #include <linux/netfilter_ipv4/listhelp.h> | ||
73 | 66 | ||
74 | #if 0 | 67 | #if 0 |
75 | /* All the better to debug you with... */ | 68 | /* All the better to debug you with... */ |
@@ -86,36 +79,6 @@ static DECLARE_MUTEX(ipt_mutex); | |||
86 | 79 | ||
87 | Hence the start of any table is given by get_table() below. */ | 80 | Hence the start of any table is given by get_table() below. */ |
88 | 81 | ||
89 | /* The table itself */ | ||
90 | struct ipt_table_info | ||
91 | { | ||
92 | /* Size per table */ | ||
93 | unsigned int size; | ||
94 | /* Number of entries: FIXME. --RR */ | ||
95 | unsigned int number; | ||
96 | /* Initial number of entries. Needed for module usage count */ | ||
97 | unsigned int initial_entries; | ||
98 | |||
99 | /* Entry points and underflows */ | ||
100 | unsigned int hook_entry[NF_IP_NUMHOOKS]; | ||
101 | unsigned int underflow[NF_IP_NUMHOOKS]; | ||
102 | |||
103 | /* ipt_entry tables: one per CPU */ | ||
104 | void *entries[NR_CPUS]; | ||
105 | }; | ||
106 | |||
107 | static LIST_HEAD(ipt_target); | ||
108 | static LIST_HEAD(ipt_match); | ||
109 | static LIST_HEAD(ipt_tables); | ||
110 | #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) | ||
111 | #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) | ||
112 | |||
113 | #if 0 | ||
114 | #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) | ||
115 | #define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; }) | ||
116 | #define up(x) do { printk("UP:%u:" #x "\n", __LINE__); up(x); } while(0) | ||
117 | #endif | ||
118 | |||
119 | /* Returns whether matches rule or not. */ | 82 | /* Returns whether matches rule or not. */ |
120 | static inline int | 83 | static inline int |
121 | ip_packet_match(const struct iphdr *ip, | 84 | ip_packet_match(const struct iphdr *ip, |
@@ -234,7 +197,8 @@ int do_match(struct ipt_entry_match *m, | |||
234 | int *hotdrop) | 197 | int *hotdrop) |
235 | { | 198 | { |
236 | /* Stop iteration if it doesn't match */ | 199 | /* Stop iteration if it doesn't match */ |
237 | if (!m->u.kernel.match->match(skb, in, out, m->data, offset, hotdrop)) | 200 | if (!m->u.kernel.match->match(skb, in, out, m->data, offset, |
201 | skb->nh.iph->ihl*4, hotdrop)) | ||
238 | return 1; | 202 | return 1; |
239 | else | 203 | else |
240 | return 0; | 204 | return 0; |
@@ -265,6 +229,7 @@ ipt_do_table(struct sk_buff **pskb, | |||
265 | const char *indev, *outdev; | 229 | const char *indev, *outdev; |
266 | void *table_base; | 230 | void *table_base; |
267 | struct ipt_entry *e, *back; | 231 | struct ipt_entry *e, *back; |
232 | struct xt_table_info *private = table->private; | ||
268 | 233 | ||
269 | /* Initialization */ | 234 | /* Initialization */ |
270 | ip = (*pskb)->nh.iph; | 235 | ip = (*pskb)->nh.iph; |
@@ -281,24 +246,11 @@ ipt_do_table(struct sk_buff **pskb, | |||
281 | 246 | ||
282 | read_lock_bh(&table->lock); | 247 | read_lock_bh(&table->lock); |
283 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); | 248 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); |
284 | table_base = (void *)table->private->entries[smp_processor_id()]; | 249 | table_base = (void *)private->entries[smp_processor_id()]; |
285 | e = get_entry(table_base, table->private->hook_entry[hook]); | 250 | e = get_entry(table_base, private->hook_entry[hook]); |
286 | |||
287 | #ifdef CONFIG_NETFILTER_DEBUG | ||
288 | /* Check noone else using our table */ | ||
289 | if (((struct ipt_entry *)table_base)->comefrom != 0xdead57ac | ||
290 | && ((struct ipt_entry *)table_base)->comefrom != 0xeeeeeeec) { | ||
291 | printk("ASSERT: CPU #%u, %s comefrom(%p) = %X\n", | ||
292 | smp_processor_id(), | ||
293 | table->name, | ||
294 | &((struct ipt_entry *)table_base)->comefrom, | ||
295 | ((struct ipt_entry *)table_base)->comefrom); | ||
296 | } | ||
297 | ((struct ipt_entry *)table_base)->comefrom = 0x57acc001; | ||
298 | #endif | ||
299 | 251 | ||
300 | /* For return from builtin chain */ | 252 | /* For return from builtin chain */ |
301 | back = get_entry(table_base, table->private->underflow[hook]); | 253 | back = get_entry(table_base, private->underflow[hook]); |
302 | 254 | ||
303 | do { | 255 | do { |
304 | IP_NF_ASSERT(e); | 256 | IP_NF_ASSERT(e); |
@@ -384,9 +336,6 @@ ipt_do_table(struct sk_buff **pskb, | |||
384 | } | 336 | } |
385 | } while (!hotdrop); | 337 | } while (!hotdrop); |
386 | 338 | ||
387 | #ifdef CONFIG_NETFILTER_DEBUG | ||
388 | ((struct ipt_entry *)table_base)->comefrom = 0xdead57ac; | ||
389 | #endif | ||
390 | read_unlock_bh(&table->lock); | 339 | read_unlock_bh(&table->lock); |
391 | 340 | ||
392 | #ifdef DEBUG_ALLOW_ALL | 341 | #ifdef DEBUG_ALLOW_ALL |
@@ -398,145 +347,6 @@ ipt_do_table(struct sk_buff **pskb, | |||
398 | #endif | 347 | #endif |
399 | } | 348 | } |
400 | 349 | ||
401 | /* | ||
402 | * These are weird, but module loading must not be done with mutex | ||
403 | * held (since they will register), and we have to have a single | ||
404 | * function to use try_then_request_module(). | ||
405 | */ | ||
406 | |||
407 | /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ | ||
408 | static inline struct ipt_table *find_table_lock(const char *name) | ||
409 | { | ||
410 | struct ipt_table *t; | ||
411 | |||
412 | if (down_interruptible(&ipt_mutex) != 0) | ||
413 | return ERR_PTR(-EINTR); | ||
414 | |||
415 | list_for_each_entry(t, &ipt_tables, list) | ||
416 | if (strcmp(t->name, name) == 0 && try_module_get(t->me)) | ||
417 | return t; | ||
418 | up(&ipt_mutex); | ||
419 | return NULL; | ||
420 | } | ||
421 | |||
422 | /* Find match, grabs ref. Returns ERR_PTR() on error. */ | ||
423 | static inline struct ipt_match *find_match(const char *name, u8 revision) | ||
424 | { | ||
425 | struct ipt_match *m; | ||
426 | int err = 0; | ||
427 | |||
428 | if (down_interruptible(&ipt_mutex) != 0) | ||
429 | return ERR_PTR(-EINTR); | ||
430 | |||
431 | list_for_each_entry(m, &ipt_match, list) { | ||
432 | if (strcmp(m->name, name) == 0) { | ||
433 | if (m->revision == revision) { | ||
434 | if (try_module_get(m->me)) { | ||
435 | up(&ipt_mutex); | ||
436 | return m; | ||
437 | } | ||
438 | } else | ||
439 | err = -EPROTOTYPE; /* Found something. */ | ||
440 | } | ||
441 | } | ||
442 | up(&ipt_mutex); | ||
443 | return ERR_PTR(err); | ||
444 | } | ||
445 | |||
446 | /* Find target, grabs ref. Returns ERR_PTR() on error. */ | ||
447 | static inline struct ipt_target *find_target(const char *name, u8 revision) | ||
448 | { | ||
449 | struct ipt_target *t; | ||
450 | int err = 0; | ||
451 | |||
452 | if (down_interruptible(&ipt_mutex) != 0) | ||
453 | return ERR_PTR(-EINTR); | ||
454 | |||
455 | list_for_each_entry(t, &ipt_target, list) { | ||
456 | if (strcmp(t->name, name) == 0) { | ||
457 | if (t->revision == revision) { | ||
458 | if (try_module_get(t->me)) { | ||
459 | up(&ipt_mutex); | ||
460 | return t; | ||
461 | } | ||
462 | } else | ||
463 | err = -EPROTOTYPE; /* Found something. */ | ||
464 | } | ||
465 | } | ||
466 | up(&ipt_mutex); | ||
467 | return ERR_PTR(err); | ||
468 | } | ||
469 | |||
470 | struct ipt_target *ipt_find_target(const char *name, u8 revision) | ||
471 | { | ||
472 | struct ipt_target *target; | ||
473 | |||
474 | target = try_then_request_module(find_target(name, revision), | ||
475 | "ipt_%s", name); | ||
476 | if (IS_ERR(target) || !target) | ||
477 | return NULL; | ||
478 | return target; | ||
479 | } | ||
480 | |||
481 | static int match_revfn(const char *name, u8 revision, int *bestp) | ||
482 | { | ||
483 | struct ipt_match *m; | ||
484 | int have_rev = 0; | ||
485 | |||
486 | list_for_each_entry(m, &ipt_match, list) { | ||
487 | if (strcmp(m->name, name) == 0) { | ||
488 | if (m->revision > *bestp) | ||
489 | *bestp = m->revision; | ||
490 | if (m->revision == revision) | ||
491 | have_rev = 1; | ||
492 | } | ||
493 | } | ||
494 | return have_rev; | ||
495 | } | ||
496 | |||
497 | static int target_revfn(const char *name, u8 revision, int *bestp) | ||
498 | { | ||
499 | struct ipt_target *t; | ||
500 | int have_rev = 0; | ||
501 | |||
502 | list_for_each_entry(t, &ipt_target, list) { | ||
503 | if (strcmp(t->name, name) == 0) { | ||
504 | if (t->revision > *bestp) | ||
505 | *bestp = t->revision; | ||
506 | if (t->revision == revision) | ||
507 | have_rev = 1; | ||
508 | } | ||
509 | } | ||
510 | return have_rev; | ||
511 | } | ||
512 | |||
513 | /* Returns true or false (if no such extension at all) */ | ||
514 | static inline int find_revision(const char *name, u8 revision, | ||
515 | int (*revfn)(const char *, u8, int *), | ||
516 | int *err) | ||
517 | { | ||
518 | int have_rev, best = -1; | ||
519 | |||
520 | if (down_interruptible(&ipt_mutex) != 0) { | ||
521 | *err = -EINTR; | ||
522 | return 1; | ||
523 | } | ||
524 | have_rev = revfn(name, revision, &best); | ||
525 | up(&ipt_mutex); | ||
526 | |||
527 | /* Nothing at all? Return 0 to try loading module. */ | ||
528 | if (best == -1) { | ||
529 | *err = -ENOENT; | ||
530 | return 0; | ||
531 | } | ||
532 | |||
533 | *err = best; | ||
534 | if (!have_rev) | ||
535 | *err = -EPROTONOSUPPORT; | ||
536 | return 1; | ||
537 | } | ||
538 | |||
539 | |||
540 | /* All zeroes == unconditional rule. */ | 350 | /* All zeroes == unconditional rule. */ |
541 | static inline int | 351 | static inline int |
542 | unconditional(const struct ipt_ip *ip) | 352 | unconditional(const struct ipt_ip *ip) |
@@ -553,7 +363,7 @@ unconditional(const struct ipt_ip *ip) | |||
553 | /* Figures out from what hook each rule can be called: returns 0 if | 363 | /* Figures out from what hook each rule can be called: returns 0 if |
554 | there are loops. Puts hook bitmask in comefrom. */ | 364 | there are loops. Puts hook bitmask in comefrom. */ |
555 | static int | 365 | static int |
556 | mark_source_chains(struct ipt_table_info *newinfo, | 366 | mark_source_chains(struct xt_table_info *newinfo, |
557 | unsigned int valid_hooks, void *entry0) | 367 | unsigned int valid_hooks, void *entry0) |
558 | { | 368 | { |
559 | unsigned int hook; | 369 | unsigned int hook; |
@@ -699,7 +509,7 @@ check_match(struct ipt_entry_match *m, | |||
699 | { | 509 | { |
700 | struct ipt_match *match; | 510 | struct ipt_match *match; |
701 | 511 | ||
702 | match = try_then_request_module(find_match(m->u.user.name, | 512 | match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name, |
703 | m->u.user.revision), | 513 | m->u.user.revision), |
704 | "ipt_%s", m->u.user.name); | 514 | "ipt_%s", m->u.user.name); |
705 | if (IS_ERR(match) || !match) { | 515 | if (IS_ERR(match) || !match) { |
@@ -744,7 +554,8 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size, | |||
744 | goto cleanup_matches; | 554 | goto cleanup_matches; |
745 | 555 | ||
746 | t = ipt_get_target(e); | 556 | t = ipt_get_target(e); |
747 | target = try_then_request_module(find_target(t->u.user.name, | 557 | target = try_then_request_module(xt_find_target(AF_INET, |
558 | t->u.user.name, | ||
748 | t->u.user.revision), | 559 | t->u.user.revision), |
749 | "ipt_%s", t->u.user.name); | 560 | "ipt_%s", t->u.user.name); |
750 | if (IS_ERR(target) || !target) { | 561 | if (IS_ERR(target) || !target) { |
@@ -781,7 +592,7 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size, | |||
781 | 592 | ||
782 | static inline int | 593 | static inline int |
783 | check_entry_size_and_hooks(struct ipt_entry *e, | 594 | check_entry_size_and_hooks(struct ipt_entry *e, |
784 | struct ipt_table_info *newinfo, | 595 | struct xt_table_info *newinfo, |
785 | unsigned char *base, | 596 | unsigned char *base, |
786 | unsigned char *limit, | 597 | unsigned char *limit, |
787 | const unsigned int *hook_entries, | 598 | const unsigned int *hook_entries, |
@@ -815,7 +626,7 @@ check_entry_size_and_hooks(struct ipt_entry *e, | |||
815 | < 0 (not IPT_RETURN). --RR */ | 626 | < 0 (not IPT_RETURN). --RR */ |
816 | 627 | ||
817 | /* Clear counters and comefrom */ | 628 | /* Clear counters and comefrom */ |
818 | e->counters = ((struct ipt_counters) { 0, 0 }); | 629 | e->counters = ((struct xt_counters) { 0, 0 }); |
819 | e->comefrom = 0; | 630 | e->comefrom = 0; |
820 | 631 | ||
821 | (*i)++; | 632 | (*i)++; |
@@ -845,7 +656,7 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i) | |||
845 | static int | 656 | static int |
846 | translate_table(const char *name, | 657 | translate_table(const char *name, |
847 | unsigned int valid_hooks, | 658 | unsigned int valid_hooks, |
848 | struct ipt_table_info *newinfo, | 659 | struct xt_table_info *newinfo, |
849 | void *entry0, | 660 | void *entry0, |
850 | unsigned int size, | 661 | unsigned int size, |
851 | unsigned int number, | 662 | unsigned int number, |
@@ -922,48 +733,10 @@ translate_table(const char *name, | |||
922 | return ret; | 733 | return ret; |
923 | } | 734 | } |
924 | 735 | ||
925 | static struct ipt_table_info * | ||
926 | replace_table(struct ipt_table *table, | ||
927 | unsigned int num_counters, | ||
928 | struct ipt_table_info *newinfo, | ||
929 | int *error) | ||
930 | { | ||
931 | struct ipt_table_info *oldinfo; | ||
932 | |||
933 | #ifdef CONFIG_NETFILTER_DEBUG | ||
934 | { | ||
935 | int cpu; | ||
936 | |||
937 | for_each_cpu(cpu) { | ||
938 | struct ipt_entry *table_base = newinfo->entries[cpu]; | ||
939 | if (table_base) | ||
940 | table_base->comefrom = 0xdead57ac; | ||
941 | } | ||
942 | } | ||
943 | #endif | ||
944 | |||
945 | /* Do the substitution. */ | ||
946 | write_lock_bh(&table->lock); | ||
947 | /* Check inside lock: is the old number correct? */ | ||
948 | if (num_counters != table->private->number) { | ||
949 | duprintf("num_counters != table->private->number (%u/%u)\n", | ||
950 | num_counters, table->private->number); | ||
951 | write_unlock_bh(&table->lock); | ||
952 | *error = -EAGAIN; | ||
953 | return NULL; | ||
954 | } | ||
955 | oldinfo = table->private; | ||
956 | table->private = newinfo; | ||
957 | newinfo->initial_entries = oldinfo->initial_entries; | ||
958 | write_unlock_bh(&table->lock); | ||
959 | |||
960 | return oldinfo; | ||
961 | } | ||
962 | |||
963 | /* Gets counters. */ | 736 | /* Gets counters. */ |
964 | static inline int | 737 | static inline int |
965 | add_entry_to_counter(const struct ipt_entry *e, | 738 | add_entry_to_counter(const struct ipt_entry *e, |
966 | struct ipt_counters total[], | 739 | struct xt_counters total[], |
967 | unsigned int *i) | 740 | unsigned int *i) |
968 | { | 741 | { |
969 | ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); | 742 | ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); |
@@ -984,8 +757,8 @@ set_entry_to_counter(const struct ipt_entry *e, | |||
984 | } | 757 | } |
985 | 758 | ||
986 | static void | 759 | static void |
987 | get_counters(const struct ipt_table_info *t, | 760 | get_counters(const struct xt_table_info *t, |
988 | struct ipt_counters counters[]) | 761 | struct xt_counters counters[]) |
989 | { | 762 | { |
990 | unsigned int cpu; | 763 | unsigned int cpu; |
991 | unsigned int i; | 764 | unsigned int i; |
@@ -1024,14 +797,15 @@ copy_entries_to_user(unsigned int total_size, | |||
1024 | { | 797 | { |
1025 | unsigned int off, num, countersize; | 798 | unsigned int off, num, countersize; |
1026 | struct ipt_entry *e; | 799 | struct ipt_entry *e; |
1027 | struct ipt_counters *counters; | 800 | struct xt_counters *counters; |
801 | struct xt_table_info *private = table->private; | ||
1028 | int ret = 0; | 802 | int ret = 0; |
1029 | void *loc_cpu_entry; | 803 | void *loc_cpu_entry; |
1030 | 804 | ||
1031 | /* We need atomic snapshot of counters: rest doesn't change | 805 | /* We need atomic snapshot of counters: rest doesn't change |
1032 | (other than comefrom, which userspace doesn't care | 806 | (other than comefrom, which userspace doesn't care |
1033 | about). */ | 807 | about). */ |
1034 | countersize = sizeof(struct ipt_counters) * table->private->number; | 808 | countersize = sizeof(struct xt_counters) * private->number; |
1035 | counters = vmalloc_node(countersize, numa_node_id()); | 809 | counters = vmalloc_node(countersize, numa_node_id()); |
1036 | 810 | ||
1037 | if (counters == NULL) | 811 | if (counters == NULL) |
@@ -1039,14 +813,14 @@ copy_entries_to_user(unsigned int total_size, | |||
1039 | 813 | ||
1040 | /* First, sum counters... */ | 814 | /* First, sum counters... */ |
1041 | write_lock_bh(&table->lock); | 815 | write_lock_bh(&table->lock); |
1042 | get_counters(table->private, counters); | 816 | get_counters(private, counters); |
1043 | write_unlock_bh(&table->lock); | 817 | write_unlock_bh(&table->lock); |
1044 | 818 | ||
1045 | /* choose the copy that is on our node/cpu, ... | 819 | /* choose the copy that is on our node/cpu, ... |
1046 | * This choice is lazy (because current thread is | 820 | * This choice is lazy (because current thread is |
1047 | * allowed to migrate to another cpu) | 821 | * allowed to migrate to another cpu) |
1048 | */ | 822 | */ |
1049 | loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; | 823 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; |
1050 | /* ... then copy entire thing ... */ | 824 | /* ... then copy entire thing ... */ |
1051 | if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { | 825 | if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { |
1052 | ret = -EFAULT; | 826 | ret = -EFAULT; |
@@ -1108,74 +882,36 @@ get_entries(const struct ipt_get_entries *entries, | |||
1108 | int ret; | 882 | int ret; |
1109 | struct ipt_table *t; | 883 | struct ipt_table *t; |
1110 | 884 | ||
1111 | t = find_table_lock(entries->name); | 885 | t = xt_find_table_lock(AF_INET, entries->name); |
1112 | if (t && !IS_ERR(t)) { | 886 | if (t && !IS_ERR(t)) { |
887 | struct xt_table_info *private = t->private; | ||
1113 | duprintf("t->private->number = %u\n", | 888 | duprintf("t->private->number = %u\n", |
1114 | t->private->number); | 889 | private->number); |
1115 | if (entries->size == t->private->size) | 890 | if (entries->size == private->size) |
1116 | ret = copy_entries_to_user(t->private->size, | 891 | ret = copy_entries_to_user(private->size, |
1117 | t, uptr->entrytable); | 892 | t, uptr->entrytable); |
1118 | else { | 893 | else { |
1119 | duprintf("get_entries: I've got %u not %u!\n", | 894 | duprintf("get_entries: I've got %u not %u!\n", |
1120 | t->private->size, | 895 | private->size, |
1121 | entries->size); | 896 | entries->size); |
1122 | ret = -EINVAL; | 897 | ret = -EINVAL; |
1123 | } | 898 | } |
1124 | module_put(t->me); | 899 | module_put(t->me); |
1125 | up(&ipt_mutex); | 900 | xt_table_unlock(t); |
1126 | } else | 901 | } else |
1127 | ret = t ? PTR_ERR(t) : -ENOENT; | 902 | ret = t ? PTR_ERR(t) : -ENOENT; |
1128 | 903 | ||
1129 | return ret; | 904 | return ret; |
1130 | } | 905 | } |
1131 | 906 | ||
1132 | static void free_table_info(struct ipt_table_info *info) | ||
1133 | { | ||
1134 | int cpu; | ||
1135 | for_each_cpu(cpu) { | ||
1136 | if (info->size <= PAGE_SIZE) | ||
1137 | kfree(info->entries[cpu]); | ||
1138 | else | ||
1139 | vfree(info->entries[cpu]); | ||
1140 | } | ||
1141 | kfree(info); | ||
1142 | } | ||
1143 | |||
1144 | static struct ipt_table_info *alloc_table_info(unsigned int size) | ||
1145 | { | ||
1146 | struct ipt_table_info *newinfo; | ||
1147 | int cpu; | ||
1148 | |||
1149 | newinfo = kzalloc(sizeof(struct ipt_table_info), GFP_KERNEL); | ||
1150 | if (!newinfo) | ||
1151 | return NULL; | ||
1152 | |||
1153 | newinfo->size = size; | ||
1154 | |||
1155 | for_each_cpu(cpu) { | ||
1156 | if (size <= PAGE_SIZE) | ||
1157 | newinfo->entries[cpu] = kmalloc_node(size, | ||
1158 | GFP_KERNEL, | ||
1159 | cpu_to_node(cpu)); | ||
1160 | else | ||
1161 | newinfo->entries[cpu] = vmalloc_node(size, cpu_to_node(cpu)); | ||
1162 | if (newinfo->entries[cpu] == 0) { | ||
1163 | free_table_info(newinfo); | ||
1164 | return NULL; | ||
1165 | } | ||
1166 | } | ||
1167 | |||
1168 | return newinfo; | ||
1169 | } | ||
1170 | |||
1171 | static int | 907 | static int |
1172 | do_replace(void __user *user, unsigned int len) | 908 | do_replace(void __user *user, unsigned int len) |
1173 | { | 909 | { |
1174 | int ret; | 910 | int ret; |
1175 | struct ipt_replace tmp; | 911 | struct ipt_replace tmp; |
1176 | struct ipt_table *t; | 912 | struct ipt_table *t; |
1177 | struct ipt_table_info *newinfo, *oldinfo; | 913 | struct xt_table_info *newinfo, *oldinfo; |
1178 | struct ipt_counters *counters; | 914 | struct xt_counters *counters; |
1179 | void *loc_cpu_entry, *loc_cpu_old_entry; | 915 | void *loc_cpu_entry, *loc_cpu_old_entry; |
1180 | 916 | ||
1181 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 917 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
@@ -1185,11 +921,7 @@ do_replace(void __user *user, unsigned int len) | |||
1185 | if (len != sizeof(tmp) + tmp.size) | 921 | if (len != sizeof(tmp) + tmp.size) |
1186 | return -ENOPROTOOPT; | 922 | return -ENOPROTOOPT; |
1187 | 923 | ||
1188 | /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ | 924 | newinfo = xt_alloc_table_info(tmp.size); |
1189 | if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) | ||
1190 | return -ENOMEM; | ||
1191 | |||
1192 | newinfo = alloc_table_info(tmp.size); | ||
1193 | if (!newinfo) | 925 | if (!newinfo) |
1194 | return -ENOMEM; | 926 | return -ENOMEM; |
1195 | 927 | ||
@@ -1201,7 +933,7 @@ do_replace(void __user *user, unsigned int len) | |||
1201 | goto free_newinfo; | 933 | goto free_newinfo; |
1202 | } | 934 | } |
1203 | 935 | ||
1204 | counters = vmalloc(tmp.num_counters * sizeof(struct ipt_counters)); | 936 | counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters)); |
1205 | if (!counters) { | 937 | if (!counters) { |
1206 | ret = -ENOMEM; | 938 | ret = -ENOMEM; |
1207 | goto free_newinfo; | 939 | goto free_newinfo; |
@@ -1215,7 +947,7 @@ do_replace(void __user *user, unsigned int len) | |||
1215 | 947 | ||
1216 | duprintf("ip_tables: Translated table\n"); | 948 | duprintf("ip_tables: Translated table\n"); |
1217 | 949 | ||
1218 | t = try_then_request_module(find_table_lock(tmp.name), | 950 | t = try_then_request_module(xt_find_table_lock(AF_INET, tmp.name), |
1219 | "iptable_%s", tmp.name); | 951 | "iptable_%s", tmp.name); |
1220 | if (!t || IS_ERR(t)) { | 952 | if (!t || IS_ERR(t)) { |
1221 | ret = t ? PTR_ERR(t) : -ENOENT; | 953 | ret = t ? PTR_ERR(t) : -ENOENT; |
@@ -1230,7 +962,7 @@ do_replace(void __user *user, unsigned int len) | |||
1230 | goto put_module; | 962 | goto put_module; |
1231 | } | 963 | } |
1232 | 964 | ||
1233 | oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); | 965 | oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret); |
1234 | if (!oldinfo) | 966 | if (!oldinfo) |
1235 | goto put_module; | 967 | goto put_module; |
1236 | 968 | ||
@@ -1249,23 +981,23 @@ do_replace(void __user *user, unsigned int len) | |||
1249 | /* Decrease module usage counts and free resource */ | 981 | /* Decrease module usage counts and free resource */ |
1250 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; | 982 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; |
1251 | IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); | 983 | IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); |
1252 | free_table_info(oldinfo); | 984 | xt_free_table_info(oldinfo); |
1253 | if (copy_to_user(tmp.counters, counters, | 985 | if (copy_to_user(tmp.counters, counters, |
1254 | sizeof(struct ipt_counters) * tmp.num_counters) != 0) | 986 | sizeof(struct xt_counters) * tmp.num_counters) != 0) |
1255 | ret = -EFAULT; | 987 | ret = -EFAULT; |
1256 | vfree(counters); | 988 | vfree(counters); |
1257 | up(&ipt_mutex); | 989 | xt_table_unlock(t); |
1258 | return ret; | 990 | return ret; |
1259 | 991 | ||
1260 | put_module: | 992 | put_module: |
1261 | module_put(t->me); | 993 | module_put(t->me); |
1262 | up(&ipt_mutex); | 994 | xt_table_unlock(t); |
1263 | free_newinfo_counters_untrans: | 995 | free_newinfo_counters_untrans: |
1264 | IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); | 996 | IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); |
1265 | free_newinfo_counters: | 997 | free_newinfo_counters: |
1266 | vfree(counters); | 998 | vfree(counters); |
1267 | free_newinfo: | 999 | free_newinfo: |
1268 | free_table_info(newinfo); | 1000 | xt_free_table_info(newinfo); |
1269 | return ret; | 1001 | return ret; |
1270 | } | 1002 | } |
1271 | 1003 | ||
@@ -1273,7 +1005,7 @@ do_replace(void __user *user, unsigned int len) | |||
1273 | * and everything is OK. */ | 1005 | * and everything is OK. */ |
1274 | static inline int | 1006 | static inline int |
1275 | add_counter_to_entry(struct ipt_entry *e, | 1007 | add_counter_to_entry(struct ipt_entry *e, |
1276 | const struct ipt_counters addme[], | 1008 | const struct xt_counters addme[], |
1277 | unsigned int *i) | 1009 | unsigned int *i) |
1278 | { | 1010 | { |
1279 | #if 0 | 1011 | #if 0 |
@@ -1295,15 +1027,16 @@ static int | |||
1295 | do_add_counters(void __user *user, unsigned int len) | 1027 | do_add_counters(void __user *user, unsigned int len) |
1296 | { | 1028 | { |
1297 | unsigned int i; | 1029 | unsigned int i; |
1298 | struct ipt_counters_info tmp, *paddc; | 1030 | struct xt_counters_info tmp, *paddc; |
1299 | struct ipt_table *t; | 1031 | struct ipt_table *t; |
1032 | struct xt_table_info *private; | ||
1300 | int ret = 0; | 1033 | int ret = 0; |
1301 | void *loc_cpu_entry; | 1034 | void *loc_cpu_entry; |
1302 | 1035 | ||
1303 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 1036 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
1304 | return -EFAULT; | 1037 | return -EFAULT; |
1305 | 1038 | ||
1306 | if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct ipt_counters)) | 1039 | if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters)) |
1307 | return -EINVAL; | 1040 | return -EINVAL; |
1308 | 1041 | ||
1309 | paddc = vmalloc_node(len, numa_node_id()); | 1042 | paddc = vmalloc_node(len, numa_node_id()); |
@@ -1315,29 +1048,30 @@ do_add_counters(void __user *user, unsigned int len) | |||
1315 | goto free; | 1048 | goto free; |
1316 | } | 1049 | } |
1317 | 1050 | ||
1318 | t = find_table_lock(tmp.name); | 1051 | t = xt_find_table_lock(AF_INET, tmp.name); |
1319 | if (!t || IS_ERR(t)) { | 1052 | if (!t || IS_ERR(t)) { |
1320 | ret = t ? PTR_ERR(t) : -ENOENT; | 1053 | ret = t ? PTR_ERR(t) : -ENOENT; |
1321 | goto free; | 1054 | goto free; |
1322 | } | 1055 | } |
1323 | 1056 | ||
1324 | write_lock_bh(&t->lock); | 1057 | write_lock_bh(&t->lock); |
1325 | if (t->private->number != paddc->num_counters) { | 1058 | private = t->private; |
1059 | if (private->number != paddc->num_counters) { | ||
1326 | ret = -EINVAL; | 1060 | ret = -EINVAL; |
1327 | goto unlock_up_free; | 1061 | goto unlock_up_free; |
1328 | } | 1062 | } |
1329 | 1063 | ||
1330 | i = 0; | 1064 | i = 0; |
1331 | /* Choose the copy that is on our node */ | 1065 | /* Choose the copy that is on our node */ |
1332 | loc_cpu_entry = t->private->entries[raw_smp_processor_id()]; | 1066 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; |
1333 | IPT_ENTRY_ITERATE(loc_cpu_entry, | 1067 | IPT_ENTRY_ITERATE(loc_cpu_entry, |
1334 | t->private->size, | 1068 | private->size, |
1335 | add_counter_to_entry, | 1069 | add_counter_to_entry, |
1336 | paddc->counters, | 1070 | paddc->counters, |
1337 | &i); | 1071 | &i); |
1338 | unlock_up_free: | 1072 | unlock_up_free: |
1339 | write_unlock_bh(&t->lock); | 1073 | write_unlock_bh(&t->lock); |
1340 | up(&ipt_mutex); | 1074 | xt_table_unlock(t); |
1341 | module_put(t->me); | 1075 | module_put(t->me); |
1342 | free: | 1076 | free: |
1343 | vfree(paddc); | 1077 | vfree(paddc); |
@@ -1396,25 +1130,26 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1396 | } | 1130 | } |
1397 | name[IPT_TABLE_MAXNAMELEN-1] = '\0'; | 1131 | name[IPT_TABLE_MAXNAMELEN-1] = '\0'; |
1398 | 1132 | ||
1399 | t = try_then_request_module(find_table_lock(name), | 1133 | t = try_then_request_module(xt_find_table_lock(AF_INET, name), |
1400 | "iptable_%s", name); | 1134 | "iptable_%s", name); |
1401 | if (t && !IS_ERR(t)) { | 1135 | if (t && !IS_ERR(t)) { |
1402 | struct ipt_getinfo info; | 1136 | struct ipt_getinfo info; |
1137 | struct xt_table_info *private = t->private; | ||
1403 | 1138 | ||
1404 | info.valid_hooks = t->valid_hooks; | 1139 | info.valid_hooks = t->valid_hooks; |
1405 | memcpy(info.hook_entry, t->private->hook_entry, | 1140 | memcpy(info.hook_entry, private->hook_entry, |
1406 | sizeof(info.hook_entry)); | 1141 | sizeof(info.hook_entry)); |
1407 | memcpy(info.underflow, t->private->underflow, | 1142 | memcpy(info.underflow, private->underflow, |
1408 | sizeof(info.underflow)); | 1143 | sizeof(info.underflow)); |
1409 | info.num_entries = t->private->number; | 1144 | info.num_entries = private->number; |
1410 | info.size = t->private->size; | 1145 | info.size = private->size; |
1411 | memcpy(info.name, name, sizeof(info.name)); | 1146 | memcpy(info.name, name, sizeof(info.name)); |
1412 | 1147 | ||
1413 | if (copy_to_user(user, &info, *len) != 0) | 1148 | if (copy_to_user(user, &info, *len) != 0) |
1414 | ret = -EFAULT; | 1149 | ret = -EFAULT; |
1415 | else | 1150 | else |
1416 | ret = 0; | 1151 | ret = 0; |
1417 | up(&ipt_mutex); | 1152 | xt_table_unlock(t); |
1418 | module_put(t->me); | 1153 | module_put(t->me); |
1419 | } else | 1154 | } else |
1420 | ret = t ? PTR_ERR(t) : -ENOENT; | 1155 | ret = t ? PTR_ERR(t) : -ENOENT; |
@@ -1441,7 +1176,7 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1441 | case IPT_SO_GET_REVISION_MATCH: | 1176 | case IPT_SO_GET_REVISION_MATCH: |
1442 | case IPT_SO_GET_REVISION_TARGET: { | 1177 | case IPT_SO_GET_REVISION_TARGET: { |
1443 | struct ipt_get_revision rev; | 1178 | struct ipt_get_revision rev; |
1444 | int (*revfn)(const char *, u8, int *); | 1179 | int target; |
1445 | 1180 | ||
1446 | if (*len != sizeof(rev)) { | 1181 | if (*len != sizeof(rev)) { |
1447 | ret = -EINVAL; | 1182 | ret = -EINVAL; |
@@ -1453,12 +1188,13 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1453 | } | 1188 | } |
1454 | 1189 | ||
1455 | if (cmd == IPT_SO_GET_REVISION_TARGET) | 1190 | if (cmd == IPT_SO_GET_REVISION_TARGET) |
1456 | revfn = target_revfn; | 1191 | target = 1; |
1457 | else | 1192 | else |
1458 | revfn = match_revfn; | 1193 | target = 0; |
1459 | 1194 | ||
1460 | try_then_request_module(find_revision(rev.name, rev.revision, | 1195 | try_then_request_module(xt_find_revision(AF_INET, rev.name, |
1461 | revfn, &ret), | 1196 | rev.revision, |
1197 | target, &ret), | ||
1462 | "ipt_%s", rev.name); | 1198 | "ipt_%s", rev.name); |
1463 | break; | 1199 | break; |
1464 | } | 1200 | } |
@@ -1471,60 +1207,15 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1471 | return ret; | 1207 | return ret; |
1472 | } | 1208 | } |
1473 | 1209 | ||
1474 | /* Registration hooks for targets. */ | 1210 | int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl) |
1475 | int | ||
1476 | ipt_register_target(struct ipt_target *target) | ||
1477 | { | 1211 | { |
1478 | int ret; | 1212 | int ret; |
1479 | 1213 | struct xt_table_info *newinfo; | |
1480 | ret = down_interruptible(&ipt_mutex); | 1214 | static struct xt_table_info bootstrap |
1481 | if (ret != 0) | ||
1482 | return ret; | ||
1483 | list_add(&target->list, &ipt_target); | ||
1484 | up(&ipt_mutex); | ||
1485 | return ret; | ||
1486 | } | ||
1487 | |||
1488 | void | ||
1489 | ipt_unregister_target(struct ipt_target *target) | ||
1490 | { | ||
1491 | down(&ipt_mutex); | ||
1492 | LIST_DELETE(&ipt_target, target); | ||
1493 | up(&ipt_mutex); | ||
1494 | } | ||
1495 | |||
1496 | int | ||
1497 | ipt_register_match(struct ipt_match *match) | ||
1498 | { | ||
1499 | int ret; | ||
1500 | |||
1501 | ret = down_interruptible(&ipt_mutex); | ||
1502 | if (ret != 0) | ||
1503 | return ret; | ||
1504 | |||
1505 | list_add(&match->list, &ipt_match); | ||
1506 | up(&ipt_mutex); | ||
1507 | |||
1508 | return ret; | ||
1509 | } | ||
1510 | |||
1511 | void | ||
1512 | ipt_unregister_match(struct ipt_match *match) | ||
1513 | { | ||
1514 | down(&ipt_mutex); | ||
1515 | LIST_DELETE(&ipt_match, match); | ||
1516 | up(&ipt_mutex); | ||
1517 | } | ||
1518 | |||
1519 | int ipt_register_table(struct ipt_table *table, const struct ipt_replace *repl) | ||
1520 | { | ||
1521 | int ret; | ||
1522 | struct ipt_table_info *newinfo; | ||
1523 | static struct ipt_table_info bootstrap | ||
1524 | = { 0, 0, 0, { 0 }, { 0 }, { } }; | 1215 | = { 0, 0, 0, { 0 }, { 0 }, { } }; |
1525 | void *loc_cpu_entry; | 1216 | void *loc_cpu_entry; |
1526 | 1217 | ||
1527 | newinfo = alloc_table_info(repl->size); | 1218 | newinfo = xt_alloc_table_info(repl->size); |
1528 | if (!newinfo) | 1219 | if (!newinfo) |
1529 | return -ENOMEM; | 1220 | return -ENOMEM; |
1530 | 1221 | ||
@@ -1540,246 +1231,29 @@ int ipt_register_table(struct ipt_table *table, const struct ipt_replace *repl) | |||
1540 | repl->hook_entry, | 1231 | repl->hook_entry, |
1541 | repl->underflow); | 1232 | repl->underflow); |
1542 | if (ret != 0) { | 1233 | if (ret != 0) { |
1543 | free_table_info(newinfo); | 1234 | xt_free_table_info(newinfo); |
1544 | return ret; | 1235 | return ret; |
1545 | } | 1236 | } |
1546 | 1237 | ||
1547 | ret = down_interruptible(&ipt_mutex); | 1238 | if (xt_register_table(table, &bootstrap, newinfo) != 0) { |
1548 | if (ret != 0) { | 1239 | xt_free_table_info(newinfo); |
1549 | free_table_info(newinfo); | ||
1550 | return ret; | 1240 | return ret; |
1551 | } | 1241 | } |
1552 | 1242 | ||
1553 | /* Don't autoload: we'd eat our tail... */ | 1243 | return 0; |
1554 | if (list_named_find(&ipt_tables, table->name)) { | ||
1555 | ret = -EEXIST; | ||
1556 | goto free_unlock; | ||
1557 | } | ||
1558 | |||
1559 | /* Simplifies replace_table code. */ | ||
1560 | table->private = &bootstrap; | ||
1561 | if (!replace_table(table, 0, newinfo, &ret)) | ||
1562 | goto free_unlock; | ||
1563 | |||
1564 | duprintf("table->private->number = %u\n", | ||
1565 | table->private->number); | ||
1566 | |||
1567 | /* save number of initial entries */ | ||
1568 | table->private->initial_entries = table->private->number; | ||
1569 | |||
1570 | rwlock_init(&table->lock); | ||
1571 | list_prepend(&ipt_tables, table); | ||
1572 | |||
1573 | unlock: | ||
1574 | up(&ipt_mutex); | ||
1575 | return ret; | ||
1576 | |||
1577 | free_unlock: | ||
1578 | free_table_info(newinfo); | ||
1579 | goto unlock; | ||
1580 | } | 1244 | } |
1581 | 1245 | ||
1582 | void ipt_unregister_table(struct ipt_table *table) | 1246 | void ipt_unregister_table(struct ipt_table *table) |
1583 | { | 1247 | { |
1248 | struct xt_table_info *private; | ||
1584 | void *loc_cpu_entry; | 1249 | void *loc_cpu_entry; |
1585 | 1250 | ||
1586 | down(&ipt_mutex); | 1251 | private = xt_unregister_table(table); |
1587 | LIST_DELETE(&ipt_tables, table); | ||
1588 | up(&ipt_mutex); | ||
1589 | 1252 | ||
1590 | /* Decrease module usage counts and free resources */ | 1253 | /* Decrease module usage counts and free resources */ |
1591 | loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; | 1254 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; |
1592 | IPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size, | 1255 | IPT_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL); |
1593 | cleanup_entry, NULL); | 1256 | xt_free_table_info(private); |
1594 | free_table_info(table->private); | ||
1595 | } | ||
1596 | |||
1597 | /* Returns 1 if the port is matched by the range, 0 otherwise */ | ||
1598 | static inline int | ||
1599 | port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert) | ||
1600 | { | ||
1601 | int ret; | ||
1602 | |||
1603 | ret = (port >= min && port <= max) ^ invert; | ||
1604 | return ret; | ||
1605 | } | ||
1606 | |||
1607 | static int | ||
1608 | tcp_find_option(u_int8_t option, | ||
1609 | const struct sk_buff *skb, | ||
1610 | unsigned int optlen, | ||
1611 | int invert, | ||
1612 | int *hotdrop) | ||
1613 | { | ||
1614 | /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ | ||
1615 | u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; | ||
1616 | unsigned int i; | ||
1617 | |||
1618 | duprintf("tcp_match: finding option\n"); | ||
1619 | |||
1620 | if (!optlen) | ||
1621 | return invert; | ||
1622 | |||
1623 | /* If we don't have the whole header, drop packet. */ | ||
1624 | op = skb_header_pointer(skb, | ||
1625 | skb->nh.iph->ihl*4 + sizeof(struct tcphdr), | ||
1626 | optlen, _opt); | ||
1627 | if (op == NULL) { | ||
1628 | *hotdrop = 1; | ||
1629 | return 0; | ||
1630 | } | ||
1631 | |||
1632 | for (i = 0; i < optlen; ) { | ||
1633 | if (op[i] == option) return !invert; | ||
1634 | if (op[i] < 2) i++; | ||
1635 | else i += op[i+1]?:1; | ||
1636 | } | ||
1637 | |||
1638 | return invert; | ||
1639 | } | ||
1640 | |||
1641 | static int | ||
1642 | tcp_match(const struct sk_buff *skb, | ||
1643 | const struct net_device *in, | ||
1644 | const struct net_device *out, | ||
1645 | const void *matchinfo, | ||
1646 | int offset, | ||
1647 | int *hotdrop) | ||
1648 | { | ||
1649 | struct tcphdr _tcph, *th; | ||
1650 | const struct ipt_tcp *tcpinfo = matchinfo; | ||
1651 | |||
1652 | if (offset) { | ||
1653 | /* To quote Alan: | ||
1654 | |||
1655 | Don't allow a fragment of TCP 8 bytes in. Nobody normal | ||
1656 | causes this. Its a cracker trying to break in by doing a | ||
1657 | flag overwrite to pass the direction checks. | ||
1658 | */ | ||
1659 | if (offset == 1) { | ||
1660 | duprintf("Dropping evil TCP offset=1 frag.\n"); | ||
1661 | *hotdrop = 1; | ||
1662 | } | ||
1663 | /* Must not be a fragment. */ | ||
1664 | return 0; | ||
1665 | } | ||
1666 | |||
1667 | #define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) | ||
1668 | |||
1669 | th = skb_header_pointer(skb, skb->nh.iph->ihl*4, | ||
1670 | sizeof(_tcph), &_tcph); | ||
1671 | if (th == NULL) { | ||
1672 | /* We've been asked to examine this packet, and we | ||
1673 | can't. Hence, no choice but to drop. */ | ||
1674 | duprintf("Dropping evil TCP offset=0 tinygram.\n"); | ||
1675 | *hotdrop = 1; | ||
1676 | return 0; | ||
1677 | } | ||
1678 | |||
1679 | if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1], | ||
1680 | ntohs(th->source), | ||
1681 | !!(tcpinfo->invflags & IPT_TCP_INV_SRCPT))) | ||
1682 | return 0; | ||
1683 | if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1], | ||
1684 | ntohs(th->dest), | ||
1685 | !!(tcpinfo->invflags & IPT_TCP_INV_DSTPT))) | ||
1686 | return 0; | ||
1687 | if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask) | ||
1688 | == tcpinfo->flg_cmp, | ||
1689 | IPT_TCP_INV_FLAGS)) | ||
1690 | return 0; | ||
1691 | if (tcpinfo->option) { | ||
1692 | if (th->doff * 4 < sizeof(_tcph)) { | ||
1693 | *hotdrop = 1; | ||
1694 | return 0; | ||
1695 | } | ||
1696 | if (!tcp_find_option(tcpinfo->option, skb, | ||
1697 | th->doff*4 - sizeof(_tcph), | ||
1698 | tcpinfo->invflags & IPT_TCP_INV_OPTION, | ||
1699 | hotdrop)) | ||
1700 | return 0; | ||
1701 | } | ||
1702 | return 1; | ||
1703 | } | ||
1704 | |||
1705 | /* Called when user tries to insert an entry of this type. */ | ||
1706 | static int | ||
1707 | tcp_checkentry(const char *tablename, | ||
1708 | const struct ipt_ip *ip, | ||
1709 | void *matchinfo, | ||
1710 | unsigned int matchsize, | ||
1711 | unsigned int hook_mask) | ||
1712 | { | ||
1713 | const struct ipt_tcp *tcpinfo = matchinfo; | ||
1714 | |||
1715 | /* Must specify proto == TCP, and no unknown invflags */ | ||
1716 | return ip->proto == IPPROTO_TCP | ||
1717 | && !(ip->invflags & IPT_INV_PROTO) | ||
1718 | && matchsize == IPT_ALIGN(sizeof(struct ipt_tcp)) | ||
1719 | && !(tcpinfo->invflags & ~IPT_TCP_INV_MASK); | ||
1720 | } | ||
1721 | |||
1722 | static int | ||
1723 | udp_match(const struct sk_buff *skb, | ||
1724 | const struct net_device *in, | ||
1725 | const struct net_device *out, | ||
1726 | const void *matchinfo, | ||
1727 | int offset, | ||
1728 | int *hotdrop) | ||
1729 | { | ||
1730 | struct udphdr _udph, *uh; | ||
1731 | const struct ipt_udp *udpinfo = matchinfo; | ||
1732 | |||
1733 | /* Must not be a fragment. */ | ||
1734 | if (offset) | ||
1735 | return 0; | ||
1736 | |||
1737 | uh = skb_header_pointer(skb, skb->nh.iph->ihl*4, | ||
1738 | sizeof(_udph), &_udph); | ||
1739 | if (uh == NULL) { | ||
1740 | /* We've been asked to examine this packet, and we | ||
1741 | can't. Hence, no choice but to drop. */ | ||
1742 | duprintf("Dropping evil UDP tinygram.\n"); | ||
1743 | *hotdrop = 1; | ||
1744 | return 0; | ||
1745 | } | ||
1746 | |||
1747 | return port_match(udpinfo->spts[0], udpinfo->spts[1], | ||
1748 | ntohs(uh->source), | ||
1749 | !!(udpinfo->invflags & IPT_UDP_INV_SRCPT)) | ||
1750 | && port_match(udpinfo->dpts[0], udpinfo->dpts[1], | ||
1751 | ntohs(uh->dest), | ||
1752 | !!(udpinfo->invflags & IPT_UDP_INV_DSTPT)); | ||
1753 | } | ||
1754 | |||
1755 | /* Called when user tries to insert an entry of this type. */ | ||
1756 | static int | ||
1757 | udp_checkentry(const char *tablename, | ||
1758 | const struct ipt_ip *ip, | ||
1759 | void *matchinfo, | ||
1760 | unsigned int matchinfosize, | ||
1761 | unsigned int hook_mask) | ||
1762 | { | ||
1763 | const struct ipt_udp *udpinfo = matchinfo; | ||
1764 | |||
1765 | /* Must specify proto == UDP, and no unknown invflags */ | ||
1766 | if (ip->proto != IPPROTO_UDP || (ip->invflags & IPT_INV_PROTO)) { | ||
1767 | duprintf("ipt_udp: Protocol %u != %u\n", ip->proto, | ||
1768 | IPPROTO_UDP); | ||
1769 | return 0; | ||
1770 | } | ||
1771 | if (matchinfosize != IPT_ALIGN(sizeof(struct ipt_udp))) { | ||
1772 | duprintf("ipt_udp: matchsize %u != %u\n", | ||
1773 | matchinfosize, IPT_ALIGN(sizeof(struct ipt_udp))); | ||
1774 | return 0; | ||
1775 | } | ||
1776 | if (udpinfo->invflags & ~IPT_UDP_INV_MASK) { | ||
1777 | duprintf("ipt_udp: unknown flags %X\n", | ||
1778 | udpinfo->invflags); | ||
1779 | return 0; | ||
1780 | } | ||
1781 | |||
1782 | return 1; | ||
1783 | } | 1257 | } |
1784 | 1258 | ||
1785 | /* Returns 1 if the type and code is matched by the range, 0 otherwise */ | 1259 | /* Returns 1 if the type and code is matched by the range, 0 otherwise */ |
@@ -1798,6 +1272,7 @@ icmp_match(const struct sk_buff *skb, | |||
1798 | const struct net_device *out, | 1272 | const struct net_device *out, |
1799 | const void *matchinfo, | 1273 | const void *matchinfo, |
1800 | int offset, | 1274 | int offset, |
1275 | unsigned int protoff, | ||
1801 | int *hotdrop) | 1276 | int *hotdrop) |
1802 | { | 1277 | { |
1803 | struct icmphdr _icmph, *ic; | 1278 | struct icmphdr _icmph, *ic; |
@@ -1807,8 +1282,7 @@ icmp_match(const struct sk_buff *skb, | |||
1807 | if (offset) | 1282 | if (offset) |
1808 | return 0; | 1283 | return 0; |
1809 | 1284 | ||
1810 | ic = skb_header_pointer(skb, skb->nh.iph->ihl*4, | 1285 | ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph); |
1811 | sizeof(_icmph), &_icmph); | ||
1812 | if (ic == NULL) { | 1286 | if (ic == NULL) { |
1813 | /* We've been asked to examine this packet, and we | 1287 | /* We've been asked to examine this packet, and we |
1814 | * can't. Hence, no choice but to drop. | 1288 | * can't. Hence, no choice but to drop. |
@@ -1828,11 +1302,12 @@ icmp_match(const struct sk_buff *skb, | |||
1828 | /* Called when user tries to insert an entry of this type. */ | 1302 | /* Called when user tries to insert an entry of this type. */ |
1829 | static int | 1303 | static int |
1830 | icmp_checkentry(const char *tablename, | 1304 | icmp_checkentry(const char *tablename, |
1831 | const struct ipt_ip *ip, | 1305 | const void *info, |
1832 | void *matchinfo, | 1306 | void *matchinfo, |
1833 | unsigned int matchsize, | 1307 | unsigned int matchsize, |
1834 | unsigned int hook_mask) | 1308 | unsigned int hook_mask) |
1835 | { | 1309 | { |
1310 | const struct ipt_ip *ip = info; | ||
1836 | const struct ipt_icmp *icmpinfo = matchinfo; | 1311 | const struct ipt_icmp *icmpinfo = matchinfo; |
1837 | 1312 | ||
1838 | /* Must specify proto == ICMP, and no unknown invflags */ | 1313 | /* Must specify proto == ICMP, and no unknown invflags */ |
@@ -1862,123 +1337,22 @@ static struct nf_sockopt_ops ipt_sockopts = { | |||
1862 | .get = do_ipt_get_ctl, | 1337 | .get = do_ipt_get_ctl, |
1863 | }; | 1338 | }; |
1864 | 1339 | ||
1865 | static struct ipt_match tcp_matchstruct = { | ||
1866 | .name = "tcp", | ||
1867 | .match = &tcp_match, | ||
1868 | .checkentry = &tcp_checkentry, | ||
1869 | }; | ||
1870 | |||
1871 | static struct ipt_match udp_matchstruct = { | ||
1872 | .name = "udp", | ||
1873 | .match = &udp_match, | ||
1874 | .checkentry = &udp_checkentry, | ||
1875 | }; | ||
1876 | |||
1877 | static struct ipt_match icmp_matchstruct = { | 1340 | static struct ipt_match icmp_matchstruct = { |
1878 | .name = "icmp", | 1341 | .name = "icmp", |
1879 | .match = &icmp_match, | 1342 | .match = &icmp_match, |
1880 | .checkentry = &icmp_checkentry, | 1343 | .checkentry = &icmp_checkentry, |
1881 | }; | 1344 | }; |
1882 | 1345 | ||
1883 | #ifdef CONFIG_PROC_FS | ||
1884 | static inline int print_name(const char *i, | ||
1885 | off_t start_offset, char *buffer, int length, | ||
1886 | off_t *pos, unsigned int *count) | ||
1887 | { | ||
1888 | if ((*count)++ >= start_offset) { | ||
1889 | unsigned int namelen; | ||
1890 | |||
1891 | namelen = sprintf(buffer + *pos, "%s\n", | ||
1892 | i + sizeof(struct list_head)); | ||
1893 | if (*pos + namelen > length) { | ||
1894 | /* Stop iterating */ | ||
1895 | return 1; | ||
1896 | } | ||
1897 | *pos += namelen; | ||
1898 | } | ||
1899 | return 0; | ||
1900 | } | ||
1901 | |||
1902 | static inline int print_target(const struct ipt_target *t, | ||
1903 | off_t start_offset, char *buffer, int length, | ||
1904 | off_t *pos, unsigned int *count) | ||
1905 | { | ||
1906 | if (t == &ipt_standard_target || t == &ipt_error_target) | ||
1907 | return 0; | ||
1908 | return print_name((char *)t, start_offset, buffer, length, pos, count); | ||
1909 | } | ||
1910 | |||
1911 | static int ipt_get_tables(char *buffer, char **start, off_t offset, int length) | ||
1912 | { | ||
1913 | off_t pos = 0; | ||
1914 | unsigned int count = 0; | ||
1915 | |||
1916 | if (down_interruptible(&ipt_mutex) != 0) | ||
1917 | return 0; | ||
1918 | |||
1919 | LIST_FIND(&ipt_tables, print_name, void *, | ||
1920 | offset, buffer, length, &pos, &count); | ||
1921 | |||
1922 | up(&ipt_mutex); | ||
1923 | |||
1924 | /* `start' hack - see fs/proc/generic.c line ~105 */ | ||
1925 | *start=(char *)((unsigned long)count-offset); | ||
1926 | return pos; | ||
1927 | } | ||
1928 | |||
1929 | static int ipt_get_targets(char *buffer, char **start, off_t offset, int length) | ||
1930 | { | ||
1931 | off_t pos = 0; | ||
1932 | unsigned int count = 0; | ||
1933 | |||
1934 | if (down_interruptible(&ipt_mutex) != 0) | ||
1935 | return 0; | ||
1936 | |||
1937 | LIST_FIND(&ipt_target, print_target, struct ipt_target *, | ||
1938 | offset, buffer, length, &pos, &count); | ||
1939 | |||
1940 | up(&ipt_mutex); | ||
1941 | |||
1942 | *start = (char *)((unsigned long)count - offset); | ||
1943 | return pos; | ||
1944 | } | ||
1945 | |||
1946 | static int ipt_get_matches(char *buffer, char **start, off_t offset, int length) | ||
1947 | { | ||
1948 | off_t pos = 0; | ||
1949 | unsigned int count = 0; | ||
1950 | |||
1951 | if (down_interruptible(&ipt_mutex) != 0) | ||
1952 | return 0; | ||
1953 | |||
1954 | LIST_FIND(&ipt_match, print_name, void *, | ||
1955 | offset, buffer, length, &pos, &count); | ||
1956 | |||
1957 | up(&ipt_mutex); | ||
1958 | |||
1959 | *start = (char *)((unsigned long)count - offset); | ||
1960 | return pos; | ||
1961 | } | ||
1962 | |||
1963 | static const struct { char *name; get_info_t *get_info; } ipt_proc_entry[] = | ||
1964 | { { "ip_tables_names", ipt_get_tables }, | ||
1965 | { "ip_tables_targets", ipt_get_targets }, | ||
1966 | { "ip_tables_matches", ipt_get_matches }, | ||
1967 | { NULL, NULL} }; | ||
1968 | #endif /*CONFIG_PROC_FS*/ | ||
1969 | |||
1970 | static int __init init(void) | 1346 | static int __init init(void) |
1971 | { | 1347 | { |
1972 | int ret; | 1348 | int ret; |
1973 | 1349 | ||
1350 | xt_proto_init(AF_INET); | ||
1351 | |||
1974 | /* Noone else will be downing sem now, so we won't sleep */ | 1352 | /* Noone else will be downing sem now, so we won't sleep */ |
1975 | down(&ipt_mutex); | 1353 | xt_register_target(AF_INET, &ipt_standard_target); |
1976 | list_append(&ipt_target, &ipt_standard_target); | 1354 | xt_register_target(AF_INET, &ipt_error_target); |
1977 | list_append(&ipt_target, &ipt_error_target); | 1355 | xt_register_match(AF_INET, &icmp_matchstruct); |
1978 | list_append(&ipt_match, &tcp_matchstruct); | ||
1979 | list_append(&ipt_match, &udp_matchstruct); | ||
1980 | list_append(&ipt_match, &icmp_matchstruct); | ||
1981 | up(&ipt_mutex); | ||
1982 | 1356 | ||
1983 | /* Register setsockopt */ | 1357 | /* Register setsockopt */ |
1984 | ret = nf_register_sockopt(&ipt_sockopts); | 1358 | ret = nf_register_sockopt(&ipt_sockopts); |
@@ -1987,49 +1361,23 @@ static int __init init(void) | |||
1987 | return ret; | 1361 | return ret; |
1988 | } | 1362 | } |
1989 | 1363 | ||
1990 | #ifdef CONFIG_PROC_FS | 1364 | printk("ip_tables: (C) 2000-2006 Netfilter Core Team\n"); |
1991 | { | ||
1992 | struct proc_dir_entry *proc; | ||
1993 | int i; | ||
1994 | |||
1995 | for (i = 0; ipt_proc_entry[i].name; i++) { | ||
1996 | proc = proc_net_create(ipt_proc_entry[i].name, 0, | ||
1997 | ipt_proc_entry[i].get_info); | ||
1998 | if (!proc) { | ||
1999 | while (--i >= 0) | ||
2000 | proc_net_remove(ipt_proc_entry[i].name); | ||
2001 | nf_unregister_sockopt(&ipt_sockopts); | ||
2002 | return -ENOMEM; | ||
2003 | } | ||
2004 | proc->owner = THIS_MODULE; | ||
2005 | } | ||
2006 | } | ||
2007 | #endif | ||
2008 | |||
2009 | printk("ip_tables: (C) 2000-2002 Netfilter core team\n"); | ||
2010 | return 0; | 1365 | return 0; |
2011 | } | 1366 | } |
2012 | 1367 | ||
2013 | static void __exit fini(void) | 1368 | static void __exit fini(void) |
2014 | { | 1369 | { |
2015 | nf_unregister_sockopt(&ipt_sockopts); | 1370 | nf_unregister_sockopt(&ipt_sockopts); |
2016 | #ifdef CONFIG_PROC_FS | 1371 | |
2017 | { | 1372 | xt_unregister_match(AF_INET, &icmp_matchstruct); |
2018 | int i; | 1373 | xt_unregister_target(AF_INET, &ipt_error_target); |
2019 | for (i = 0; ipt_proc_entry[i].name; i++) | 1374 | xt_unregister_target(AF_INET, &ipt_standard_target); |
2020 | proc_net_remove(ipt_proc_entry[i].name); | 1375 | |
2021 | } | 1376 | xt_proto_fini(AF_INET); |
2022 | #endif | ||
2023 | } | 1377 | } |
2024 | 1378 | ||
2025 | EXPORT_SYMBOL(ipt_register_table); | 1379 | EXPORT_SYMBOL(ipt_register_table); |
2026 | EXPORT_SYMBOL(ipt_unregister_table); | 1380 | EXPORT_SYMBOL(ipt_unregister_table); |
2027 | EXPORT_SYMBOL(ipt_register_match); | ||
2028 | EXPORT_SYMBOL(ipt_unregister_match); | ||
2029 | EXPORT_SYMBOL(ipt_do_table); | 1381 | EXPORT_SYMBOL(ipt_do_table); |
2030 | EXPORT_SYMBOL(ipt_register_target); | ||
2031 | EXPORT_SYMBOL(ipt_unregister_target); | ||
2032 | EXPORT_SYMBOL(ipt_find_target); | ||
2033 | |||
2034 | module_init(init); | 1382 | module_init(init); |
2035 | module_exit(fini); | 1383 | module_exit(fini); |
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 45c52d8f4d99..d9bc971f03af 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -379,12 +379,13 @@ target(struct sk_buff **pskb, | |||
379 | 379 | ||
380 | static int | 380 | static int |
381 | checkentry(const char *tablename, | 381 | checkentry(const char *tablename, |
382 | const struct ipt_entry *e, | 382 | const void *e_void, |
383 | void *targinfo, | 383 | void *targinfo, |
384 | unsigned int targinfosize, | 384 | unsigned int targinfosize, |
385 | unsigned int hook_mask) | 385 | unsigned int hook_mask) |
386 | { | 386 | { |
387 | struct ipt_clusterip_tgt_info *cipinfo = targinfo; | 387 | struct ipt_clusterip_tgt_info *cipinfo = targinfo; |
388 | const struct ipt_entry *e = e_void; | ||
388 | 389 | ||
389 | struct clusterip_config *config; | 390 | struct clusterip_config *config; |
390 | 391 | ||
diff --git a/net/ipv4/netfilter/ipt_DSCP.c b/net/ipv4/netfilter/ipt_DSCP.c index 6e319570a28c..898cdf79ce18 100644 --- a/net/ipv4/netfilter/ipt_DSCP.c +++ b/net/ipv4/netfilter/ipt_DSCP.c | |||
@@ -57,7 +57,7 @@ target(struct sk_buff **pskb, | |||
57 | 57 | ||
58 | static int | 58 | static int |
59 | checkentry(const char *tablename, | 59 | checkentry(const char *tablename, |
60 | const struct ipt_entry *e, | 60 | const void *e_void, |
61 | void *targinfo, | 61 | void *targinfo, |
62 | unsigned int targinfosize, | 62 | unsigned int targinfosize, |
63 | unsigned int hook_mask) | 63 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c index a1319693f648..706445426a6d 100644 --- a/net/ipv4/netfilter/ipt_ECN.c +++ b/net/ipv4/netfilter/ipt_ECN.c | |||
@@ -113,12 +113,13 @@ target(struct sk_buff **pskb, | |||
113 | 113 | ||
114 | static int | 114 | static int |
115 | checkentry(const char *tablename, | 115 | checkentry(const char *tablename, |
116 | const struct ipt_entry *e, | 116 | const void *e_void, |
117 | void *targinfo, | 117 | void *targinfo, |
118 | unsigned int targinfosize, | 118 | unsigned int targinfosize, |
119 | unsigned int hook_mask) | 119 | unsigned int hook_mask) |
120 | { | 120 | { |
121 | const struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)targinfo; | 121 | const struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)targinfo; |
122 | const struct ipt_entry *e = e_void; | ||
122 | 123 | ||
123 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ECN_info))) { | 124 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ECN_info))) { |
124 | printk(KERN_WARNING "ECN: targinfosize %u != %Zu\n", | 125 | printk(KERN_WARNING "ECN: targinfosize %u != %Zu\n", |
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index 30be0f1dae37..6606ddb66a29 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c | |||
@@ -431,7 +431,7 @@ ipt_log_target(struct sk_buff **pskb, | |||
431 | } | 431 | } |
432 | 432 | ||
433 | static int ipt_log_checkentry(const char *tablename, | 433 | static int ipt_log_checkentry(const char *tablename, |
434 | const struct ipt_entry *e, | 434 | const void *e, |
435 | void *targinfo, | 435 | void *targinfo, |
436 | unsigned int targinfosize, | 436 | unsigned int targinfosize, |
437 | unsigned int hook_mask) | 437 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c index 27860510ca6d..12c56d3343ca 100644 --- a/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c | |||
@@ -40,7 +40,7 @@ static DEFINE_RWLOCK(masq_lock); | |||
40 | /* FIXME: Multiple targets. --RR */ | 40 | /* FIXME: Multiple targets. --RR */ |
41 | static int | 41 | static int |
42 | masquerade_check(const char *tablename, | 42 | masquerade_check(const char *tablename, |
43 | const struct ipt_entry *e, | 43 | const void *e, |
44 | void *targinfo, | 44 | void *targinfo, |
45 | unsigned int targinfosize, | 45 | unsigned int targinfosize, |
46 | unsigned int hook_mask) | 46 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c index e6e7b6095363..b074467fe67b 100644 --- a/net/ipv4/netfilter/ipt_NETMAP.c +++ b/net/ipv4/netfilter/ipt_NETMAP.c | |||
@@ -31,7 +31,7 @@ MODULE_DESCRIPTION("iptables 1:1 NAT mapping of IP networks target"); | |||
31 | 31 | ||
32 | static int | 32 | static int |
33 | check(const char *tablename, | 33 | check(const char *tablename, |
34 | const struct ipt_entry *e, | 34 | const void *e, |
35 | void *targinfo, | 35 | void *targinfo, |
36 | unsigned int targinfosize, | 36 | unsigned int targinfosize, |
37 | unsigned int hook_mask) | 37 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_NFQUEUE.c b/net/ipv4/netfilter/ipt_NFQUEUE.c deleted file mode 100644 index 3cedc9be8807..000000000000 --- a/net/ipv4/netfilter/ipt_NFQUEUE.c +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
1 | /* iptables module for using new netfilter netlink queue | ||
2 | * | ||
3 | * (C) 2005 by Harald Welte <laforge@netfilter.org> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/skbuff.h> | ||
13 | |||
14 | #include <linux/netfilter.h> | ||
15 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
16 | #include <linux/netfilter_ipv4/ipt_NFQUEUE.h> | ||
17 | |||
18 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | ||
19 | MODULE_DESCRIPTION("iptables NFQUEUE target"); | ||
20 | MODULE_LICENSE("GPL"); | ||
21 | |||
22 | static unsigned int | ||
23 | target(struct sk_buff **pskb, | ||
24 | const struct net_device *in, | ||
25 | const struct net_device *out, | ||
26 | unsigned int hooknum, | ||
27 | const void *targinfo, | ||
28 | void *userinfo) | ||
29 | { | ||
30 | const struct ipt_NFQ_info *tinfo = targinfo; | ||
31 | |||
32 | return NF_QUEUE_NR(tinfo->queuenum); | ||
33 | } | ||
34 | |||
35 | static int | ||
36 | checkentry(const char *tablename, | ||
37 | const struct ipt_entry *e, | ||
38 | void *targinfo, | ||
39 | unsigned int targinfosize, | ||
40 | unsigned int hook_mask) | ||
41 | { | ||
42 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_NFQ_info))) { | ||
43 | printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n", | ||
44 | targinfosize, | ||
45 | IPT_ALIGN(sizeof(struct ipt_NFQ_info))); | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | return 1; | ||
50 | } | ||
51 | |||
52 | static struct ipt_target ipt_NFQ_reg = { | ||
53 | .name = "NFQUEUE", | ||
54 | .target = target, | ||
55 | .checkentry = checkentry, | ||
56 | .me = THIS_MODULE, | ||
57 | }; | ||
58 | |||
59 | static int __init init(void) | ||
60 | { | ||
61 | return ipt_register_target(&ipt_NFQ_reg); | ||
62 | } | ||
63 | |||
64 | static void __exit fini(void) | ||
65 | { | ||
66 | ipt_unregister_target(&ipt_NFQ_reg); | ||
67 | } | ||
68 | |||
69 | module_init(init); | ||
70 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c index 5245bfd33d52..140be51f2f01 100644 --- a/net/ipv4/netfilter/ipt_REDIRECT.c +++ b/net/ipv4/netfilter/ipt_REDIRECT.c | |||
@@ -33,7 +33,7 @@ MODULE_DESCRIPTION("iptables REDIRECT target module"); | |||
33 | /* FIXME: Take multiple ranges --RR */ | 33 | /* FIXME: Take multiple ranges --RR */ |
34 | static int | 34 | static int |
35 | redirect_check(const char *tablename, | 35 | redirect_check(const char *tablename, |
36 | const struct ipt_entry *e, | 36 | const void *e, |
37 | void *targinfo, | 37 | void *targinfo, |
38 | unsigned int targinfosize, | 38 | unsigned int targinfosize, |
39 | unsigned int hook_mask) | 39 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 6693526ae128..3eb47aae78c5 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -282,12 +282,13 @@ static unsigned int reject(struct sk_buff **pskb, | |||
282 | } | 282 | } |
283 | 283 | ||
284 | static int check(const char *tablename, | 284 | static int check(const char *tablename, |
285 | const struct ipt_entry *e, | 285 | const void *e_void, |
286 | void *targinfo, | 286 | void *targinfo, |
287 | unsigned int targinfosize, | 287 | unsigned int targinfosize, |
288 | unsigned int hook_mask) | 288 | unsigned int hook_mask) |
289 | { | 289 | { |
290 | const struct ipt_reject_info *rejinfo = targinfo; | 290 | const struct ipt_reject_info *rejinfo = targinfo; |
291 | const struct ipt_entry *e = e_void; | ||
291 | 292 | ||
292 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_reject_info))) { | 293 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_reject_info))) { |
293 | DEBUGP("REJECT: targinfosize %u != 0\n", targinfosize); | 294 | DEBUGP("REJECT: targinfosize %u != 0\n", targinfosize); |
diff --git a/net/ipv4/netfilter/ipt_SAME.c b/net/ipv4/netfilter/ipt_SAME.c index 7a0536d864ac..a22de59bba0e 100644 --- a/net/ipv4/netfilter/ipt_SAME.c +++ b/net/ipv4/netfilter/ipt_SAME.c | |||
@@ -49,7 +49,7 @@ MODULE_DESCRIPTION("iptables special SNAT module for consistent sourceip"); | |||
49 | 49 | ||
50 | static int | 50 | static int |
51 | same_check(const char *tablename, | 51 | same_check(const char *tablename, |
52 | const struct ipt_entry *e, | 52 | const void *e, |
53 | void *targinfo, | 53 | void *targinfo, |
54 | unsigned int targinfosize, | 54 | unsigned int targinfosize, |
55 | unsigned int hook_mask) | 55 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_TCPMSS.c b/net/ipv4/netfilter/ipt_TCPMSS.c index 8db70d6908c3..c122841e182c 100644 --- a/net/ipv4/netfilter/ipt_TCPMSS.c +++ b/net/ipv4/netfilter/ipt_TCPMSS.c | |||
@@ -210,12 +210,13 @@ static inline int find_syn_match(const struct ipt_entry_match *m) | |||
210 | /* Must specify -p tcp --syn/--tcp-flags SYN */ | 210 | /* Must specify -p tcp --syn/--tcp-flags SYN */ |
211 | static int | 211 | static int |
212 | ipt_tcpmss_checkentry(const char *tablename, | 212 | ipt_tcpmss_checkentry(const char *tablename, |
213 | const struct ipt_entry *e, | 213 | const void *e_void, |
214 | void *targinfo, | 214 | void *targinfo, |
215 | unsigned int targinfosize, | 215 | unsigned int targinfosize, |
216 | unsigned int hook_mask) | 216 | unsigned int hook_mask) |
217 | { | 217 | { |
218 | const struct ipt_tcpmss_info *tcpmssinfo = targinfo; | 218 | const struct ipt_tcpmss_info *tcpmssinfo = targinfo; |
219 | const struct ipt_entry *e = e_void; | ||
219 | 220 | ||
220 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_tcpmss_info))) { | 221 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_tcpmss_info))) { |
221 | DEBUGP("ipt_tcpmss_checkentry: targinfosize %u != %u\n", | 222 | DEBUGP("ipt_tcpmss_checkentry: targinfosize %u != %u\n", |
diff --git a/net/ipv4/netfilter/ipt_TOS.c b/net/ipv4/netfilter/ipt_TOS.c index deadb36d4428..3a44a56db239 100644 --- a/net/ipv4/netfilter/ipt_TOS.c +++ b/net/ipv4/netfilter/ipt_TOS.c | |||
@@ -52,7 +52,7 @@ target(struct sk_buff **pskb, | |||
52 | 52 | ||
53 | static int | 53 | static int |
54 | checkentry(const char *tablename, | 54 | checkentry(const char *tablename, |
55 | const struct ipt_entry *e, | 55 | const void *e_void, |
56 | void *targinfo, | 56 | void *targinfo, |
57 | unsigned int targinfosize, | 57 | unsigned int targinfosize, |
58 | unsigned int hook_mask) | 58 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_TTL.c b/net/ipv4/netfilter/ipt_TTL.c index b9ae6a9382f3..b769eb231970 100644 --- a/net/ipv4/netfilter/ipt_TTL.c +++ b/net/ipv4/netfilter/ipt_TTL.c | |||
@@ -66,7 +66,7 @@ ipt_ttl_target(struct sk_buff **pskb, const struct net_device *in, | |||
66 | } | 66 | } |
67 | 67 | ||
68 | static int ipt_ttl_checkentry(const char *tablename, | 68 | static int ipt_ttl_checkentry(const char *tablename, |
69 | const struct ipt_entry *e, | 69 | const void *e, |
70 | void *targinfo, | 70 | void *targinfo, |
71 | unsigned int targinfosize, | 71 | unsigned int targinfosize, |
72 | unsigned int hook_mask) | 72 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index 38641cd06123..641dbc477650 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c | |||
@@ -330,7 +330,7 @@ static void ipt_logfn(unsigned int pf, | |||
330 | } | 330 | } |
331 | 331 | ||
332 | static int ipt_ulog_checkentry(const char *tablename, | 332 | static int ipt_ulog_checkentry(const char *tablename, |
333 | const struct ipt_entry *e, | 333 | const void *e, |
334 | void *targinfo, | 334 | void *targinfo, |
335 | unsigned int targinfosize, | 335 | unsigned int targinfosize, |
336 | unsigned int hookmask) | 336 | unsigned int hookmask) |
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c index e19c2a52d00c..d6b83a976518 100644 --- a/net/ipv4/netfilter/ipt_addrtype.c +++ b/net/ipv4/netfilter/ipt_addrtype.c | |||
@@ -29,7 +29,7 @@ static inline int match_type(u_int32_t addr, u_int16_t mask) | |||
29 | 29 | ||
30 | static int match(const struct sk_buff *skb, const struct net_device *in, | 30 | static int match(const struct sk_buff *skb, const struct net_device *in, |
31 | const struct net_device *out, const void *matchinfo, | 31 | const struct net_device *out, const void *matchinfo, |
32 | int offset, int *hotdrop) | 32 | int offset, unsigned int protoff, int *hotdrop) |
33 | { | 33 | { |
34 | const struct ipt_addrtype_info *info = matchinfo; | 34 | const struct ipt_addrtype_info *info = matchinfo; |
35 | const struct iphdr *iph = skb->nh.iph; | 35 | const struct iphdr *iph = skb->nh.iph; |
@@ -43,7 +43,7 @@ static int match(const struct sk_buff *skb, const struct net_device *in, | |||
43 | return ret; | 43 | return ret; |
44 | } | 44 | } |
45 | 45 | ||
46 | static int checkentry(const char *tablename, const struct ipt_ip *ip, | 46 | static int checkentry(const char *tablename, const void *ip, |
47 | void *matchinfo, unsigned int matchsize, | 47 | void *matchinfo, unsigned int matchsize, |
48 | unsigned int hook_mask) | 48 | unsigned int hook_mask) |
49 | { | 49 | { |
diff --git a/net/ipv4/netfilter/ipt_ah.c b/net/ipv4/netfilter/ipt_ah.c index a0fea847cb72..144adfec13cc 100644 --- a/net/ipv4/netfilter/ipt_ah.c +++ b/net/ipv4/netfilter/ipt_ah.c | |||
@@ -41,6 +41,7 @@ match(const struct sk_buff *skb, | |||
41 | const struct net_device *out, | 41 | const struct net_device *out, |
42 | const void *matchinfo, | 42 | const void *matchinfo, |
43 | int offset, | 43 | int offset, |
44 | unsigned int protoff, | ||
44 | int *hotdrop) | 45 | int *hotdrop) |
45 | { | 46 | { |
46 | struct ip_auth_hdr _ahdr, *ah; | 47 | struct ip_auth_hdr _ahdr, *ah; |
@@ -50,7 +51,7 @@ match(const struct sk_buff *skb, | |||
50 | if (offset) | 51 | if (offset) |
51 | return 0; | 52 | return 0; |
52 | 53 | ||
53 | ah = skb_header_pointer(skb, skb->nh.iph->ihl * 4, | 54 | ah = skb_header_pointer(skb, protoff, |
54 | sizeof(_ahdr), &_ahdr); | 55 | sizeof(_ahdr), &_ahdr); |
55 | if (ah == NULL) { | 56 | if (ah == NULL) { |
56 | /* We've been asked to examine this packet, and we | 57 | /* We've been asked to examine this packet, and we |
@@ -69,12 +70,13 @@ match(const struct sk_buff *skb, | |||
69 | /* Called when user tries to insert an entry of this type. */ | 70 | /* Called when user tries to insert an entry of this type. */ |
70 | static int | 71 | static int |
71 | checkentry(const char *tablename, | 72 | checkentry(const char *tablename, |
72 | const struct ipt_ip *ip, | 73 | const void *ip_void, |
73 | void *matchinfo, | 74 | void *matchinfo, |
74 | unsigned int matchinfosize, | 75 | unsigned int matchinfosize, |
75 | unsigned int hook_mask) | 76 | unsigned int hook_mask) |
76 | { | 77 | { |
77 | const struct ipt_ah *ahinfo = matchinfo; | 78 | const struct ipt_ah *ahinfo = matchinfo; |
79 | const struct ipt_ip *ip = ip_void; | ||
78 | 80 | ||
79 | /* Must specify proto == AH, and no unknown invflags */ | 81 | /* Must specify proto == AH, and no unknown invflags */ |
80 | if (ip->proto != IPPROTO_AH || (ip->invflags & IPT_INV_PROTO)) { | 82 | if (ip->proto != IPPROTO_AH || (ip->invflags & IPT_INV_PROTO)) { |
diff --git a/net/ipv4/netfilter/ipt_dscp.c b/net/ipv4/netfilter/ipt_dscp.c index 5df52a64a5d4..92063b4f8602 100644 --- a/net/ipv4/netfilter/ipt_dscp.c +++ b/net/ipv4/netfilter/ipt_dscp.c | |||
@@ -21,7 +21,7 @@ MODULE_LICENSE("GPL"); | |||
21 | 21 | ||
22 | static int match(const struct sk_buff *skb, const struct net_device *in, | 22 | static int match(const struct sk_buff *skb, const struct net_device *in, |
23 | const struct net_device *out, const void *matchinfo, | 23 | const struct net_device *out, const void *matchinfo, |
24 | int offset, int *hotdrop) | 24 | int offset, unsigned int protoff, int *hotdrop) |
25 | { | 25 | { |
26 | const struct ipt_dscp_info *info = matchinfo; | 26 | const struct ipt_dscp_info *info = matchinfo; |
27 | const struct iphdr *iph = skb->nh.iph; | 27 | const struct iphdr *iph = skb->nh.iph; |
@@ -31,7 +31,7 @@ static int match(const struct sk_buff *skb, const struct net_device *in, | |||
31 | return ((iph->tos&IPT_DSCP_MASK) == sh_dscp) ^ info->invert; | 31 | return ((iph->tos&IPT_DSCP_MASK) == sh_dscp) ^ info->invert; |
32 | } | 32 | } |
33 | 33 | ||
34 | static int checkentry(const char *tablename, const struct ipt_ip *ip, | 34 | static int checkentry(const char *tablename, const void *ip, |
35 | void *matchinfo, unsigned int matchsize, | 35 | void *matchinfo, unsigned int matchsize, |
36 | unsigned int hook_mask) | 36 | unsigned int hook_mask) |
37 | { | 37 | { |
diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c index b6f7181e89cc..e68b0c7981f0 100644 --- a/net/ipv4/netfilter/ipt_ecn.c +++ b/net/ipv4/netfilter/ipt_ecn.c | |||
@@ -67,7 +67,7 @@ static inline int match_tcp(const struct sk_buff *skb, | |||
67 | 67 | ||
68 | static int match(const struct sk_buff *skb, const struct net_device *in, | 68 | static int match(const struct sk_buff *skb, const struct net_device *in, |
69 | const struct net_device *out, const void *matchinfo, | 69 | const struct net_device *out, const void *matchinfo, |
70 | int offset, int *hotdrop) | 70 | int offset, unsigned int protoff, int *hotdrop) |
71 | { | 71 | { |
72 | const struct ipt_ecn_info *info = matchinfo; | 72 | const struct ipt_ecn_info *info = matchinfo; |
73 | 73 | ||
@@ -85,11 +85,12 @@ static int match(const struct sk_buff *skb, const struct net_device *in, | |||
85 | return 1; | 85 | return 1; |
86 | } | 86 | } |
87 | 87 | ||
88 | static int checkentry(const char *tablename, const struct ipt_ip *ip, | 88 | static int checkentry(const char *tablename, const void *ip_void, |
89 | void *matchinfo, unsigned int matchsize, | 89 | void *matchinfo, unsigned int matchsize, |
90 | unsigned int hook_mask) | 90 | unsigned int hook_mask) |
91 | { | 91 | { |
92 | const struct ipt_ecn_info *info = matchinfo; | 92 | const struct ipt_ecn_info *info = matchinfo; |
93 | const struct ipt_ip *ip = ip_void; | ||
93 | 94 | ||
94 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_ecn_info))) | 95 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_ecn_info))) |
95 | return 0; | 96 | return 0; |
diff --git a/net/ipv4/netfilter/ipt_esp.c b/net/ipv4/netfilter/ipt_esp.c index e1d0dd31e117..9de191a8162d 100644 --- a/net/ipv4/netfilter/ipt_esp.c +++ b/net/ipv4/netfilter/ipt_esp.c | |||
@@ -42,6 +42,7 @@ match(const struct sk_buff *skb, | |||
42 | const struct net_device *out, | 42 | const struct net_device *out, |
43 | const void *matchinfo, | 43 | const void *matchinfo, |
44 | int offset, | 44 | int offset, |
45 | unsigned int protoff, | ||
45 | int *hotdrop) | 46 | int *hotdrop) |
46 | { | 47 | { |
47 | struct ip_esp_hdr _esp, *eh; | 48 | struct ip_esp_hdr _esp, *eh; |
@@ -51,7 +52,7 @@ match(const struct sk_buff *skb, | |||
51 | if (offset) | 52 | if (offset) |
52 | return 0; | 53 | return 0; |
53 | 54 | ||
54 | eh = skb_header_pointer(skb, skb->nh.iph->ihl * 4, | 55 | eh = skb_header_pointer(skb, protoff, |
55 | sizeof(_esp), &_esp); | 56 | sizeof(_esp), &_esp); |
56 | if (eh == NULL) { | 57 | if (eh == NULL) { |
57 | /* We've been asked to examine this packet, and we | 58 | /* We've been asked to examine this packet, and we |
@@ -70,12 +71,13 @@ match(const struct sk_buff *skb, | |||
70 | /* Called when user tries to insert an entry of this type. */ | 71 | /* Called when user tries to insert an entry of this type. */ |
71 | static int | 72 | static int |
72 | checkentry(const char *tablename, | 73 | checkentry(const char *tablename, |
73 | const struct ipt_ip *ip, | 74 | const void *ip_void, |
74 | void *matchinfo, | 75 | void *matchinfo, |
75 | unsigned int matchinfosize, | 76 | unsigned int matchinfosize, |
76 | unsigned int hook_mask) | 77 | unsigned int hook_mask) |
77 | { | 78 | { |
78 | const struct ipt_esp *espinfo = matchinfo; | 79 | const struct ipt_esp *espinfo = matchinfo; |
80 | const struct ipt_ip *ip = ip_void; | ||
79 | 81 | ||
80 | /* Must specify proto == ESP, and no unknown invflags */ | 82 | /* Must specify proto == ESP, and no unknown invflags */ |
81 | if (ip->proto != IPPROTO_ESP || (ip->invflags & IPT_INV_PROTO)) { | 83 | if (ip->proto != IPPROTO_ESP || (ip->invflags & IPT_INV_PROTO)) { |
diff --git a/net/ipv4/netfilter/ipt_hashlimit.c b/net/ipv4/netfilter/ipt_hashlimit.c index 2dd1cccbdab9..4fe48c1bd5f3 100644 --- a/net/ipv4/netfilter/ipt_hashlimit.c +++ b/net/ipv4/netfilter/ipt_hashlimit.c | |||
@@ -429,6 +429,7 @@ hashlimit_match(const struct sk_buff *skb, | |||
429 | const struct net_device *out, | 429 | const struct net_device *out, |
430 | const void *matchinfo, | 430 | const void *matchinfo, |
431 | int offset, | 431 | int offset, |
432 | unsigned int protoff, | ||
432 | int *hotdrop) | 433 | int *hotdrop) |
433 | { | 434 | { |
434 | struct ipt_hashlimit_info *r = | 435 | struct ipt_hashlimit_info *r = |
@@ -504,7 +505,7 @@ hashlimit_match(const struct sk_buff *skb, | |||
504 | 505 | ||
505 | static int | 506 | static int |
506 | hashlimit_checkentry(const char *tablename, | 507 | hashlimit_checkentry(const char *tablename, |
507 | const struct ipt_ip *ip, | 508 | const void *inf, |
508 | void *matchinfo, | 509 | void *matchinfo, |
509 | unsigned int matchsize, | 510 | unsigned int matchsize, |
510 | unsigned int hook_mask) | 511 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_iprange.c b/net/ipv4/netfilter/ipt_iprange.c index b835b7b2e560..13fb16fb7892 100644 --- a/net/ipv4/netfilter/ipt_iprange.c +++ b/net/ipv4/netfilter/ipt_iprange.c | |||
@@ -28,7 +28,7 @@ match(const struct sk_buff *skb, | |||
28 | const struct net_device *in, | 28 | const struct net_device *in, |
29 | const struct net_device *out, | 29 | const struct net_device *out, |
30 | const void *matchinfo, | 30 | const void *matchinfo, |
31 | int offset, int *hotdrop) | 31 | int offset, unsigned int protoff, int *hotdrop) |
32 | { | 32 | { |
33 | const struct ipt_iprange_info *info = matchinfo; | 33 | const struct ipt_iprange_info *info = matchinfo; |
34 | const struct iphdr *iph = skb->nh.iph; | 34 | const struct iphdr *iph = skb->nh.iph; |
@@ -63,7 +63,7 @@ match(const struct sk_buff *skb, | |||
63 | } | 63 | } |
64 | 64 | ||
65 | static int check(const char *tablename, | 65 | static int check(const char *tablename, |
66 | const struct ipt_ip *ip, | 66 | const void *inf, |
67 | void *matchinfo, | 67 | void *matchinfo, |
68 | unsigned int matchsize, | 68 | unsigned int matchsize, |
69 | unsigned int hook_mask) | 69 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_length.c b/net/ipv4/netfilter/ipt_length.c deleted file mode 100644 index 4eabcfbda9d1..000000000000 --- a/net/ipv4/netfilter/ipt_length.c +++ /dev/null | |||
@@ -1,64 +0,0 @@ | |||
1 | /* Kernel module to match packet length. */ | ||
2 | /* (C) 1999-2001 James Morris <jmorros@intercode.com.au> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/skbuff.h> | ||
11 | |||
12 | #include <linux/netfilter_ipv4/ipt_length.h> | ||
13 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
14 | |||
15 | MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); | ||
16 | MODULE_DESCRIPTION("IP tables packet length matching module"); | ||
17 | MODULE_LICENSE("GPL"); | ||
18 | |||
19 | static int | ||
20 | match(const struct sk_buff *skb, | ||
21 | const struct net_device *in, | ||
22 | const struct net_device *out, | ||
23 | const void *matchinfo, | ||
24 | int offset, | ||
25 | int *hotdrop) | ||
26 | { | ||
27 | const struct ipt_length_info *info = matchinfo; | ||
28 | u_int16_t pktlen = ntohs(skb->nh.iph->tot_len); | ||
29 | |||
30 | return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; | ||
31 | } | ||
32 | |||
33 | static int | ||
34 | checkentry(const char *tablename, | ||
35 | const struct ipt_ip *ip, | ||
36 | void *matchinfo, | ||
37 | unsigned int matchsize, | ||
38 | unsigned int hook_mask) | ||
39 | { | ||
40 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_length_info))) | ||
41 | return 0; | ||
42 | |||
43 | return 1; | ||
44 | } | ||
45 | |||
46 | static struct ipt_match length_match = { | ||
47 | .name = "length", | ||
48 | .match = &match, | ||
49 | .checkentry = &checkentry, | ||
50 | .me = THIS_MODULE, | ||
51 | }; | ||
52 | |||
53 | static int __init init(void) | ||
54 | { | ||
55 | return ipt_register_match(&length_match); | ||
56 | } | ||
57 | |||
58 | static void __exit fini(void) | ||
59 | { | ||
60 | ipt_unregister_match(&length_match); | ||
61 | } | ||
62 | |||
63 | module_init(init); | ||
64 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_multiport.c b/net/ipv4/netfilter/ipt_multiport.c index 99e8188162e2..2d52326553f1 100644 --- a/net/ipv4/netfilter/ipt_multiport.c +++ b/net/ipv4/netfilter/ipt_multiport.c | |||
@@ -97,6 +97,7 @@ match(const struct sk_buff *skb, | |||
97 | const struct net_device *out, | 97 | const struct net_device *out, |
98 | const void *matchinfo, | 98 | const void *matchinfo, |
99 | int offset, | 99 | int offset, |
100 | unsigned int protoff, | ||
100 | int *hotdrop) | 101 | int *hotdrop) |
101 | { | 102 | { |
102 | u16 _ports[2], *pptr; | 103 | u16 _ports[2], *pptr; |
@@ -105,7 +106,7 @@ match(const struct sk_buff *skb, | |||
105 | if (offset) | 106 | if (offset) |
106 | return 0; | 107 | return 0; |
107 | 108 | ||
108 | pptr = skb_header_pointer(skb, skb->nh.iph->ihl * 4, | 109 | pptr = skb_header_pointer(skb, protoff, |
109 | sizeof(_ports), _ports); | 110 | sizeof(_ports), _ports); |
110 | if (pptr == NULL) { | 111 | if (pptr == NULL) { |
111 | /* We've been asked to examine this packet, and we | 112 | /* We've been asked to examine this packet, and we |
@@ -128,6 +129,7 @@ match_v1(const struct sk_buff *skb, | |||
128 | const struct net_device *out, | 129 | const struct net_device *out, |
129 | const void *matchinfo, | 130 | const void *matchinfo, |
130 | int offset, | 131 | int offset, |
132 | unsigned int protoff, | ||
131 | int *hotdrop) | 133 | int *hotdrop) |
132 | { | 134 | { |
133 | u16 _ports[2], *pptr; | 135 | u16 _ports[2], *pptr; |
@@ -136,7 +138,7 @@ match_v1(const struct sk_buff *skb, | |||
136 | if (offset) | 138 | if (offset) |
137 | return 0; | 139 | return 0; |
138 | 140 | ||
139 | pptr = skb_header_pointer(skb, skb->nh.iph->ihl * 4, | 141 | pptr = skb_header_pointer(skb, protoff, |
140 | sizeof(_ports), _ports); | 142 | sizeof(_ports), _ports); |
141 | if (pptr == NULL) { | 143 | if (pptr == NULL) { |
142 | /* We've been asked to examine this packet, and we | 144 | /* We've been asked to examine this packet, and we |
@@ -154,7 +156,7 @@ match_v1(const struct sk_buff *skb, | |||
154 | /* Called when user tries to insert an entry of this type. */ | 156 | /* Called when user tries to insert an entry of this type. */ |
155 | static int | 157 | static int |
156 | checkentry(const char *tablename, | 158 | checkentry(const char *tablename, |
157 | const struct ipt_ip *ip, | 159 | const void *ip, |
158 | void *matchinfo, | 160 | void *matchinfo, |
159 | unsigned int matchsize, | 161 | unsigned int matchsize, |
160 | unsigned int hook_mask) | 162 | unsigned int hook_mask) |
@@ -164,7 +166,7 @@ checkentry(const char *tablename, | |||
164 | 166 | ||
165 | static int | 167 | static int |
166 | checkentry_v1(const char *tablename, | 168 | checkentry_v1(const char *tablename, |
167 | const struct ipt_ip *ip, | 169 | const void *ip, |
168 | void *matchinfo, | 170 | void *matchinfo, |
169 | unsigned int matchsize, | 171 | unsigned int matchsize, |
170 | unsigned int hook_mask) | 172 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c index 0cee2862ed85..4843d0c9734f 100644 --- a/net/ipv4/netfilter/ipt_owner.c +++ b/net/ipv4/netfilter/ipt_owner.c | |||
@@ -27,6 +27,7 @@ match(const struct sk_buff *skb, | |||
27 | const struct net_device *out, | 27 | const struct net_device *out, |
28 | const void *matchinfo, | 28 | const void *matchinfo, |
29 | int offset, | 29 | int offset, |
30 | unsigned int protoff, | ||
30 | int *hotdrop) | 31 | int *hotdrop) |
31 | { | 32 | { |
32 | const struct ipt_owner_info *info = matchinfo; | 33 | const struct ipt_owner_info *info = matchinfo; |
@@ -51,7 +52,7 @@ match(const struct sk_buff *skb, | |||
51 | 52 | ||
52 | static int | 53 | static int |
53 | checkentry(const char *tablename, | 54 | checkentry(const char *tablename, |
54 | const struct ipt_ip *ip, | 55 | const void *ip, |
55 | void *matchinfo, | 56 | void *matchinfo, |
56 | unsigned int matchsize, | 57 | unsigned int matchsize, |
57 | unsigned int hook_mask) | 58 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_physdev.c b/net/ipv4/netfilter/ipt_physdev.c deleted file mode 100644 index 03f554857a4d..000000000000 --- a/net/ipv4/netfilter/ipt_physdev.c +++ /dev/null | |||
@@ -1,135 +0,0 @@ | |||
1 | /* Kernel module to match the bridge port in and | ||
2 | * out device for IP packets coming into contact with a bridge. */ | ||
3 | |||
4 | /* (C) 2001-2003 Bart De Schuymer <bdschuym@pandora.be> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/netdevice.h> | ||
13 | #include <linux/skbuff.h> | ||
14 | #include <linux/netfilter_ipv4/ipt_physdev.h> | ||
15 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
16 | #include <linux/netfilter_bridge.h> | ||
17 | #define MATCH 1 | ||
18 | #define NOMATCH 0 | ||
19 | |||
20 | MODULE_LICENSE("GPL"); | ||
21 | MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); | ||
22 | MODULE_DESCRIPTION("iptables bridge physical device match module"); | ||
23 | |||
24 | static int | ||
25 | match(const struct sk_buff *skb, | ||
26 | const struct net_device *in, | ||
27 | const struct net_device *out, | ||
28 | const void *matchinfo, | ||
29 | int offset, | ||
30 | int *hotdrop) | ||
31 | { | ||
32 | int i; | ||
33 | static const char nulldevname[IFNAMSIZ]; | ||
34 | const struct ipt_physdev_info *info = matchinfo; | ||
35 | unsigned int ret; | ||
36 | const char *indev, *outdev; | ||
37 | struct nf_bridge_info *nf_bridge; | ||
38 | |||
39 | /* Not a bridged IP packet or no info available yet: | ||
40 | * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if | ||
41 | * the destination device will be a bridge. */ | ||
42 | if (!(nf_bridge = skb->nf_bridge)) { | ||
43 | /* Return MATCH if the invert flags of the used options are on */ | ||
44 | if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) && | ||
45 | !(info->invert & IPT_PHYSDEV_OP_BRIDGED)) | ||
46 | return NOMATCH; | ||
47 | if ((info->bitmask & IPT_PHYSDEV_OP_ISIN) && | ||
48 | !(info->invert & IPT_PHYSDEV_OP_ISIN)) | ||
49 | return NOMATCH; | ||
50 | if ((info->bitmask & IPT_PHYSDEV_OP_ISOUT) && | ||
51 | !(info->invert & IPT_PHYSDEV_OP_ISOUT)) | ||
52 | return NOMATCH; | ||
53 | if ((info->bitmask & IPT_PHYSDEV_OP_IN) && | ||
54 | !(info->invert & IPT_PHYSDEV_OP_IN)) | ||
55 | return NOMATCH; | ||
56 | if ((info->bitmask & IPT_PHYSDEV_OP_OUT) && | ||
57 | !(info->invert & IPT_PHYSDEV_OP_OUT)) | ||
58 | return NOMATCH; | ||
59 | return MATCH; | ||
60 | } | ||
61 | |||
62 | /* This only makes sense in the FORWARD and POSTROUTING chains */ | ||
63 | if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) && | ||
64 | (!!(nf_bridge->mask & BRNF_BRIDGED) ^ | ||
65 | !(info->invert & IPT_PHYSDEV_OP_BRIDGED))) | ||
66 | return NOMATCH; | ||
67 | |||
68 | if ((info->bitmask & IPT_PHYSDEV_OP_ISIN && | ||
69 | (!nf_bridge->physindev ^ !!(info->invert & IPT_PHYSDEV_OP_ISIN))) || | ||
70 | (info->bitmask & IPT_PHYSDEV_OP_ISOUT && | ||
71 | (!nf_bridge->physoutdev ^ !!(info->invert & IPT_PHYSDEV_OP_ISOUT)))) | ||
72 | return NOMATCH; | ||
73 | |||
74 | if (!(info->bitmask & IPT_PHYSDEV_OP_IN)) | ||
75 | goto match_outdev; | ||
76 | indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; | ||
77 | for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { | ||
78 | ret |= (((const unsigned int *)indev)[i] | ||
79 | ^ ((const unsigned int *)info->physindev)[i]) | ||
80 | & ((const unsigned int *)info->in_mask)[i]; | ||
81 | } | ||
82 | |||
83 | if ((ret == 0) ^ !(info->invert & IPT_PHYSDEV_OP_IN)) | ||
84 | return NOMATCH; | ||
85 | |||
86 | match_outdev: | ||
87 | if (!(info->bitmask & IPT_PHYSDEV_OP_OUT)) | ||
88 | return MATCH; | ||
89 | outdev = nf_bridge->physoutdev ? | ||
90 | nf_bridge->physoutdev->name : nulldevname; | ||
91 | for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { | ||
92 | ret |= (((const unsigned int *)outdev)[i] | ||
93 | ^ ((const unsigned int *)info->physoutdev)[i]) | ||
94 | & ((const unsigned int *)info->out_mask)[i]; | ||
95 | } | ||
96 | |||
97 | return (ret != 0) ^ !(info->invert & IPT_PHYSDEV_OP_OUT); | ||
98 | } | ||
99 | |||
100 | static int | ||
101 | checkentry(const char *tablename, | ||
102 | const struct ipt_ip *ip, | ||
103 | void *matchinfo, | ||
104 | unsigned int matchsize, | ||
105 | unsigned int hook_mask) | ||
106 | { | ||
107 | const struct ipt_physdev_info *info = matchinfo; | ||
108 | |||
109 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_physdev_info))) | ||
110 | return 0; | ||
111 | if (!(info->bitmask & IPT_PHYSDEV_OP_MASK) || | ||
112 | info->bitmask & ~IPT_PHYSDEV_OP_MASK) | ||
113 | return 0; | ||
114 | return 1; | ||
115 | } | ||
116 | |||
117 | static struct ipt_match physdev_match = { | ||
118 | .name = "physdev", | ||
119 | .match = &match, | ||
120 | .checkentry = &checkentry, | ||
121 | .me = THIS_MODULE, | ||
122 | }; | ||
123 | |||
124 | static int __init init(void) | ||
125 | { | ||
126 | return ipt_register_match(&physdev_match); | ||
127 | } | ||
128 | |||
129 | static void __exit fini(void) | ||
130 | { | ||
131 | ipt_unregister_match(&physdev_match); | ||
132 | } | ||
133 | |||
134 | module_init(init); | ||
135 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c index 5ddccb18c65e..44611d6d14f5 100644 --- a/net/ipv4/netfilter/ipt_recent.c +++ b/net/ipv4/netfilter/ipt_recent.c | |||
@@ -104,6 +104,7 @@ match(const struct sk_buff *skb, | |||
104 | const struct net_device *out, | 104 | const struct net_device *out, |
105 | const void *matchinfo, | 105 | const void *matchinfo, |
106 | int offset, | 106 | int offset, |
107 | unsigned int protoff, | ||
107 | int *hotdrop); | 108 | int *hotdrop); |
108 | 109 | ||
109 | /* Function to hash a given address into the hash table of table_size size */ | 110 | /* Function to hash a given address into the hash table of table_size size */ |
@@ -317,7 +318,7 @@ static int ip_recent_ctrl(struct file *file, const char __user *input, unsigned | |||
317 | skb->nh.iph->daddr = 0; | 318 | skb->nh.iph->daddr = 0; |
318 | /* Clear ttl since we have no way of knowing it */ | 319 | /* Clear ttl since we have no way of knowing it */ |
319 | skb->nh.iph->ttl = 0; | 320 | skb->nh.iph->ttl = 0; |
320 | match(skb,NULL,NULL,info,0,NULL); | 321 | match(skb,NULL,NULL,info,0,0,NULL); |
321 | 322 | ||
322 | kfree(skb->nh.iph); | 323 | kfree(skb->nh.iph); |
323 | out_free_skb: | 324 | out_free_skb: |
@@ -357,6 +358,7 @@ match(const struct sk_buff *skb, | |||
357 | const struct net_device *out, | 358 | const struct net_device *out, |
358 | const void *matchinfo, | 359 | const void *matchinfo, |
359 | int offset, | 360 | int offset, |
361 | unsigned int protoff, | ||
360 | int *hotdrop) | 362 | int *hotdrop) |
361 | { | 363 | { |
362 | int pkt_count, hits_found, ans; | 364 | int pkt_count, hits_found, ans; |
@@ -654,7 +656,7 @@ match(const struct sk_buff *skb, | |||
654 | */ | 656 | */ |
655 | static int | 657 | static int |
656 | checkentry(const char *tablename, | 658 | checkentry(const char *tablename, |
657 | const struct ipt_ip *ip, | 659 | const void *ip, |
658 | void *matchinfo, | 660 | void *matchinfo, |
659 | unsigned int matchsize, | 661 | unsigned int matchsize, |
660 | unsigned int hook_mask) | 662 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_tos.c b/net/ipv4/netfilter/ipt_tos.c index 086a1bb61e3e..9ab765e126f2 100644 --- a/net/ipv4/netfilter/ipt_tos.c +++ b/net/ipv4/netfilter/ipt_tos.c | |||
@@ -23,6 +23,7 @@ match(const struct sk_buff *skb, | |||
23 | const struct net_device *out, | 23 | const struct net_device *out, |
24 | const void *matchinfo, | 24 | const void *matchinfo, |
25 | int offset, | 25 | int offset, |
26 | unsigned int protoff, | ||
26 | int *hotdrop) | 27 | int *hotdrop) |
27 | { | 28 | { |
28 | const struct ipt_tos_info *info = matchinfo; | 29 | const struct ipt_tos_info *info = matchinfo; |
@@ -32,7 +33,7 @@ match(const struct sk_buff *skb, | |||
32 | 33 | ||
33 | static int | 34 | static int |
34 | checkentry(const char *tablename, | 35 | checkentry(const char *tablename, |
35 | const struct ipt_ip *ip, | 36 | const void *ip, |
36 | void *matchinfo, | 37 | void *matchinfo, |
37 | unsigned int matchsize, | 38 | unsigned int matchsize, |
38 | unsigned int hook_mask) | 39 | unsigned int hook_mask) |
diff --git a/net/ipv4/netfilter/ipt_ttl.c b/net/ipv4/netfilter/ipt_ttl.c index 219aa9de88cc..82da53f430ab 100644 --- a/net/ipv4/netfilter/ipt_ttl.c +++ b/net/ipv4/netfilter/ipt_ttl.c | |||
@@ -21,7 +21,7 @@ MODULE_LICENSE("GPL"); | |||
21 | 21 | ||
22 | static int match(const struct sk_buff *skb, const struct net_device *in, | 22 | static int match(const struct sk_buff *skb, const struct net_device *in, |
23 | const struct net_device *out, const void *matchinfo, | 23 | const struct net_device *out, const void *matchinfo, |
24 | int offset, int *hotdrop) | 24 | int offset, unsigned int protoff, int *hotdrop) |
25 | { | 25 | { |
26 | const struct ipt_ttl_info *info = matchinfo; | 26 | const struct ipt_ttl_info *info = matchinfo; |
27 | 27 | ||
@@ -47,7 +47,7 @@ static int match(const struct sk_buff *skb, const struct net_device *in, | |||
47 | return 0; | 47 | return 0; |
48 | } | 48 | } |
49 | 49 | ||
50 | static int checkentry(const char *tablename, const struct ipt_ip *ip, | 50 | static int checkentry(const char *tablename, const void *ip, |
51 | void *matchinfo, unsigned int matchsize, | 51 | void *matchinfo, unsigned int matchsize, |
52 | unsigned int hook_mask) | 52 | unsigned int hook_mask) |
53 | { | 53 | { |
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 260a4f0a2a90..212a3079085b 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c | |||
@@ -78,7 +78,8 @@ static struct ipt_table packet_filter = { | |||
78 | .name = "filter", | 78 | .name = "filter", |
79 | .valid_hooks = FILTER_VALID_HOOKS, | 79 | .valid_hooks = FILTER_VALID_HOOKS, |
80 | .lock = RW_LOCK_UNLOCKED, | 80 | .lock = RW_LOCK_UNLOCKED, |
81 | .me = THIS_MODULE | 81 | .me = THIS_MODULE, |
82 | .af = AF_INET, | ||
82 | }; | 83 | }; |
83 | 84 | ||
84 | /* The work comes in here from netfilter.c. */ | 85 | /* The work comes in here from netfilter.c. */ |
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index 160eb11b6e2f..3212a5cc4b6b 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c | |||
@@ -109,6 +109,7 @@ static struct ipt_table packet_mangler = { | |||
109 | .valid_hooks = MANGLE_VALID_HOOKS, | 109 | .valid_hooks = MANGLE_VALID_HOOKS, |
110 | .lock = RW_LOCK_UNLOCKED, | 110 | .lock = RW_LOCK_UNLOCKED, |
111 | .me = THIS_MODULE, | 111 | .me = THIS_MODULE, |
112 | .af = AF_INET, | ||
112 | }; | 113 | }; |
113 | 114 | ||
114 | /* The work comes in here from netfilter.c. */ | 115 | /* The work comes in here from netfilter.c. */ |
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index 47449ba83eb9..fdb9e9c81e81 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c | |||
@@ -83,7 +83,8 @@ static struct ipt_table packet_raw = { | |||
83 | .name = "raw", | 83 | .name = "raw", |
84 | .valid_hooks = RAW_VALID_HOOKS, | 84 | .valid_hooks = RAW_VALID_HOOKS, |
85 | .lock = RW_LOCK_UNLOCKED, | 85 | .lock = RW_LOCK_UNLOCKED, |
86 | .me = THIS_MODULE | 86 | .me = THIS_MODULE, |
87 | .af = AF_INET, | ||
87 | }; | 88 | }; |
88 | 89 | ||
89 | /* The work comes in here from netfilter.c. */ | 90 | /* The work comes in here from netfilter.c. */ |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 0c56c52a3831..167619f638c6 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
@@ -575,7 +575,7 @@ MODULE_LICENSE("GPL"); | |||
575 | 575 | ||
576 | static int __init init(void) | 576 | static int __init init(void) |
577 | { | 577 | { |
578 | need_nf_conntrack(); | 578 | need_conntrack(); |
579 | return init_or_cleanup(1); | 579 | return init_or_cleanup(1); |
580 | } | 580 | } |
581 | 581 | ||
@@ -587,9 +587,4 @@ static void __exit fini(void) | |||
587 | module_init(init); | 587 | module_init(init); |
588 | module_exit(fini); | 588 | module_exit(fini); |
589 | 589 | ||
590 | void need_ip_conntrack(void) | ||
591 | { | ||
592 | } | ||
593 | |||
594 | EXPORT_SYMBOL(need_ip_conntrack); | ||
595 | EXPORT_SYMBOL(nf_ct_ipv4_gather_frags); | 590 | EXPORT_SYMBOL(nf_ct_ipv4_gather_frags); |
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 105dd69ee9fb..2d6f8ecbc27b 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
@@ -41,6 +41,7 @@ config IP6_NF_QUEUE | |||
41 | 41 | ||
42 | config IP6_NF_IPTABLES | 42 | config IP6_NF_IPTABLES |
43 | tristate "IP6 tables support (required for filtering/masq/NAT)" | 43 | tristate "IP6 tables support (required for filtering/masq/NAT)" |
44 | depends on NETFILTER_XTABLES | ||
44 | help | 45 | help |
45 | ip6tables is a general, extensible packet identification framework. | 46 | ip6tables is a general, extensible packet identification framework. |
46 | Currently only the packet filtering and packet mangling subsystem | 47 | Currently only the packet filtering and packet mangling subsystem |
@@ -50,25 +51,6 @@ config IP6_NF_IPTABLES | |||
50 | To compile it as a module, choose M here. If unsure, say N. | 51 | To compile it as a module, choose M here. If unsure, say N. |
51 | 52 | ||
52 | # The simple matches. | 53 | # The simple matches. |
53 | config IP6_NF_MATCH_LIMIT | ||
54 | tristate "limit match support" | ||
55 | depends on IP6_NF_IPTABLES | ||
56 | help | ||
57 | limit matching allows you to control the rate at which a rule can be | ||
58 | matched: mainly useful in combination with the LOG target ("LOG | ||
59 | target support", below) and to avoid some Denial of Service attacks. | ||
60 | |||
61 | To compile it as a module, choose M here. If unsure, say N. | ||
62 | |||
63 | config IP6_NF_MATCH_MAC | ||
64 | tristate "MAC address match support" | ||
65 | depends on IP6_NF_IPTABLES | ||
66 | help | ||
67 | mac matching allows you to match packets based on the source | ||
68 | Ethernet address of the packet. | ||
69 | |||
70 | To compile it as a module, choose M here. If unsure, say N. | ||
71 | |||
72 | config IP6_NF_MATCH_RT | 54 | config IP6_NF_MATCH_RT |
73 | tristate "Routing header match support" | 55 | tristate "Routing header match support" |
74 | depends on IP6_NF_IPTABLES | 56 | depends on IP6_NF_IPTABLES |
@@ -124,16 +106,6 @@ config IP6_NF_MATCH_OWNER | |||
124 | 106 | ||
125 | To compile it as a module, choose M here. If unsure, say N. | 107 | To compile it as a module, choose M here. If unsure, say N. |
126 | 108 | ||
127 | config IP6_NF_MATCH_MARK | ||
128 | tristate "netfilter MARK match support" | ||
129 | depends on IP6_NF_IPTABLES | ||
130 | help | ||
131 | Netfilter mark matching allows you to match packets based on the | ||
132 | `nfmark' value in the packet. This can be set by the MARK target | ||
133 | (see below). | ||
134 | |||
135 | To compile it as a module, choose M here. If unsure, say N. | ||
136 | |||
137 | config IP6_NF_MATCH_IPV6HEADER | 109 | config IP6_NF_MATCH_IPV6HEADER |
138 | tristate "IPv6 Extension Headers Match" | 110 | tristate "IPv6 Extension Headers Match" |
139 | depends on IP6_NF_IPTABLES | 111 | depends on IP6_NF_IPTABLES |
@@ -151,15 +123,6 @@ config IP6_NF_MATCH_AHESP | |||
151 | 123 | ||
152 | To compile it as a module, choose M here. If unsure, say N. | 124 | To compile it as a module, choose M here. If unsure, say N. |
153 | 125 | ||
154 | config IP6_NF_MATCH_LENGTH | ||
155 | tristate "Packet Length match support" | ||
156 | depends on IP6_NF_IPTABLES | ||
157 | help | ||
158 | This option allows you to match the length of a packet against a | ||
159 | specific value or range of values. | ||
160 | |||
161 | To compile it as a module, choose M here. If unsure, say N. | ||
162 | |||
163 | config IP6_NF_MATCH_EUI64 | 126 | config IP6_NF_MATCH_EUI64 |
164 | tristate "EUI64 address check" | 127 | tristate "EUI64 address check" |
165 | depends on IP6_NF_IPTABLES | 128 | depends on IP6_NF_IPTABLES |
@@ -170,15 +133,6 @@ config IP6_NF_MATCH_EUI64 | |||
170 | 133 | ||
171 | To compile it as a module, choose M here. If unsure, say N. | 134 | To compile it as a module, choose M here. If unsure, say N. |
172 | 135 | ||
173 | config IP6_NF_MATCH_PHYSDEV | ||
174 | tristate "Physdev match support" | ||
175 | depends on IP6_NF_IPTABLES && BRIDGE_NETFILTER | ||
176 | help | ||
177 | Physdev packet matching matches against the physical bridge ports | ||
178 | the IP packet arrived on or will leave by. | ||
179 | |||
180 | To compile it as a module, choose M here. If unsure, say N. | ||
181 | |||
182 | config IP6_NF_MATCH_POLICY | 136 | config IP6_NF_MATCH_POLICY |
183 | tristate "IPsec policy match support" | 137 | tristate "IPsec policy match support" |
184 | depends on IP6_NF_IPTABLES && XFRM | 138 | depends on IP6_NF_IPTABLES && XFRM |
@@ -219,17 +173,6 @@ config IP6_NF_TARGET_REJECT | |||
219 | 173 | ||
220 | To compile it as a module, choose M here. If unsure, say N. | 174 | To compile it as a module, choose M here. If unsure, say N. |
221 | 175 | ||
222 | config IP6_NF_TARGET_NFQUEUE | ||
223 | tristate "NFQUEUE Target Support" | ||
224 | depends on IP6_NF_IPTABLES | ||
225 | help | ||
226 | This Target replaced the old obsolete QUEUE target. | ||
227 | |||
228 | As opposed to QUEUE, it supports 65535 different queues, | ||
229 | not just one. | ||
230 | |||
231 | To compile it as a module, choose M here. If unsure, say N. | ||
232 | |||
233 | config IP6_NF_MANGLE | 176 | config IP6_NF_MANGLE |
234 | tristate "Packet mangling" | 177 | tristate "Packet mangling" |
235 | depends on IP6_NF_IPTABLES | 178 | depends on IP6_NF_IPTABLES |
@@ -240,19 +183,6 @@ config IP6_NF_MANGLE | |||
240 | 183 | ||
241 | To compile it as a module, choose M here. If unsure, say N. | 184 | To compile it as a module, choose M here. If unsure, say N. |
242 | 185 | ||
243 | config IP6_NF_TARGET_MARK | ||
244 | tristate "MARK target support" | ||
245 | depends on IP6_NF_MANGLE | ||
246 | help | ||
247 | This option adds a `MARK' target, which allows you to create rules | ||
248 | in the `mangle' table which alter the netfilter mark (nfmark) field | ||
249 | associated with the packet packet prior to routing. This can change | ||
250 | the routing method (see `Use netfilter MARK value as routing | ||
251 | key') and can also be used by other subsystems to change their | ||
252 | behavior. | ||
253 | |||
254 | To compile it as a module, choose M here. If unsure, say N. | ||
255 | |||
256 | config IP6_NF_TARGET_HL | 186 | config IP6_NF_TARGET_HL |
257 | tristate 'HL (hoplimit) target support' | 187 | tristate 'HL (hoplimit) target support' |
258 | depends on IP6_NF_MANGLE | 188 | depends on IP6_NF_MANGLE |
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index c0c809b426e8..663b4749820d 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile | |||
@@ -4,10 +4,7 @@ | |||
4 | 4 | ||
5 | # Link order matters here. | 5 | # Link order matters here. |
6 | obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o | 6 | obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o |
7 | obj-$(CONFIG_IP6_NF_MATCH_LIMIT) += ip6t_limit.o | ||
8 | obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o | ||
9 | obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o | 7 | obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o |
10 | obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o | ||
11 | obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o | 8 | obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o |
12 | obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o | 9 | obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o |
13 | obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o | 10 | obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o |
@@ -17,12 +14,9 @@ obj-$(CONFIG_IP6_NF_MATCH_POLICY) += ip6t_policy.o | |||
17 | obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o | 14 | obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o |
18 | obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o | 15 | obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o |
19 | obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o | 16 | obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o |
20 | obj-$(CONFIG_IP6_NF_MATCH_PHYSDEV) += ip6t_physdev.o | ||
21 | obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o | 17 | obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o |
22 | obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o | 18 | obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o |
23 | obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o | ||
24 | obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o | 19 | obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o |
25 | obj-$(CONFIG_IP6_NF_TARGET_NFQUEUE) += ip6t_NFQUEUE.o | ||
26 | obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o | 20 | obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o |
27 | obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o | 21 | obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o |
28 | obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o | 22 | obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 1390370186d9..847068fd3367 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -13,6 +13,9 @@ | |||
13 | * a table | 13 | * a table |
14 | * 06 Jun 2002 Andras Kis-Szabo <kisza@sch.bme.hu> | 14 | * 06 Jun 2002 Andras Kis-Szabo <kisza@sch.bme.hu> |
15 | * - new extension header parser code | 15 | * - new extension header parser code |
16 | * 15 Oct 2005 Harald Welte <laforge@netfilter.org> | ||
17 | * - Unification of {ip,ip6}_tables into x_tables | ||
18 | * - Removed tcp and udp code, since it's not ipv6 specific | ||
16 | */ | 19 | */ |
17 | 20 | ||
18 | #include <linux/capability.h> | 21 | #include <linux/capability.h> |
@@ -23,8 +26,6 @@ | |||
23 | #include <linux/vmalloc.h> | 26 | #include <linux/vmalloc.h> |
24 | #include <linux/netdevice.h> | 27 | #include <linux/netdevice.h> |
25 | #include <linux/module.h> | 28 | #include <linux/module.h> |
26 | #include <linux/tcp.h> | ||
27 | #include <linux/udp.h> | ||
28 | #include <linux/icmpv6.h> | 29 | #include <linux/icmpv6.h> |
29 | #include <net/ipv6.h> | 30 | #include <net/ipv6.h> |
30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
@@ -33,6 +34,7 @@ | |||
33 | #include <linux/cpumask.h> | 34 | #include <linux/cpumask.h> |
34 | 35 | ||
35 | #include <linux/netfilter_ipv6/ip6_tables.h> | 36 | #include <linux/netfilter_ipv6/ip6_tables.h> |
37 | #include <linux/netfilter/x_tables.h> | ||
36 | 38 | ||
37 | MODULE_LICENSE("GPL"); | 39 | MODULE_LICENSE("GPL"); |
38 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); | 40 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); |
@@ -67,13 +69,8 @@ do { \ | |||
67 | #else | 69 | #else |
68 | #define IP_NF_ASSERT(x) | 70 | #define IP_NF_ASSERT(x) |
69 | #endif | 71 | #endif |
70 | #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) | ||
71 | 72 | ||
72 | static DECLARE_MUTEX(ip6t_mutex); | ||
73 | 73 | ||
74 | /* Must have mutex */ | ||
75 | #define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0) | ||
76 | #define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0) | ||
77 | #include <linux/netfilter_ipv4/listhelp.h> | 74 | #include <linux/netfilter_ipv4/listhelp.h> |
78 | 75 | ||
79 | #if 0 | 76 | #if 0 |
@@ -91,30 +88,6 @@ static DECLARE_MUTEX(ip6t_mutex); | |||
91 | 88 | ||
92 | Hence the start of any table is given by get_table() below. */ | 89 | Hence the start of any table is given by get_table() below. */ |
93 | 90 | ||
94 | /* The table itself */ | ||
95 | struct ip6t_table_info | ||
96 | { | ||
97 | /* Size per table */ | ||
98 | unsigned int size; | ||
99 | /* Number of entries: FIXME. --RR */ | ||
100 | unsigned int number; | ||
101 | /* Initial number of entries. Needed for module usage count */ | ||
102 | unsigned int initial_entries; | ||
103 | |||
104 | /* Entry points and underflows */ | ||
105 | unsigned int hook_entry[NF_IP6_NUMHOOKS]; | ||
106 | unsigned int underflow[NF_IP6_NUMHOOKS]; | ||
107 | |||
108 | /* ip6t_entry tables: one per CPU */ | ||
109 | void *entries[NR_CPUS]; | ||
110 | }; | ||
111 | |||
112 | static LIST_HEAD(ip6t_target); | ||
113 | static LIST_HEAD(ip6t_match); | ||
114 | static LIST_HEAD(ip6t_tables); | ||
115 | #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) | ||
116 | #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) | ||
117 | |||
118 | #if 0 | 91 | #if 0 |
119 | #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) | 92 | #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) |
120 | #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; }) | 93 | #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; }) |
@@ -297,7 +270,7 @@ ip6t_do_table(struct sk_buff **pskb, | |||
297 | unsigned int hook, | 270 | unsigned int hook, |
298 | const struct net_device *in, | 271 | const struct net_device *in, |
299 | const struct net_device *out, | 272 | const struct net_device *out, |
300 | struct ip6t_table *table, | 273 | struct xt_table *table, |
301 | void *userdata) | 274 | void *userdata) |
302 | { | 275 | { |
303 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); | 276 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); |
@@ -309,6 +282,7 @@ ip6t_do_table(struct sk_buff **pskb, | |||
309 | const char *indev, *outdev; | 282 | const char *indev, *outdev; |
310 | void *table_base; | 283 | void *table_base; |
311 | struct ip6t_entry *e, *back; | 284 | struct ip6t_entry *e, *back; |
285 | struct xt_table_info *private; | ||
312 | 286 | ||
313 | /* Initialization */ | 287 | /* Initialization */ |
314 | indev = in ? in->name : nulldevname; | 288 | indev = in ? in->name : nulldevname; |
@@ -321,9 +295,10 @@ ip6t_do_table(struct sk_buff **pskb, | |||
321 | * match it. */ | 295 | * match it. */ |
322 | 296 | ||
323 | read_lock_bh(&table->lock); | 297 | read_lock_bh(&table->lock); |
298 | private = table->private; | ||
324 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); | 299 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); |
325 | table_base = (void *)table->private->entries[smp_processor_id()]; | 300 | table_base = (void *)private->entries[smp_processor_id()]; |
326 | e = get_entry(table_base, table->private->hook_entry[hook]); | 301 | e = get_entry(table_base, private->hook_entry[hook]); |
327 | 302 | ||
328 | #ifdef CONFIG_NETFILTER_DEBUG | 303 | #ifdef CONFIG_NETFILTER_DEBUG |
329 | /* Check noone else using our table */ | 304 | /* Check noone else using our table */ |
@@ -339,7 +314,7 @@ ip6t_do_table(struct sk_buff **pskb, | |||
339 | #endif | 314 | #endif |
340 | 315 | ||
341 | /* For return from builtin chain */ | 316 | /* For return from builtin chain */ |
342 | back = get_entry(table_base, table->private->underflow[hook]); | 317 | back = get_entry(table_base, private->underflow[hook]); |
343 | 318 | ||
344 | do { | 319 | do { |
345 | IP_NF_ASSERT(e); | 320 | IP_NF_ASSERT(e); |
@@ -439,145 +414,6 @@ ip6t_do_table(struct sk_buff **pskb, | |||
439 | #endif | 414 | #endif |
440 | } | 415 | } |
441 | 416 | ||
442 | /* | ||
443 | * These are weird, but module loading must not be done with mutex | ||
444 | * held (since they will register), and we have to have a single | ||
445 | * function to use try_then_request_module(). | ||
446 | */ | ||
447 | |||
448 | /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ | ||
449 | static inline struct ip6t_table *find_table_lock(const char *name) | ||
450 | { | ||
451 | struct ip6t_table *t; | ||
452 | |||
453 | if (down_interruptible(&ip6t_mutex) != 0) | ||
454 | return ERR_PTR(-EINTR); | ||
455 | |||
456 | list_for_each_entry(t, &ip6t_tables, list) | ||
457 | if (strcmp(t->name, name) == 0 && try_module_get(t->me)) | ||
458 | return t; | ||
459 | up(&ip6t_mutex); | ||
460 | return NULL; | ||
461 | } | ||
462 | |||
463 | /* Find match, grabs ref. Returns ERR_PTR() on error. */ | ||
464 | static inline struct ip6t_match *find_match(const char *name, u8 revision) | ||
465 | { | ||
466 | struct ip6t_match *m; | ||
467 | int err = 0; | ||
468 | |||
469 | if (down_interruptible(&ip6t_mutex) != 0) | ||
470 | return ERR_PTR(-EINTR); | ||
471 | |||
472 | list_for_each_entry(m, &ip6t_match, list) { | ||
473 | if (strcmp(m->name, name) == 0) { | ||
474 | if (m->revision == revision) { | ||
475 | if (try_module_get(m->me)) { | ||
476 | up(&ip6t_mutex); | ||
477 | return m; | ||
478 | } | ||
479 | } else | ||
480 | err = -EPROTOTYPE; /* Found something. */ | ||
481 | } | ||
482 | } | ||
483 | up(&ip6t_mutex); | ||
484 | return ERR_PTR(err); | ||
485 | } | ||
486 | |||
487 | /* Find target, grabs ref. Returns ERR_PTR() on error. */ | ||
488 | static inline struct ip6t_target *find_target(const char *name, u8 revision) | ||
489 | { | ||
490 | struct ip6t_target *t; | ||
491 | int err = 0; | ||
492 | |||
493 | if (down_interruptible(&ip6t_mutex) != 0) | ||
494 | return ERR_PTR(-EINTR); | ||
495 | |||
496 | list_for_each_entry(t, &ip6t_target, list) { | ||
497 | if (strcmp(t->name, name) == 0) { | ||
498 | if (t->revision == revision) { | ||
499 | if (try_module_get(t->me)) { | ||
500 | up(&ip6t_mutex); | ||
501 | return t; | ||
502 | } | ||
503 | } else | ||
504 | err = -EPROTOTYPE; /* Found something. */ | ||
505 | } | ||
506 | } | ||
507 | up(&ip6t_mutex); | ||
508 | return ERR_PTR(err); | ||
509 | } | ||
510 | |||
511 | struct ip6t_target *ip6t_find_target(const char *name, u8 revision) | ||
512 | { | ||
513 | struct ip6t_target *target; | ||
514 | |||
515 | target = try_then_request_module(find_target(name, revision), | ||
516 | "ip6t_%s", name); | ||
517 | if (IS_ERR(target) || !target) | ||
518 | return NULL; | ||
519 | return target; | ||
520 | } | ||
521 | |||
522 | static int match_revfn(const char *name, u8 revision, int *bestp) | ||
523 | { | ||
524 | struct ip6t_match *m; | ||
525 | int have_rev = 0; | ||
526 | |||
527 | list_for_each_entry(m, &ip6t_match, list) { | ||
528 | if (strcmp(m->name, name) == 0) { | ||
529 | if (m->revision > *bestp) | ||
530 | *bestp = m->revision; | ||
531 | if (m->revision == revision) | ||
532 | have_rev = 1; | ||
533 | } | ||
534 | } | ||
535 | return have_rev; | ||
536 | } | ||
537 | |||
538 | static int target_revfn(const char *name, u8 revision, int *bestp) | ||
539 | { | ||
540 | struct ip6t_target *t; | ||
541 | int have_rev = 0; | ||
542 | |||
543 | list_for_each_entry(t, &ip6t_target, list) { | ||
544 | if (strcmp(t->name, name) == 0) { | ||
545 | if (t->revision > *bestp) | ||
546 | *bestp = t->revision; | ||
547 | if (t->revision == revision) | ||
548 | have_rev = 1; | ||
549 | } | ||
550 | } | ||
551 | return have_rev; | ||
552 | } | ||
553 | |||
554 | /* Returns true or fals (if no such extension at all) */ | ||
555 | static inline int find_revision(const char *name, u8 revision, | ||
556 | int (*revfn)(const char *, u8, int *), | ||
557 | int *err) | ||
558 | { | ||
559 | int have_rev, best = -1; | ||
560 | |||
561 | if (down_interruptible(&ip6t_mutex) != 0) { | ||
562 | *err = -EINTR; | ||
563 | return 1; | ||
564 | } | ||
565 | have_rev = revfn(name, revision, &best); | ||
566 | up(&ip6t_mutex); | ||
567 | |||
568 | /* Nothing at all? Return 0 to try loading module. */ | ||
569 | if (best == -1) { | ||
570 | *err = -ENOENT; | ||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | *err = best; | ||
575 | if (!have_rev) | ||
576 | *err = -EPROTONOSUPPORT; | ||
577 | return 1; | ||
578 | } | ||
579 | |||
580 | |||
581 | /* All zeroes == unconditional rule. */ | 417 | /* All zeroes == unconditional rule. */ |
582 | static inline int | 418 | static inline int |
583 | unconditional(const struct ip6t_ip6 *ipv6) | 419 | unconditional(const struct ip6t_ip6 *ipv6) |
@@ -594,7 +430,7 @@ unconditional(const struct ip6t_ip6 *ipv6) | |||
594 | /* Figures out from what hook each rule can be called: returns 0 if | 430 | /* Figures out from what hook each rule can be called: returns 0 if |
595 | there are loops. Puts hook bitmask in comefrom. */ | 431 | there are loops. Puts hook bitmask in comefrom. */ |
596 | static int | 432 | static int |
597 | mark_source_chains(struct ip6t_table_info *newinfo, | 433 | mark_source_chains(struct xt_table_info *newinfo, |
598 | unsigned int valid_hooks, void *entry0) | 434 | unsigned int valid_hooks, void *entry0) |
599 | { | 435 | { |
600 | unsigned int hook; | 436 | unsigned int hook; |
@@ -740,11 +576,11 @@ check_match(struct ip6t_entry_match *m, | |||
740 | { | 576 | { |
741 | struct ip6t_match *match; | 577 | struct ip6t_match *match; |
742 | 578 | ||
743 | match = try_then_request_module(find_match(m->u.user.name, | 579 | match = try_then_request_module(xt_find_match(AF_INET6, m->u.user.name, |
744 | m->u.user.revision), | 580 | m->u.user.revision), |
745 | "ip6t_%s", m->u.user.name); | 581 | "ip6t_%s", m->u.user.name); |
746 | if (IS_ERR(match) || !match) { | 582 | if (IS_ERR(match) || !match) { |
747 | duprintf("check_match: `%s' not found\n", m->u.user.name); | 583 | duprintf("check_match: `%s' not found\n", m->u.user.name); |
748 | return match ? PTR_ERR(match) : -ENOENT; | 584 | return match ? PTR_ERR(match) : -ENOENT; |
749 | } | 585 | } |
750 | m->u.kernel.match = match; | 586 | m->u.kernel.match = match; |
@@ -785,8 +621,9 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size, | |||
785 | goto cleanup_matches; | 621 | goto cleanup_matches; |
786 | 622 | ||
787 | t = ip6t_get_target(e); | 623 | t = ip6t_get_target(e); |
788 | target = try_then_request_module(find_target(t->u.user.name, | 624 | target = try_then_request_module(xt_find_target(AF_INET6, |
789 | t->u.user.revision), | 625 | t->u.user.name, |
626 | t->u.user.revision), | ||
790 | "ip6t_%s", t->u.user.name); | 627 | "ip6t_%s", t->u.user.name); |
791 | if (IS_ERR(target) || !target) { | 628 | if (IS_ERR(target) || !target) { |
792 | duprintf("check_entry: `%s' not found\n", t->u.user.name); | 629 | duprintf("check_entry: `%s' not found\n", t->u.user.name); |
@@ -822,7 +659,7 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size, | |||
822 | 659 | ||
823 | static inline int | 660 | static inline int |
824 | check_entry_size_and_hooks(struct ip6t_entry *e, | 661 | check_entry_size_and_hooks(struct ip6t_entry *e, |
825 | struct ip6t_table_info *newinfo, | 662 | struct xt_table_info *newinfo, |
826 | unsigned char *base, | 663 | unsigned char *base, |
827 | unsigned char *limit, | 664 | unsigned char *limit, |
828 | const unsigned int *hook_entries, | 665 | const unsigned int *hook_entries, |
@@ -856,7 +693,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e, | |||
856 | < 0 (not IP6T_RETURN). --RR */ | 693 | < 0 (not IP6T_RETURN). --RR */ |
857 | 694 | ||
858 | /* Clear counters and comefrom */ | 695 | /* Clear counters and comefrom */ |
859 | e->counters = ((struct ip6t_counters) { 0, 0 }); | 696 | e->counters = ((struct xt_counters) { 0, 0 }); |
860 | e->comefrom = 0; | 697 | e->comefrom = 0; |
861 | 698 | ||
862 | (*i)++; | 699 | (*i)++; |
@@ -886,7 +723,7 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i) | |||
886 | static int | 723 | static int |
887 | translate_table(const char *name, | 724 | translate_table(const char *name, |
888 | unsigned int valid_hooks, | 725 | unsigned int valid_hooks, |
889 | struct ip6t_table_info *newinfo, | 726 | struct xt_table_info *newinfo, |
890 | void *entry0, | 727 | void *entry0, |
891 | unsigned int size, | 728 | unsigned int size, |
892 | unsigned int number, | 729 | unsigned int number, |
@@ -963,48 +800,10 @@ translate_table(const char *name, | |||
963 | return ret; | 800 | return ret; |
964 | } | 801 | } |
965 | 802 | ||
966 | static struct ip6t_table_info * | ||
967 | replace_table(struct ip6t_table *table, | ||
968 | unsigned int num_counters, | ||
969 | struct ip6t_table_info *newinfo, | ||
970 | int *error) | ||
971 | { | ||
972 | struct ip6t_table_info *oldinfo; | ||
973 | |||
974 | #ifdef CONFIG_NETFILTER_DEBUG | ||
975 | { | ||
976 | int cpu; | ||
977 | |||
978 | for_each_cpu(cpu) { | ||
979 | struct ip6t_entry *table_base = newinfo->entries[cpu]; | ||
980 | if (table_base) | ||
981 | table_base->comefrom = 0xdead57ac; | ||
982 | } | ||
983 | } | ||
984 | #endif | ||
985 | |||
986 | /* Do the substitution. */ | ||
987 | write_lock_bh(&table->lock); | ||
988 | /* Check inside lock: is the old number correct? */ | ||
989 | if (num_counters != table->private->number) { | ||
990 | duprintf("num_counters != table->private->number (%u/%u)\n", | ||
991 | num_counters, table->private->number); | ||
992 | write_unlock_bh(&table->lock); | ||
993 | *error = -EAGAIN; | ||
994 | return NULL; | ||
995 | } | ||
996 | oldinfo = table->private; | ||
997 | table->private = newinfo; | ||
998 | newinfo->initial_entries = oldinfo->initial_entries; | ||
999 | write_unlock_bh(&table->lock); | ||
1000 | |||
1001 | return oldinfo; | ||
1002 | } | ||
1003 | |||
1004 | /* Gets counters. */ | 803 | /* Gets counters. */ |
1005 | static inline int | 804 | static inline int |
1006 | add_entry_to_counter(const struct ip6t_entry *e, | 805 | add_entry_to_counter(const struct ip6t_entry *e, |
1007 | struct ip6t_counters total[], | 806 | struct xt_counters total[], |
1008 | unsigned int *i) | 807 | unsigned int *i) |
1009 | { | 808 | { |
1010 | ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); | 809 | ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); |
@@ -1025,8 +824,8 @@ set_entry_to_counter(const struct ip6t_entry *e, | |||
1025 | } | 824 | } |
1026 | 825 | ||
1027 | static void | 826 | static void |
1028 | get_counters(const struct ip6t_table_info *t, | 827 | get_counters(const struct xt_table_info *t, |
1029 | struct ip6t_counters counters[]) | 828 | struct xt_counters counters[]) |
1030 | { | 829 | { |
1031 | unsigned int cpu; | 830 | unsigned int cpu; |
1032 | unsigned int i; | 831 | unsigned int i; |
@@ -1060,19 +859,20 @@ get_counters(const struct ip6t_table_info *t, | |||
1060 | 859 | ||
1061 | static int | 860 | static int |
1062 | copy_entries_to_user(unsigned int total_size, | 861 | copy_entries_to_user(unsigned int total_size, |
1063 | struct ip6t_table *table, | 862 | struct xt_table *table, |
1064 | void __user *userptr) | 863 | void __user *userptr) |
1065 | { | 864 | { |
1066 | unsigned int off, num, countersize; | 865 | unsigned int off, num, countersize; |
1067 | struct ip6t_entry *e; | 866 | struct ip6t_entry *e; |
1068 | struct ip6t_counters *counters; | 867 | struct xt_counters *counters; |
868 | struct xt_table_info *private = table->private; | ||
1069 | int ret = 0; | 869 | int ret = 0; |
1070 | void *loc_cpu_entry; | 870 | void *loc_cpu_entry; |
1071 | 871 | ||
1072 | /* We need atomic snapshot of counters: rest doesn't change | 872 | /* We need atomic snapshot of counters: rest doesn't change |
1073 | (other than comefrom, which userspace doesn't care | 873 | (other than comefrom, which userspace doesn't care |
1074 | about). */ | 874 | about). */ |
1075 | countersize = sizeof(struct ip6t_counters) * table->private->number; | 875 | countersize = sizeof(struct xt_counters) * private->number; |
1076 | counters = vmalloc(countersize); | 876 | counters = vmalloc(countersize); |
1077 | 877 | ||
1078 | if (counters == NULL) | 878 | if (counters == NULL) |
@@ -1080,11 +880,11 @@ copy_entries_to_user(unsigned int total_size, | |||
1080 | 880 | ||
1081 | /* First, sum counters... */ | 881 | /* First, sum counters... */ |
1082 | write_lock_bh(&table->lock); | 882 | write_lock_bh(&table->lock); |
1083 | get_counters(table->private, counters); | 883 | get_counters(private, counters); |
1084 | write_unlock_bh(&table->lock); | 884 | write_unlock_bh(&table->lock); |
1085 | 885 | ||
1086 | /* choose the copy that is on ourc node/cpu */ | 886 | /* choose the copy that is on ourc node/cpu */ |
1087 | loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; | 887 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; |
1088 | if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { | 888 | if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { |
1089 | ret = -EFAULT; | 889 | ret = -EFAULT; |
1090 | goto free_counters; | 890 | goto free_counters; |
@@ -1143,87 +943,42 @@ get_entries(const struct ip6t_get_entries *entries, | |||
1143 | struct ip6t_get_entries __user *uptr) | 943 | struct ip6t_get_entries __user *uptr) |
1144 | { | 944 | { |
1145 | int ret; | 945 | int ret; |
1146 | struct ip6t_table *t; | 946 | struct xt_table *t; |
1147 | 947 | ||
1148 | t = find_table_lock(entries->name); | 948 | t = xt_find_table_lock(AF_INET6, entries->name); |
1149 | if (t && !IS_ERR(t)) { | 949 | if (t && !IS_ERR(t)) { |
1150 | duprintf("t->private->number = %u\n", | 950 | struct xt_table_info *private = t->private; |
1151 | t->private->number); | 951 | duprintf("t->private->number = %u\n", private->number); |
1152 | if (entries->size == t->private->size) | 952 | if (entries->size == private->size) |
1153 | ret = copy_entries_to_user(t->private->size, | 953 | ret = copy_entries_to_user(private->size, |
1154 | t, uptr->entrytable); | 954 | t, uptr->entrytable); |
1155 | else { | 955 | else { |
1156 | duprintf("get_entries: I've got %u not %u!\n", | 956 | duprintf("get_entries: I've got %u not %u!\n", |
1157 | t->private->size, | 957 | private->size, entries->size); |
1158 | entries->size); | ||
1159 | ret = -EINVAL; | 958 | ret = -EINVAL; |
1160 | } | 959 | } |
1161 | module_put(t->me); | 960 | module_put(t->me); |
1162 | up(&ip6t_mutex); | 961 | xt_table_unlock(t); |
1163 | } else | 962 | } else |
1164 | ret = t ? PTR_ERR(t) : -ENOENT; | 963 | ret = t ? PTR_ERR(t) : -ENOENT; |
1165 | 964 | ||
1166 | return ret; | 965 | return ret; |
1167 | } | 966 | } |
1168 | 967 | ||
1169 | static void free_table_info(struct ip6t_table_info *info) | ||
1170 | { | ||
1171 | int cpu; | ||
1172 | for_each_cpu(cpu) { | ||
1173 | if (info->size <= PAGE_SIZE) | ||
1174 | kfree(info->entries[cpu]); | ||
1175 | else | ||
1176 | vfree(info->entries[cpu]); | ||
1177 | } | ||
1178 | kfree(info); | ||
1179 | } | ||
1180 | |||
1181 | static struct ip6t_table_info *alloc_table_info(unsigned int size) | ||
1182 | { | ||
1183 | struct ip6t_table_info *newinfo; | ||
1184 | int cpu; | ||
1185 | |||
1186 | newinfo = kzalloc(sizeof(struct ip6t_table_info), GFP_KERNEL); | ||
1187 | if (!newinfo) | ||
1188 | return NULL; | ||
1189 | |||
1190 | newinfo->size = size; | ||
1191 | |||
1192 | for_each_cpu(cpu) { | ||
1193 | if (size <= PAGE_SIZE) | ||
1194 | newinfo->entries[cpu] = kmalloc_node(size, | ||
1195 | GFP_KERNEL, | ||
1196 | cpu_to_node(cpu)); | ||
1197 | else | ||
1198 | newinfo->entries[cpu] = vmalloc_node(size, | ||
1199 | cpu_to_node(cpu)); | ||
1200 | if (newinfo->entries[cpu] == NULL) { | ||
1201 | free_table_info(newinfo); | ||
1202 | return NULL; | ||
1203 | } | ||
1204 | } | ||
1205 | |||
1206 | return newinfo; | ||
1207 | } | ||
1208 | |||
1209 | static int | 968 | static int |
1210 | do_replace(void __user *user, unsigned int len) | 969 | do_replace(void __user *user, unsigned int len) |
1211 | { | 970 | { |
1212 | int ret; | 971 | int ret; |
1213 | struct ip6t_replace tmp; | 972 | struct ip6t_replace tmp; |
1214 | struct ip6t_table *t; | 973 | struct xt_table *t; |
1215 | struct ip6t_table_info *newinfo, *oldinfo; | 974 | struct xt_table_info *newinfo, *oldinfo; |
1216 | struct ip6t_counters *counters; | 975 | struct xt_counters *counters; |
1217 | void *loc_cpu_entry, *loc_cpu_old_entry; | 976 | void *loc_cpu_entry, *loc_cpu_old_entry; |
1218 | 977 | ||
1219 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 978 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
1220 | return -EFAULT; | 979 | return -EFAULT; |
1221 | 980 | ||
1222 | /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ | 981 | newinfo = xt_alloc_table_info(tmp.size); |
1223 | if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) | ||
1224 | return -ENOMEM; | ||
1225 | |||
1226 | newinfo = alloc_table_info(tmp.size); | ||
1227 | if (!newinfo) | 982 | if (!newinfo) |
1228 | return -ENOMEM; | 983 | return -ENOMEM; |
1229 | 984 | ||
@@ -1235,7 +990,7 @@ do_replace(void __user *user, unsigned int len) | |||
1235 | goto free_newinfo; | 990 | goto free_newinfo; |
1236 | } | 991 | } |
1237 | 992 | ||
1238 | counters = vmalloc(tmp.num_counters * sizeof(struct ip6t_counters)); | 993 | counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters)); |
1239 | if (!counters) { | 994 | if (!counters) { |
1240 | ret = -ENOMEM; | 995 | ret = -ENOMEM; |
1241 | goto free_newinfo; | 996 | goto free_newinfo; |
@@ -1249,7 +1004,7 @@ do_replace(void __user *user, unsigned int len) | |||
1249 | 1004 | ||
1250 | duprintf("ip_tables: Translated table\n"); | 1005 | duprintf("ip_tables: Translated table\n"); |
1251 | 1006 | ||
1252 | t = try_then_request_module(find_table_lock(tmp.name), | 1007 | t = try_then_request_module(xt_find_table_lock(AF_INET6, tmp.name), |
1253 | "ip6table_%s", tmp.name); | 1008 | "ip6table_%s", tmp.name); |
1254 | if (!t || IS_ERR(t)) { | 1009 | if (!t || IS_ERR(t)) { |
1255 | ret = t ? PTR_ERR(t) : -ENOENT; | 1010 | ret = t ? PTR_ERR(t) : -ENOENT; |
@@ -1264,7 +1019,7 @@ do_replace(void __user *user, unsigned int len) | |||
1264 | goto put_module; | 1019 | goto put_module; |
1265 | } | 1020 | } |
1266 | 1021 | ||
1267 | oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); | 1022 | oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret); |
1268 | if (!oldinfo) | 1023 | if (!oldinfo) |
1269 | goto put_module; | 1024 | goto put_module; |
1270 | 1025 | ||
@@ -1283,23 +1038,23 @@ do_replace(void __user *user, unsigned int len) | |||
1283 | /* Decrease module usage counts and free resource */ | 1038 | /* Decrease module usage counts and free resource */ |
1284 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; | 1039 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; |
1285 | IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); | 1040 | IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); |
1286 | free_table_info(oldinfo); | 1041 | xt_free_table_info(oldinfo); |
1287 | if (copy_to_user(tmp.counters, counters, | 1042 | if (copy_to_user(tmp.counters, counters, |
1288 | sizeof(struct ip6t_counters) * tmp.num_counters) != 0) | 1043 | sizeof(struct xt_counters) * tmp.num_counters) != 0) |
1289 | ret = -EFAULT; | 1044 | ret = -EFAULT; |
1290 | vfree(counters); | 1045 | vfree(counters); |
1291 | up(&ip6t_mutex); | 1046 | xt_table_unlock(t); |
1292 | return ret; | 1047 | return ret; |
1293 | 1048 | ||
1294 | put_module: | 1049 | put_module: |
1295 | module_put(t->me); | 1050 | module_put(t->me); |
1296 | up(&ip6t_mutex); | 1051 | xt_table_unlock(t); |
1297 | free_newinfo_counters_untrans: | 1052 | free_newinfo_counters_untrans: |
1298 | IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); | 1053 | IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); |
1299 | free_newinfo_counters: | 1054 | free_newinfo_counters: |
1300 | vfree(counters); | 1055 | vfree(counters); |
1301 | free_newinfo: | 1056 | free_newinfo: |
1302 | free_table_info(newinfo); | 1057 | xt_free_table_info(newinfo); |
1303 | return ret; | 1058 | return ret; |
1304 | } | 1059 | } |
1305 | 1060 | ||
@@ -1307,7 +1062,7 @@ do_replace(void __user *user, unsigned int len) | |||
1307 | * and everything is OK. */ | 1062 | * and everything is OK. */ |
1308 | static inline int | 1063 | static inline int |
1309 | add_counter_to_entry(struct ip6t_entry *e, | 1064 | add_counter_to_entry(struct ip6t_entry *e, |
1310 | const struct ip6t_counters addme[], | 1065 | const struct xt_counters addme[], |
1311 | unsigned int *i) | 1066 | unsigned int *i) |
1312 | { | 1067 | { |
1313 | #if 0 | 1068 | #if 0 |
@@ -1329,15 +1084,16 @@ static int | |||
1329 | do_add_counters(void __user *user, unsigned int len) | 1084 | do_add_counters(void __user *user, unsigned int len) |
1330 | { | 1085 | { |
1331 | unsigned int i; | 1086 | unsigned int i; |
1332 | struct ip6t_counters_info tmp, *paddc; | 1087 | struct xt_counters_info tmp, *paddc; |
1333 | struct ip6t_table *t; | 1088 | struct xt_table_info *private; |
1089 | struct xt_table *t; | ||
1334 | int ret = 0; | 1090 | int ret = 0; |
1335 | void *loc_cpu_entry; | 1091 | void *loc_cpu_entry; |
1336 | 1092 | ||
1337 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 1093 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
1338 | return -EFAULT; | 1094 | return -EFAULT; |
1339 | 1095 | ||
1340 | if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct ip6t_counters)) | 1096 | if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters)) |
1341 | return -EINVAL; | 1097 | return -EINVAL; |
1342 | 1098 | ||
1343 | paddc = vmalloc(len); | 1099 | paddc = vmalloc(len); |
@@ -1349,29 +1105,30 @@ do_add_counters(void __user *user, unsigned int len) | |||
1349 | goto free; | 1105 | goto free; |
1350 | } | 1106 | } |
1351 | 1107 | ||
1352 | t = find_table_lock(tmp.name); | 1108 | t = xt_find_table_lock(AF_INET6, tmp.name); |
1353 | if (!t || IS_ERR(t)) { | 1109 | if (!t || IS_ERR(t)) { |
1354 | ret = t ? PTR_ERR(t) : -ENOENT; | 1110 | ret = t ? PTR_ERR(t) : -ENOENT; |
1355 | goto free; | 1111 | goto free; |
1356 | } | 1112 | } |
1357 | 1113 | ||
1358 | write_lock_bh(&t->lock); | 1114 | write_lock_bh(&t->lock); |
1359 | if (t->private->number != paddc->num_counters) { | 1115 | private = t->private; |
1116 | if (private->number != paddc->num_counters) { | ||
1360 | ret = -EINVAL; | 1117 | ret = -EINVAL; |
1361 | goto unlock_up_free; | 1118 | goto unlock_up_free; |
1362 | } | 1119 | } |
1363 | 1120 | ||
1364 | i = 0; | 1121 | i = 0; |
1365 | /* Choose the copy that is on our node */ | 1122 | /* Choose the copy that is on our node */ |
1366 | loc_cpu_entry = t->private->entries[smp_processor_id()]; | 1123 | loc_cpu_entry = private->entries[smp_processor_id()]; |
1367 | IP6T_ENTRY_ITERATE(loc_cpu_entry, | 1124 | IP6T_ENTRY_ITERATE(loc_cpu_entry, |
1368 | t->private->size, | 1125 | private->size, |
1369 | add_counter_to_entry, | 1126 | add_counter_to_entry, |
1370 | paddc->counters, | 1127 | paddc->counters, |
1371 | &i); | 1128 | &i); |
1372 | unlock_up_free: | 1129 | unlock_up_free: |
1373 | write_unlock_bh(&t->lock); | 1130 | write_unlock_bh(&t->lock); |
1374 | up(&ip6t_mutex); | 1131 | xt_table_unlock(t); |
1375 | module_put(t->me); | 1132 | module_put(t->me); |
1376 | free: | 1133 | free: |
1377 | vfree(paddc); | 1134 | vfree(paddc); |
@@ -1415,7 +1172,7 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1415 | switch (cmd) { | 1172 | switch (cmd) { |
1416 | case IP6T_SO_GET_INFO: { | 1173 | case IP6T_SO_GET_INFO: { |
1417 | char name[IP6T_TABLE_MAXNAMELEN]; | 1174 | char name[IP6T_TABLE_MAXNAMELEN]; |
1418 | struct ip6t_table *t; | 1175 | struct xt_table *t; |
1419 | 1176 | ||
1420 | if (*len != sizeof(struct ip6t_getinfo)) { | 1177 | if (*len != sizeof(struct ip6t_getinfo)) { |
1421 | duprintf("length %u != %u\n", *len, | 1178 | duprintf("length %u != %u\n", *len, |
@@ -1430,25 +1187,26 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1430 | } | 1187 | } |
1431 | name[IP6T_TABLE_MAXNAMELEN-1] = '\0'; | 1188 | name[IP6T_TABLE_MAXNAMELEN-1] = '\0'; |
1432 | 1189 | ||
1433 | t = try_then_request_module(find_table_lock(name), | 1190 | t = try_then_request_module(xt_find_table_lock(AF_INET6, name), |
1434 | "ip6table_%s", name); | 1191 | "ip6table_%s", name); |
1435 | if (t && !IS_ERR(t)) { | 1192 | if (t && !IS_ERR(t)) { |
1436 | struct ip6t_getinfo info; | 1193 | struct ip6t_getinfo info; |
1194 | struct xt_table_info *private = t->private; | ||
1437 | 1195 | ||
1438 | info.valid_hooks = t->valid_hooks; | 1196 | info.valid_hooks = t->valid_hooks; |
1439 | memcpy(info.hook_entry, t->private->hook_entry, | 1197 | memcpy(info.hook_entry, private->hook_entry, |
1440 | sizeof(info.hook_entry)); | 1198 | sizeof(info.hook_entry)); |
1441 | memcpy(info.underflow, t->private->underflow, | 1199 | memcpy(info.underflow, private->underflow, |
1442 | sizeof(info.underflow)); | 1200 | sizeof(info.underflow)); |
1443 | info.num_entries = t->private->number; | 1201 | info.num_entries = private->number; |
1444 | info.size = t->private->size; | 1202 | info.size = private->size; |
1445 | memcpy(info.name, name, sizeof(info.name)); | 1203 | memcpy(info.name, name, sizeof(info.name)); |
1446 | 1204 | ||
1447 | if (copy_to_user(user, &info, *len) != 0) | 1205 | if (copy_to_user(user, &info, *len) != 0) |
1448 | ret = -EFAULT; | 1206 | ret = -EFAULT; |
1449 | else | 1207 | else |
1450 | ret = 0; | 1208 | ret = 0; |
1451 | up(&ip6t_mutex); | 1209 | xt_table_unlock(t); |
1452 | module_put(t->me); | 1210 | module_put(t->me); |
1453 | } else | 1211 | } else |
1454 | ret = t ? PTR_ERR(t) : -ENOENT; | 1212 | ret = t ? PTR_ERR(t) : -ENOENT; |
@@ -1475,7 +1233,7 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1475 | case IP6T_SO_GET_REVISION_MATCH: | 1233 | case IP6T_SO_GET_REVISION_MATCH: |
1476 | case IP6T_SO_GET_REVISION_TARGET: { | 1234 | case IP6T_SO_GET_REVISION_TARGET: { |
1477 | struct ip6t_get_revision rev; | 1235 | struct ip6t_get_revision rev; |
1478 | int (*revfn)(const char *, u8, int *); | 1236 | int target; |
1479 | 1237 | ||
1480 | if (*len != sizeof(rev)) { | 1238 | if (*len != sizeof(rev)) { |
1481 | ret = -EINVAL; | 1239 | ret = -EINVAL; |
@@ -1487,12 +1245,13 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1487 | } | 1245 | } |
1488 | 1246 | ||
1489 | if (cmd == IP6T_SO_GET_REVISION_TARGET) | 1247 | if (cmd == IP6T_SO_GET_REVISION_TARGET) |
1490 | revfn = target_revfn; | 1248 | target = 1; |
1491 | else | 1249 | else |
1492 | revfn = match_revfn; | 1250 | target = 0; |
1493 | 1251 | ||
1494 | try_then_request_module(find_revision(rev.name, rev.revision, | 1252 | try_then_request_module(xt_find_revision(AF_INET6, rev.name, |
1495 | revfn, &ret), | 1253 | rev.revision, |
1254 | target, &ret), | ||
1496 | "ip6t_%s", rev.name); | 1255 | "ip6t_%s", rev.name); |
1497 | break; | 1256 | break; |
1498 | } | 1257 | } |
@@ -1505,61 +1264,16 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1505 | return ret; | 1264 | return ret; |
1506 | } | 1265 | } |
1507 | 1266 | ||
1508 | /* Registration hooks for targets. */ | 1267 | int ip6t_register_table(struct xt_table *table, |
1509 | int | ||
1510 | ip6t_register_target(struct ip6t_target *target) | ||
1511 | { | ||
1512 | int ret; | ||
1513 | |||
1514 | ret = down_interruptible(&ip6t_mutex); | ||
1515 | if (ret != 0) | ||
1516 | return ret; | ||
1517 | list_add(&target->list, &ip6t_target); | ||
1518 | up(&ip6t_mutex); | ||
1519 | return ret; | ||
1520 | } | ||
1521 | |||
1522 | void | ||
1523 | ip6t_unregister_target(struct ip6t_target *target) | ||
1524 | { | ||
1525 | down(&ip6t_mutex); | ||
1526 | LIST_DELETE(&ip6t_target, target); | ||
1527 | up(&ip6t_mutex); | ||
1528 | } | ||
1529 | |||
1530 | int | ||
1531 | ip6t_register_match(struct ip6t_match *match) | ||
1532 | { | ||
1533 | int ret; | ||
1534 | |||
1535 | ret = down_interruptible(&ip6t_mutex); | ||
1536 | if (ret != 0) | ||
1537 | return ret; | ||
1538 | |||
1539 | list_add(&match->list, &ip6t_match); | ||
1540 | up(&ip6t_mutex); | ||
1541 | |||
1542 | return ret; | ||
1543 | } | ||
1544 | |||
1545 | void | ||
1546 | ip6t_unregister_match(struct ip6t_match *match) | ||
1547 | { | ||
1548 | down(&ip6t_mutex); | ||
1549 | LIST_DELETE(&ip6t_match, match); | ||
1550 | up(&ip6t_mutex); | ||
1551 | } | ||
1552 | |||
1553 | int ip6t_register_table(struct ip6t_table *table, | ||
1554 | const struct ip6t_replace *repl) | 1268 | const struct ip6t_replace *repl) |
1555 | { | 1269 | { |
1556 | int ret; | 1270 | int ret; |
1557 | struct ip6t_table_info *newinfo; | 1271 | struct xt_table_info *newinfo; |
1558 | static struct ip6t_table_info bootstrap | 1272 | static struct xt_table_info bootstrap |
1559 | = { 0, 0, 0, { 0 }, { 0 }, { } }; | 1273 | = { 0, 0, 0, { 0 }, { 0 }, { } }; |
1560 | void *loc_cpu_entry; | 1274 | void *loc_cpu_entry; |
1561 | 1275 | ||
1562 | newinfo = alloc_table_info(repl->size); | 1276 | newinfo = xt_alloc_table_info(repl->size); |
1563 | if (!newinfo) | 1277 | if (!newinfo) |
1564 | return -ENOMEM; | 1278 | return -ENOMEM; |
1565 | 1279 | ||
@@ -1573,244 +1287,29 @@ int ip6t_register_table(struct ip6t_table *table, | |||
1573 | repl->hook_entry, | 1287 | repl->hook_entry, |
1574 | repl->underflow); | 1288 | repl->underflow); |
1575 | if (ret != 0) { | 1289 | if (ret != 0) { |
1576 | free_table_info(newinfo); | 1290 | xt_free_table_info(newinfo); |
1577 | return ret; | 1291 | return ret; |
1578 | } | 1292 | } |
1579 | 1293 | ||
1580 | ret = down_interruptible(&ip6t_mutex); | 1294 | if (xt_register_table(table, &bootstrap, newinfo) != 0) { |
1581 | if (ret != 0) { | 1295 | xt_free_table_info(newinfo); |
1582 | free_table_info(newinfo); | ||
1583 | return ret; | 1296 | return ret; |
1584 | } | 1297 | } |
1585 | 1298 | ||
1586 | /* Don't autoload: we'd eat our tail... */ | 1299 | return 0; |
1587 | if (list_named_find(&ip6t_tables, table->name)) { | ||
1588 | ret = -EEXIST; | ||
1589 | goto free_unlock; | ||
1590 | } | ||
1591 | |||
1592 | /* Simplifies replace_table code. */ | ||
1593 | table->private = &bootstrap; | ||
1594 | if (!replace_table(table, 0, newinfo, &ret)) | ||
1595 | goto free_unlock; | ||
1596 | |||
1597 | duprintf("table->private->number = %u\n", | ||
1598 | table->private->number); | ||
1599 | |||
1600 | /* save number of initial entries */ | ||
1601 | table->private->initial_entries = table->private->number; | ||
1602 | |||
1603 | rwlock_init(&table->lock); | ||
1604 | list_prepend(&ip6t_tables, table); | ||
1605 | |||
1606 | unlock: | ||
1607 | up(&ip6t_mutex); | ||
1608 | return ret; | ||
1609 | |||
1610 | free_unlock: | ||
1611 | free_table_info(newinfo); | ||
1612 | goto unlock; | ||
1613 | } | 1300 | } |
1614 | 1301 | ||
1615 | void ip6t_unregister_table(struct ip6t_table *table) | 1302 | void ip6t_unregister_table(struct xt_table *table) |
1616 | { | 1303 | { |
1304 | struct xt_table_info *private; | ||
1617 | void *loc_cpu_entry; | 1305 | void *loc_cpu_entry; |
1618 | 1306 | ||
1619 | down(&ip6t_mutex); | 1307 | private = xt_unregister_table(table); |
1620 | LIST_DELETE(&ip6t_tables, table); | ||
1621 | up(&ip6t_mutex); | ||
1622 | 1308 | ||
1623 | /* Decrease module usage counts and free resources */ | 1309 | /* Decrease module usage counts and free resources */ |
1624 | loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; | 1310 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; |
1625 | IP6T_ENTRY_ITERATE(loc_cpu_entry, table->private->size, | 1311 | IP6T_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL); |
1626 | cleanup_entry, NULL); | 1312 | xt_free_table_info(private); |
1627 | free_table_info(table->private); | ||
1628 | } | ||
1629 | |||
1630 | /* Returns 1 if the port is matched by the range, 0 otherwise */ | ||
1631 | static inline int | ||
1632 | port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert) | ||
1633 | { | ||
1634 | int ret; | ||
1635 | |||
1636 | ret = (port >= min && port <= max) ^ invert; | ||
1637 | return ret; | ||
1638 | } | ||
1639 | |||
1640 | static int | ||
1641 | tcp_find_option(u_int8_t option, | ||
1642 | const struct sk_buff *skb, | ||
1643 | unsigned int tcpoff, | ||
1644 | unsigned int optlen, | ||
1645 | int invert, | ||
1646 | int *hotdrop) | ||
1647 | { | ||
1648 | /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ | ||
1649 | u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; | ||
1650 | unsigned int i; | ||
1651 | |||
1652 | duprintf("tcp_match: finding option\n"); | ||
1653 | if (!optlen) | ||
1654 | return invert; | ||
1655 | /* If we don't have the whole header, drop packet. */ | ||
1656 | op = skb_header_pointer(skb, tcpoff + sizeof(struct tcphdr), optlen, | ||
1657 | _opt); | ||
1658 | if (op == NULL) { | ||
1659 | *hotdrop = 1; | ||
1660 | return 0; | ||
1661 | } | ||
1662 | |||
1663 | for (i = 0; i < optlen; ) { | ||
1664 | if (op[i] == option) return !invert; | ||
1665 | if (op[i] < 2) i++; | ||
1666 | else i += op[i+1]?:1; | ||
1667 | } | ||
1668 | |||
1669 | return invert; | ||
1670 | } | ||
1671 | |||
1672 | static int | ||
1673 | tcp_match(const struct sk_buff *skb, | ||
1674 | const struct net_device *in, | ||
1675 | const struct net_device *out, | ||
1676 | const void *matchinfo, | ||
1677 | int offset, | ||
1678 | unsigned int protoff, | ||
1679 | int *hotdrop) | ||
1680 | { | ||
1681 | struct tcphdr _tcph, *th; | ||
1682 | const struct ip6t_tcp *tcpinfo = matchinfo; | ||
1683 | |||
1684 | if (offset) { | ||
1685 | /* To quote Alan: | ||
1686 | |||
1687 | Don't allow a fragment of TCP 8 bytes in. Nobody normal | ||
1688 | causes this. Its a cracker trying to break in by doing a | ||
1689 | flag overwrite to pass the direction checks. | ||
1690 | */ | ||
1691 | if (offset == 1) { | ||
1692 | duprintf("Dropping evil TCP offset=1 frag.\n"); | ||
1693 | *hotdrop = 1; | ||
1694 | } | ||
1695 | /* Must not be a fragment. */ | ||
1696 | return 0; | ||
1697 | } | ||
1698 | |||
1699 | #define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) | ||
1700 | |||
1701 | th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); | ||
1702 | if (th == NULL) { | ||
1703 | /* We've been asked to examine this packet, and we | ||
1704 | can't. Hence, no choice but to drop. */ | ||
1705 | duprintf("Dropping evil TCP offset=0 tinygram.\n"); | ||
1706 | *hotdrop = 1; | ||
1707 | return 0; | ||
1708 | } | ||
1709 | |||
1710 | if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1], | ||
1711 | ntohs(th->source), | ||
1712 | !!(tcpinfo->invflags & IP6T_TCP_INV_SRCPT))) | ||
1713 | return 0; | ||
1714 | if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1], | ||
1715 | ntohs(th->dest), | ||
1716 | !!(tcpinfo->invflags & IP6T_TCP_INV_DSTPT))) | ||
1717 | return 0; | ||
1718 | if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask) | ||
1719 | == tcpinfo->flg_cmp, | ||
1720 | IP6T_TCP_INV_FLAGS)) | ||
1721 | return 0; | ||
1722 | if (tcpinfo->option) { | ||
1723 | if (th->doff * 4 < sizeof(_tcph)) { | ||
1724 | *hotdrop = 1; | ||
1725 | return 0; | ||
1726 | } | ||
1727 | if (!tcp_find_option(tcpinfo->option, skb, protoff, | ||
1728 | th->doff*4 - sizeof(*th), | ||
1729 | tcpinfo->invflags & IP6T_TCP_INV_OPTION, | ||
1730 | hotdrop)) | ||
1731 | return 0; | ||
1732 | } | ||
1733 | return 1; | ||
1734 | } | ||
1735 | |||
1736 | /* Called when user tries to insert an entry of this type. */ | ||
1737 | static int | ||
1738 | tcp_checkentry(const char *tablename, | ||
1739 | const struct ip6t_ip6 *ipv6, | ||
1740 | void *matchinfo, | ||
1741 | unsigned int matchsize, | ||
1742 | unsigned int hook_mask) | ||
1743 | { | ||
1744 | const struct ip6t_tcp *tcpinfo = matchinfo; | ||
1745 | |||
1746 | /* Must specify proto == TCP, and no unknown invflags */ | ||
1747 | return ipv6->proto == IPPROTO_TCP | ||
1748 | && !(ipv6->invflags & IP6T_INV_PROTO) | ||
1749 | && matchsize == IP6T_ALIGN(sizeof(struct ip6t_tcp)) | ||
1750 | && !(tcpinfo->invflags & ~IP6T_TCP_INV_MASK); | ||
1751 | } | ||
1752 | |||
1753 | static int | ||
1754 | udp_match(const struct sk_buff *skb, | ||
1755 | const struct net_device *in, | ||
1756 | const struct net_device *out, | ||
1757 | const void *matchinfo, | ||
1758 | int offset, | ||
1759 | unsigned int protoff, | ||
1760 | int *hotdrop) | ||
1761 | { | ||
1762 | struct udphdr _udph, *uh; | ||
1763 | const struct ip6t_udp *udpinfo = matchinfo; | ||
1764 | |||
1765 | /* Must not be a fragment. */ | ||
1766 | if (offset) | ||
1767 | return 0; | ||
1768 | |||
1769 | uh = skb_header_pointer(skb, protoff, sizeof(_udph), &_udph); | ||
1770 | if (uh == NULL) { | ||
1771 | /* We've been asked to examine this packet, and we | ||
1772 | can't. Hence, no choice but to drop. */ | ||
1773 | duprintf("Dropping evil UDP tinygram.\n"); | ||
1774 | *hotdrop = 1; | ||
1775 | return 0; | ||
1776 | } | ||
1777 | |||
1778 | return port_match(udpinfo->spts[0], udpinfo->spts[1], | ||
1779 | ntohs(uh->source), | ||
1780 | !!(udpinfo->invflags & IP6T_UDP_INV_SRCPT)) | ||
1781 | && port_match(udpinfo->dpts[0], udpinfo->dpts[1], | ||
1782 | ntohs(uh->dest), | ||
1783 | !!(udpinfo->invflags & IP6T_UDP_INV_DSTPT)); | ||
1784 | } | ||
1785 | |||
1786 | /* Called when user tries to insert an entry of this type. */ | ||
1787 | static int | ||
1788 | udp_checkentry(const char *tablename, | ||
1789 | const struct ip6t_ip6 *ipv6, | ||
1790 | void *matchinfo, | ||
1791 | unsigned int matchinfosize, | ||
1792 | unsigned int hook_mask) | ||
1793 | { | ||
1794 | const struct ip6t_udp *udpinfo = matchinfo; | ||
1795 | |||
1796 | /* Must specify proto == UDP, and no unknown invflags */ | ||
1797 | if (ipv6->proto != IPPROTO_UDP || (ipv6->invflags & IP6T_INV_PROTO)) { | ||
1798 | duprintf("ip6t_udp: Protocol %u != %u\n", ipv6->proto, | ||
1799 | IPPROTO_UDP); | ||
1800 | return 0; | ||
1801 | } | ||
1802 | if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_udp))) { | ||
1803 | duprintf("ip6t_udp: matchsize %u != %u\n", | ||
1804 | matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_udp))); | ||
1805 | return 0; | ||
1806 | } | ||
1807 | if (udpinfo->invflags & ~IP6T_UDP_INV_MASK) { | ||
1808 | duprintf("ip6t_udp: unknown flags %X\n", | ||
1809 | udpinfo->invflags); | ||
1810 | return 0; | ||
1811 | } | ||
1812 | |||
1813 | return 1; | ||
1814 | } | 1313 | } |
1815 | 1314 | ||
1816 | /* Returns 1 if the type and code is matched by the range, 0 otherwise */ | 1315 | /* Returns 1 if the type and code is matched by the range, 0 otherwise */ |
@@ -1858,11 +1357,12 @@ icmp6_match(const struct sk_buff *skb, | |||
1858 | /* Called when user tries to insert an entry of this type. */ | 1357 | /* Called when user tries to insert an entry of this type. */ |
1859 | static int | 1358 | static int |
1860 | icmp6_checkentry(const char *tablename, | 1359 | icmp6_checkentry(const char *tablename, |
1861 | const struct ip6t_ip6 *ipv6, | 1360 | const void *entry, |
1862 | void *matchinfo, | 1361 | void *matchinfo, |
1863 | unsigned int matchsize, | 1362 | unsigned int matchsize, |
1864 | unsigned int hook_mask) | 1363 | unsigned int hook_mask) |
1865 | { | 1364 | { |
1365 | const struct ip6t_ip6 *ipv6 = entry; | ||
1866 | const struct ip6t_icmp *icmpinfo = matchinfo; | 1366 | const struct ip6t_icmp *icmpinfo = matchinfo; |
1867 | 1367 | ||
1868 | /* Must specify proto == ICMP, and no unknown invflags */ | 1368 | /* Must specify proto == ICMP, and no unknown invflags */ |
@@ -1892,164 +1392,42 @@ static struct nf_sockopt_ops ip6t_sockopts = { | |||
1892 | .get = do_ip6t_get_ctl, | 1392 | .get = do_ip6t_get_ctl, |
1893 | }; | 1393 | }; |
1894 | 1394 | ||
1895 | static struct ip6t_match tcp_matchstruct = { | ||
1896 | .name = "tcp", | ||
1897 | .match = &tcp_match, | ||
1898 | .checkentry = &tcp_checkentry, | ||
1899 | }; | ||
1900 | |||
1901 | static struct ip6t_match udp_matchstruct = { | ||
1902 | .name = "udp", | ||
1903 | .match = &udp_match, | ||
1904 | .checkentry = &udp_checkentry, | ||
1905 | }; | ||
1906 | |||
1907 | static struct ip6t_match icmp6_matchstruct = { | 1395 | static struct ip6t_match icmp6_matchstruct = { |
1908 | .name = "icmp6", | 1396 | .name = "icmp6", |
1909 | .match = &icmp6_match, | 1397 | .match = &icmp6_match, |
1910 | .checkentry = &icmp6_checkentry, | 1398 | .checkentry = &icmp6_checkentry, |
1911 | }; | 1399 | }; |
1912 | 1400 | ||
1913 | #ifdef CONFIG_PROC_FS | ||
1914 | static inline int print_name(const char *i, | ||
1915 | off_t start_offset, char *buffer, int length, | ||
1916 | off_t *pos, unsigned int *count) | ||
1917 | { | ||
1918 | if ((*count)++ >= start_offset) { | ||
1919 | unsigned int namelen; | ||
1920 | |||
1921 | namelen = sprintf(buffer + *pos, "%s\n", | ||
1922 | i + sizeof(struct list_head)); | ||
1923 | if (*pos + namelen > length) { | ||
1924 | /* Stop iterating */ | ||
1925 | return 1; | ||
1926 | } | ||
1927 | *pos += namelen; | ||
1928 | } | ||
1929 | return 0; | ||
1930 | } | ||
1931 | |||
1932 | static inline int print_target(const struct ip6t_target *t, | ||
1933 | off_t start_offset, char *buffer, int length, | ||
1934 | off_t *pos, unsigned int *count) | ||
1935 | { | ||
1936 | if (t == &ip6t_standard_target || t == &ip6t_error_target) | ||
1937 | return 0; | ||
1938 | return print_name((char *)t, start_offset, buffer, length, pos, count); | ||
1939 | } | ||
1940 | |||
1941 | static int ip6t_get_tables(char *buffer, char **start, off_t offset, int length) | ||
1942 | { | ||
1943 | off_t pos = 0; | ||
1944 | unsigned int count = 0; | ||
1945 | |||
1946 | if (down_interruptible(&ip6t_mutex) != 0) | ||
1947 | return 0; | ||
1948 | |||
1949 | LIST_FIND(&ip6t_tables, print_name, char *, | ||
1950 | offset, buffer, length, &pos, &count); | ||
1951 | |||
1952 | up(&ip6t_mutex); | ||
1953 | |||
1954 | /* `start' hack - see fs/proc/generic.c line ~105 */ | ||
1955 | *start=(char *)((unsigned long)count-offset); | ||
1956 | return pos; | ||
1957 | } | ||
1958 | |||
1959 | static int ip6t_get_targets(char *buffer, char **start, off_t offset, int length) | ||
1960 | { | ||
1961 | off_t pos = 0; | ||
1962 | unsigned int count = 0; | ||
1963 | |||
1964 | if (down_interruptible(&ip6t_mutex) != 0) | ||
1965 | return 0; | ||
1966 | |||
1967 | LIST_FIND(&ip6t_target, print_target, struct ip6t_target *, | ||
1968 | offset, buffer, length, &pos, &count); | ||
1969 | |||
1970 | up(&ip6t_mutex); | ||
1971 | |||
1972 | *start = (char *)((unsigned long)count - offset); | ||
1973 | return pos; | ||
1974 | } | ||
1975 | |||
1976 | static int ip6t_get_matches(char *buffer, char **start, off_t offset, int length) | ||
1977 | { | ||
1978 | off_t pos = 0; | ||
1979 | unsigned int count = 0; | ||
1980 | |||
1981 | if (down_interruptible(&ip6t_mutex) != 0) | ||
1982 | return 0; | ||
1983 | |||
1984 | LIST_FIND(&ip6t_match, print_name, char *, | ||
1985 | offset, buffer, length, &pos, &count); | ||
1986 | |||
1987 | up(&ip6t_mutex); | ||
1988 | |||
1989 | *start = (char *)((unsigned long)count - offset); | ||
1990 | return pos; | ||
1991 | } | ||
1992 | |||
1993 | static const struct { char *name; get_info_t *get_info; } ip6t_proc_entry[] = | ||
1994 | { { "ip6_tables_names", ip6t_get_tables }, | ||
1995 | { "ip6_tables_targets", ip6t_get_targets }, | ||
1996 | { "ip6_tables_matches", ip6t_get_matches }, | ||
1997 | { NULL, NULL} }; | ||
1998 | #endif /*CONFIG_PROC_FS*/ | ||
1999 | |||
2000 | static int __init init(void) | 1401 | static int __init init(void) |
2001 | { | 1402 | { |
2002 | int ret; | 1403 | int ret; |
2003 | 1404 | ||
1405 | xt_proto_init(AF_INET6); | ||
1406 | |||
2004 | /* Noone else will be downing sem now, so we won't sleep */ | 1407 | /* Noone else will be downing sem now, so we won't sleep */ |
2005 | down(&ip6t_mutex); | 1408 | xt_register_target(AF_INET6, &ip6t_standard_target); |
2006 | list_append(&ip6t_target, &ip6t_standard_target); | 1409 | xt_register_target(AF_INET6, &ip6t_error_target); |
2007 | list_append(&ip6t_target, &ip6t_error_target); | 1410 | xt_register_match(AF_INET6, &icmp6_matchstruct); |
2008 | list_append(&ip6t_match, &tcp_matchstruct); | ||
2009 | list_append(&ip6t_match, &udp_matchstruct); | ||
2010 | list_append(&ip6t_match, &icmp6_matchstruct); | ||
2011 | up(&ip6t_mutex); | ||
2012 | 1411 | ||
2013 | /* Register setsockopt */ | 1412 | /* Register setsockopt */ |
2014 | ret = nf_register_sockopt(&ip6t_sockopts); | 1413 | ret = nf_register_sockopt(&ip6t_sockopts); |
2015 | if (ret < 0) { | 1414 | if (ret < 0) { |
2016 | duprintf("Unable to register sockopts.\n"); | 1415 | duprintf("Unable to register sockopts.\n"); |
1416 | xt_proto_fini(AF_INET6); | ||
2017 | return ret; | 1417 | return ret; |
2018 | } | 1418 | } |
2019 | 1419 | ||
2020 | #ifdef CONFIG_PROC_FS | 1420 | printk("ip6_tables: (C) 2000-2006 Netfilter Core Team\n"); |
2021 | { | ||
2022 | struct proc_dir_entry *proc; | ||
2023 | int i; | ||
2024 | |||
2025 | for (i = 0; ip6t_proc_entry[i].name; i++) { | ||
2026 | proc = proc_net_create(ip6t_proc_entry[i].name, 0, | ||
2027 | ip6t_proc_entry[i].get_info); | ||
2028 | if (!proc) { | ||
2029 | while (--i >= 0) | ||
2030 | proc_net_remove(ip6t_proc_entry[i].name); | ||
2031 | nf_unregister_sockopt(&ip6t_sockopts); | ||
2032 | return -ENOMEM; | ||
2033 | } | ||
2034 | proc->owner = THIS_MODULE; | ||
2035 | } | ||
2036 | } | ||
2037 | #endif | ||
2038 | |||
2039 | printk("ip6_tables: (C) 2000-2002 Netfilter core team\n"); | ||
2040 | return 0; | 1421 | return 0; |
2041 | } | 1422 | } |
2042 | 1423 | ||
2043 | static void __exit fini(void) | 1424 | static void __exit fini(void) |
2044 | { | 1425 | { |
2045 | nf_unregister_sockopt(&ip6t_sockopts); | 1426 | nf_unregister_sockopt(&ip6t_sockopts); |
2046 | #ifdef CONFIG_PROC_FS | 1427 | xt_unregister_match(AF_INET6, &icmp6_matchstruct); |
2047 | { | 1428 | xt_unregister_target(AF_INET6, &ip6t_error_target); |
2048 | int i; | 1429 | xt_unregister_target(AF_INET6, &ip6t_standard_target); |
2049 | for (i = 0; ip6t_proc_entry[i].name; i++) | 1430 | xt_proto_fini(AF_INET6); |
2050 | proc_net_remove(ip6t_proc_entry[i].name); | ||
2051 | } | ||
2052 | #endif | ||
2053 | } | 1431 | } |
2054 | 1432 | ||
2055 | /* | 1433 | /* |
@@ -2128,10 +1506,6 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, | |||
2128 | EXPORT_SYMBOL(ip6t_register_table); | 1506 | EXPORT_SYMBOL(ip6t_register_table); |
2129 | EXPORT_SYMBOL(ip6t_unregister_table); | 1507 | EXPORT_SYMBOL(ip6t_unregister_table); |
2130 | EXPORT_SYMBOL(ip6t_do_table); | 1508 | EXPORT_SYMBOL(ip6t_do_table); |
2131 | EXPORT_SYMBOL(ip6t_register_match); | ||
2132 | EXPORT_SYMBOL(ip6t_unregister_match); | ||
2133 | EXPORT_SYMBOL(ip6t_register_target); | ||
2134 | EXPORT_SYMBOL(ip6t_unregister_target); | ||
2135 | EXPORT_SYMBOL(ip6t_ext_hdr); | 1509 | EXPORT_SYMBOL(ip6t_ext_hdr); |
2136 | EXPORT_SYMBOL(ipv6_find_hdr); | 1510 | EXPORT_SYMBOL(ipv6_find_hdr); |
2137 | EXPORT_SYMBOL(ip6_masked_addrcmp); | 1511 | EXPORT_SYMBOL(ip6_masked_addrcmp); |
diff --git a/net/ipv6/netfilter/ip6t_HL.c b/net/ipv6/netfilter/ip6t_HL.c index 8f5549b72720..306200c35057 100644 --- a/net/ipv6/netfilter/ip6t_HL.c +++ b/net/ipv6/netfilter/ip6t_HL.c | |||
@@ -62,7 +62,7 @@ static unsigned int ip6t_hl_target(struct sk_buff **pskb, | |||
62 | } | 62 | } |
63 | 63 | ||
64 | static int ip6t_hl_checkentry(const char *tablename, | 64 | static int ip6t_hl_checkentry(const char *tablename, |
65 | const struct ip6t_entry *e, | 65 | const void *entry, |
66 | void *targinfo, | 66 | void *targinfo, |
67 | unsigned int targinfosize, | 67 | unsigned int targinfosize, |
68 | unsigned int hook_mask) | 68 | unsigned int hook_mask) |
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c index ae4653bfd654..fc19d8a4ca68 100644 --- a/net/ipv6/netfilter/ip6t_LOG.c +++ b/net/ipv6/netfilter/ip6t_LOG.c | |||
@@ -444,7 +444,7 @@ ip6t_log_target(struct sk_buff **pskb, | |||
444 | 444 | ||
445 | 445 | ||
446 | static int ip6t_log_checkentry(const char *tablename, | 446 | static int ip6t_log_checkentry(const char *tablename, |
447 | const struct ip6t_entry *e, | 447 | const void *entry, |
448 | void *targinfo, | 448 | void *targinfo, |
449 | unsigned int targinfosize, | 449 | unsigned int targinfosize, |
450 | unsigned int hook_mask) | 450 | unsigned int hook_mask) |
diff --git a/net/ipv6/netfilter/ip6t_MARK.c b/net/ipv6/netfilter/ip6t_MARK.c deleted file mode 100644 index eab8fb864ee0..000000000000 --- a/net/ipv6/netfilter/ip6t_MARK.c +++ /dev/null | |||
@@ -1,81 +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_ipv6/ip6_tables.h> | ||
16 | #include <linux/netfilter_ipv6/ip6t_MARK.h> | ||
17 | |||
18 | MODULE_LICENSE("GPL"); | ||
19 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); | ||
20 | |||
21 | static unsigned int | ||
22 | target(struct sk_buff **pskb, | ||
23 | const struct net_device *in, | ||
24 | const struct net_device *out, | ||
25 | unsigned int hooknum, | ||
26 | const void *targinfo, | ||
27 | void *userinfo) | ||
28 | { | ||
29 | const struct ip6t_mark_target_info *markinfo = targinfo; | ||
30 | |||
31 | if((*pskb)->nfmark != markinfo->mark) | ||
32 | (*pskb)->nfmark = markinfo->mark; | ||
33 | |||
34 | return IP6T_CONTINUE; | ||
35 | } | ||
36 | |||
37 | static int | ||
38 | checkentry(const char *tablename, | ||
39 | const struct ip6t_entry *e, | ||
40 | void *targinfo, | ||
41 | unsigned int targinfosize, | ||
42 | unsigned int hook_mask) | ||
43 | { | ||
44 | if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_mark_target_info))) { | ||
45 | printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", | ||
46 | targinfosize, | ||
47 | IP6T_ALIGN(sizeof(struct ip6t_mark_target_info))); | ||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | if (strcmp(tablename, "mangle") != 0) { | ||
52 | printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename); | ||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | return 1; | ||
57 | } | ||
58 | |||
59 | static struct ip6t_target ip6t_mark_reg = { | ||
60 | .name = "MARK", | ||
61 | .target = target, | ||
62 | .checkentry = checkentry, | ||
63 | .me = THIS_MODULE | ||
64 | }; | ||
65 | |||
66 | static int __init init(void) | ||
67 | { | ||
68 | printk(KERN_DEBUG "registering ipv6 mark target\n"); | ||
69 | if (ip6t_register_target(&ip6t_mark_reg)) | ||
70 | return -EINVAL; | ||
71 | |||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static void __exit fini(void) | ||
76 | { | ||
77 | ip6t_unregister_target(&ip6t_mark_reg); | ||
78 | } | ||
79 | |||
80 | module_init(init); | ||
81 | module_exit(fini); | ||
diff --git a/net/ipv6/netfilter/ip6t_NFQUEUE.c b/net/ipv6/netfilter/ip6t_NFQUEUE.c deleted file mode 100644 index c6e3730e7409..000000000000 --- a/net/ipv6/netfilter/ip6t_NFQUEUE.c +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
1 | /* ip6tables 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_ipv6/ip6_tables.h> | ||
16 | #include <linux/netfilter_ipv4/ipt_NFQUEUE.h> | ||
17 | |||
18 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | ||
19 | MODULE_DESCRIPTION("ip6tables NFQUEUE target"); | ||
20 | MODULE_LICENSE("GPL"); | ||
21 | |||
22 | static unsigned int | ||
23 | target(struct sk_buff **pskb, | ||
24 | const struct net_device *in, | ||
25 | const struct net_device *out, | ||
26 | unsigned int hooknum, | ||
27 | const void *targinfo, | ||
28 | void *userinfo) | ||
29 | { | ||
30 | const struct ipt_NFQ_info *tinfo = targinfo; | ||
31 | |||
32 | return NF_QUEUE_NR(tinfo->queuenum); | ||
33 | } | ||
34 | |||
35 | static int | ||
36 | checkentry(const char *tablename, | ||
37 | const struct ip6t_entry *e, | ||
38 | void *targinfo, | ||
39 | unsigned int targinfosize, | ||
40 | unsigned int hook_mask) | ||
41 | { | ||
42 | if (targinfosize != IP6T_ALIGN(sizeof(struct ipt_NFQ_info))) { | ||
43 | printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n", | ||
44 | targinfosize, | ||
45 | IP6T_ALIGN(sizeof(struct ipt_NFQ_info))); | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | return 1; | ||
50 | } | ||
51 | |||
52 | static struct ip6t_target ipt_NFQ_reg = { | ||
53 | .name = "NFQUEUE", | ||
54 | .target = target, | ||
55 | .checkentry = checkentry, | ||
56 | .me = THIS_MODULE, | ||
57 | }; | ||
58 | |||
59 | static int __init init(void) | ||
60 | { | ||
61 | return ip6t_register_target(&ipt_NFQ_reg); | ||
62 | } | ||
63 | |||
64 | static void __exit fini(void) | ||
65 | { | ||
66 | ip6t_unregister_target(&ipt_NFQ_reg); | ||
67 | } | ||
68 | |||
69 | module_init(init); | ||
70 | module_exit(fini); | ||
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index b03e87adca93..c745717b4ce2 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c | |||
@@ -218,12 +218,13 @@ static unsigned int reject6_target(struct sk_buff **pskb, | |||
218 | } | 218 | } |
219 | 219 | ||
220 | static int check(const char *tablename, | 220 | static int check(const char *tablename, |
221 | const struct ip6t_entry *e, | 221 | const void *entry, |
222 | void *targinfo, | 222 | void *targinfo, |
223 | unsigned int targinfosize, | 223 | unsigned int targinfosize, |
224 | unsigned int hook_mask) | 224 | unsigned int hook_mask) |
225 | { | 225 | { |
226 | const struct ip6t_reject_info *rejinfo = targinfo; | 226 | const struct ip6t_reject_info *rejinfo = targinfo; |
227 | const struct ip6t_entry *e = entry; | ||
227 | 228 | ||
228 | if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) { | 229 | if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) { |
229 | DEBUGP("ip6t_REJECT: targinfosize %u != 0\n", targinfosize); | 230 | DEBUGP("ip6t_REJECT: targinfosize %u != 0\n", targinfosize); |
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c index f5c1a7ff4a1f..219a30365dff 100644 --- a/net/ipv6/netfilter/ip6t_ah.c +++ b/net/ipv6/netfilter/ip6t_ah.c | |||
@@ -98,7 +98,7 @@ match(const struct sk_buff *skb, | |||
98 | /* Called when user tries to insert an entry of this type. */ | 98 | /* Called when user tries to insert an entry of this type. */ |
99 | static int | 99 | static int |
100 | checkentry(const char *tablename, | 100 | checkentry(const char *tablename, |
101 | const struct ip6t_ip6 *ip, | 101 | const void *entry, |
102 | void *matchinfo, | 102 | void *matchinfo, |
103 | unsigned int matchinfosize, | 103 | unsigned int matchinfosize, |
104 | unsigned int hook_mask) | 104 | unsigned int hook_mask) |
diff --git a/net/ipv6/netfilter/ip6t_dst.c b/net/ipv6/netfilter/ip6t_dst.c index 48cf5f9efc95..80fe82669ce2 100644 --- a/net/ipv6/netfilter/ip6t_dst.c +++ b/net/ipv6/netfilter/ip6t_dst.c | |||
@@ -178,7 +178,7 @@ match(const struct sk_buff *skb, | |||
178 | /* Called when user tries to insert an entry of this type. */ | 178 | /* Called when user tries to insert an entry of this type. */ |
179 | static int | 179 | static int |
180 | checkentry(const char *tablename, | 180 | checkentry(const char *tablename, |
181 | const struct ip6t_ip6 *ip, | 181 | const void *info, |
182 | void *matchinfo, | 182 | void *matchinfo, |
183 | unsigned int matchinfosize, | 183 | unsigned int matchinfosize, |
184 | unsigned int hook_mask) | 184 | unsigned int hook_mask) |
diff --git a/net/ipv6/netfilter/ip6t_esp.c b/net/ipv6/netfilter/ip6t_esp.c index e1828f6d0a40..724285df8711 100644 --- a/net/ipv6/netfilter/ip6t_esp.c +++ b/net/ipv6/netfilter/ip6t_esp.c | |||
@@ -76,7 +76,7 @@ match(const struct sk_buff *skb, | |||
76 | /* Called when user tries to insert an entry of this type. */ | 76 | /* Called when user tries to insert an entry of this type. */ |
77 | static int | 77 | static int |
78 | checkentry(const char *tablename, | 78 | checkentry(const char *tablename, |
79 | const struct ip6t_ip6 *ip, | 79 | const void *ip, |
80 | void *matchinfo, | 80 | void *matchinfo, |
81 | unsigned int matchinfosize, | 81 | unsigned int matchinfosize, |
82 | unsigned int hook_mask) | 82 | unsigned int hook_mask) |
diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c index 616c2cbcd54d..ddf5f571909c 100644 --- a/net/ipv6/netfilter/ip6t_eui64.c +++ b/net/ipv6/netfilter/ip6t_eui64.c | |||
@@ -62,7 +62,7 @@ match(const struct sk_buff *skb, | |||
62 | 62 | ||
63 | static int | 63 | static int |
64 | ip6t_eui64_checkentry(const char *tablename, | 64 | ip6t_eui64_checkentry(const char *tablename, |
65 | const struct ip6t_ip6 *ip, | 65 | const void *ip, |
66 | void *matchinfo, | 66 | void *matchinfo, |
67 | unsigned int matchsize, | 67 | unsigned int matchsize, |
68 | unsigned int hook_mask) | 68 | unsigned int hook_mask) |
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c index d1549b268669..a9964b946ed5 100644 --- a/net/ipv6/netfilter/ip6t_frag.c +++ b/net/ipv6/netfilter/ip6t_frag.c | |||
@@ -115,7 +115,7 @@ match(const struct sk_buff *skb, | |||
115 | /* Called when user tries to insert an entry of this type. */ | 115 | /* Called when user tries to insert an entry of this type. */ |
116 | static int | 116 | static int |
117 | checkentry(const char *tablename, | 117 | checkentry(const char *tablename, |
118 | const struct ip6t_ip6 *ip, | 118 | const void *ip, |
119 | void *matchinfo, | 119 | void *matchinfo, |
120 | unsigned int matchinfosize, | 120 | unsigned int matchinfosize, |
121 | unsigned int hook_mask) | 121 | unsigned int hook_mask) |
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c index e3bc8e2700e7..ed8ded18bbd4 100644 --- a/net/ipv6/netfilter/ip6t_hbh.c +++ b/net/ipv6/netfilter/ip6t_hbh.c | |||
@@ -178,7 +178,7 @@ match(const struct sk_buff *skb, | |||
178 | /* Called when user tries to insert an entry of this type. */ | 178 | /* Called when user tries to insert an entry of this type. */ |
179 | static int | 179 | static int |
180 | checkentry(const char *tablename, | 180 | checkentry(const char *tablename, |
181 | const struct ip6t_ip6 *ip, | 181 | const void *entry, |
182 | void *matchinfo, | 182 | void *matchinfo, |
183 | unsigned int matchinfosize, | 183 | unsigned int matchinfosize, |
184 | unsigned int hook_mask) | 184 | unsigned int hook_mask) |
diff --git a/net/ipv6/netfilter/ip6t_hl.c b/net/ipv6/netfilter/ip6t_hl.c index 0beaff5471dd..c5d9079f2d9d 100644 --- a/net/ipv6/netfilter/ip6t_hl.c +++ b/net/ipv6/netfilter/ip6t_hl.c | |||
@@ -48,7 +48,7 @@ static int match(const struct sk_buff *skb, const struct net_device *in, | |||
48 | return 0; | 48 | return 0; |
49 | } | 49 | } |
50 | 50 | ||
51 | static int checkentry(const char *tablename, const struct ip6t_ip6 *ip, | 51 | static int checkentry(const char *tablename, const void *entry, |
52 | void *matchinfo, unsigned int matchsize, | 52 | void *matchinfo, unsigned int matchsize, |
53 | unsigned int hook_mask) | 53 | unsigned int hook_mask) |
54 | { | 54 | { |
diff --git a/net/ipv6/netfilter/ip6t_ipv6header.c b/net/ipv6/netfilter/ip6t_ipv6header.c index 32e67f05845b..fda1ceaf5a29 100644 --- a/net/ipv6/netfilter/ip6t_ipv6header.c +++ b/net/ipv6/netfilter/ip6t_ipv6header.c | |||
@@ -124,7 +124,7 @@ ipv6header_match(const struct sk_buff *skb, | |||
124 | 124 | ||
125 | static int | 125 | static int |
126 | ipv6header_checkentry(const char *tablename, | 126 | ipv6header_checkentry(const char *tablename, |
127 | const struct ip6t_ip6 *ip, | 127 | const void *ip, |
128 | void *matchinfo, | 128 | void *matchinfo, |
129 | unsigned int matchsize, | 129 | unsigned int matchsize, |
130 | unsigned int hook_mask) | 130 | unsigned int hook_mask) |
diff --git a/net/ipv6/netfilter/ip6t_length.c b/net/ipv6/netfilter/ip6t_length.c deleted file mode 100644 index e0537d3811d5..000000000000 --- a/net/ipv6/netfilter/ip6t_length.c +++ /dev/null | |||
@@ -1,66 +0,0 @@ | |||
1 | /* Length Match - IPv6 Port */ | ||
2 | |||
3 | /* (C) 1999-2001 James Morris <jmorros@intercode.com.au> | ||
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 | #include <linux/netfilter_ipv6/ip6t_length.h> | ||
14 | #include <linux/netfilter_ipv6/ip6_tables.h> | ||
15 | |||
16 | MODULE_LICENSE("GPL"); | ||
17 | MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); | ||
18 | MODULE_DESCRIPTION("IPv6 packet length match"); | ||
19 | |||
20 | static int | ||
21 | match(const struct sk_buff *skb, | ||
22 | const struct net_device *in, | ||
23 | const struct net_device *out, | ||
24 | const void *matchinfo, | ||
25 | int offset, | ||
26 | unsigned int protoff, | ||
27 | int *hotdrop) | ||
28 | { | ||
29 | const struct ip6t_length_info *info = matchinfo; | ||
30 | u_int16_t pktlen = ntohs(skb->nh.ipv6h->payload_len) + sizeof(struct ipv6hdr); | ||
31 | |||
32 | return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; | ||
33 | } | ||
34 | |||
35 | static int | ||
36 | checkentry(const char *tablename, | ||
37 | const struct ip6t_ip6 *ip, | ||
38 | void *matchinfo, | ||
39 | unsigned int matchsize, | ||
40 | unsigned int hook_mask) | ||
41 | { | ||
42 | if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_length_info))) | ||
43 | return 0; | ||
44 | |||
45 | return 1; | ||
46 | } | ||
47 | |||
48 | static struct ip6t_match length_match = { | ||
49 | .name = "length", | ||
50 | .match = &match, | ||
51 | .checkentry = &checkentry, | ||
52 | .me = THIS_MODULE, | ||
53 | }; | ||
54 | |||
55 | static int __init init(void) | ||
56 | { | ||
57 | return ip6t_register_match(&length_match); | ||
58 | } | ||
59 | |||
60 | static void __exit fini(void) | ||
61 | { | ||
62 | ip6t_unregister_match(&length_match); | ||
63 | } | ||
64 | |||
65 | module_init(init); | ||
66 | module_exit(fini); | ||
diff --git a/net/ipv6/netfilter/ip6t_limit.c b/net/ipv6/netfilter/ip6t_limit.c deleted file mode 100644 index fb782f610be2..000000000000 --- a/net/ipv6/netfilter/ip6t_limit.c +++ /dev/null | |||
@@ -1,147 +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_ipv6/ip6_tables.h> | ||
22 | #include <linux/netfilter_ipv6/ip6t_limit.h> | ||
23 | |||
24 | MODULE_LICENSE("GPL"); | ||
25 | MODULE_AUTHOR("Herve Eychenne <rv@wallfire.org>"); | ||
26 | MODULE_DESCRIPTION("rate limiting within ip6tables"); | ||
27 | |||
28 | /* The algorithm used is the Simple Token Bucket Filter (TBF) | ||
29 | * see net/sched/sch_tbf.c in the linux source tree | ||
30 | */ | ||
31 | |||
32 | static DEFINE_SPINLOCK(limit_lock); | ||
33 | |||
34 | /* Rusty: This is my (non-mathematically-inclined) understanding of | ||
35 | this algorithm. The `average rate' in jiffies becomes your initial | ||
36 | amount of credit `credit' and the most credit you can ever have | ||
37 | `credit_cap'. The `peak rate' becomes the cost of passing the | ||
38 | test, `cost'. | ||
39 | |||
40 | `prev' tracks the last packet hit: you gain one credit per jiffy. | ||
41 | If you get credit balance more than this, the extra credit is | ||
42 | discarded. Every time the match passes, you lose `cost' credits; | ||
43 | if you don't have that many, the test fails. | ||
44 | |||
45 | See Alexey's formal explanation in net/sched/sch_tbf.c. | ||
46 | |||
47 | To avoid underflow, we multiply by 128 (ie. you get 128 credits per | ||
48 | jiffy). Hence a cost of 2^32-1, means one pass per 32768 seconds | ||
49 | at 1024HZ (or one every 9 hours). A cost of 1 means 12800 passes | ||
50 | per second at 100HZ. */ | ||
51 | |||
52 | #define CREDITS_PER_JIFFY 128 | ||
53 | |||
54 | static int | ||
55 | ip6t_limit_match(const struct sk_buff *skb, | ||
56 | const struct net_device *in, | ||
57 | const struct net_device *out, | ||
58 | const void *matchinfo, | ||
59 | int offset, | ||
60 | unsigned int protoff, | ||
61 | int *hotdrop) | ||
62 | { | ||
63 | struct ip6t_rateinfo *r = ((struct ip6t_rateinfo *)matchinfo)->master; | ||
64 | unsigned long now = jiffies; | ||
65 | |||
66 | spin_lock_bh(&limit_lock); | ||
67 | r->credit += (now - xchg(&r->prev, now)) * CREDITS_PER_JIFFY; | ||
68 | if (r->credit > r->credit_cap) | ||
69 | r->credit = r->credit_cap; | ||
70 | |||
71 | if (r->credit >= r->cost) { | ||
72 | /* We're not limited. */ | ||
73 | r->credit -= r->cost; | ||
74 | spin_unlock_bh(&limit_lock); | ||
75 | return 1; | ||
76 | } | ||
77 | |||
78 | spin_unlock_bh(&limit_lock); | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | /* Precision saver. */ | ||
83 | static u_int32_t | ||
84 | user2credits(u_int32_t user) | ||
85 | { | ||
86 | /* If multiplying would overflow... */ | ||
87 | if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) | ||
88 | /* Divide first. */ | ||
89 | return (user / IP6T_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY; | ||
90 | |||
91 | return (user * HZ * CREDITS_PER_JIFFY) / IP6T_LIMIT_SCALE; | ||
92 | } | ||
93 | |||
94 | static int | ||
95 | ip6t_limit_checkentry(const char *tablename, | ||
96 | const struct ip6t_ip6 *ip, | ||
97 | void *matchinfo, | ||
98 | unsigned int matchsize, | ||
99 | unsigned int hook_mask) | ||
100 | { | ||
101 | struct ip6t_rateinfo *r = matchinfo; | ||
102 | |||
103 | if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_rateinfo))) | ||
104 | return 0; | ||
105 | |||
106 | /* Check for overflow. */ | ||
107 | if (r->burst == 0 | ||
108 | || user2credits(r->avg * r->burst) < user2credits(r->avg)) { | ||
109 | printk("Call rusty: overflow in ip6t_limit: %u/%u\n", | ||
110 | r->avg, r->burst); | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | /* User avg in seconds * IP6T_LIMIT_SCALE: convert to jiffies * | ||
115 | 128. */ | ||
116 | r->prev = jiffies; | ||
117 | r->credit = user2credits(r->avg * r->burst); /* Credits full. */ | ||
118 | r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */ | ||
119 | r->cost = user2credits(r->avg); | ||
120 | |||
121 | /* For SMP, we only want to use one set of counters. */ | ||
122 | r->master = r; | ||
123 | |||
124 | return 1; | ||
125 | } | ||
126 | |||
127 | static struct ip6t_match ip6t_limit_reg = { | ||
128 | .name = "limit", | ||
129 | .match = ip6t_limit_match, | ||
130 | .checkentry = ip6t_limit_checkentry, | ||
131 | .me = THIS_MODULE, | ||
132 | }; | ||
133 | |||
134 | static int __init init(void) | ||
135 | { | ||
136 | if (ip6t_register_match(&ip6t_limit_reg)) | ||
137 | return -EINVAL; | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static void __exit fini(void) | ||
142 | { | ||
143 | ip6t_unregister_match(&ip6t_limit_reg); | ||
144 | } | ||
145 | |||
146 | module_init(init); | ||
147 | module_exit(fini); | ||
diff --git a/net/ipv6/netfilter/ip6t_mac.c b/net/ipv6/netfilter/ip6t_mac.c deleted file mode 100644 index c848152315bc..000000000000 --- a/net/ipv6/netfilter/ip6t_mac.c +++ /dev/null | |||
@@ -1,81 +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_ipv6/ip6t_mac.h> | ||
17 | #include <linux/netfilter_ipv6/ip6_tables.h> | ||
18 | |||
19 | MODULE_LICENSE("GPL"); | ||
20 | MODULE_DESCRIPTION("MAC address matching module for IPv6"); | ||
21 | MODULE_AUTHOR("Netfilter Core Teaam <coreteam@netfilter.org>"); | ||
22 | |||
23 | static int | ||
24 | match(const struct sk_buff *skb, | ||
25 | const struct net_device *in, | ||
26 | const struct net_device *out, | ||
27 | const void *matchinfo, | ||
28 | int offset, | ||
29 | unsigned int protoff, | ||
30 | int *hotdrop) | ||
31 | { | ||
32 | const struct ip6t_mac_info *info = matchinfo; | ||
33 | |||
34 | /* Is mac pointer valid? */ | ||
35 | return (skb->mac.raw >= skb->head | ||
36 | && (skb->mac.raw + ETH_HLEN) <= skb->data | ||
37 | /* If so, compare... */ | ||
38 | && ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr)) | ||
39 | ^ info->invert)); | ||
40 | } | ||
41 | |||
42 | static int | ||
43 | ip6t_mac_checkentry(const char *tablename, | ||
44 | const struct ip6t_ip6 *ip, | ||
45 | void *matchinfo, | ||
46 | unsigned int matchsize, | ||
47 | unsigned int hook_mask) | ||
48 | { | ||
49 | if (hook_mask | ||
50 | & ~((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN) | ||
51 | | (1 << NF_IP6_FORWARD))) { | ||
52 | printk("ip6t_mac: only valid for PRE_ROUTING, LOCAL_IN or" | ||
53 | " FORWARD\n"); | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_mac_info))) | ||
58 | return 0; | ||
59 | |||
60 | return 1; | ||
61 | } | ||
62 | |||
63 | static struct ip6t_match mac_match = { | ||
64 | .name = "mac", | ||
65 | .match = &match, | ||
66 | .checkentry = &ip6t_mac_checkentry, | ||
67 | .me = THIS_MODULE, | ||
68 | }; | ||
69 | |||
70 | static int __init init(void) | ||
71 | { | ||
72 | return ip6t_register_match(&mac_match); | ||
73 | } | ||
74 | |||
75 | static void __exit fini(void) | ||
76 | { | ||
77 | ip6t_unregister_match(&mac_match); | ||
78 | } | ||
79 | |||
80 | module_init(init); | ||
81 | module_exit(fini); | ||
diff --git a/net/ipv6/netfilter/ip6t_mark.c b/net/ipv6/netfilter/ip6t_mark.c deleted file mode 100644 index affc3de364fc..000000000000 --- a/net/ipv6/netfilter/ip6t_mark.c +++ /dev/null | |||
@@ -1,66 +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 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/skbuff.h> | ||
13 | |||
14 | #include <linux/netfilter_ipv6/ip6t_mark.h> | ||
15 | #include <linux/netfilter_ipv6/ip6_tables.h> | ||
16 | |||
17 | MODULE_LICENSE("GPL"); | ||
18 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); | ||
19 | MODULE_DESCRIPTION("ip6tables mark match"); | ||
20 | |||
21 | static int | ||
22 | match(const struct sk_buff *skb, | ||
23 | const struct net_device *in, | ||
24 | const struct net_device *out, | ||
25 | const void *matchinfo, | ||
26 | int offset, | ||
27 | unsigned int protoff, | ||
28 | int *hotdrop) | ||
29 | { | ||
30 | const struct ip6t_mark_info *info = matchinfo; | ||
31 | |||
32 | return ((skb->nfmark & info->mask) == info->mark) ^ info->invert; | ||
33 | } | ||
34 | |||
35 | static int | ||
36 | checkentry(const char *tablename, | ||
37 | const struct ip6t_ip6 *ip, | ||
38 | void *matchinfo, | ||
39 | unsigned int matchsize, | ||
40 | unsigned int hook_mask) | ||
41 | { | ||
42 | if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_mark_info))) | ||
43 | return 0; | ||
44 | |||
45 | return 1; | ||
46 | } | ||
47 | |||
48 | static struct ip6t_match mark_match = { | ||
49 | .name = "mark", | ||
50 | .match = &match, | ||
51 | .checkentry = &checkentry, | ||
52 | .me = THIS_MODULE, | ||
53 | }; | ||
54 | |||
55 | static int __init init(void) | ||
56 | { | ||
57 | return ip6t_register_match(&mark_match); | ||
58 | } | ||
59 | |||
60 | static void __exit fini(void) | ||
61 | { | ||
62 | ip6t_unregister_match(&mark_match); | ||
63 | } | ||
64 | |||
65 | module_init(init); | ||
66 | module_exit(fini); | ||
diff --git a/net/ipv6/netfilter/ip6t_multiport.c b/net/ipv6/netfilter/ip6t_multiport.c index 6e3246153fa3..49f7829dfbc2 100644 --- a/net/ipv6/netfilter/ip6t_multiport.c +++ b/net/ipv6/netfilter/ip6t_multiport.c | |||
@@ -84,11 +84,12 @@ match(const struct sk_buff *skb, | |||
84 | /* Called when user tries to insert an entry of this type. */ | 84 | /* Called when user tries to insert an entry of this type. */ |
85 | static int | 85 | static int |
86 | checkentry(const char *tablename, | 86 | checkentry(const char *tablename, |
87 | const struct ip6t_ip6 *ip, | 87 | const void *info, |
88 | void *matchinfo, | 88 | void *matchinfo, |
89 | unsigned int matchsize, | 89 | unsigned int matchsize, |
90 | unsigned int hook_mask) | 90 | unsigned int hook_mask) |
91 | { | 91 | { |
92 | const struct ip6t_ip6 *ip = info; | ||
92 | const struct ip6t_multiport *multiinfo = matchinfo; | 93 | const struct ip6t_multiport *multiinfo = matchinfo; |
93 | 94 | ||
94 | if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_multiport))) | 95 | if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_multiport))) |
diff --git a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c index 4de4cdad4b7d..5409b375b512 100644 --- a/net/ipv6/netfilter/ip6t_owner.c +++ b/net/ipv6/netfilter/ip6t_owner.c | |||
@@ -53,7 +53,7 @@ match(const struct sk_buff *skb, | |||
53 | 53 | ||
54 | static int | 54 | static int |
55 | checkentry(const char *tablename, | 55 | checkentry(const char *tablename, |
56 | const struct ip6t_ip6 *ip, | 56 | const void *ip, |
57 | void *matchinfo, | 57 | void *matchinfo, |
58 | unsigned int matchsize, | 58 | unsigned int matchsize, |
59 | unsigned int hook_mask) | 59 | unsigned int hook_mask) |
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c index c1e770e45543..8465b4375855 100644 --- a/net/ipv6/netfilter/ip6t_rt.c +++ b/net/ipv6/netfilter/ip6t_rt.c | |||
@@ -183,7 +183,7 @@ match(const struct sk_buff *skb, | |||
183 | /* Called when user tries to insert an entry of this type. */ | 183 | /* Called when user tries to insert an entry of this type. */ |
184 | static int | 184 | static int |
185 | checkentry(const char *tablename, | 185 | checkentry(const char *tablename, |
186 | const struct ip6t_ip6 *ip, | 186 | const void *entry, |
187 | void *matchinfo, | 187 | void *matchinfo, |
188 | unsigned int matchinfosize, | 188 | unsigned int matchinfosize, |
189 | unsigned int hook_mask) | 189 | unsigned int hook_mask) |
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c index 4c0028671c20..ce4a968e1f70 100644 --- a/net/ipv6/netfilter/ip6table_filter.c +++ b/net/ipv6/netfilter/ip6table_filter.c | |||
@@ -97,6 +97,7 @@ static struct ip6t_table packet_filter = { | |||
97 | .valid_hooks = FILTER_VALID_HOOKS, | 97 | .valid_hooks = FILTER_VALID_HOOKS, |
98 | .lock = RW_LOCK_UNLOCKED, | 98 | .lock = RW_LOCK_UNLOCKED, |
99 | .me = THIS_MODULE, | 99 | .me = THIS_MODULE, |
100 | .af = AF_INET6, | ||
100 | }; | 101 | }; |
101 | 102 | ||
102 | /* The work comes in here from netfilter.c. */ | 103 | /* The work comes in here from netfilter.c. */ |
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index 85c1e6eada19..30a4627e000d 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c | |||
@@ -127,6 +127,7 @@ static struct ip6t_table packet_mangler = { | |||
127 | .valid_hooks = MANGLE_VALID_HOOKS, | 127 | .valid_hooks = MANGLE_VALID_HOOKS, |
128 | .lock = RW_LOCK_UNLOCKED, | 128 | .lock = RW_LOCK_UNLOCKED, |
129 | .me = THIS_MODULE, | 129 | .me = THIS_MODULE, |
130 | .af = AF_INET6, | ||
130 | }; | 131 | }; |
131 | 132 | ||
132 | /* The work comes in here from netfilter.c. */ | 133 | /* The work comes in here from netfilter.c. */ |
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c index c2982efd14af..db28ba3855e2 100644 --- a/net/ipv6/netfilter/ip6table_raw.c +++ b/net/ipv6/netfilter/ip6table_raw.c | |||
@@ -106,11 +106,12 @@ static struct | |||
106 | } | 106 | } |
107 | }; | 107 | }; |
108 | 108 | ||
109 | static struct ip6t_table packet_raw = { | 109 | static struct xt_table packet_raw = { |
110 | .name = "raw", | 110 | .name = "raw", |
111 | .valid_hooks = RAW_VALID_HOOKS, | 111 | .valid_hooks = RAW_VALID_HOOKS, |
112 | .lock = RW_LOCK_UNLOCKED, | 112 | .lock = RW_LOCK_UNLOCKED, |
113 | .me = THIS_MODULE | 113 | .me = THIS_MODULE, |
114 | .af = AF_INET6, | ||
114 | }; | 115 | }; |
115 | 116 | ||
116 | /* The work comes in here from netfilter.c. */ | 117 | /* The work comes in here from netfilter.c. */ |
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index e57d6fc9957a..92ad53d8f8c3 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
@@ -584,7 +584,7 @@ MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>"); | |||
584 | 584 | ||
585 | static int __init init(void) | 585 | static int __init init(void) |
586 | { | 586 | { |
587 | need_nf_conntrack(); | 587 | need_conntrack(); |
588 | return init_or_cleanup(1); | 588 | return init_or_cleanup(1); |
589 | } | 589 | } |
590 | 590 | ||
@@ -595,9 +595,3 @@ static void __exit fini(void) | |||
595 | 595 | ||
596 | module_init(init); | 596 | module_init(init); |
597 | module_exit(fini); | 597 | module_exit(fini); |
598 | |||
599 | void need_ip6_conntrack(void) | ||
600 | { | ||
601 | } | ||
602 | |||
603 | EXPORT_SYMBOL(need_ip6_conntrack); | ||
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index f3e5ffbd592f..84ef9a13108d 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
@@ -70,8 +70,8 @@ struct nf_ct_frag6_skb_cb | |||
70 | 70 | ||
71 | struct nf_ct_frag6_queue | 71 | struct nf_ct_frag6_queue |
72 | { | 72 | { |
73 | struct nf_ct_frag6_queue *next; | 73 | struct hlist_node list; |
74 | struct list_head lru_list; /* lru list member */ | 74 | struct list_head lru_list; /* lru list member */ |
75 | 75 | ||
76 | __u32 id; /* fragment id */ | 76 | __u32 id; /* fragment id */ |
77 | struct in6_addr saddr; | 77 | struct in6_addr saddr; |
@@ -90,14 +90,13 @@ struct nf_ct_frag6_queue | |||
90 | #define FIRST_IN 2 | 90 | #define FIRST_IN 2 |
91 | #define LAST_IN 1 | 91 | #define LAST_IN 1 |
92 | __u16 nhoffset; | 92 | __u16 nhoffset; |
93 | struct nf_ct_frag6_queue **pprev; | ||
94 | }; | 93 | }; |
95 | 94 | ||
96 | /* Hash table. */ | 95 | /* Hash table. */ |
97 | 96 | ||
98 | #define FRAG6Q_HASHSZ 64 | 97 | #define FRAG6Q_HASHSZ 64 |
99 | 98 | ||
100 | static struct nf_ct_frag6_queue *nf_ct_frag6_hash[FRAG6Q_HASHSZ]; | 99 | static struct hlist_head nf_ct_frag6_hash[FRAG6Q_HASHSZ]; |
101 | static DEFINE_RWLOCK(nf_ct_frag6_lock); | 100 | static DEFINE_RWLOCK(nf_ct_frag6_lock); |
102 | static u32 nf_ct_frag6_hash_rnd; | 101 | static u32 nf_ct_frag6_hash_rnd; |
103 | static LIST_HEAD(nf_ct_frag6_lru_list); | 102 | static LIST_HEAD(nf_ct_frag6_lru_list); |
@@ -105,9 +104,7 @@ int nf_ct_frag6_nqueues = 0; | |||
105 | 104 | ||
106 | static __inline__ void __fq_unlink(struct nf_ct_frag6_queue *fq) | 105 | static __inline__ void __fq_unlink(struct nf_ct_frag6_queue *fq) |
107 | { | 106 | { |
108 | if (fq->next) | 107 | hlist_del(&fq->list); |
109 | fq->next->pprev = fq->pprev; | ||
110 | *fq->pprev = fq->next; | ||
111 | list_del(&fq->lru_list); | 108 | list_del(&fq->lru_list); |
112 | nf_ct_frag6_nqueues--; | 109 | nf_ct_frag6_nqueues--; |
113 | } | 110 | } |
@@ -158,28 +155,18 @@ static void nf_ct_frag6_secret_rebuild(unsigned long dummy) | |||
158 | get_random_bytes(&nf_ct_frag6_hash_rnd, sizeof(u32)); | 155 | get_random_bytes(&nf_ct_frag6_hash_rnd, sizeof(u32)); |
159 | for (i = 0; i < FRAG6Q_HASHSZ; i++) { | 156 | for (i = 0; i < FRAG6Q_HASHSZ; i++) { |
160 | struct nf_ct_frag6_queue *q; | 157 | struct nf_ct_frag6_queue *q; |
158 | struct hlist_node *p, *n; | ||
161 | 159 | ||
162 | q = nf_ct_frag6_hash[i]; | 160 | hlist_for_each_entry_safe(q, p, n, &nf_ct_frag6_hash[i], list) { |
163 | while (q) { | ||
164 | struct nf_ct_frag6_queue *next = q->next; | ||
165 | unsigned int hval = ip6qhashfn(q->id, | 161 | unsigned int hval = ip6qhashfn(q->id, |
166 | &q->saddr, | 162 | &q->saddr, |
167 | &q->daddr); | 163 | &q->daddr); |
168 | |||
169 | if (hval != i) { | 164 | if (hval != i) { |
170 | /* Unlink. */ | 165 | hlist_del(&q->list); |
171 | if (q->next) | ||
172 | q->next->pprev = q->pprev; | ||
173 | *q->pprev = q->next; | ||
174 | |||
175 | /* Relink to new hash chain. */ | 166 | /* Relink to new hash chain. */ |
176 | if ((q->next = nf_ct_frag6_hash[hval]) != NULL) | 167 | hlist_add_head(&q->list, |
177 | q->next->pprev = &q->next; | 168 | &nf_ct_frag6_hash[hval]); |
178 | nf_ct_frag6_hash[hval] = q; | ||
179 | q->pprev = &nf_ct_frag6_hash[hval]; | ||
180 | } | 169 | } |
181 | |||
182 | q = next; | ||
183 | } | 170 | } |
184 | } | 171 | } |
185 | write_unlock(&nf_ct_frag6_lock); | 172 | write_unlock(&nf_ct_frag6_lock); |
@@ -314,15 +301,17 @@ out: | |||
314 | 301 | ||
315 | /* Creation primitives. */ | 302 | /* Creation primitives. */ |
316 | 303 | ||
317 | |||
318 | static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash, | 304 | static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash, |
319 | struct nf_ct_frag6_queue *fq_in) | 305 | struct nf_ct_frag6_queue *fq_in) |
320 | { | 306 | { |
321 | struct nf_ct_frag6_queue *fq; | 307 | struct nf_ct_frag6_queue *fq; |
308 | #ifdef CONFIG_SMP | ||
309 | struct hlist_node *n; | ||
310 | #endif | ||
322 | 311 | ||
323 | write_lock(&nf_ct_frag6_lock); | 312 | write_lock(&nf_ct_frag6_lock); |
324 | #ifdef CONFIG_SMP | 313 | #ifdef CONFIG_SMP |
325 | for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) { | 314 | hlist_for_each_entry(fq, n, &nf_ct_frag6_hash[hash], list) { |
326 | if (fq->id == fq_in->id && | 315 | if (fq->id == fq_in->id && |
327 | !ipv6_addr_cmp(&fq_in->saddr, &fq->saddr) && | 316 | !ipv6_addr_cmp(&fq_in->saddr, &fq->saddr) && |
328 | !ipv6_addr_cmp(&fq_in->daddr, &fq->daddr)) { | 317 | !ipv6_addr_cmp(&fq_in->daddr, &fq->daddr)) { |
@@ -340,10 +329,7 @@ static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash, | |||
340 | atomic_inc(&fq->refcnt); | 329 | atomic_inc(&fq->refcnt); |
341 | 330 | ||
342 | atomic_inc(&fq->refcnt); | 331 | atomic_inc(&fq->refcnt); |
343 | if ((fq->next = nf_ct_frag6_hash[hash]) != NULL) | 332 | hlist_add_head(&fq->list, &nf_ct_frag6_hash[hash]); |
344 | fq->next->pprev = &fq->next; | ||
345 | nf_ct_frag6_hash[hash] = fq; | ||
346 | fq->pprev = &nf_ct_frag6_hash[hash]; | ||
347 | INIT_LIST_HEAD(&fq->lru_list); | 333 | INIT_LIST_HEAD(&fq->lru_list); |
348 | list_add_tail(&fq->lru_list, &nf_ct_frag6_lru_list); | 334 | list_add_tail(&fq->lru_list, &nf_ct_frag6_lru_list); |
349 | nf_ct_frag6_nqueues++; | 335 | nf_ct_frag6_nqueues++; |
@@ -384,10 +370,11 @@ static __inline__ struct nf_ct_frag6_queue * | |||
384 | fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst) | 370 | fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst) |
385 | { | 371 | { |
386 | struct nf_ct_frag6_queue *fq; | 372 | struct nf_ct_frag6_queue *fq; |
373 | struct hlist_node *n; | ||
387 | unsigned int hash = ip6qhashfn(id, src, dst); | 374 | unsigned int hash = ip6qhashfn(id, src, dst); |
388 | 375 | ||
389 | read_lock(&nf_ct_frag6_lock); | 376 | read_lock(&nf_ct_frag6_lock); |
390 | for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) { | 377 | hlist_for_each_entry(fq, n, &nf_ct_frag6_hash[hash], list) { |
391 | if (fq->id == id && | 378 | if (fq->id == id && |
392 | !ipv6_addr_cmp(src, &fq->saddr) && | 379 | !ipv6_addr_cmp(src, &fq->saddr) && |
393 | !ipv6_addr_cmp(dst, &fq->daddr)) { | 380 | !ipv6_addr_cmp(dst, &fq->daddr)) { |
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 7d55f9cbd853..99c0a0fa4a97 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig | |||
@@ -103,3 +103,261 @@ config NF_CT_NETLINK | |||
103 | This option enables support for a netlink-based userspace interface | 103 | This option enables support for a netlink-based userspace interface |
104 | 104 | ||
105 | endmenu | 105 | endmenu |
106 | |||
107 | config NETFILTER_XTABLES | ||
108 | tristate "Netfilter Xtables support (required for ip_tables)" | ||
109 | help | ||
110 | This is required if you intend to use any of ip_tables, | ||
111 | ip6_tables or arp_tables. | ||
112 | |||
113 | # alphabetically ordered list of targets | ||
114 | |||
115 | config NETFILTER_XT_TARGET_CLASSIFY | ||
116 | tristate '"CLASSIFY" target support' | ||
117 | depends on NETFILTER_XTABLES | ||
118 | help | ||
119 | This option adds a `CLASSIFY' target, which enables the user to set | ||
120 | the priority of a packet. Some qdiscs can use this value for | ||
121 | classification, among these are: | ||
122 | |||
123 | atm, cbq, dsmark, pfifo_fast, htb, prio | ||
124 | |||
125 | To compile it as a module, choose M here. If unsure, say N. | ||
126 | |||
127 | config NETFILTER_XT_TARGET_CONNMARK | ||
128 | tristate '"CONNMARK" target support' | ||
129 | depends on NETFILTER_XTABLES | ||
130 | depends on IP_NF_MANGLE || IP6_NF_MANGLE | ||
131 | depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4) | ||
132 | help | ||
133 | This option adds a `CONNMARK' target, which allows one to manipulate | ||
134 | the connection mark value. Similar to the MARK target, but | ||
135 | affects the connection mark value rather than the packet mark value. | ||
136 | |||
137 | If you want to compile it as a module, say M here and read | ||
138 | <file:Documentation/modules.txt>. The module will be called | ||
139 | ipt_CONNMARK.o. If unsure, say `N'. | ||
140 | |||
141 | config NETFILTER_XT_TARGET_MARK | ||
142 | tristate '"MARK" target support' | ||
143 | depends on NETFILTER_XTABLES | ||
144 | help | ||
145 | This option adds a `MARK' target, which allows you to create rules | ||
146 | in the `mangle' table which alter the netfilter mark (nfmark) field | ||
147 | associated with the packet prior to routing. This can change | ||
148 | the routing method (see `Use netfilter MARK value as routing | ||
149 | key') and can also be used by other subsystems to change their | ||
150 | behavior. | ||
151 | |||
152 | To compile it as a module, choose M here. If unsure, say N. | ||
153 | |||
154 | config NETFILTER_XT_TARGET_NFQUEUE | ||
155 | tristate '"NFQUEUE" target Support' | ||
156 | depends on NETFILTER_XTABLES | ||
157 | help | ||
158 | This Target replaced the old obsolete QUEUE target. | ||
159 | |||
160 | As opposed to QUEUE, it supports 65535 different queues, | ||
161 | not just one. | ||
162 | |||
163 | To compile it as a module, choose M here. If unsure, say N. | ||
164 | |||
165 | config NETFILTER_XT_TARGET_NOTRACK | ||
166 | tristate '"NOTRACK" target support' | ||
167 | depends on NETFILTER_XTABLES | ||
168 | depends on IP_NF_RAW || IP6_NF_RAW | ||
169 | depends on IP_NF_CONNTRACK || NF_CONNTRACK | ||
170 | help | ||
171 | The NOTRACK target allows a select rule to specify | ||
172 | which packets *not* to enter the conntrack/NAT | ||
173 | subsystem with all the consequences (no ICMP error tracking, | ||
174 | no protocol helpers for the selected packets). | ||
175 | |||
176 | If you want to compile it as a module, say M here and read | ||
177 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
178 | |||
179 | config NETFILTER_XT_MATCH_COMMENT | ||
180 | tristate '"comment" match support' | ||
181 | depends on NETFILTER_XTABLES | ||
182 | help | ||
183 | This option adds a `comment' dummy-match, which allows you to put | ||
184 | comments in your iptables ruleset. | ||
185 | |||
186 | If you want to compile it as a module, say M here and read | ||
187 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
188 | |||
189 | config NETFILTER_XT_MATCH_CONNBYTES | ||
190 | tristate '"connbytes" per-connection counter match support' | ||
191 | depends on NETFILTER_XTABLES | ||
192 | depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || NF_CT_ACCT | ||
193 | help | ||
194 | This option adds a `connbytes' match, which allows you to match the | ||
195 | number of bytes and/or packets for each direction within a connection. | ||
196 | |||
197 | If you want to compile it as a module, say M here and read | ||
198 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
199 | |||
200 | config NETFILTER_XT_MATCH_CONNMARK | ||
201 | tristate '"connmark" connection mark match support' | ||
202 | depends on NETFILTER_XTABLES | ||
203 | depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || NF_CONNTRACK_MARK | ||
204 | help | ||
205 | This option adds a `connmark' match, which allows you to match the | ||
206 | connection mark value previously set for the session by `CONNMARK'. | ||
207 | |||
208 | If you want to compile it as a module, say M here and read | ||
209 | <file:Documentation/modules.txt>. The module will be called | ||
210 | ipt_connmark.o. If unsure, say `N'. | ||
211 | |||
212 | config NETFILTER_XT_MATCH_CONNTRACK | ||
213 | tristate '"conntrack" connection tracking match support' | ||
214 | depends on NETFILTER_XTABLES | ||
215 | depends on IP_NF_CONNTRACK || NF_CONNTRACK | ||
216 | help | ||
217 | This is a general conntrack match module, a superset of the state match. | ||
218 | |||
219 | It allows matching on additional conntrack information, which is | ||
220 | useful in complex configurations, such as NAT gateways with multiple | ||
221 | internet links or tunnels. | ||
222 | |||
223 | To compile it as a module, choose M here. If unsure, say N. | ||
224 | |||
225 | config NETFILTER_XT_MATCH_DCCP | ||
226 | tristate '"DCCP" protocol match support' | ||
227 | depends on NETFILTER_XTABLES | ||
228 | help | ||
229 | With this option enabled, you will be able to use the iptables | ||
230 | `dccp' match in order to match on DCCP source/destination ports | ||
231 | and DCCP flags. | ||
232 | |||
233 | If you want to compile it as a module, say M here and read | ||
234 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
235 | |||
236 | config NETFILTER_XT_MATCH_HELPER | ||
237 | tristate '"helper" match support' | ||
238 | depends on NETFILTER_XTABLES | ||
239 | depends on IP_NF_CONNTRACK || NF_CONNTRACK | ||
240 | help | ||
241 | Helper matching allows you to match packets in dynamic connections | ||
242 | tracked by a conntrack-helper, ie. ip_conntrack_ftp | ||
243 | |||
244 | To compile it as a module, choose M here. If unsure, say Y. | ||
245 | |||
246 | config NETFILTER_XT_MATCH_LENGTH | ||
247 | tristate '"length" match support' | ||
248 | depends on NETFILTER_XTABLES | ||
249 | help | ||
250 | This option allows you to match the length of a packet against a | ||
251 | specific value or range of values. | ||
252 | |||
253 | To compile it as a module, choose M here. If unsure, say N. | ||
254 | |||
255 | config NETFILTER_XT_MATCH_LIMIT | ||
256 | tristate '"limit" match support' | ||
257 | depends on NETFILTER_XTABLES | ||
258 | help | ||
259 | limit matching allows you to control the rate at which a rule can be | ||
260 | matched: mainly useful in combination with the LOG target ("LOG | ||
261 | target support", below) and to avoid some Denial of Service attacks. | ||
262 | |||
263 | To compile it as a module, choose M here. If unsure, say N. | ||
264 | |||
265 | config NETFILTER_XT_MATCH_MAC | ||
266 | tristate '"mac" address match support' | ||
267 | depends on NETFILTER_XTABLES | ||
268 | help | ||
269 | MAC matching allows you to match packets based on the source | ||
270 | Ethernet address of the packet. | ||
271 | |||
272 | To compile it as a module, choose M here. If unsure, say N. | ||
273 | |||
274 | config NETFILTER_XT_MATCH_MARK | ||
275 | tristate '"mark" match support' | ||
276 | depends on NETFILTER_XTABLES | ||
277 | help | ||
278 | Netfilter mark matching allows you to match packets based on the | ||
279 | `nfmark' value in the packet. This can be set by the MARK target | ||
280 | (see below). | ||
281 | |||
282 | To compile it as a module, choose M here. If unsure, say N. | ||
283 | |||
284 | config NETFILTER_XT_MATCH_PHYSDEV | ||
285 | tristate '"physdev" match support' | ||
286 | depends on NETFILTER_XTABLES && BRIDGE_NETFILTER | ||
287 | help | ||
288 | Physdev packet matching matches against the physical bridge ports | ||
289 | the IP packet arrived on or will leave by. | ||
290 | |||
291 | To compile it as a module, choose M here. If unsure, say N. | ||
292 | |||
293 | config NETFILTER_XT_MATCH_PKTTYPE | ||
294 | tristate '"pkttype" packet type match support' | ||
295 | depends on NETFILTER_XTABLES | ||
296 | help | ||
297 | Packet type matching allows you to match a packet by | ||
298 | its "class", eg. BROADCAST, MULTICAST, ... | ||
299 | |||
300 | Typical usage: | ||
301 | iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG | ||
302 | |||
303 | To compile it as a module, choose M here. If unsure, say N. | ||
304 | |||
305 | config NETFILTER_XT_MATCH_REALM | ||
306 | tristate '"realm" match support' | ||
307 | depends on NETFILTER_XTABLES | ||
308 | select NET_CLS_ROUTE | ||
309 | help | ||
310 | This option adds a `realm' match, which allows you to use the realm | ||
311 | key from the routing subsystem inside iptables. | ||
312 | |||
313 | This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option | ||
314 | in tc world. | ||
315 | |||
316 | If you want to compile it as a module, say M here and read | ||
317 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
318 | |||
319 | config NETFILTER_XT_MATCH_SCTP | ||
320 | tristate '"sctp" protocol match support' | ||
321 | depends on NETFILTER_XTABLES | ||
322 | help | ||
323 | With this option enabled, you will be able to use the | ||
324 | `sctp' match in order to match on SCTP source/destination ports | ||
325 | and SCTP chunk types. | ||
326 | |||
327 | If you want to compile it as a module, say M here and read | ||
328 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
329 | |||
330 | config NETFILTER_XT_MATCH_STATE | ||
331 | tristate '"state" match support' | ||
332 | depends on NETFILTER_XTABLES | ||
333 | depends on IP_NF_CONNTRACK || NF_CONNTRACK | ||
334 | help | ||
335 | Connection state matching allows you to match packets based on their | ||
336 | relationship to a tracked connection (ie. previous packets). This | ||
337 | is a powerful tool for packet classification. | ||
338 | |||
339 | To compile it as a module, choose M here. If unsure, say N. | ||
340 | |||
341 | config NETFILTER_XT_MATCH_STRING | ||
342 | tristate '"string" match support' | ||
343 | depends on NETFILTER_XTABLES | ||
344 | select TEXTSEARCH | ||
345 | select TEXTSEARCH_KMP | ||
346 | select TEXTSEARCH_BM | ||
347 | select TEXTSEARCH_FSM | ||
348 | help | ||
349 | This option adds a `string' match, which allows you to look for | ||
350 | pattern matchings in packets. | ||
351 | |||
352 | To compile it as a module, choose M here. If unsure, say N. | ||
353 | |||
354 | config NETFILTER_XT_MATCH_TCPMSS | ||
355 | tristate '"tcpmss" match support' | ||
356 | depends on NETFILTER_XTABLES | ||
357 | help | ||
358 | This option adds a `tcpmss' match, which allows you to examine the | ||
359 | MSS value of TCP SYN packets, which control the maximum packet size | ||
360 | for that connection. | ||
361 | |||
362 | To compile it as a module, choose M here. If unsure, say N. | ||
363 | |||
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index cb2183145c37..746172ebc91b 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile | |||
@@ -1,4 +1,5 @@ | |||
1 | netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o | 1 | netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o |
2 | nf_conntrack-objs := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o | ||
2 | 3 | ||
3 | obj-$(CONFIG_NETFILTER) = netfilter.o | 4 | obj-$(CONFIG_NETFILTER) = netfilter.o |
4 | 5 | ||
@@ -6,13 +7,43 @@ obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o | |||
6 | obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o | 7 | obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o |
7 | obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o | 8 | obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o |
8 | 9 | ||
9 | nf_conntrack-objs := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o | 10 | # connection tracking |
10 | |||
11 | obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o | 11 | obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o |
12 | obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o | ||
13 | 12 | ||
14 | # SCTP protocol connection tracking | 13 | # SCTP protocol connection tracking |
15 | obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o | 14 | obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o |
16 | 15 | ||
17 | # netlink interface for nf_conntrack | 16 | # netlink interface for nf_conntrack |
18 | obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o | 17 | obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o |
18 | |||
19 | # connection tracking helpers | ||
20 | obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o | ||
21 | |||
22 | # generic X tables | ||
23 | obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o | ||
24 | |||
25 | # targets | ||
26 | obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o | ||
27 | obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o | ||
28 | obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o | ||
29 | obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o | ||
30 | obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o | ||
31 | |||
32 | # matches | ||
33 | obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o | ||
34 | obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o | ||
35 | obj-$(CONFIG_NETFILTER_XT_MATCH_CONNMARK) += xt_connmark.o | ||
36 | obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o | ||
37 | obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o | ||
38 | obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o | ||
39 | obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o | ||
40 | obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o | ||
41 | obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o | ||
42 | obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o | ||
43 | obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o | ||
44 | obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o | ||
45 | obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o | ||
46 | obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o | ||
47 | obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o | ||
48 | obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o | ||
49 | obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o | ||
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 3531d142f693..617599aeeead 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c | |||
@@ -821,7 +821,7 @@ module_exit(fini); | |||
821 | 821 | ||
822 | /* Some modules need us, but don't depend directly on any symbol. | 822 | /* Some modules need us, but don't depend directly on any symbol. |
823 | They should call this. */ | 823 | They should call this. */ |
824 | void need_nf_conntrack(void) | 824 | void need_conntrack(void) |
825 | { | 825 | { |
826 | } | 826 | } |
827 | 827 | ||
@@ -841,7 +841,7 @@ EXPORT_SYMBOL(nf_conntrack_protocol_unregister); | |||
841 | EXPORT_SYMBOL(nf_ct_invert_tuplepr); | 841 | EXPORT_SYMBOL(nf_ct_invert_tuplepr); |
842 | EXPORT_SYMBOL(nf_conntrack_alter_reply); | 842 | EXPORT_SYMBOL(nf_conntrack_alter_reply); |
843 | EXPORT_SYMBOL(nf_conntrack_destroyed); | 843 | EXPORT_SYMBOL(nf_conntrack_destroyed); |
844 | EXPORT_SYMBOL(need_nf_conntrack); | 844 | EXPORT_SYMBOL(need_conntrack); |
845 | EXPORT_SYMBOL(nf_conntrack_helper_register); | 845 | EXPORT_SYMBOL(nf_conntrack_helper_register); |
846 | EXPORT_SYMBOL(nf_conntrack_helper_unregister); | 846 | EXPORT_SYMBOL(nf_conntrack_helper_unregister); |
847 | EXPORT_SYMBOL(nf_ct_iterate_cleanup); | 847 | EXPORT_SYMBOL(nf_ct_iterate_cleanup); |
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c new file mode 100644 index 000000000000..d7817afc6b96 --- /dev/null +++ b/net/netfilter/x_tables.c | |||
@@ -0,0 +1,624 @@ | |||
1 | /* | ||
2 | * x_tables core - Backend for {ip,ip6,arp}_tables | ||
3 | * | ||
4 | * Copyright (C) 2006-2006 Harald Welte <laforge@netfilter.org> | ||
5 | * | ||
6 | * Based on existing ip_tables code which is | ||
7 | * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling | ||
8 | * Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/config.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/socket.h> | ||
19 | #include <linux/net.h> | ||
20 | #include <linux/proc_fs.h> | ||
21 | #include <linux/seq_file.h> | ||
22 | #include <linux/string.h> | ||
23 | #include <linux/vmalloc.h> | ||
24 | |||
25 | #include <linux/netfilter/x_tables.h> | ||
26 | #include <linux/netfilter_arp.h> | ||
27 | |||
28 | MODULE_LICENSE("GPL"); | ||
29 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | ||
30 | MODULE_DESCRIPTION("[ip,ip6,arp]_tables backend module"); | ||
31 | |||
32 | #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) | ||
33 | |||
34 | struct xt_af { | ||
35 | struct semaphore mutex; | ||
36 | struct list_head match; | ||
37 | struct list_head target; | ||
38 | struct list_head tables; | ||
39 | }; | ||
40 | |||
41 | static struct xt_af *xt; | ||
42 | |||
43 | #ifdef DEBUG_IP_FIREWALL_USER | ||
44 | #define duprintf(format, args...) printk(format , ## args) | ||
45 | #else | ||
46 | #define duprintf(format, args...) | ||
47 | #endif | ||
48 | |||
49 | enum { | ||
50 | TABLE, | ||
51 | TARGET, | ||
52 | MATCH, | ||
53 | }; | ||
54 | |||
55 | /* Registration hooks for targets. */ | ||
56 | int | ||
57 | xt_register_target(int af, struct xt_target *target) | ||
58 | { | ||
59 | int ret; | ||
60 | |||
61 | ret = down_interruptible(&xt[af].mutex); | ||
62 | if (ret != 0) | ||
63 | return ret; | ||
64 | list_add(&target->list, &xt[af].target); | ||
65 | up(&xt[af].mutex); | ||
66 | return ret; | ||
67 | } | ||
68 | EXPORT_SYMBOL(xt_register_target); | ||
69 | |||
70 | void | ||
71 | xt_unregister_target(int af, struct xt_target *target) | ||
72 | { | ||
73 | down(&xt[af].mutex); | ||
74 | LIST_DELETE(&xt[af].target, target); | ||
75 | up(&xt[af].mutex); | ||
76 | } | ||
77 | EXPORT_SYMBOL(xt_unregister_target); | ||
78 | |||
79 | int | ||
80 | xt_register_match(int af, struct xt_match *match) | ||
81 | { | ||
82 | int ret; | ||
83 | |||
84 | ret = down_interruptible(&xt[af].mutex); | ||
85 | if (ret != 0) | ||
86 | return ret; | ||
87 | |||
88 | list_add(&match->list, &xt[af].match); | ||
89 | up(&xt[af].mutex); | ||
90 | |||
91 | return ret; | ||
92 | } | ||
93 | EXPORT_SYMBOL(xt_register_match); | ||
94 | |||
95 | void | ||
96 | xt_unregister_match(int af, struct xt_match *match) | ||
97 | { | ||
98 | down(&xt[af].mutex); | ||
99 | LIST_DELETE(&xt[af].match, match); | ||
100 | up(&xt[af].mutex); | ||
101 | } | ||
102 | EXPORT_SYMBOL(xt_unregister_match); | ||
103 | |||
104 | |||
105 | /* | ||
106 | * These are weird, but module loading must not be done with mutex | ||
107 | * held (since they will register), and we have to have a single | ||
108 | * function to use try_then_request_module(). | ||
109 | */ | ||
110 | |||
111 | /* Find match, grabs ref. Returns ERR_PTR() on error. */ | ||
112 | struct xt_match *xt_find_match(int af, const char *name, u8 revision) | ||
113 | { | ||
114 | struct xt_match *m; | ||
115 | int err = 0; | ||
116 | |||
117 | if (down_interruptible(&xt[af].mutex) != 0) | ||
118 | return ERR_PTR(-EINTR); | ||
119 | |||
120 | list_for_each_entry(m, &xt[af].match, list) { | ||
121 | if (strcmp(m->name, name) == 0) { | ||
122 | if (m->revision == revision) { | ||
123 | if (try_module_get(m->me)) { | ||
124 | up(&xt[af].mutex); | ||
125 | return m; | ||
126 | } | ||
127 | } else | ||
128 | err = -EPROTOTYPE; /* Found something. */ | ||
129 | } | ||
130 | } | ||
131 | up(&xt[af].mutex); | ||
132 | return ERR_PTR(err); | ||
133 | } | ||
134 | EXPORT_SYMBOL(xt_find_match); | ||
135 | |||
136 | /* Find target, grabs ref. Returns ERR_PTR() on error. */ | ||
137 | struct xt_target *xt_find_target(int af, const char *name, u8 revision) | ||
138 | { | ||
139 | struct xt_target *t; | ||
140 | int err = 0; | ||
141 | |||
142 | if (down_interruptible(&xt[af].mutex) != 0) | ||
143 | return ERR_PTR(-EINTR); | ||
144 | |||
145 | list_for_each_entry(t, &xt[af].target, list) { | ||
146 | if (strcmp(t->name, name) == 0) { | ||
147 | if (t->revision == revision) { | ||
148 | if (try_module_get(t->me)) { | ||
149 | up(&xt[af].mutex); | ||
150 | return t; | ||
151 | } | ||
152 | } else | ||
153 | err = -EPROTOTYPE; /* Found something. */ | ||
154 | } | ||
155 | } | ||
156 | up(&xt[af].mutex); | ||
157 | return ERR_PTR(err); | ||
158 | } | ||
159 | EXPORT_SYMBOL(xt_find_target); | ||
160 | |||
161 | static const char *xt_prefix[NPROTO] = { | ||
162 | [AF_INET] = "ipt_%s", | ||
163 | [AF_INET6] = "ip6t_%s", | ||
164 | [NF_ARP] = "arpt_%s", | ||
165 | }; | ||
166 | |||
167 | struct xt_target *xt_request_find_target(int af, const char *name, u8 revision) | ||
168 | { | ||
169 | struct xt_target *target; | ||
170 | |||
171 | target = try_then_request_module(xt_find_target(af, name, revision), | ||
172 | xt_prefix[af], name); | ||
173 | if (IS_ERR(target) || !target) | ||
174 | return NULL; | ||
175 | return target; | ||
176 | } | ||
177 | EXPORT_SYMBOL_GPL(xt_request_find_target); | ||
178 | |||
179 | static int match_revfn(int af, const char *name, u8 revision, int *bestp) | ||
180 | { | ||
181 | struct xt_match *m; | ||
182 | int have_rev = 0; | ||
183 | |||
184 | list_for_each_entry(m, &xt[af].match, list) { | ||
185 | if (strcmp(m->name, name) == 0) { | ||
186 | if (m->revision > *bestp) | ||
187 | *bestp = m->revision; | ||
188 | if (m->revision == revision) | ||
189 | have_rev = 1; | ||
190 | } | ||
191 | } | ||
192 | return have_rev; | ||
193 | } | ||
194 | |||
195 | static int target_revfn(int af, const char *name, u8 revision, int *bestp) | ||
196 | { | ||
197 | struct xt_target *t; | ||
198 | int have_rev = 0; | ||
199 | |||
200 | list_for_each_entry(t, &xt[af].target, list) { | ||
201 | if (strcmp(t->name, name) == 0) { | ||
202 | if (t->revision > *bestp) | ||
203 | *bestp = t->revision; | ||
204 | if (t->revision == revision) | ||
205 | have_rev = 1; | ||
206 | } | ||
207 | } | ||
208 | return have_rev; | ||
209 | } | ||
210 | |||
211 | /* Returns true or false (if no such extension at all) */ | ||
212 | int xt_find_revision(int af, const char *name, u8 revision, int target, | ||
213 | int *err) | ||
214 | { | ||
215 | int have_rev, best = -1; | ||
216 | |||
217 | if (down_interruptible(&xt[af].mutex) != 0) { | ||
218 | *err = -EINTR; | ||
219 | return 1; | ||
220 | } | ||
221 | if (target == 1) | ||
222 | have_rev = target_revfn(af, name, revision, &best); | ||
223 | else | ||
224 | have_rev = match_revfn(af, name, revision, &best); | ||
225 | up(&xt[af].mutex); | ||
226 | |||
227 | /* Nothing at all? Return 0 to try loading module. */ | ||
228 | if (best == -1) { | ||
229 | *err = -ENOENT; | ||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | *err = best; | ||
234 | if (!have_rev) | ||
235 | *err = -EPROTONOSUPPORT; | ||
236 | return 1; | ||
237 | } | ||
238 | EXPORT_SYMBOL_GPL(xt_find_revision); | ||
239 | |||
240 | struct xt_table_info *xt_alloc_table_info(unsigned int size) | ||
241 | { | ||
242 | struct xt_table_info *newinfo; | ||
243 | int cpu; | ||
244 | |||
245 | /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ | ||
246 | if ((SMP_ALIGN(size) >> PAGE_SHIFT) + 2 > num_physpages) | ||
247 | return NULL; | ||
248 | |||
249 | newinfo = kzalloc(sizeof(struct xt_table_info), GFP_KERNEL); | ||
250 | if (!newinfo) | ||
251 | return NULL; | ||
252 | |||
253 | newinfo->size = size; | ||
254 | |||
255 | for_each_cpu(cpu) { | ||
256 | if (size <= PAGE_SIZE) | ||
257 | newinfo->entries[cpu] = kmalloc_node(size, | ||
258 | GFP_KERNEL, | ||
259 | cpu_to_node(cpu)); | ||
260 | else | ||
261 | newinfo->entries[cpu] = vmalloc_node(size, | ||
262 | cpu_to_node(cpu)); | ||
263 | |||
264 | if (newinfo->entries[cpu] == NULL) { | ||
265 | xt_free_table_info(newinfo); | ||
266 | return NULL; | ||
267 | } | ||
268 | } | ||
269 | |||
270 | return newinfo; | ||
271 | } | ||
272 | EXPORT_SYMBOL(xt_alloc_table_info); | ||
273 | |||
274 | void xt_free_table_info(struct xt_table_info *info) | ||
275 | { | ||
276 | int cpu; | ||
277 | |||
278 | for_each_cpu(cpu) { | ||
279 | if (info->size <= PAGE_SIZE) | ||
280 | kfree(info->entries[cpu]); | ||
281 | else | ||
282 | vfree(info->entries[cpu]); | ||
283 | } | ||
284 | kfree(info); | ||
285 | } | ||
286 | EXPORT_SYMBOL(xt_free_table_info); | ||
287 | |||
288 | /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ | ||
289 | struct xt_table *xt_find_table_lock(int af, const char *name) | ||
290 | { | ||
291 | struct xt_table *t; | ||
292 | |||
293 | if (down_interruptible(&xt[af].mutex) != 0) | ||
294 | return ERR_PTR(-EINTR); | ||
295 | |||
296 | list_for_each_entry(t, &xt[af].tables, list) | ||
297 | if (strcmp(t->name, name) == 0 && try_module_get(t->me)) | ||
298 | return t; | ||
299 | up(&xt[af].mutex); | ||
300 | return NULL; | ||
301 | } | ||
302 | EXPORT_SYMBOL_GPL(xt_find_table_lock); | ||
303 | |||
304 | void xt_table_unlock(struct xt_table *table) | ||
305 | { | ||
306 | up(&xt[table->af].mutex); | ||
307 | } | ||
308 | EXPORT_SYMBOL_GPL(xt_table_unlock); | ||
309 | |||
310 | |||
311 | struct xt_table_info * | ||
312 | xt_replace_table(struct xt_table *table, | ||
313 | unsigned int num_counters, | ||
314 | struct xt_table_info *newinfo, | ||
315 | int *error) | ||
316 | { | ||
317 | struct xt_table_info *oldinfo, *private; | ||
318 | |||
319 | /* Do the substitution. */ | ||
320 | write_lock_bh(&table->lock); | ||
321 | private = table->private; | ||
322 | /* Check inside lock: is the old number correct? */ | ||
323 | if (num_counters != private->number) { | ||
324 | duprintf("num_counters != table->private->number (%u/%u)\n", | ||
325 | num_counters, private->number); | ||
326 | write_unlock_bh(&table->lock); | ||
327 | *error = -EAGAIN; | ||
328 | return NULL; | ||
329 | } | ||
330 | oldinfo = private; | ||
331 | table->private = newinfo; | ||
332 | newinfo->initial_entries = oldinfo->initial_entries; | ||
333 | write_unlock_bh(&table->lock); | ||
334 | |||
335 | return oldinfo; | ||
336 | } | ||
337 | EXPORT_SYMBOL_GPL(xt_replace_table); | ||
338 | |||
339 | int xt_register_table(struct xt_table *table, | ||
340 | struct xt_table_info *bootstrap, | ||
341 | struct xt_table_info *newinfo) | ||
342 | { | ||
343 | int ret; | ||
344 | struct xt_table_info *private; | ||
345 | |||
346 | ret = down_interruptible(&xt[table->af].mutex); | ||
347 | if (ret != 0) | ||
348 | return ret; | ||
349 | |||
350 | /* Don't autoload: we'd eat our tail... */ | ||
351 | if (list_named_find(&xt[table->af].tables, table->name)) { | ||
352 | ret = -EEXIST; | ||
353 | goto unlock; | ||
354 | } | ||
355 | |||
356 | /* Simplifies replace_table code. */ | ||
357 | table->private = bootstrap; | ||
358 | if (!xt_replace_table(table, 0, newinfo, &ret)) | ||
359 | goto unlock; | ||
360 | |||
361 | private = table->private; | ||
362 | duprintf("table->private->number = %u\n", private->number); | ||
363 | |||
364 | /* save number of initial entries */ | ||
365 | private->initial_entries = private->number; | ||
366 | |||
367 | rwlock_init(&table->lock); | ||
368 | list_prepend(&xt[table->af].tables, table); | ||
369 | |||
370 | ret = 0; | ||
371 | unlock: | ||
372 | up(&xt[table->af].mutex); | ||
373 | return ret; | ||
374 | } | ||
375 | EXPORT_SYMBOL_GPL(xt_register_table); | ||
376 | |||
377 | void *xt_unregister_table(struct xt_table *table) | ||
378 | { | ||
379 | struct xt_table_info *private; | ||
380 | |||
381 | down(&xt[table->af].mutex); | ||
382 | private = table->private; | ||
383 | LIST_DELETE(&xt[table->af].tables, table); | ||
384 | up(&xt[table->af].mutex); | ||
385 | |||
386 | return private; | ||
387 | } | ||
388 | EXPORT_SYMBOL_GPL(xt_unregister_table); | ||
389 | |||
390 | #ifdef CONFIG_PROC_FS | ||
391 | static char *xt_proto_prefix[NPROTO] = { | ||
392 | [AF_INET] = "ip", | ||
393 | [AF_INET6] = "ip6", | ||
394 | [NF_ARP] = "arp", | ||
395 | }; | ||
396 | |||
397 | static struct list_head *xt_get_idx(struct list_head *list, struct seq_file *seq, loff_t pos) | ||
398 | { | ||
399 | struct list_head *head = list->next; | ||
400 | |||
401 | if (!head || list_empty(list)) | ||
402 | return NULL; | ||
403 | |||
404 | while (pos && (head = head->next)) { | ||
405 | if (head == list) | ||
406 | return NULL; | ||
407 | pos--; | ||
408 | } | ||
409 | return pos ? NULL : head; | ||
410 | } | ||
411 | |||
412 | static struct list_head *type2list(u_int16_t af, u_int16_t type) | ||
413 | { | ||
414 | struct list_head *list; | ||
415 | |||
416 | switch (type) { | ||
417 | case TARGET: | ||
418 | list = &xt[af].target; | ||
419 | break; | ||
420 | case MATCH: | ||
421 | list = &xt[af].match; | ||
422 | break; | ||
423 | case TABLE: | ||
424 | list = &xt[af].tables; | ||
425 | break; | ||
426 | default: | ||
427 | list = NULL; | ||
428 | break; | ||
429 | } | ||
430 | |||
431 | return list; | ||
432 | } | ||
433 | |||
434 | static void *xt_tgt_seq_start(struct seq_file *seq, loff_t *pos) | ||
435 | { | ||
436 | struct proc_dir_entry *pde = (struct proc_dir_entry *) seq->private; | ||
437 | u_int16_t af = (unsigned long)pde->data & 0xffff; | ||
438 | u_int16_t type = (unsigned long)pde->data >> 16; | ||
439 | struct list_head *list; | ||
440 | |||
441 | if (af >= NPROTO) | ||
442 | return NULL; | ||
443 | |||
444 | list = type2list(af, type); | ||
445 | if (!list) | ||
446 | return NULL; | ||
447 | |||
448 | if (down_interruptible(&xt[af].mutex) != 0) | ||
449 | return NULL; | ||
450 | |||
451 | return xt_get_idx(list, seq, *pos); | ||
452 | } | ||
453 | |||
454 | static void *xt_tgt_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||
455 | { | ||
456 | struct proc_dir_entry *pde = seq->private; | ||
457 | u_int16_t af = (unsigned long)pde->data & 0xffff; | ||
458 | u_int16_t type = (unsigned long)pde->data >> 16; | ||
459 | struct list_head *list; | ||
460 | |||
461 | if (af >= NPROTO) | ||
462 | return NULL; | ||
463 | |||
464 | list = type2list(af, type); | ||
465 | if (!list) | ||
466 | return NULL; | ||
467 | |||
468 | (*pos)++; | ||
469 | return xt_get_idx(list, seq, *pos); | ||
470 | } | ||
471 | |||
472 | static void xt_tgt_seq_stop(struct seq_file *seq, void *v) | ||
473 | { | ||
474 | struct proc_dir_entry *pde = seq->private; | ||
475 | u_int16_t af = (unsigned long)pde->data & 0xffff; | ||
476 | |||
477 | up(&xt[af].mutex); | ||
478 | } | ||
479 | |||
480 | static int xt_name_seq_show(struct seq_file *seq, void *v) | ||
481 | { | ||
482 | char *name = (char *)v + sizeof(struct list_head); | ||
483 | |||
484 | if (strlen(name)) | ||
485 | return seq_printf(seq, "%s\n", name); | ||
486 | else | ||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | static struct seq_operations xt_tgt_seq_ops = { | ||
491 | .start = xt_tgt_seq_start, | ||
492 | .next = xt_tgt_seq_next, | ||
493 | .stop = xt_tgt_seq_stop, | ||
494 | .show = xt_name_seq_show, | ||
495 | }; | ||
496 | |||
497 | static int xt_tgt_open(struct inode *inode, struct file *file) | ||
498 | { | ||
499 | int ret; | ||
500 | |||
501 | ret = seq_open(file, &xt_tgt_seq_ops); | ||
502 | if (!ret) { | ||
503 | struct seq_file *seq = file->private_data; | ||
504 | struct proc_dir_entry *pde = PDE(inode); | ||
505 | |||
506 | seq->private = pde; | ||
507 | } | ||
508 | |||
509 | return ret; | ||
510 | } | ||
511 | |||
512 | static struct file_operations xt_file_ops = { | ||
513 | .owner = THIS_MODULE, | ||
514 | .open = xt_tgt_open, | ||
515 | .read = seq_read, | ||
516 | .llseek = seq_lseek, | ||
517 | .release = seq_release, | ||
518 | }; | ||
519 | |||
520 | #define FORMAT_TABLES "_tables_names" | ||
521 | #define FORMAT_MATCHES "_tables_matches" | ||
522 | #define FORMAT_TARGETS "_tables_targets" | ||
523 | |||
524 | #endif /* CONFIG_PROC_FS */ | ||
525 | |||
526 | int xt_proto_init(int af) | ||
527 | { | ||
528 | #ifdef CONFIG_PROC_FS | ||
529 | char buf[XT_FUNCTION_MAXNAMELEN]; | ||
530 | struct proc_dir_entry *proc; | ||
531 | #endif | ||
532 | |||
533 | if (af >= NPROTO) | ||
534 | return -EINVAL; | ||
535 | |||
536 | |||
537 | #ifdef CONFIG_PROC_FS | ||
538 | strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); | ||
539 | strlcat(buf, FORMAT_TABLES, sizeof(buf)); | ||
540 | proc = proc_net_fops_create(buf, 0440, &xt_file_ops); | ||
541 | if (!proc) | ||
542 | goto out; | ||
543 | proc->data = (void *) ((unsigned long) af | (TABLE << 16)); | ||
544 | |||
545 | |||
546 | strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); | ||
547 | strlcat(buf, FORMAT_MATCHES, sizeof(buf)); | ||
548 | proc = proc_net_fops_create(buf, 0440, &xt_file_ops); | ||
549 | if (!proc) | ||
550 | goto out_remove_tables; | ||
551 | proc->data = (void *) ((unsigned long) af | (MATCH << 16)); | ||
552 | |||
553 | strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); | ||
554 | strlcat(buf, FORMAT_TARGETS, sizeof(buf)); | ||
555 | proc = proc_net_fops_create(buf, 0440, &xt_file_ops); | ||
556 | if (!proc) | ||
557 | goto out_remove_matches; | ||
558 | proc->data = (void *) ((unsigned long) af | (TARGET << 16)); | ||
559 | #endif | ||
560 | |||
561 | return 0; | ||
562 | |||
563 | #ifdef CONFIG_PROC_FS | ||
564 | out_remove_matches: | ||
565 | strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); | ||
566 | strlcat(buf, FORMAT_MATCHES, sizeof(buf)); | ||
567 | proc_net_remove(buf); | ||
568 | |||
569 | out_remove_tables: | ||
570 | strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); | ||
571 | strlcat(buf, FORMAT_TABLES, sizeof(buf)); | ||
572 | proc_net_remove(buf); | ||
573 | out: | ||
574 | return -1; | ||
575 | #endif | ||
576 | } | ||
577 | EXPORT_SYMBOL_GPL(xt_proto_init); | ||
578 | |||
579 | void xt_proto_fini(int af) | ||
580 | { | ||
581 | #ifdef CONFIG_PROC_FS | ||
582 | char buf[XT_FUNCTION_MAXNAMELEN]; | ||
583 | |||
584 | strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); | ||
585 | strlcat(buf, FORMAT_TABLES, sizeof(buf)); | ||
586 | proc_net_remove(buf); | ||
587 | |||
588 | strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); | ||
589 | strlcat(buf, FORMAT_TARGETS, sizeof(buf)); | ||
590 | proc_net_remove(buf); | ||
591 | |||
592 | strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); | ||
593 | strlcat(buf, FORMAT_MATCHES, sizeof(buf)); | ||
594 | proc_net_remove(buf); | ||
595 | #endif /*CONFIG_PROC_FS*/ | ||
596 | } | ||
597 | EXPORT_SYMBOL_GPL(xt_proto_fini); | ||
598 | |||
599 | |||
600 | static int __init xt_init(void) | ||
601 | { | ||
602 | int i; | ||
603 | |||
604 | xt = kmalloc(sizeof(struct xt_af) * NPROTO, GFP_KERNEL); | ||
605 | if (!xt) | ||
606 | return -ENOMEM; | ||
607 | |||
608 | for (i = 0; i < NPROTO; i++) { | ||
609 | init_MUTEX(&xt[i].mutex); | ||
610 | INIT_LIST_HEAD(&xt[i].target); | ||
611 | INIT_LIST_HEAD(&xt[i].match); | ||
612 | INIT_LIST_HEAD(&xt[i].tables); | ||
613 | } | ||
614 | return 0; | ||
615 | } | ||
616 | |||
617 | static void __exit xt_fini(void) | ||
618 | { | ||
619 | kfree(xt); | ||
620 | } | ||
621 | |||
622 | module_init(xt_init); | ||
623 | module_exit(xt_fini); | ||
624 | |||
diff --git a/net/ipv4/netfilter/ipt_CLASSIFY.c b/net/netfilter/xt_CLASSIFY.c index dab78d8bd494..78ee266a12ee 100644 --- a/net/ipv4/netfilter/ipt_CLASSIFY.c +++ b/net/netfilter/xt_CLASSIFY.c | |||
@@ -15,12 +15,13 @@ | |||
15 | #include <linux/ip.h> | 15 | #include <linux/ip.h> |
16 | #include <net/checksum.h> | 16 | #include <net/checksum.h> |
17 | 17 | ||
18 | #include <linux/netfilter_ipv4/ip_tables.h> | 18 | #include <linux/netfilter/x_tables.h> |
19 | #include <linux/netfilter_ipv4/ipt_CLASSIFY.h> | 19 | #include <linux/netfilter/xt_CLASSIFY.h> |
20 | 20 | ||
21 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | 21 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); |
22 | MODULE_LICENSE("GPL"); | 22 | MODULE_LICENSE("GPL"); |
23 | MODULE_DESCRIPTION("iptables qdisc classification target module"); | 23 | MODULE_DESCRIPTION("iptables qdisc classification target module"); |
24 | MODULE_ALIAS("ipt_CLASSIFY"); | ||
24 | 25 | ||
25 | static unsigned int | 26 | static unsigned int |
26 | target(struct sk_buff **pskb, | 27 | target(struct sk_buff **pskb, |
@@ -30,25 +31,25 @@ target(struct sk_buff **pskb, | |||
30 | const void *targinfo, | 31 | const void *targinfo, |
31 | void *userinfo) | 32 | void *userinfo) |
32 | { | 33 | { |
33 | const struct ipt_classify_target_info *clinfo = targinfo; | 34 | const struct xt_classify_target_info *clinfo = targinfo; |
34 | 35 | ||
35 | if((*pskb)->priority != clinfo->priority) | 36 | if ((*pskb)->priority != clinfo->priority) |
36 | (*pskb)->priority = clinfo->priority; | 37 | (*pskb)->priority = clinfo->priority; |
37 | 38 | ||
38 | return IPT_CONTINUE; | 39 | return XT_CONTINUE; |
39 | } | 40 | } |
40 | 41 | ||
41 | static int | 42 | static int |
42 | checkentry(const char *tablename, | 43 | checkentry(const char *tablename, |
43 | const struct ipt_entry *e, | 44 | const void *e, |
44 | void *targinfo, | 45 | void *targinfo, |
45 | unsigned int targinfosize, | 46 | unsigned int targinfosize, |
46 | unsigned int hook_mask) | 47 | unsigned int hook_mask) |
47 | { | 48 | { |
48 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_classify_target_info))){ | 49 | if (targinfosize != XT_ALIGN(sizeof(struct xt_classify_target_info))){ |
49 | printk(KERN_ERR "CLASSIFY: invalid size (%u != %Zu).\n", | 50 | printk(KERN_ERR "CLASSIFY: invalid size (%u != %Zu).\n", |
50 | targinfosize, | 51 | targinfosize, |
51 | IPT_ALIGN(sizeof(struct ipt_classify_target_info))); | 52 | XT_ALIGN(sizeof(struct xt_classify_target_info))); |
52 | return 0; | 53 | return 0; |
53 | } | 54 | } |
54 | 55 | ||
@@ -69,21 +70,39 @@ checkentry(const char *tablename, | |||
69 | return 1; | 70 | return 1; |
70 | } | 71 | } |
71 | 72 | ||
72 | static struct ipt_target ipt_classify_reg = { | 73 | static struct xt_target classify_reg = { |
74 | .name = "CLASSIFY", | ||
75 | .target = target, | ||
76 | .checkentry = checkentry, | ||
77 | .me = THIS_MODULE, | ||
78 | }; | ||
79 | static struct xt_target classify6_reg = { | ||
73 | .name = "CLASSIFY", | 80 | .name = "CLASSIFY", |
74 | .target = target, | 81 | .target = target, |
75 | .checkentry = checkentry, | 82 | .checkentry = checkentry, |
76 | .me = THIS_MODULE, | 83 | .me = THIS_MODULE, |
77 | }; | 84 | }; |
78 | 85 | ||
86 | |||
79 | static int __init init(void) | 87 | static int __init init(void) |
80 | { | 88 | { |
81 | return ipt_register_target(&ipt_classify_reg); | 89 | int ret; |
90 | |||
91 | ret = xt_register_target(AF_INET, &classify_reg); | ||
92 | if (ret) | ||
93 | return ret; | ||
94 | |||
95 | ret = xt_register_target(AF_INET6, &classify6_reg); | ||
96 | if (ret) | ||
97 | xt_unregister_target(AF_INET, &classify_reg); | ||
98 | |||
99 | return ret; | ||
82 | } | 100 | } |
83 | 101 | ||
84 | static void __exit fini(void) | 102 | static void __exit fini(void) |
85 | { | 103 | { |
86 | ipt_unregister_target(&ipt_classify_reg); | 104 | xt_unregister_target(AF_INET, &classify_reg); |
105 | xt_unregister_target(AF_INET6, &classify6_reg); | ||
87 | } | 106 | } |
88 | 107 | ||
89 | module_init(init); | 108 | module_init(init); |
diff --git a/net/ipv4/netfilter/ipt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c index 8acac5a40a92..22506e376be5 100644 --- a/net/ipv4/netfilter/ipt_CONNMARK.c +++ b/net/netfilter/xt_CONNMARK.c | |||
@@ -26,9 +26,10 @@ | |||
26 | MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>"); | 26 | MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>"); |
27 | MODULE_DESCRIPTION("IP tables CONNMARK matching module"); | 27 | MODULE_DESCRIPTION("IP tables CONNMARK matching module"); |
28 | MODULE_LICENSE("GPL"); | 28 | MODULE_LICENSE("GPL"); |
29 | MODULE_ALIAS("ipt_CONNMARK"); | ||
29 | 30 | ||
30 | #include <linux/netfilter_ipv4/ip_tables.h> | 31 | #include <linux/netfilter/x_tables.h> |
31 | #include <linux/netfilter_ipv4/ipt_CONNMARK.h> | 32 | #include <linux/netfilter/xt_CONNMARK.h> |
32 | #include <net/netfilter/nf_conntrack_compat.h> | 33 | #include <net/netfilter/nf_conntrack_compat.h> |
33 | 34 | ||
34 | static unsigned int | 35 | static unsigned int |
@@ -39,7 +40,7 @@ target(struct sk_buff **pskb, | |||
39 | const void *targinfo, | 40 | const void *targinfo, |
40 | void *userinfo) | 41 | void *userinfo) |
41 | { | 42 | { |
42 | const struct ipt_connmark_target_info *markinfo = targinfo; | 43 | const struct xt_connmark_target_info *markinfo = targinfo; |
43 | u_int32_t diff; | 44 | u_int32_t diff; |
44 | u_int32_t nfmark; | 45 | u_int32_t nfmark; |
45 | u_int32_t newmark; | 46 | u_int32_t newmark; |
@@ -48,17 +49,17 @@ target(struct sk_buff **pskb, | |||
48 | 49 | ||
49 | if (ctmark) { | 50 | if (ctmark) { |
50 | switch(markinfo->mode) { | 51 | switch(markinfo->mode) { |
51 | case IPT_CONNMARK_SET: | 52 | case XT_CONNMARK_SET: |
52 | newmark = (*ctmark & ~markinfo->mask) | markinfo->mark; | 53 | newmark = (*ctmark & ~markinfo->mask) | markinfo->mark; |
53 | if (newmark != *ctmark) | 54 | if (newmark != *ctmark) |
54 | *ctmark = newmark; | 55 | *ctmark = newmark; |
55 | break; | 56 | break; |
56 | case IPT_CONNMARK_SAVE: | 57 | case XT_CONNMARK_SAVE: |
57 | newmark = (*ctmark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask); | 58 | newmark = (*ctmark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask); |
58 | if (*ctmark != newmark) | 59 | if (*ctmark != newmark) |
59 | *ctmark = newmark; | 60 | *ctmark = newmark; |
60 | break; | 61 | break; |
61 | case IPT_CONNMARK_RESTORE: | 62 | case XT_CONNMARK_RESTORE: |
62 | nfmark = (*pskb)->nfmark; | 63 | nfmark = (*pskb)->nfmark; |
63 | diff = (*ctmark ^ nfmark) & markinfo->mask; | 64 | diff = (*ctmark ^ nfmark) & markinfo->mask; |
64 | if (diff != 0) | 65 | if (diff != 0) |
@@ -67,25 +68,25 @@ target(struct sk_buff **pskb, | |||
67 | } | 68 | } |
68 | } | 69 | } |
69 | 70 | ||
70 | return IPT_CONTINUE; | 71 | return XT_CONTINUE; |
71 | } | 72 | } |
72 | 73 | ||
73 | static int | 74 | static int |
74 | checkentry(const char *tablename, | 75 | checkentry(const char *tablename, |
75 | const struct ipt_entry *e, | 76 | const void *entry, |
76 | void *targinfo, | 77 | void *targinfo, |
77 | unsigned int targinfosize, | 78 | unsigned int targinfosize, |
78 | unsigned int hook_mask) | 79 | unsigned int hook_mask) |
79 | { | 80 | { |
80 | struct ipt_connmark_target_info *matchinfo = targinfo; | 81 | struct xt_connmark_target_info *matchinfo = targinfo; |
81 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_connmark_target_info))) { | 82 | if (targinfosize != XT_ALIGN(sizeof(struct xt_connmark_target_info))) { |
82 | printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n", | 83 | printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n", |
83 | targinfosize, | 84 | targinfosize, |
84 | IPT_ALIGN(sizeof(struct ipt_connmark_target_info))); | 85 | XT_ALIGN(sizeof(struct xt_connmark_target_info))); |
85 | return 0; | 86 | return 0; |
86 | } | 87 | } |
87 | 88 | ||
88 | if (matchinfo->mode == IPT_CONNMARK_RESTORE) { | 89 | if (matchinfo->mode == XT_CONNMARK_RESTORE) { |
89 | if (strcmp(tablename, "mangle") != 0) { | 90 | if (strcmp(tablename, "mangle") != 0) { |
90 | printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename); | 91 | printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename); |
91 | return 0; | 92 | return 0; |
@@ -100,7 +101,13 @@ checkentry(const char *tablename, | |||
100 | return 1; | 101 | return 1; |
101 | } | 102 | } |
102 | 103 | ||
103 | static struct ipt_target ipt_connmark_reg = { | 104 | static struct xt_target connmark_reg = { |
105 | .name = "CONNMARK", | ||
106 | .target = &target, | ||
107 | .checkentry = &checkentry, | ||
108 | .me = THIS_MODULE | ||
109 | }; | ||
110 | static struct xt_target connmark6_reg = { | ||
104 | .name = "CONNMARK", | 111 | .name = "CONNMARK", |
105 | .target = &target, | 112 | .target = &target, |
106 | .checkentry = &checkentry, | 113 | .checkentry = &checkentry, |
@@ -109,13 +116,25 @@ static struct ipt_target ipt_connmark_reg = { | |||
109 | 116 | ||
110 | static int __init init(void) | 117 | static int __init init(void) |
111 | { | 118 | { |
112 | need_ip_conntrack(); | 119 | int ret; |
113 | return ipt_register_target(&ipt_connmark_reg); | 120 | |
121 | need_conntrack(); | ||
122 | |||
123 | ret = xt_register_target(AF_INET, &connmark_reg); | ||
124 | if (ret) | ||
125 | return ret; | ||
126 | |||
127 | ret = xt_register_target(AF_INET6, &connmark6_reg); | ||
128 | if (ret) | ||
129 | xt_unregister_target(AF_INET, &connmark_reg); | ||
130 | |||
131 | return ret; | ||
114 | } | 132 | } |
115 | 133 | ||
116 | static void __exit fini(void) | 134 | static void __exit fini(void) |
117 | { | 135 | { |
118 | ipt_unregister_target(&ipt_connmark_reg); | 136 | xt_unregister_target(AF_INET, &connmark_reg); |
137 | xt_unregister_target(AF_INET6, &connmark6_reg); | ||
119 | } | 138 | } |
120 | 139 | ||
121 | module_init(init); | 140 | module_init(init); |
diff --git a/net/ipv4/netfilter/ipt_MARK.c b/net/netfilter/xt_MARK.c index 52b4f2c296bf..0c11ee9550f3 100644 --- a/net/ipv4/netfilter/ipt_MARK.c +++ b/net/netfilter/xt_MARK.c | |||
@@ -12,12 +12,14 @@ | |||
12 | #include <linux/ip.h> | 12 | #include <linux/ip.h> |
13 | #include <net/checksum.h> | 13 | #include <net/checksum.h> |
14 | 14 | ||
15 | #include <linux/netfilter_ipv4/ip_tables.h> | 15 | #include <linux/netfilter/x_tables.h> |
16 | #include <linux/netfilter_ipv4/ipt_MARK.h> | 16 | #include <linux/netfilter/xt_MARK.h> |
17 | 17 | ||
18 | MODULE_LICENSE("GPL"); | 18 | MODULE_LICENSE("GPL"); |
19 | MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); | 19 | MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); |
20 | MODULE_DESCRIPTION("iptables MARK modification module"); | 20 | MODULE_DESCRIPTION("ip[6]tables MARK modification module"); |
21 | MODULE_ALIAS("ipt_MARK"); | ||
22 | MODULE_ALIAS("ip6t_MARK"); | ||
21 | 23 | ||
22 | static unsigned int | 24 | static unsigned int |
23 | target_v0(struct sk_buff **pskb, | 25 | target_v0(struct sk_buff **pskb, |
@@ -27,12 +29,12 @@ target_v0(struct sk_buff **pskb, | |||
27 | const void *targinfo, | 29 | const void *targinfo, |
28 | void *userinfo) | 30 | void *userinfo) |
29 | { | 31 | { |
30 | const struct ipt_mark_target_info *markinfo = targinfo; | 32 | const struct xt_mark_target_info *markinfo = targinfo; |
31 | 33 | ||
32 | if((*pskb)->nfmark != markinfo->mark) | 34 | if((*pskb)->nfmark != markinfo->mark) |
33 | (*pskb)->nfmark = markinfo->mark; | 35 | (*pskb)->nfmark = markinfo->mark; |
34 | 36 | ||
35 | return IPT_CONTINUE; | 37 | return XT_CONTINUE; |
36 | } | 38 | } |
37 | 39 | ||
38 | static unsigned int | 40 | static unsigned int |
@@ -43,19 +45,19 @@ target_v1(struct sk_buff **pskb, | |||
43 | const void *targinfo, | 45 | const void *targinfo, |
44 | void *userinfo) | 46 | void *userinfo) |
45 | { | 47 | { |
46 | const struct ipt_mark_target_info_v1 *markinfo = targinfo; | 48 | const struct xt_mark_target_info_v1 *markinfo = targinfo; |
47 | int mark = 0; | 49 | int mark = 0; |
48 | 50 | ||
49 | switch (markinfo->mode) { | 51 | switch (markinfo->mode) { |
50 | case IPT_MARK_SET: | 52 | case XT_MARK_SET: |
51 | mark = markinfo->mark; | 53 | mark = markinfo->mark; |
52 | break; | 54 | break; |
53 | 55 | ||
54 | case IPT_MARK_AND: | 56 | case XT_MARK_AND: |
55 | mark = (*pskb)->nfmark & markinfo->mark; | 57 | mark = (*pskb)->nfmark & markinfo->mark; |
56 | break; | 58 | break; |
57 | 59 | ||
58 | case IPT_MARK_OR: | 60 | case XT_MARK_OR: |
59 | mark = (*pskb)->nfmark | markinfo->mark; | 61 | mark = (*pskb)->nfmark | markinfo->mark; |
60 | break; | 62 | break; |
61 | } | 63 | } |
@@ -63,23 +65,23 @@ target_v1(struct sk_buff **pskb, | |||
63 | if((*pskb)->nfmark != mark) | 65 | if((*pskb)->nfmark != mark) |
64 | (*pskb)->nfmark = mark; | 66 | (*pskb)->nfmark = mark; |
65 | 67 | ||
66 | return IPT_CONTINUE; | 68 | return XT_CONTINUE; |
67 | } | 69 | } |
68 | 70 | ||
69 | 71 | ||
70 | static int | 72 | static int |
71 | checkentry_v0(const char *tablename, | 73 | checkentry_v0(const char *tablename, |
72 | const struct ipt_entry *e, | 74 | const void *entry, |
73 | void *targinfo, | 75 | void *targinfo, |
74 | unsigned int targinfosize, | 76 | unsigned int targinfosize, |
75 | unsigned int hook_mask) | 77 | unsigned int hook_mask) |
76 | { | 78 | { |
77 | struct ipt_mark_target_info *markinfo = targinfo; | 79 | struct xt_mark_target_info *markinfo = targinfo; |
78 | 80 | ||
79 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info))) { | 81 | if (targinfosize != XT_ALIGN(sizeof(struct xt_mark_target_info))) { |
80 | printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", | 82 | printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", |
81 | targinfosize, | 83 | targinfosize, |
82 | IPT_ALIGN(sizeof(struct ipt_mark_target_info))); | 84 | XT_ALIGN(sizeof(struct xt_mark_target_info))); |
83 | return 0; | 85 | return 0; |
84 | } | 86 | } |
85 | 87 | ||
@@ -98,17 +100,17 @@ checkentry_v0(const char *tablename, | |||
98 | 100 | ||
99 | static int | 101 | static int |
100 | checkentry_v1(const char *tablename, | 102 | checkentry_v1(const char *tablename, |
101 | const struct ipt_entry *e, | 103 | const void *entry, |
102 | void *targinfo, | 104 | void *targinfo, |
103 | unsigned int targinfosize, | 105 | unsigned int targinfosize, |
104 | unsigned int hook_mask) | 106 | unsigned int hook_mask) |
105 | { | 107 | { |
106 | struct ipt_mark_target_info_v1 *markinfo = targinfo; | 108 | struct xt_mark_target_info_v1 *markinfo = targinfo; |
107 | 109 | ||
108 | if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1))){ | 110 | if (targinfosize != XT_ALIGN(sizeof(struct xt_mark_target_info_v1))){ |
109 | printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", | 111 | printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", |
110 | targinfosize, | 112 | targinfosize, |
111 | IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1))); | 113 | XT_ALIGN(sizeof(struct xt_mark_target_info_v1))); |
112 | return 0; | 114 | return 0; |
113 | } | 115 | } |
114 | 116 | ||
@@ -117,9 +119,9 @@ checkentry_v1(const char *tablename, | |||
117 | return 0; | 119 | return 0; |
118 | } | 120 | } |
119 | 121 | ||
120 | if (markinfo->mode != IPT_MARK_SET | 122 | if (markinfo->mode != XT_MARK_SET |
121 | && markinfo->mode != IPT_MARK_AND | 123 | && markinfo->mode != XT_MARK_AND |
122 | && markinfo->mode != IPT_MARK_OR) { | 124 | && markinfo->mode != XT_MARK_OR) { |
123 | printk(KERN_WARNING "MARK: unknown mode %u\n", | 125 | printk(KERN_WARNING "MARK: unknown mode %u\n", |
124 | markinfo->mode); | 126 | markinfo->mode); |
125 | return 0; | 127 | return 0; |
@@ -133,7 +135,7 @@ checkentry_v1(const char *tablename, | |||
133 | return 1; | 135 | return 1; |
134 | } | 136 | } |
135 | 137 | ||
136 | static struct ipt_target ipt_mark_reg_v0 = { | 138 | static struct xt_target ipt_mark_reg_v0 = { |
137 | .name = "MARK", | 139 | .name = "MARK", |
138 | .target = target_v0, | 140 | .target = target_v0, |
139 | .checkentry = checkentry_v0, | 141 | .checkentry = checkentry_v0, |
@@ -141,7 +143,7 @@ static struct ipt_target ipt_mark_reg_v0 = { | |||
141 | .revision = 0, | 143 | .revision = 0, |
142 | }; | 144 | }; |
143 | 145 | ||
144 | static struct ipt_target ipt_mark_reg_v1 = { | 146 | static struct xt_target ipt_mark_reg_v1 = { |
145 | .name = "MARK", | 147 | .name = "MARK", |
146 | .target = target_v1, | 148 | .target = target_v1, |
147 | .checkentry = checkentry_v1, | 149 | .checkentry = checkentry_v1, |
@@ -149,23 +151,40 @@ static struct ipt_target ipt_mark_reg_v1 = { | |||
149 | .revision = 1, | 151 | .revision = 1, |
150 | }; | 152 | }; |
151 | 153 | ||
154 | static struct xt_target ip6t_mark_reg_v0 = { | ||
155 | .name = "MARK", | ||
156 | .target = target_v0, | ||
157 | .checkentry = checkentry_v0, | ||
158 | .me = THIS_MODULE, | ||
159 | .revision = 0, | ||
160 | }; | ||
161 | |||
152 | static int __init init(void) | 162 | static int __init init(void) |
153 | { | 163 | { |
154 | int err; | 164 | int err; |
155 | 165 | ||
156 | err = ipt_register_target(&ipt_mark_reg_v0); | 166 | err = xt_register_target(AF_INET, &ipt_mark_reg_v0); |
157 | if (!err) { | 167 | if (err) |
158 | err = ipt_register_target(&ipt_mark_reg_v1); | 168 | return err; |
159 | if (err) | 169 | |
160 | ipt_unregister_target(&ipt_mark_reg_v0); | 170 | err = xt_register_target(AF_INET, &ipt_mark_reg_v1); |
171 | if (err) | ||
172 | xt_unregister_target(AF_INET, &ipt_mark_reg_v0); | ||
173 | |||
174 | err = xt_register_target(AF_INET6, &ip6t_mark_reg_v0); | ||
175 | if (err) { | ||
176 | xt_unregister_target(AF_INET, &ipt_mark_reg_v0); | ||
177 | xt_unregister_target(AF_INET, &ipt_mark_reg_v1); | ||
161 | } | 178 | } |
179 | |||
162 | return err; | 180 | return err; |
163 | } | 181 | } |
164 | 182 | ||
165 | static void __exit fini(void) | 183 | static void __exit fini(void) |
166 | { | 184 | { |
167 | ipt_unregister_target(&ipt_mark_reg_v0); | 185 | xt_unregister_target(AF_INET, &ipt_mark_reg_v0); |
168 | ipt_unregister_target(&ipt_mark_reg_v1); | 186 | xt_unregister_target(AF_INET, &ipt_mark_reg_v1); |
187 | xt_unregister_target(AF_INET6, &ip6t_mark_reg_v0); | ||
169 | } | 188 | } |
170 | 189 | ||
171 | module_init(init); | 190 | module_init(init); |
diff --git a/net/netfilter/xt_NFQUEUE.c b/net/netfilter/xt_NFQUEUE.c new file mode 100644 index 000000000000..8b76b6f8d1e4 --- /dev/null +++ b/net/netfilter/xt_NFQUEUE.c | |||
@@ -0,0 +1,107 @@ | |||
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_arp.h> | ||
16 | #include <linux/netfilter/x_tables.h> | ||
17 | #include <linux/netfilter/xt_NFQUEUE.h> | ||
18 | |||
19 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | ||
20 | MODULE_DESCRIPTION("[ip,ip6,arp]_tables NFQUEUE target"); | ||
21 | MODULE_LICENSE("GPL"); | ||
22 | MODULE_ALIAS("ipt_NFQUEUE"); | ||
23 | MODULE_ALIAS("ip6t_NFQUEUE"); | ||
24 | MODULE_ALIAS("arpt_NFQUEUE"); | ||
25 | |||
26 | static unsigned int | ||
27 | target(struct sk_buff **pskb, | ||
28 | const struct net_device *in, | ||
29 | const struct net_device *out, | ||
30 | unsigned int hooknum, | ||
31 | const void *targinfo, | ||
32 | void *userinfo) | ||
33 | { | ||
34 | const struct xt_NFQ_info *tinfo = targinfo; | ||
35 | |||
36 | return NF_QUEUE_NR(tinfo->queuenum); | ||
37 | } | ||
38 | |||
39 | static int | ||
40 | checkentry(const char *tablename, | ||
41 | const void *entry, | ||
42 | void *targinfo, | ||
43 | unsigned int targinfosize, | ||
44 | unsigned int hook_mask) | ||
45 | { | ||
46 | if (targinfosize != XT_ALIGN(sizeof(struct xt_NFQ_info))) { | ||
47 | printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n", | ||
48 | targinfosize, | ||
49 | XT_ALIGN(sizeof(struct xt_NFQ_info))); | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | return 1; | ||
54 | } | ||
55 | |||
56 | static struct xt_target ipt_NFQ_reg = { | ||
57 | .name = "NFQUEUE", | ||
58 | .target = target, | ||
59 | .checkentry = checkentry, | ||
60 | .me = THIS_MODULE, | ||
61 | }; | ||
62 | |||
63 | static struct xt_target ip6t_NFQ_reg = { | ||
64 | .name = "NFQUEUE", | ||
65 | .target = target, | ||
66 | .checkentry = checkentry, | ||
67 | .me = THIS_MODULE, | ||
68 | }; | ||
69 | |||
70 | static struct xt_target arpt_NFQ_reg = { | ||
71 | .name = "NFQUEUE", | ||
72 | .target = target, | ||
73 | .checkentry = checkentry, | ||
74 | .me = THIS_MODULE, | ||
75 | }; | ||
76 | |||
77 | static int __init init(void) | ||
78 | { | ||
79 | int ret; | ||
80 | ret = xt_register_target(AF_INET, &ipt_NFQ_reg); | ||
81 | if (ret) | ||
82 | return ret; | ||
83 | ret = xt_register_target(AF_INET6, &ip6t_NFQ_reg); | ||
84 | if (ret) | ||
85 | goto out_ip; | ||
86 | ret = xt_register_target(NF_ARP, &arpt_NFQ_reg); | ||
87 | if (ret) | ||
88 | goto out_ip6; | ||
89 | |||
90 | return ret; | ||
91 | out_ip6: | ||
92 | xt_unregister_target(AF_INET6, &ip6t_NFQ_reg); | ||
93 | out_ip: | ||
94 | xt_unregister_target(AF_INET, &ipt_NFQ_reg); | ||
95 | |||
96 | return ret; | ||
97 | } | ||
98 | |||
99 | static void __exit fini(void) | ||
100 | { | ||
101 | xt_unregister_target(NF_ARP, &arpt_NFQ_reg); | ||
102 | xt_unregister_target(AF_INET6, &ip6t_NFQ_reg); | ||
103 | xt_unregister_target(AF_INET, &ipt_NFQ_reg); | ||
104 | } | ||
105 | |||
106 | module_init(init); | ||
107 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_NOTRACK.c b/net/netfilter/xt_NOTRACK.c index e3c69d072c6e..24d477afa939 100644 --- a/net/ipv4/netfilter/ipt_NOTRACK.c +++ b/net/netfilter/xt_NOTRACK.c | |||
@@ -4,9 +4,12 @@ | |||
4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
5 | #include <linux/skbuff.h> | 5 | #include <linux/skbuff.h> |
6 | 6 | ||
7 | #include <linux/netfilter_ipv4/ip_tables.h> | 7 | #include <linux/netfilter/x_tables.h> |
8 | #include <net/netfilter/nf_conntrack_compat.h> | 8 | #include <net/netfilter/nf_conntrack_compat.h> |
9 | 9 | ||
10 | MODULE_LICENSE("GPL"); | ||
11 | MODULE_ALIAS("ipt_NOTRACK"); | ||
12 | |||
10 | static unsigned int | 13 | static unsigned int |
11 | target(struct sk_buff **pskb, | 14 | target(struct sk_buff **pskb, |
12 | const struct net_device *in, | 15 | const struct net_device *in, |
@@ -17,7 +20,7 @@ target(struct sk_buff **pskb, | |||
17 | { | 20 | { |
18 | /* Previously seen (loopback)? Ignore. */ | 21 | /* Previously seen (loopback)? Ignore. */ |
19 | if ((*pskb)->nfct != NULL) | 22 | if ((*pskb)->nfct != NULL) |
20 | return IPT_CONTINUE; | 23 | return XT_CONTINUE; |
21 | 24 | ||
22 | /* Attach fake conntrack entry. | 25 | /* Attach fake conntrack entry. |
23 | If there is a real ct entry correspondig to this packet, | 26 | If there is a real ct entry correspondig to this packet, |
@@ -27,12 +30,12 @@ target(struct sk_buff **pskb, | |||
27 | (*pskb)->nfctinfo = IP_CT_NEW; | 30 | (*pskb)->nfctinfo = IP_CT_NEW; |
28 | nf_conntrack_get((*pskb)->nfct); | 31 | nf_conntrack_get((*pskb)->nfct); |
29 | 32 | ||
30 | return IPT_CONTINUE; | 33 | return XT_CONTINUE; |
31 | } | 34 | } |
32 | 35 | ||
33 | static int | 36 | static int |
34 | checkentry(const char *tablename, | 37 | checkentry(const char *tablename, |
35 | const struct ipt_entry *e, | 38 | const void *entry, |
36 | void *targinfo, | 39 | void *targinfo, |
37 | unsigned int targinfosize, | 40 | unsigned int targinfosize, |
38 | unsigned int hook_mask) | 41 | unsigned int hook_mask) |
@@ -51,26 +54,39 @@ checkentry(const char *tablename, | |||
51 | return 1; | 54 | return 1; |
52 | } | 55 | } |
53 | 56 | ||
54 | static struct ipt_target ipt_notrack_reg = { | 57 | static struct xt_target notrack_reg = { |
55 | .name = "NOTRACK", | 58 | .name = "NOTRACK", |
56 | .target = target, | 59 | .target = target, |
57 | .checkentry = checkentry, | 60 | .checkentry = checkentry, |
58 | .me = THIS_MODULE | 61 | .me = THIS_MODULE, |
62 | }; | ||
63 | static struct xt_target notrack6_reg = { | ||
64 | .name = "NOTRACK", | ||
65 | .target = target, | ||
66 | .checkentry = checkentry, | ||
67 | .me = THIS_MODULE, | ||
59 | }; | 68 | }; |
60 | 69 | ||
61 | static int __init init(void) | 70 | static int __init init(void) |
62 | { | 71 | { |
63 | if (ipt_register_target(&ipt_notrack_reg)) | 72 | int ret; |
64 | return -EINVAL; | 73 | |
74 | ret = xt_register_target(AF_INET, ¬rack_reg); | ||
75 | if (ret) | ||
76 | return ret; | ||
65 | 77 | ||
66 | return 0; | 78 | ret = xt_register_target(AF_INET6, ¬rack6_reg); |
79 | if (ret) | ||
80 | xt_unregister_target(AF_INET, ¬rack_reg); | ||
81 | |||
82 | return ret; | ||
67 | } | 83 | } |
68 | 84 | ||
69 | static void __exit fini(void) | 85 | static void __exit fini(void) |
70 | { | 86 | { |
71 | ipt_unregister_target(&ipt_notrack_reg); | 87 | xt_unregister_target(AF_INET6, ¬rack6_reg); |
88 | xt_unregister_target(AF_INET, ¬rack_reg); | ||
72 | } | 89 | } |
73 | 90 | ||
74 | module_init(init); | 91 | module_init(init); |
75 | module_exit(fini); | 92 | module_exit(fini); |
76 | MODULE_LICENSE("GPL"); | ||
diff --git a/net/ipv4/netfilter/ipt_comment.c b/net/netfilter/xt_comment.c index 6b76a1ea5245..4ba6fd65c6e9 100644 --- a/net/ipv4/netfilter/ipt_comment.c +++ b/net/netfilter/xt_comment.c | |||
@@ -6,12 +6,14 @@ | |||
6 | 6 | ||
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/skbuff.h> | 8 | #include <linux/skbuff.h> |
9 | #include <linux/netfilter_ipv4/ip_tables.h> | 9 | #include <linux/netfilter/x_tables.h> |
10 | #include <linux/netfilter_ipv4/ipt_comment.h> | 10 | #include <linux/netfilter/xt_comment.h> |
11 | 11 | ||
12 | MODULE_AUTHOR("Brad Fisher <brad@info-link.net>"); | 12 | MODULE_AUTHOR("Brad Fisher <brad@info-link.net>"); |
13 | MODULE_DESCRIPTION("iptables comment match module"); | 13 | MODULE_DESCRIPTION("iptables comment match module"); |
14 | MODULE_LICENSE("GPL"); | 14 | MODULE_LICENSE("GPL"); |
15 | MODULE_ALIAS("ipt_comment"); | ||
16 | MODULE_ALIAS("ip6t_comment"); | ||
15 | 17 | ||
16 | static int | 18 | static int |
17 | match(const struct sk_buff *skb, | 19 | match(const struct sk_buff *skb, |
@@ -19,6 +21,7 @@ match(const struct sk_buff *skb, | |||
19 | const struct net_device *out, | 21 | const struct net_device *out, |
20 | const void *matchinfo, | 22 | const void *matchinfo, |
21 | int offset, | 23 | int offset, |
24 | unsigned int protooff, | ||
22 | int *hotdrop) | 25 | int *hotdrop) |
23 | { | 26 | { |
24 | /* We always match */ | 27 | /* We always match */ |
@@ -27,18 +30,25 @@ match(const struct sk_buff *skb, | |||
27 | 30 | ||
28 | static int | 31 | static int |
29 | checkentry(const char *tablename, | 32 | checkentry(const char *tablename, |
30 | const struct ipt_ip *ip, | 33 | const void *ip, |
31 | void *matchinfo, | 34 | void *matchinfo, |
32 | unsigned int matchsize, | 35 | unsigned int matchsize, |
33 | unsigned int hook_mask) | 36 | unsigned int hook_mask) |
34 | { | 37 | { |
35 | /* Check the size */ | 38 | /* Check the size */ |
36 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_comment_info))) | 39 | if (matchsize != XT_ALIGN(sizeof(struct xt_comment_info))) |
37 | return 0; | 40 | return 0; |
38 | return 1; | 41 | return 1; |
39 | } | 42 | } |
40 | 43 | ||
41 | static struct ipt_match comment_match = { | 44 | static struct xt_match comment_match = { |
45 | .name = "comment", | ||
46 | .match = match, | ||
47 | .checkentry = checkentry, | ||
48 | .me = THIS_MODULE | ||
49 | }; | ||
50 | |||
51 | static struct xt_match comment6_match = { | ||
42 | .name = "comment", | 52 | .name = "comment", |
43 | .match = match, | 53 | .match = match, |
44 | .checkentry = checkentry, | 54 | .checkentry = checkentry, |
@@ -47,12 +57,23 @@ static struct ipt_match comment_match = { | |||
47 | 57 | ||
48 | static int __init init(void) | 58 | static int __init init(void) |
49 | { | 59 | { |
50 | return ipt_register_match(&comment_match); | 60 | int ret; |
61 | |||
62 | ret = xt_register_match(AF_INET, &comment_match); | ||
63 | if (ret) | ||
64 | return ret; | ||
65 | |||
66 | ret = xt_register_match(AF_INET6, &comment6_match); | ||
67 | if (ret) | ||
68 | xt_unregister_match(AF_INET, &comment_match); | ||
69 | |||
70 | return ret; | ||
51 | } | 71 | } |
52 | 72 | ||
53 | static void __exit fini(void) | 73 | static void __exit fini(void) |
54 | { | 74 | { |
55 | ipt_unregister_match(&comment_match); | 75 | xt_unregister_match(AF_INET, &comment_match); |
76 | xt_unregister_match(AF_INET6, &comment6_match); | ||
56 | } | 77 | } |
57 | 78 | ||
58 | module_init(init); | 79 | module_init(init); |
diff --git a/net/ipv4/netfilter/ipt_connbytes.c b/net/netfilter/xt_connbytes.c index d68a048b7176..150d2a4b0f71 100644 --- a/net/ipv4/netfilter/ipt_connbytes.c +++ b/net/netfilter/xt_connbytes.c | |||
@@ -6,13 +6,15 @@ | |||
6 | * - add functionality to match number of packets | 6 | * - add functionality to match number of packets |
7 | * - add functionality to match average packet size | 7 | * - add functionality to match average packet size |
8 | * - add support to match directions seperately | 8 | * - add support to match directions seperately |
9 | * 2005-10-16 Harald Welte <laforge@netfilter.org> | ||
10 | * - Port to x_tables | ||
9 | * | 11 | * |
10 | */ | 12 | */ |
11 | #include <linux/module.h> | 13 | #include <linux/module.h> |
12 | #include <linux/skbuff.h> | 14 | #include <linux/skbuff.h> |
13 | #include <net/netfilter/nf_conntrack_compat.h> | 15 | #include <net/netfilter/nf_conntrack_compat.h> |
14 | #include <linux/netfilter_ipv4/ip_tables.h> | 16 | #include <linux/netfilter/x_tables.h> |
15 | #include <linux/netfilter_ipv4/ipt_connbytes.h> | 17 | #include <linux/netfilter/xt_connbytes.h> |
16 | 18 | ||
17 | #include <asm/div64.h> | 19 | #include <asm/div64.h> |
18 | #include <asm/bitops.h> | 20 | #include <asm/bitops.h> |
@@ -20,6 +22,7 @@ | |||
20 | MODULE_LICENSE("GPL"); | 22 | MODULE_LICENSE("GPL"); |
21 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | 23 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); |
22 | MODULE_DESCRIPTION("iptables match for matching number of pkts/bytes per connection"); | 24 | MODULE_DESCRIPTION("iptables match for matching number of pkts/bytes per connection"); |
25 | MODULE_ALIAS("ipt_connbytes"); | ||
23 | 26 | ||
24 | /* 64bit divisor, dividend and result. dynamic precision */ | 27 | /* 64bit divisor, dividend and result. dynamic precision */ |
25 | static u_int64_t div64_64(u_int64_t dividend, u_int64_t divisor) | 28 | static u_int64_t div64_64(u_int64_t dividend, u_int64_t divisor) |
@@ -43,9 +46,10 @@ match(const struct sk_buff *skb, | |||
43 | const struct net_device *out, | 46 | const struct net_device *out, |
44 | const void *matchinfo, | 47 | const void *matchinfo, |
45 | int offset, | 48 | int offset, |
49 | unsigned int protoff, | ||
46 | int *hotdrop) | 50 | int *hotdrop) |
47 | { | 51 | { |
48 | const struct ipt_connbytes_info *sinfo = matchinfo; | 52 | const struct xt_connbytes_info *sinfo = matchinfo; |
49 | u_int64_t what = 0; /* initialize to make gcc happy */ | 53 | u_int64_t what = 0; /* initialize to make gcc happy */ |
50 | const struct ip_conntrack_counter *counters; | 54 | const struct ip_conntrack_counter *counters; |
51 | 55 | ||
@@ -53,45 +57,45 @@ match(const struct sk_buff *skb, | |||
53 | return 0; /* no match */ | 57 | return 0; /* no match */ |
54 | 58 | ||
55 | switch (sinfo->what) { | 59 | switch (sinfo->what) { |
56 | case IPT_CONNBYTES_PKTS: | 60 | case XT_CONNBYTES_PKTS: |
57 | switch (sinfo->direction) { | 61 | switch (sinfo->direction) { |
58 | case IPT_CONNBYTES_DIR_ORIGINAL: | 62 | case XT_CONNBYTES_DIR_ORIGINAL: |
59 | what = counters[IP_CT_DIR_ORIGINAL].packets; | 63 | what = counters[IP_CT_DIR_ORIGINAL].packets; |
60 | break; | 64 | break; |
61 | case IPT_CONNBYTES_DIR_REPLY: | 65 | case XT_CONNBYTES_DIR_REPLY: |
62 | what = counters[IP_CT_DIR_REPLY].packets; | 66 | what = counters[IP_CT_DIR_REPLY].packets; |
63 | break; | 67 | break; |
64 | case IPT_CONNBYTES_DIR_BOTH: | 68 | case XT_CONNBYTES_DIR_BOTH: |
65 | what = counters[IP_CT_DIR_ORIGINAL].packets; | 69 | what = counters[IP_CT_DIR_ORIGINAL].packets; |
66 | what += counters[IP_CT_DIR_REPLY].packets; | 70 | what += counters[IP_CT_DIR_REPLY].packets; |
67 | break; | 71 | break; |
68 | } | 72 | } |
69 | break; | 73 | break; |
70 | case IPT_CONNBYTES_BYTES: | 74 | case XT_CONNBYTES_BYTES: |
71 | switch (sinfo->direction) { | 75 | switch (sinfo->direction) { |
72 | case IPT_CONNBYTES_DIR_ORIGINAL: | 76 | case XT_CONNBYTES_DIR_ORIGINAL: |
73 | what = counters[IP_CT_DIR_ORIGINAL].bytes; | 77 | what = counters[IP_CT_DIR_ORIGINAL].bytes; |
74 | break; | 78 | break; |
75 | case IPT_CONNBYTES_DIR_REPLY: | 79 | case XT_CONNBYTES_DIR_REPLY: |
76 | what = counters[IP_CT_DIR_REPLY].bytes; | 80 | what = counters[IP_CT_DIR_REPLY].bytes; |
77 | break; | 81 | break; |
78 | case IPT_CONNBYTES_DIR_BOTH: | 82 | case XT_CONNBYTES_DIR_BOTH: |
79 | what = counters[IP_CT_DIR_ORIGINAL].bytes; | 83 | what = counters[IP_CT_DIR_ORIGINAL].bytes; |
80 | what += counters[IP_CT_DIR_REPLY].bytes; | 84 | what += counters[IP_CT_DIR_REPLY].bytes; |
81 | break; | 85 | break; |
82 | } | 86 | } |
83 | break; | 87 | break; |
84 | case IPT_CONNBYTES_AVGPKT: | 88 | case XT_CONNBYTES_AVGPKT: |
85 | switch (sinfo->direction) { | 89 | switch (sinfo->direction) { |
86 | case IPT_CONNBYTES_DIR_ORIGINAL: | 90 | case XT_CONNBYTES_DIR_ORIGINAL: |
87 | what = div64_64(counters[IP_CT_DIR_ORIGINAL].bytes, | 91 | what = div64_64(counters[IP_CT_DIR_ORIGINAL].bytes, |
88 | counters[IP_CT_DIR_ORIGINAL].packets); | 92 | counters[IP_CT_DIR_ORIGINAL].packets); |
89 | break; | 93 | break; |
90 | case IPT_CONNBYTES_DIR_REPLY: | 94 | case XT_CONNBYTES_DIR_REPLY: |
91 | what = div64_64(counters[IP_CT_DIR_REPLY].bytes, | 95 | what = div64_64(counters[IP_CT_DIR_REPLY].bytes, |
92 | counters[IP_CT_DIR_REPLY].packets); | 96 | counters[IP_CT_DIR_REPLY].packets); |
93 | break; | 97 | break; |
94 | case IPT_CONNBYTES_DIR_BOTH: | 98 | case XT_CONNBYTES_DIR_BOTH: |
95 | { | 99 | { |
96 | u_int64_t bytes; | 100 | u_int64_t bytes; |
97 | u_int64_t pkts; | 101 | u_int64_t pkts; |
@@ -117,30 +121,36 @@ match(const struct sk_buff *skb, | |||
117 | } | 121 | } |
118 | 122 | ||
119 | static int check(const char *tablename, | 123 | static int check(const char *tablename, |
120 | const struct ipt_ip *ip, | 124 | const void *ip, |
121 | void *matchinfo, | 125 | void *matchinfo, |
122 | unsigned int matchsize, | 126 | unsigned int matchsize, |
123 | unsigned int hook_mask) | 127 | unsigned int hook_mask) |
124 | { | 128 | { |
125 | const struct ipt_connbytes_info *sinfo = matchinfo; | 129 | const struct xt_connbytes_info *sinfo = matchinfo; |
126 | 130 | ||
127 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_connbytes_info))) | 131 | if (matchsize != XT_ALIGN(sizeof(struct xt_connbytes_info))) |
128 | return 0; | 132 | return 0; |
129 | 133 | ||
130 | if (sinfo->what != IPT_CONNBYTES_PKTS && | 134 | if (sinfo->what != XT_CONNBYTES_PKTS && |
131 | sinfo->what != IPT_CONNBYTES_BYTES && | 135 | sinfo->what != XT_CONNBYTES_BYTES && |
132 | sinfo->what != IPT_CONNBYTES_AVGPKT) | 136 | sinfo->what != XT_CONNBYTES_AVGPKT) |
133 | return 0; | 137 | return 0; |
134 | 138 | ||
135 | if (sinfo->direction != IPT_CONNBYTES_DIR_ORIGINAL && | 139 | if (sinfo->direction != XT_CONNBYTES_DIR_ORIGINAL && |
136 | sinfo->direction != IPT_CONNBYTES_DIR_REPLY && | 140 | sinfo->direction != XT_CONNBYTES_DIR_REPLY && |
137 | sinfo->direction != IPT_CONNBYTES_DIR_BOTH) | 141 | sinfo->direction != XT_CONNBYTES_DIR_BOTH) |
138 | return 0; | 142 | return 0; |
139 | 143 | ||
140 | return 1; | 144 | return 1; |
141 | } | 145 | } |
142 | 146 | ||
143 | static struct ipt_match state_match = { | 147 | static struct xt_match connbytes_match = { |
148 | .name = "connbytes", | ||
149 | .match = &match, | ||
150 | .checkentry = &check, | ||
151 | .me = THIS_MODULE | ||
152 | }; | ||
153 | static struct xt_match connbytes6_match = { | ||
144 | .name = "connbytes", | 154 | .name = "connbytes", |
145 | .match = &match, | 155 | .match = &match, |
146 | .checkentry = &check, | 156 | .checkentry = &check, |
@@ -149,12 +159,21 @@ static struct ipt_match state_match = { | |||
149 | 159 | ||
150 | static int __init init(void) | 160 | static int __init init(void) |
151 | { | 161 | { |
152 | return ipt_register_match(&state_match); | 162 | int ret; |
163 | ret = xt_register_match(AF_INET, &connbytes_match); | ||
164 | if (ret) | ||
165 | return ret; | ||
166 | |||
167 | ret = xt_register_match(AF_INET6, &connbytes6_match); | ||
168 | if (ret) | ||
169 | xt_unregister_match(AF_INET, &connbytes_match); | ||
170 | return ret; | ||
153 | } | 171 | } |
154 | 172 | ||
155 | static void __exit fini(void) | 173 | static void __exit fini(void) |
156 | { | 174 | { |
157 | ipt_unregister_match(&state_match); | 175 | xt_unregister_match(AF_INET, &connbytes_match); |
176 | xt_unregister_match(AF_INET6, &connbytes6_match); | ||
158 | } | 177 | } |
159 | 178 | ||
160 | module_init(init); | 179 | module_init(init); |
diff --git a/net/ipv4/netfilter/ipt_connmark.c b/net/netfilter/xt_connmark.c index 5306ef293b92..d06e925032da 100644 --- a/net/ipv4/netfilter/ipt_connmark.c +++ b/net/netfilter/xt_connmark.c | |||
@@ -25,9 +25,10 @@ | |||
25 | MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>"); | 25 | MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>"); |
26 | MODULE_DESCRIPTION("IP tables connmark match module"); | 26 | MODULE_DESCRIPTION("IP tables connmark match module"); |
27 | MODULE_LICENSE("GPL"); | 27 | MODULE_LICENSE("GPL"); |
28 | MODULE_ALIAS("ipt_connmark"); | ||
28 | 29 | ||
29 | #include <linux/netfilter_ipv4/ip_tables.h> | 30 | #include <linux/netfilter/x_tables.h> |
30 | #include <linux/netfilter_ipv4/ipt_connmark.h> | 31 | #include <linux/netfilter/xt_connmark.h> |
31 | #include <net/netfilter/nf_conntrack_compat.h> | 32 | #include <net/netfilter/nf_conntrack_compat.h> |
32 | 33 | ||
33 | static int | 34 | static int |
@@ -36,9 +37,10 @@ match(const struct sk_buff *skb, | |||
36 | const struct net_device *out, | 37 | const struct net_device *out, |
37 | const void *matchinfo, | 38 | const void *matchinfo, |
38 | int offset, | 39 | int offset, |
40 | unsigned int protoff, | ||
39 | int *hotdrop) | 41 | int *hotdrop) |
40 | { | 42 | { |
41 | const struct ipt_connmark_info *info = matchinfo; | 43 | const struct xt_connmark_info *info = matchinfo; |
42 | u_int32_t ctinfo; | 44 | u_int32_t ctinfo; |
43 | const u_int32_t *ctmark = nf_ct_get_mark(skb, &ctinfo); | 45 | const u_int32_t *ctmark = nf_ct_get_mark(skb, &ctinfo); |
44 | if (!ctmark) | 46 | if (!ctmark) |
@@ -49,14 +51,14 @@ match(const struct sk_buff *skb, | |||
49 | 51 | ||
50 | static int | 52 | static int |
51 | checkentry(const char *tablename, | 53 | checkentry(const char *tablename, |
52 | const struct ipt_ip *ip, | 54 | const void *ip, |
53 | void *matchinfo, | 55 | void *matchinfo, |
54 | unsigned int matchsize, | 56 | unsigned int matchsize, |
55 | unsigned int hook_mask) | 57 | unsigned int hook_mask) |
56 | { | 58 | { |
57 | struct ipt_connmark_info *cm = | 59 | struct xt_connmark_info *cm = |
58 | (struct ipt_connmark_info *)matchinfo; | 60 | (struct xt_connmark_info *)matchinfo; |
59 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_connmark_info))) | 61 | if (matchsize != XT_ALIGN(sizeof(struct xt_connmark_info))) |
60 | return 0; | 62 | return 0; |
61 | 63 | ||
62 | if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) { | 64 | if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) { |
@@ -67,21 +69,40 @@ checkentry(const char *tablename, | |||
67 | return 1; | 69 | return 1; |
68 | } | 70 | } |
69 | 71 | ||
70 | static struct ipt_match connmark_match = { | 72 | static struct xt_match connmark_match = { |
73 | .name = "connmark", | ||
74 | .match = &match, | ||
75 | .checkentry = &checkentry, | ||
76 | .me = THIS_MODULE | ||
77 | }; | ||
78 | static struct xt_match connmark6_match = { | ||
71 | .name = "connmark", | 79 | .name = "connmark", |
72 | .match = &match, | 80 | .match = &match, |
73 | .checkentry = &checkentry, | 81 | .checkentry = &checkentry, |
74 | .me = THIS_MODULE | 82 | .me = THIS_MODULE |
75 | }; | 83 | }; |
76 | 84 | ||
85 | |||
77 | static int __init init(void) | 86 | static int __init init(void) |
78 | { | 87 | { |
79 | return ipt_register_match(&connmark_match); | 88 | int ret; |
89 | |||
90 | need_conntrack(); | ||
91 | |||
92 | ret = xt_register_match(AF_INET, &connmark_match); | ||
93 | if (ret) | ||
94 | return ret; | ||
95 | |||
96 | ret = xt_register_match(AF_INET6, &connmark6_match); | ||
97 | if (ret) | ||
98 | xt_unregister_match(AF_INET, &connmark_match); | ||
99 | return ret; | ||
80 | } | 100 | } |
81 | 101 | ||
82 | static void __exit fini(void) | 102 | static void __exit fini(void) |
83 | { | 103 | { |
84 | ipt_unregister_match(&connmark_match); | 104 | xt_unregister_match(AF_INET6, &connmark6_match); |
105 | xt_unregister_match(AF_INET, &connmark_match); | ||
85 | } | 106 | } |
86 | 107 | ||
87 | module_init(init); | 108 | module_init(init); |
diff --git a/net/ipv4/netfilter/ipt_conntrack.c b/net/netfilter/xt_conntrack.c index c8d18705469b..ffdebc95eb95 100644 --- a/net/ipv4/netfilter/ipt_conntrack.c +++ b/net/netfilter/xt_conntrack.c | |||
@@ -18,12 +18,13 @@ | |||
18 | #include <net/netfilter/nf_conntrack.h> | 18 | #include <net/netfilter/nf_conntrack.h> |
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | #include <linux/netfilter_ipv4/ip_tables.h> | 21 | #include <linux/netfilter/x_tables.h> |
22 | #include <linux/netfilter_ipv4/ipt_conntrack.h> | 22 | #include <linux/netfilter/xt_conntrack.h> |
23 | 23 | ||
24 | MODULE_LICENSE("GPL"); | 24 | MODULE_LICENSE("GPL"); |
25 | MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); | 25 | MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); |
26 | MODULE_DESCRIPTION("iptables connection tracking match module"); | 26 | MODULE_DESCRIPTION("iptables connection tracking match module"); |
27 | MODULE_ALIAS("ipt_conntrack"); | ||
27 | 28 | ||
28 | #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) | 29 | #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) |
29 | 30 | ||
@@ -33,9 +34,10 @@ match(const struct sk_buff *skb, | |||
33 | const struct net_device *out, | 34 | const struct net_device *out, |
34 | const void *matchinfo, | 35 | const void *matchinfo, |
35 | int offset, | 36 | int offset, |
37 | unsigned int protoff, | ||
36 | int *hotdrop) | 38 | int *hotdrop) |
37 | { | 39 | { |
38 | const struct ipt_conntrack_info *sinfo = matchinfo; | 40 | const struct xt_conntrack_info *sinfo = matchinfo; |
39 | struct ip_conntrack *ct; | 41 | struct ip_conntrack *ct; |
40 | enum ip_conntrack_info ctinfo; | 42 | enum ip_conntrack_info ctinfo; |
41 | unsigned int statebit; | 43 | unsigned int statebit; |
@@ -45,58 +47,58 @@ match(const struct sk_buff *skb, | |||
45 | #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) | 47 | #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) |
46 | 48 | ||
47 | if (ct == &ip_conntrack_untracked) | 49 | if (ct == &ip_conntrack_untracked) |
48 | statebit = IPT_CONNTRACK_STATE_UNTRACKED; | 50 | statebit = XT_CONNTRACK_STATE_UNTRACKED; |
49 | else if (ct) | 51 | else if (ct) |
50 | statebit = IPT_CONNTRACK_STATE_BIT(ctinfo); | 52 | statebit = XT_CONNTRACK_STATE_BIT(ctinfo); |
51 | else | 53 | else |
52 | statebit = IPT_CONNTRACK_STATE_INVALID; | 54 | statebit = XT_CONNTRACK_STATE_INVALID; |
53 | 55 | ||
54 | if(sinfo->flags & IPT_CONNTRACK_STATE) { | 56 | if(sinfo->flags & XT_CONNTRACK_STATE) { |
55 | if (ct) { | 57 | if (ct) { |
56 | if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip != | 58 | if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip != |
57 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip) | 59 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip) |
58 | statebit |= IPT_CONNTRACK_STATE_SNAT; | 60 | statebit |= XT_CONNTRACK_STATE_SNAT; |
59 | 61 | ||
60 | if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip != | 62 | if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip != |
61 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip) | 63 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip) |
62 | statebit |= IPT_CONNTRACK_STATE_DNAT; | 64 | statebit |= XT_CONNTRACK_STATE_DNAT; |
63 | } | 65 | } |
64 | 66 | ||
65 | if (FWINV((statebit & sinfo->statemask) == 0, IPT_CONNTRACK_STATE)) | 67 | if (FWINV((statebit & sinfo->statemask) == 0, XT_CONNTRACK_STATE)) |
66 | return 0; | 68 | return 0; |
67 | } | 69 | } |
68 | 70 | ||
69 | if(sinfo->flags & IPT_CONNTRACK_PROTO) { | 71 | if(sinfo->flags & XT_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)) | 72 | if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, XT_CONNTRACK_PROTO)) |
71 | return 0; | 73 | return 0; |
72 | } | 74 | } |
73 | 75 | ||
74 | if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) { | 76 | if(sinfo->flags & XT_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)) | 77 | 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, XT_CONNTRACK_ORIGSRC)) |
76 | return 0; | 78 | return 0; |
77 | } | 79 | } |
78 | 80 | ||
79 | if(sinfo->flags & IPT_CONNTRACK_ORIGDST) { | 81 | if(sinfo->flags & XT_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)) | 82 | 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, XT_CONNTRACK_ORIGDST)) |
81 | return 0; | 83 | return 0; |
82 | } | 84 | } |
83 | 85 | ||
84 | if(sinfo->flags & IPT_CONNTRACK_REPLSRC) { | 86 | if(sinfo->flags & XT_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)) | 87 | 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, XT_CONNTRACK_REPLSRC)) |
86 | return 0; | 88 | return 0; |
87 | } | 89 | } |
88 | 90 | ||
89 | if(sinfo->flags & IPT_CONNTRACK_REPLDST) { | 91 | if(sinfo->flags & XT_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)) | 92 | 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, XT_CONNTRACK_REPLDST)) |
91 | return 0; | 93 | return 0; |
92 | } | 94 | } |
93 | 95 | ||
94 | if(sinfo->flags & IPT_CONNTRACK_STATUS) { | 96 | if(sinfo->flags & XT_CONNTRACK_STATUS) { |
95 | if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, IPT_CONNTRACK_STATUS)) | 97 | if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, XT_CONNTRACK_STATUS)) |
96 | return 0; | 98 | return 0; |
97 | } | 99 | } |
98 | 100 | ||
99 | if(sinfo->flags & IPT_CONNTRACK_EXPIRES) { | 101 | if(sinfo->flags & XT_CONNTRACK_EXPIRES) { |
100 | unsigned long expires; | 102 | unsigned long expires; |
101 | 103 | ||
102 | if(!ct) | 104 | if(!ct) |
@@ -104,7 +106,7 @@ match(const struct sk_buff *skb, | |||
104 | 106 | ||
105 | expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0; | 107 | expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0; |
106 | 108 | ||
107 | if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), IPT_CONNTRACK_EXPIRES)) | 109 | if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), XT_CONNTRACK_EXPIRES)) |
108 | return 0; | 110 | return 0; |
109 | } | 111 | } |
110 | 112 | ||
@@ -118,9 +120,10 @@ match(const struct sk_buff *skb, | |||
118 | const struct net_device *out, | 120 | const struct net_device *out, |
119 | const void *matchinfo, | 121 | const void *matchinfo, |
120 | int offset, | 122 | int offset, |
123 | unsigned int protoff, | ||
121 | int *hotdrop) | 124 | int *hotdrop) |
122 | { | 125 | { |
123 | const struct ipt_conntrack_info *sinfo = matchinfo; | 126 | const struct xt_conntrack_info *sinfo = matchinfo; |
124 | struct nf_conn *ct; | 127 | struct nf_conn *ct; |
125 | enum ip_conntrack_info ctinfo; | 128 | enum ip_conntrack_info ctinfo; |
126 | unsigned int statebit; | 129 | unsigned int statebit; |
@@ -130,58 +133,58 @@ match(const struct sk_buff *skb, | |||
130 | #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) | 133 | #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) |
131 | 134 | ||
132 | if (ct == &nf_conntrack_untracked) | 135 | if (ct == &nf_conntrack_untracked) |
133 | statebit = IPT_CONNTRACK_STATE_UNTRACKED; | 136 | statebit = XT_CONNTRACK_STATE_UNTRACKED; |
134 | else if (ct) | 137 | else if (ct) |
135 | statebit = IPT_CONNTRACK_STATE_BIT(ctinfo); | 138 | statebit = XT_CONNTRACK_STATE_BIT(ctinfo); |
136 | else | 139 | else |
137 | statebit = IPT_CONNTRACK_STATE_INVALID; | 140 | statebit = XT_CONNTRACK_STATE_INVALID; |
138 | 141 | ||
139 | if(sinfo->flags & IPT_CONNTRACK_STATE) { | 142 | if(sinfo->flags & XT_CONNTRACK_STATE) { |
140 | if (ct) { | 143 | if (ct) { |
141 | if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip != | 144 | if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip != |
142 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip) | 145 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip) |
143 | statebit |= IPT_CONNTRACK_STATE_SNAT; | 146 | statebit |= XT_CONNTRACK_STATE_SNAT; |
144 | 147 | ||
145 | if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip != | 148 | if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip != |
146 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip) | 149 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip) |
147 | statebit |= IPT_CONNTRACK_STATE_DNAT; | 150 | statebit |= XT_CONNTRACK_STATE_DNAT; |
148 | } | 151 | } |
149 | 152 | ||
150 | if (FWINV((statebit & sinfo->statemask) == 0, IPT_CONNTRACK_STATE)) | 153 | if (FWINV((statebit & sinfo->statemask) == 0, XT_CONNTRACK_STATE)) |
151 | return 0; | 154 | return 0; |
152 | } | 155 | } |
153 | 156 | ||
154 | if(sinfo->flags & IPT_CONNTRACK_PROTO) { | 157 | if(sinfo->flags & XT_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)) | 158 | if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, XT_CONNTRACK_PROTO)) |
156 | return 0; | 159 | return 0; |
157 | } | 160 | } |
158 | 161 | ||
159 | if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) { | 162 | if(sinfo->flags & XT_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)) | 163 | 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, XT_CONNTRACK_ORIGSRC)) |
161 | return 0; | 164 | return 0; |
162 | } | 165 | } |
163 | 166 | ||
164 | if(sinfo->flags & IPT_CONNTRACK_ORIGDST) { | 167 | if(sinfo->flags & XT_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)) | 168 | 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, XT_CONNTRACK_ORIGDST)) |
166 | return 0; | 169 | return 0; |
167 | } | 170 | } |
168 | 171 | ||
169 | if(sinfo->flags & IPT_CONNTRACK_REPLSRC) { | 172 | if(sinfo->flags & XT_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)) | 173 | 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, XT_CONNTRACK_REPLSRC)) |
171 | return 0; | 174 | return 0; |
172 | } | 175 | } |
173 | 176 | ||
174 | if(sinfo->flags & IPT_CONNTRACK_REPLDST) { | 177 | if(sinfo->flags & XT_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)) | 178 | 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, XT_CONNTRACK_REPLDST)) |
176 | return 0; | 179 | return 0; |
177 | } | 180 | } |
178 | 181 | ||
179 | if(sinfo->flags & IPT_CONNTRACK_STATUS) { | 182 | if(sinfo->flags & XT_CONNTRACK_STATUS) { |
180 | if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, IPT_CONNTRACK_STATUS)) | 183 | if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, XT_CONNTRACK_STATUS)) |
181 | return 0; | 184 | return 0; |
182 | } | 185 | } |
183 | 186 | ||
184 | if(sinfo->flags & IPT_CONNTRACK_EXPIRES) { | 187 | if(sinfo->flags & XT_CONNTRACK_EXPIRES) { |
185 | unsigned long expires; | 188 | unsigned long expires; |
186 | 189 | ||
187 | if(!ct) | 190 | if(!ct) |
@@ -189,7 +192,7 @@ match(const struct sk_buff *skb, | |||
189 | 192 | ||
190 | expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0; | 193 | expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0; |
191 | 194 | ||
192 | if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), IPT_CONNTRACK_EXPIRES)) | 195 | if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), XT_CONNTRACK_EXPIRES)) |
193 | return 0; | 196 | return 0; |
194 | } | 197 | } |
195 | 198 | ||
@@ -199,18 +202,18 @@ match(const struct sk_buff *skb, | |||
199 | #endif /* CONFIG_NF_IP_CONNTRACK */ | 202 | #endif /* CONFIG_NF_IP_CONNTRACK */ |
200 | 203 | ||
201 | static int check(const char *tablename, | 204 | static int check(const char *tablename, |
202 | const struct ipt_ip *ip, | 205 | const void *ip, |
203 | void *matchinfo, | 206 | void *matchinfo, |
204 | unsigned int matchsize, | 207 | unsigned int matchsize, |
205 | unsigned int hook_mask) | 208 | unsigned int hook_mask) |
206 | { | 209 | { |
207 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_conntrack_info))) | 210 | if (matchsize != XT_ALIGN(sizeof(struct xt_conntrack_info))) |
208 | return 0; | 211 | return 0; |
209 | 212 | ||
210 | return 1; | 213 | return 1; |
211 | } | 214 | } |
212 | 215 | ||
213 | static struct ipt_match conntrack_match = { | 216 | static struct xt_match conntrack_match = { |
214 | .name = "conntrack", | 217 | .name = "conntrack", |
215 | .match = &match, | 218 | .match = &match, |
216 | .checkentry = &check, | 219 | .checkentry = &check, |
@@ -219,13 +222,16 @@ static struct ipt_match conntrack_match = { | |||
219 | 222 | ||
220 | static int __init init(void) | 223 | static int __init init(void) |
221 | { | 224 | { |
222 | need_ip_conntrack(); | 225 | int ret; |
223 | return ipt_register_match(&conntrack_match); | 226 | need_conntrack(); |
227 | ret = xt_register_match(AF_INET, &conntrack_match); | ||
228 | |||
229 | return ret; | ||
224 | } | 230 | } |
225 | 231 | ||
226 | static void __exit fini(void) | 232 | static void __exit fini(void) |
227 | { | 233 | { |
228 | ipt_unregister_match(&conntrack_match); | 234 | xt_unregister_match(AF_INET, &conntrack_match); |
229 | } | 235 | } |
230 | 236 | ||
231 | module_init(init); | 237 | module_init(init); |
diff --git a/net/ipv4/netfilter/ipt_dccp.c b/net/netfilter/xt_dccp.c index ad3278bba6c1..779f42fc9524 100644 --- a/net/ipv4/netfilter/ipt_dccp.c +++ b/net/netfilter/xt_dccp.c | |||
@@ -14,8 +14,16 @@ | |||
14 | #include <net/ip.h> | 14 | #include <net/ip.h> |
15 | #include <linux/dccp.h> | 15 | #include <linux/dccp.h> |
16 | 16 | ||
17 | #include <linux/netfilter/x_tables.h> | ||
18 | #include <linux/netfilter/xt_dccp.h> | ||
19 | |||
17 | #include <linux/netfilter_ipv4/ip_tables.h> | 20 | #include <linux/netfilter_ipv4/ip_tables.h> |
18 | #include <linux/netfilter_ipv4/ipt_dccp.h> | 21 | #include <linux/netfilter_ipv6/ip6_tables.h> |
22 | |||
23 | MODULE_LICENSE("GPL"); | ||
24 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | ||
25 | MODULE_DESCRIPTION("Match for DCCP protocol packets"); | ||
26 | MODULE_ALIAS("ipt_dccp"); | ||
19 | 27 | ||
20 | #define DCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \ | 28 | #define DCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \ |
21 | || (!!((invflag) & (option)) ^ (cond))) | 29 | || (!!((invflag) & (option)) ^ (cond))) |
@@ -26,6 +34,7 @@ static DEFINE_SPINLOCK(dccp_buflock); | |||
26 | static inline int | 34 | static inline int |
27 | dccp_find_option(u_int8_t option, | 35 | dccp_find_option(u_int8_t option, |
28 | const struct sk_buff *skb, | 36 | const struct sk_buff *skb, |
37 | unsigned int protoff, | ||
29 | const struct dccp_hdr *dh, | 38 | const struct dccp_hdr *dh, |
30 | int *hotdrop) | 39 | int *hotdrop) |
31 | { | 40 | { |
@@ -44,9 +53,7 @@ dccp_find_option(u_int8_t option, | |||
44 | return 0; | 53 | return 0; |
45 | 54 | ||
46 | spin_lock_bh(&dccp_buflock); | 55 | spin_lock_bh(&dccp_buflock); |
47 | op = skb_header_pointer(skb, | 56 | op = skb_header_pointer(skb, protoff + optoff, optlen, dccp_optbuf); |
48 | skb->nh.iph->ihl*4 + optoff, | ||
49 | optlen, dccp_optbuf); | ||
50 | if (op == NULL) { | 57 | if (op == NULL) { |
51 | /* If we don't have the whole header, drop packet. */ | 58 | /* If we don't have the whole header, drop packet. */ |
52 | spin_unlock_bh(&dccp_buflock); | 59 | spin_unlock_bh(&dccp_buflock); |
@@ -78,10 +85,10 @@ match_types(const struct dccp_hdr *dh, u_int16_t typemask) | |||
78 | } | 85 | } |
79 | 86 | ||
80 | static inline int | 87 | static inline int |
81 | match_option(u_int8_t option, const struct sk_buff *skb, | 88 | match_option(u_int8_t option, const struct sk_buff *skb, unsigned int protoff, |
82 | const struct dccp_hdr *dh, int *hotdrop) | 89 | const struct dccp_hdr *dh, int *hotdrop) |
83 | { | 90 | { |
84 | return dccp_find_option(option, skb, dh, hotdrop); | 91 | return dccp_find_option(option, skb, protoff, dh, hotdrop); |
85 | } | 92 | } |
86 | 93 | ||
87 | static int | 94 | static int |
@@ -90,16 +97,17 @@ match(const struct sk_buff *skb, | |||
90 | const struct net_device *out, | 97 | const struct net_device *out, |
91 | const void *matchinfo, | 98 | const void *matchinfo, |
92 | int offset, | 99 | int offset, |
100 | unsigned int protoff, | ||
93 | int *hotdrop) | 101 | int *hotdrop) |
94 | { | 102 | { |
95 | const struct ipt_dccp_info *info = | 103 | const struct xt_dccp_info *info = |
96 | (const struct ipt_dccp_info *)matchinfo; | 104 | (const struct xt_dccp_info *)matchinfo; |
97 | struct dccp_hdr _dh, *dh; | 105 | struct dccp_hdr _dh, *dh; |
98 | 106 | ||
99 | if (offset) | 107 | if (offset) |
100 | return 0; | 108 | return 0; |
101 | 109 | ||
102 | dh = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_dh), &_dh); | 110 | dh = skb_header_pointer(skb, protoff, sizeof(_dh), &_dh); |
103 | if (dh == NULL) { | 111 | if (dh == NULL) { |
104 | *hotdrop = 1; | 112 | *hotdrop = 1; |
105 | return 0; | 113 | return 0; |
@@ -107,42 +115,73 @@ match(const struct sk_buff *skb, | |||
107 | 115 | ||
108 | return DCCHECK(((ntohs(dh->dccph_sport) >= info->spts[0]) | 116 | return DCCHECK(((ntohs(dh->dccph_sport) >= info->spts[0]) |
109 | && (ntohs(dh->dccph_sport) <= info->spts[1])), | 117 | && (ntohs(dh->dccph_sport) <= info->spts[1])), |
110 | IPT_DCCP_SRC_PORTS, info->flags, info->invflags) | 118 | XT_DCCP_SRC_PORTS, info->flags, info->invflags) |
111 | && DCCHECK(((ntohs(dh->dccph_dport) >= info->dpts[0]) | 119 | && DCCHECK(((ntohs(dh->dccph_dport) >= info->dpts[0]) |
112 | && (ntohs(dh->dccph_dport) <= info->dpts[1])), | 120 | && (ntohs(dh->dccph_dport) <= info->dpts[1])), |
113 | IPT_DCCP_DEST_PORTS, info->flags, info->invflags) | 121 | XT_DCCP_DEST_PORTS, info->flags, info->invflags) |
114 | && DCCHECK(match_types(dh, info->typemask), | 122 | && DCCHECK(match_types(dh, info->typemask), |
115 | IPT_DCCP_TYPE, info->flags, info->invflags) | 123 | XT_DCCP_TYPE, info->flags, info->invflags) |
116 | && DCCHECK(match_option(info->option, skb, dh, hotdrop), | 124 | && DCCHECK(match_option(info->option, skb, protoff, dh, |
117 | IPT_DCCP_OPTION, info->flags, info->invflags); | 125 | hotdrop), |
126 | XT_DCCP_OPTION, info->flags, info->invflags); | ||
118 | } | 127 | } |
119 | 128 | ||
120 | static int | 129 | static int |
121 | checkentry(const char *tablename, | 130 | checkentry(const char *tablename, |
122 | const struct ipt_ip *ip, | 131 | const void *inf, |
123 | void *matchinfo, | 132 | void *matchinfo, |
124 | unsigned int matchsize, | 133 | unsigned int matchsize, |
125 | unsigned int hook_mask) | 134 | unsigned int hook_mask) |
126 | { | 135 | { |
127 | const struct ipt_dccp_info *info; | 136 | const struct ipt_ip *ip = inf; |
137 | const struct xt_dccp_info *info; | ||
128 | 138 | ||
129 | info = (const struct ipt_dccp_info *)matchinfo; | 139 | info = (const struct xt_dccp_info *)matchinfo; |
130 | 140 | ||
131 | return ip->proto == IPPROTO_DCCP | 141 | return ip->proto == IPPROTO_DCCP |
132 | && !(ip->invflags & IPT_INV_PROTO) | 142 | && !(ip->invflags & XT_INV_PROTO) |
133 | && matchsize == IPT_ALIGN(sizeof(struct ipt_dccp_info)) | 143 | && matchsize == XT_ALIGN(sizeof(struct xt_dccp_info)) |
134 | && !(info->flags & ~IPT_DCCP_VALID_FLAGS) | 144 | && !(info->flags & ~XT_DCCP_VALID_FLAGS) |
135 | && !(info->invflags & ~IPT_DCCP_VALID_FLAGS) | 145 | && !(info->invflags & ~XT_DCCP_VALID_FLAGS) |
136 | && !(info->invflags & ~info->flags); | 146 | && !(info->invflags & ~info->flags); |
137 | } | 147 | } |
138 | 148 | ||
139 | static struct ipt_match dccp_match = | 149 | static int |
150 | checkentry6(const char *tablename, | ||
151 | const void *inf, | ||
152 | void *matchinfo, | ||
153 | unsigned int matchsize, | ||
154 | unsigned int hook_mask) | ||
155 | { | ||
156 | const struct ip6t_ip6 *ip = inf; | ||
157 | const struct xt_dccp_info *info; | ||
158 | |||
159 | info = (const struct xt_dccp_info *)matchinfo; | ||
160 | |||
161 | return ip->proto == IPPROTO_DCCP | ||
162 | && !(ip->invflags & XT_INV_PROTO) | ||
163 | && matchsize == XT_ALIGN(sizeof(struct xt_dccp_info)) | ||
164 | && !(info->flags & ~XT_DCCP_VALID_FLAGS) | ||
165 | && !(info->invflags & ~XT_DCCP_VALID_FLAGS) | ||
166 | && !(info->invflags & ~info->flags); | ||
167 | } | ||
168 | |||
169 | |||
170 | static struct xt_match dccp_match = | ||
140 | { | 171 | { |
141 | .name = "dccp", | 172 | .name = "dccp", |
142 | .match = &match, | 173 | .match = &match, |
143 | .checkentry = &checkentry, | 174 | .checkentry = &checkentry, |
144 | .me = THIS_MODULE, | 175 | .me = THIS_MODULE, |
145 | }; | 176 | }; |
177 | static struct xt_match dccp6_match = | ||
178 | { | ||
179 | .name = "dccp", | ||
180 | .match = &match, | ||
181 | .checkentry = &checkentry6, | ||
182 | .me = THIS_MODULE, | ||
183 | }; | ||
184 | |||
146 | 185 | ||
147 | static int __init init(void) | 186 | static int __init init(void) |
148 | { | 187 | { |
@@ -154,23 +193,29 @@ static int __init init(void) | |||
154 | dccp_optbuf = kmalloc(256 * 4, GFP_KERNEL); | 193 | dccp_optbuf = kmalloc(256 * 4, GFP_KERNEL); |
155 | if (!dccp_optbuf) | 194 | if (!dccp_optbuf) |
156 | return -ENOMEM; | 195 | return -ENOMEM; |
157 | ret = ipt_register_match(&dccp_match); | 196 | ret = xt_register_match(AF_INET, &dccp_match); |
158 | if (ret) | 197 | if (ret) |
159 | kfree(dccp_optbuf); | 198 | goto out_kfree; |
199 | ret = xt_register_match(AF_INET6, &dccp6_match); | ||
200 | if (ret) | ||
201 | goto out_unreg; | ||
202 | |||
203 | return ret; | ||
204 | |||
205 | out_unreg: | ||
206 | xt_unregister_match(AF_INET, &dccp_match); | ||
207 | out_kfree: | ||
208 | kfree(dccp_optbuf); | ||
160 | 209 | ||
161 | return ret; | 210 | return ret; |
162 | } | 211 | } |
163 | 212 | ||
164 | static void __exit fini(void) | 213 | static void __exit fini(void) |
165 | { | 214 | { |
166 | ipt_unregister_match(&dccp_match); | 215 | xt_unregister_match(AF_INET6, &dccp6_match); |
216 | xt_unregister_match(AF_INET, &dccp_match); | ||
167 | kfree(dccp_optbuf); | 217 | kfree(dccp_optbuf); |
168 | } | 218 | } |
169 | 219 | ||
170 | module_init(init); | 220 | module_init(init); |
171 | module_exit(fini); | 221 | module_exit(fini); |
172 | |||
173 | MODULE_LICENSE("GPL"); | ||
174 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | ||
175 | MODULE_DESCRIPTION("Match for DCCP protocol packets"); | ||
176 | |||
diff --git a/net/ipv4/netfilter/ipt_helper.c b/net/netfilter/xt_helper.c index aef649e393af..38b6715e1db4 100644 --- a/net/ipv4/netfilter/ipt_helper.c +++ b/net/netfilter/xt_helper.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/skbuff.h> | 14 | #include <linux/skbuff.h> |
15 | #include <linux/netfilter.h> | 15 | #include <linux/netfilter.h> |
16 | #include <linux/interrupt.h> | ||
17 | #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) | 16 | #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) |
18 | #include <linux/netfilter_ipv4/ip_conntrack.h> | 17 | #include <linux/netfilter_ipv4/ip_conntrack.h> |
19 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> | 18 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> |
@@ -23,12 +22,14 @@ | |||
23 | #include <net/netfilter/nf_conntrack_core.h> | 22 | #include <net/netfilter/nf_conntrack_core.h> |
24 | #include <net/netfilter/nf_conntrack_helper.h> | 23 | #include <net/netfilter/nf_conntrack_helper.h> |
25 | #endif | 24 | #endif |
26 | #include <linux/netfilter_ipv4/ip_tables.h> | 25 | #include <linux/netfilter/x_tables.h> |
27 | #include <linux/netfilter_ipv4/ipt_helper.h> | 26 | #include <linux/netfilter/xt_helper.h> |
28 | 27 | ||
29 | MODULE_LICENSE("GPL"); | 28 | MODULE_LICENSE("GPL"); |
30 | MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>"); | 29 | MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>"); |
31 | MODULE_DESCRIPTION("iptables helper match module"); | 30 | MODULE_DESCRIPTION("iptables helper match module"); |
31 | MODULE_ALIAS("ipt_helper"); | ||
32 | MODULE_ALIAS("ip6t_helper"); | ||
32 | 33 | ||
33 | #if 0 | 34 | #if 0 |
34 | #define DEBUGP printk | 35 | #define DEBUGP printk |
@@ -43,27 +44,28 @@ match(const struct sk_buff *skb, | |||
43 | const struct net_device *out, | 44 | const struct net_device *out, |
44 | const void *matchinfo, | 45 | const void *matchinfo, |
45 | int offset, | 46 | int offset, |
47 | unsigned int protoff, | ||
46 | int *hotdrop) | 48 | int *hotdrop) |
47 | { | 49 | { |
48 | const struct ipt_helper_info *info = matchinfo; | 50 | const struct xt_helper_info *info = matchinfo; |
49 | struct ip_conntrack *ct; | 51 | struct ip_conntrack *ct; |
50 | enum ip_conntrack_info ctinfo; | 52 | enum ip_conntrack_info ctinfo; |
51 | int ret = info->invert; | 53 | int ret = info->invert; |
52 | 54 | ||
53 | ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); | 55 | ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); |
54 | if (!ct) { | 56 | if (!ct) { |
55 | DEBUGP("ipt_helper: Eek! invalid conntrack?\n"); | 57 | DEBUGP("xt_helper: Eek! invalid conntrack?\n"); |
56 | return ret; | 58 | return ret; |
57 | } | 59 | } |
58 | 60 | ||
59 | if (!ct->master) { | 61 | if (!ct->master) { |
60 | DEBUGP("ipt_helper: conntrack %p has no master\n", ct); | 62 | DEBUGP("xt_helper: conntrack %p has no master\n", ct); |
61 | return ret; | 63 | return ret; |
62 | } | 64 | } |
63 | 65 | ||
64 | read_lock_bh(&ip_conntrack_lock); | 66 | read_lock_bh(&ip_conntrack_lock); |
65 | if (!ct->master->helper) { | 67 | if (!ct->master->helper) { |
66 | DEBUGP("ipt_helper: master ct %p has no helper\n", | 68 | DEBUGP("xt_helper: master ct %p has no helper\n", |
67 | exp->expectant); | 69 | exp->expectant); |
68 | goto out_unlock; | 70 | goto out_unlock; |
69 | } | 71 | } |
@@ -89,27 +91,28 @@ match(const struct sk_buff *skb, | |||
89 | const struct net_device *out, | 91 | const struct net_device *out, |
90 | const void *matchinfo, | 92 | const void *matchinfo, |
91 | int offset, | 93 | int offset, |
94 | unsigned int protoff, | ||
92 | int *hotdrop) | 95 | int *hotdrop) |
93 | { | 96 | { |
94 | const struct ipt_helper_info *info = matchinfo; | 97 | const struct xt_helper_info *info = matchinfo; |
95 | struct nf_conn *ct; | 98 | struct nf_conn *ct; |
96 | enum ip_conntrack_info ctinfo; | 99 | enum ip_conntrack_info ctinfo; |
97 | int ret = info->invert; | 100 | int ret = info->invert; |
98 | 101 | ||
99 | ct = nf_ct_get((struct sk_buff *)skb, &ctinfo); | 102 | ct = nf_ct_get((struct sk_buff *)skb, &ctinfo); |
100 | if (!ct) { | 103 | if (!ct) { |
101 | DEBUGP("ipt_helper: Eek! invalid conntrack?\n"); | 104 | DEBUGP("xt_helper: Eek! invalid conntrack?\n"); |
102 | return ret; | 105 | return ret; |
103 | } | 106 | } |
104 | 107 | ||
105 | if (!ct->master) { | 108 | if (!ct->master) { |
106 | DEBUGP("ipt_helper: conntrack %p has no master\n", ct); | 109 | DEBUGP("xt_helper: conntrack %p has no master\n", ct); |
107 | return ret; | 110 | return ret; |
108 | } | 111 | } |
109 | 112 | ||
110 | read_lock_bh(&nf_conntrack_lock); | 113 | read_lock_bh(&nf_conntrack_lock); |
111 | if (!ct->master->helper) { | 114 | if (!ct->master->helper) { |
112 | DEBUGP("ipt_helper: master ct %p has no helper\n", | 115 | DEBUGP("xt_helper: master ct %p has no helper\n", |
113 | exp->expectant); | 116 | exp->expectant); |
114 | goto out_unlock; | 117 | goto out_unlock; |
115 | } | 118 | } |
@@ -129,23 +132,29 @@ out_unlock: | |||
129 | #endif | 132 | #endif |
130 | 133 | ||
131 | static int check(const char *tablename, | 134 | static int check(const char *tablename, |
132 | const struct ipt_ip *ip, | 135 | const void *inf, |
133 | void *matchinfo, | 136 | void *matchinfo, |
134 | unsigned int matchsize, | 137 | unsigned int matchsize, |
135 | unsigned int hook_mask) | 138 | unsigned int hook_mask) |
136 | { | 139 | { |
137 | struct ipt_helper_info *info = matchinfo; | 140 | struct xt_helper_info *info = matchinfo; |
138 | 141 | ||
139 | info->name[29] = '\0'; | 142 | info->name[29] = '\0'; |
140 | 143 | ||
141 | /* verify size */ | 144 | /* verify size */ |
142 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_helper_info))) | 145 | if (matchsize != XT_ALIGN(sizeof(struct xt_helper_info))) |
143 | return 0; | 146 | return 0; |
144 | 147 | ||
145 | return 1; | 148 | return 1; |
146 | } | 149 | } |
147 | 150 | ||
148 | static struct ipt_match helper_match = { | 151 | static struct xt_match helper_match = { |
152 | .name = "helper", | ||
153 | .match = &match, | ||
154 | .checkentry = &check, | ||
155 | .me = THIS_MODULE, | ||
156 | }; | ||
157 | static struct xt_match helper6_match = { | ||
149 | .name = "helper", | 158 | .name = "helper", |
150 | .match = &match, | 159 | .match = &match, |
151 | .checkentry = &check, | 160 | .checkentry = &check, |
@@ -154,13 +163,24 @@ static struct ipt_match helper_match = { | |||
154 | 163 | ||
155 | static int __init init(void) | 164 | static int __init init(void) |
156 | { | 165 | { |
157 | need_ip_conntrack(); | 166 | int ret; |
158 | return ipt_register_match(&helper_match); | 167 | need_conntrack(); |
168 | |||
169 | ret = xt_register_match(AF_INET, &helper_match); | ||
170 | if (ret < 0) | ||
171 | return ret; | ||
172 | |||
173 | ret = xt_register_match(AF_INET6, &helper6_match); | ||
174 | if (ret < 0) | ||
175 | xt_unregister_match(AF_INET, &helper_match); | ||
176 | |||
177 | return ret; | ||
159 | } | 178 | } |
160 | 179 | ||
161 | static void __exit fini(void) | 180 | static void __exit fini(void) |
162 | { | 181 | { |
163 | ipt_unregister_match(&helper_match); | 182 | xt_unregister_match(AF_INET, &helper_match); |
183 | xt_unregister_match(AF_INET6, &helper6_match); | ||
164 | } | 184 | } |
165 | 185 | ||
166 | module_init(init); | 186 | module_init(init); |
diff --git a/net/netfilter/xt_length.c b/net/netfilter/xt_length.c new file mode 100644 index 000000000000..ab6c710cf88f --- /dev/null +++ b/net/netfilter/xt_length.c | |||
@@ -0,0 +1,98 @@ | |||
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 | #include <net/ip.h> | ||
12 | |||
13 | #include <linux/netfilter/xt_length.h> | ||
14 | #include <linux/netfilter/x_tables.h> | ||
15 | |||
16 | MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); | ||
17 | MODULE_DESCRIPTION("IP tables packet length matching module"); | ||
18 | MODULE_LICENSE("GPL"); | ||
19 | MODULE_ALIAS("ipt_length"); | ||
20 | MODULE_ALIAS("ip6t_length"); | ||
21 | |||
22 | static int | ||
23 | match(const struct sk_buff *skb, | ||
24 | const struct net_device *in, | ||
25 | const struct net_device *out, | ||
26 | const void *matchinfo, | ||
27 | int offset, | ||
28 | unsigned int protoff, | ||
29 | int *hotdrop) | ||
30 | { | ||
31 | const struct xt_length_info *info = matchinfo; | ||
32 | u_int16_t pktlen = ntohs(skb->nh.iph->tot_len); | ||
33 | |||
34 | return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; | ||
35 | } | ||
36 | |||
37 | static int | ||
38 | match6(const struct sk_buff *skb, | ||
39 | const struct net_device *in, | ||
40 | const struct net_device *out, | ||
41 | const void *matchinfo, | ||
42 | int offset, | ||
43 | unsigned int protoff, | ||
44 | int *hotdrop) | ||
45 | { | ||
46 | const struct xt_length_info *info = matchinfo; | ||
47 | u_int16_t pktlen = ntohs(skb->nh.ipv6h->payload_len) + sizeof(struct ipv6hdr); | ||
48 | |||
49 | return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; | ||
50 | } | ||
51 | |||
52 | static int | ||
53 | checkentry(const char *tablename, | ||
54 | const void *ip, | ||
55 | void *matchinfo, | ||
56 | unsigned int matchsize, | ||
57 | unsigned int hook_mask) | ||
58 | { | ||
59 | if (matchsize != XT_ALIGN(sizeof(struct xt_length_info))) | ||
60 | return 0; | ||
61 | |||
62 | return 1; | ||
63 | } | ||
64 | |||
65 | static struct xt_match length_match = { | ||
66 | .name = "length", | ||
67 | .match = &match, | ||
68 | .checkentry = &checkentry, | ||
69 | .me = THIS_MODULE, | ||
70 | }; | ||
71 | static struct xt_match length6_match = { | ||
72 | .name = "length", | ||
73 | .match = &match6, | ||
74 | .checkentry = &checkentry, | ||
75 | .me = THIS_MODULE, | ||
76 | }; | ||
77 | |||
78 | static int __init init(void) | ||
79 | { | ||
80 | int ret; | ||
81 | ret = xt_register_match(AF_INET, &length_match); | ||
82 | if (ret) | ||
83 | return ret; | ||
84 | ret = xt_register_match(AF_INET6, &length6_match); | ||
85 | if (ret) | ||
86 | xt_unregister_match(AF_INET, &length_match); | ||
87 | |||
88 | return ret; | ||
89 | } | ||
90 | |||
91 | static void __exit fini(void) | ||
92 | { | ||
93 | xt_unregister_match(AF_INET, &length_match); | ||
94 | xt_unregister_match(AF_INET6, &length6_match); | ||
95 | } | ||
96 | |||
97 | module_init(init); | ||
98 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ipt_limit.c b/net/netfilter/xt_limit.c index 0c24dcc703a5..15e40506bc3a 100644 --- a/net/ipv4/netfilter/ipt_limit.c +++ b/net/netfilter/xt_limit.c | |||
@@ -18,12 +18,14 @@ | |||
18 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | 20 | ||
21 | #include <linux/netfilter_ipv4/ip_tables.h> | 21 | #include <linux/netfilter/x_tables.h> |
22 | #include <linux/netfilter_ipv4/ipt_limit.h> | 22 | #include <linux/netfilter/xt_limit.h> |
23 | 23 | ||
24 | MODULE_LICENSE("GPL"); | 24 | MODULE_LICENSE("GPL"); |
25 | MODULE_AUTHOR("Herve Eychenne <rv@wallfire.org>"); | 25 | MODULE_AUTHOR("Herve Eychenne <rv@wallfire.org>"); |
26 | MODULE_DESCRIPTION("iptables rate limit match"); | 26 | MODULE_DESCRIPTION("iptables rate limit match"); |
27 | MODULE_ALIAS("ipt_limit"); | ||
28 | MODULE_ALIAS("ip6t_limit"); | ||
27 | 29 | ||
28 | /* The algorithm used is the Simple Token Bucket Filter (TBF) | 30 | /* The algorithm used is the Simple Token Bucket Filter (TBF) |
29 | * see net/sched/sch_tbf.c in the linux source tree | 31 | * see net/sched/sch_tbf.c in the linux source tree |
@@ -68,9 +70,10 @@ ipt_limit_match(const struct sk_buff *skb, | |||
68 | const struct net_device *out, | 70 | const struct net_device *out, |
69 | const void *matchinfo, | 71 | const void *matchinfo, |
70 | int offset, | 72 | int offset, |
73 | unsigned int protoff, | ||
71 | int *hotdrop) | 74 | int *hotdrop) |
72 | { | 75 | { |
73 | struct ipt_rateinfo *r = ((struct ipt_rateinfo *)matchinfo)->master; | 76 | struct xt_rateinfo *r = ((struct xt_rateinfo *)matchinfo)->master; |
74 | unsigned long now = jiffies; | 77 | unsigned long now = jiffies; |
75 | 78 | ||
76 | spin_lock_bh(&limit_lock); | 79 | spin_lock_bh(&limit_lock); |
@@ -96,32 +99,32 @@ user2credits(u_int32_t user) | |||
96 | /* If multiplying would overflow... */ | 99 | /* If multiplying would overflow... */ |
97 | if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) | 100 | if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) |
98 | /* Divide first. */ | 101 | /* Divide first. */ |
99 | return (user / IPT_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY; | 102 | return (user / XT_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY; |
100 | 103 | ||
101 | return (user * HZ * CREDITS_PER_JIFFY) / IPT_LIMIT_SCALE; | 104 | return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE; |
102 | } | 105 | } |
103 | 106 | ||
104 | static int | 107 | static int |
105 | ipt_limit_checkentry(const char *tablename, | 108 | ipt_limit_checkentry(const char *tablename, |
106 | const struct ipt_ip *ip, | 109 | const void *inf, |
107 | void *matchinfo, | 110 | void *matchinfo, |
108 | unsigned int matchsize, | 111 | unsigned int matchsize, |
109 | unsigned int hook_mask) | 112 | unsigned int hook_mask) |
110 | { | 113 | { |
111 | struct ipt_rateinfo *r = matchinfo; | 114 | struct xt_rateinfo *r = matchinfo; |
112 | 115 | ||
113 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_rateinfo))) | 116 | if (matchsize != XT_ALIGN(sizeof(struct xt_rateinfo))) |
114 | return 0; | 117 | return 0; |
115 | 118 | ||
116 | /* Check for overflow. */ | 119 | /* Check for overflow. */ |
117 | if (r->burst == 0 | 120 | if (r->burst == 0 |
118 | || user2credits(r->avg * r->burst) < user2credits(r->avg)) { | 121 | || user2credits(r->avg * r->burst) < user2credits(r->avg)) { |
119 | printk("Overflow in ipt_limit, try lower: %u/%u\n", | 122 | printk("Overflow in xt_limit, try lower: %u/%u\n", |
120 | r->avg, r->burst); | 123 | r->avg, r->burst); |
121 | return 0; | 124 | return 0; |
122 | } | 125 | } |
123 | 126 | ||
124 | /* User avg in seconds * IPT_LIMIT_SCALE: convert to jiffies * | 127 | /* User avg in seconds * XT_LIMIT_SCALE: convert to jiffies * |
125 | 128. */ | 128 | 128. */ |
126 | r->prev = jiffies; | 129 | r->prev = jiffies; |
127 | r->credit = user2credits(r->avg * r->burst); /* Credits full. */ | 130 | r->credit = user2credits(r->avg * r->burst); /* Credits full. */ |
@@ -134,7 +137,13 @@ ipt_limit_checkentry(const char *tablename, | |||
134 | return 1; | 137 | return 1; |
135 | } | 138 | } |
136 | 139 | ||
137 | static struct ipt_match ipt_limit_reg = { | 140 | static struct xt_match ipt_limit_reg = { |
141 | .name = "limit", | ||
142 | .match = ipt_limit_match, | ||
143 | .checkentry = ipt_limit_checkentry, | ||
144 | .me = THIS_MODULE, | ||
145 | }; | ||
146 | static struct xt_match limit6_reg = { | ||
138 | .name = "limit", | 147 | .name = "limit", |
139 | .match = ipt_limit_match, | 148 | .match = ipt_limit_match, |
140 | .checkentry = ipt_limit_checkentry, | 149 | .checkentry = ipt_limit_checkentry, |
@@ -143,14 +152,23 @@ static struct ipt_match ipt_limit_reg = { | |||
143 | 152 | ||
144 | static int __init init(void) | 153 | static int __init init(void) |
145 | { | 154 | { |
146 | if (ipt_register_match(&ipt_limit_reg)) | 155 | int ret; |
147 | return -EINVAL; | 156 | |
148 | return 0; | 157 | ret = xt_register_match(AF_INET, &ipt_limit_reg); |
158 | if (ret) | ||
159 | return ret; | ||
160 | |||
161 | ret = xt_register_match(AF_INET6, &limit6_reg); | ||
162 | if (ret) | ||
163 | xt_unregister_match(AF_INET, &ipt_limit_reg); | ||
164 | |||
165 | return ret; | ||
149 | } | 166 | } |
150 | 167 | ||
151 | static void __exit fini(void) | 168 | static void __exit fini(void) |
152 | { | 169 | { |
153 | ipt_unregister_match(&ipt_limit_reg); | 170 | xt_unregister_match(AF_INET, &ipt_limit_reg); |
171 | xt_unregister_match(AF_INET6, &limit6_reg); | ||
154 | } | 172 | } |
155 | 173 | ||
156 | module_init(init); | 174 | module_init(init); |
diff --git a/net/ipv4/netfilter/ipt_mac.c b/net/netfilter/xt_mac.c index 1b9bb4559f80..0461dcb5fc7a 100644 --- a/net/ipv4/netfilter/ipt_mac.c +++ b/net/netfilter/xt_mac.c | |||
@@ -13,12 +13,15 @@ | |||
13 | #include <linux/if_ether.h> | 13 | #include <linux/if_ether.h> |
14 | #include <linux/etherdevice.h> | 14 | #include <linux/etherdevice.h> |
15 | 15 | ||
16 | #include <linux/netfilter_ipv4/ipt_mac.h> | 16 | #include <linux/netfilter_ipv4.h> |
17 | #include <linux/netfilter_ipv4/ip_tables.h> | 17 | #include <linux/netfilter/xt_mac.h> |
18 | #include <linux/netfilter/x_tables.h> | ||
18 | 19 | ||
19 | MODULE_LICENSE("GPL"); | 20 | MODULE_LICENSE("GPL"); |
20 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); | 21 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); |
21 | MODULE_DESCRIPTION("iptables mac matching module"); | 22 | MODULE_DESCRIPTION("iptables mac matching module"); |
23 | MODULE_ALIAS("ipt_mac"); | ||
24 | MODULE_ALIAS("ip6t_mac"); | ||
22 | 25 | ||
23 | static int | 26 | static int |
24 | match(const struct sk_buff *skb, | 27 | match(const struct sk_buff *skb, |
@@ -26,9 +29,10 @@ match(const struct sk_buff *skb, | |||
26 | const struct net_device *out, | 29 | const struct net_device *out, |
27 | const void *matchinfo, | 30 | const void *matchinfo, |
28 | int offset, | 31 | int offset, |
32 | unsigned int protoff, | ||
29 | int *hotdrop) | 33 | int *hotdrop) |
30 | { | 34 | { |
31 | const struct ipt_mac_info *info = matchinfo; | 35 | const struct xt_mac_info *info = matchinfo; |
32 | 36 | ||
33 | /* Is mac pointer valid? */ | 37 | /* Is mac pointer valid? */ |
34 | return (skb->mac.raw >= skb->head | 38 | return (skb->mac.raw >= skb->head |
@@ -40,7 +44,7 @@ match(const struct sk_buff *skb, | |||
40 | 44 | ||
41 | static int | 45 | static int |
42 | ipt_mac_checkentry(const char *tablename, | 46 | ipt_mac_checkentry(const char *tablename, |
43 | const struct ipt_ip *ip, | 47 | const void *inf, |
44 | void *matchinfo, | 48 | void *matchinfo, |
45 | unsigned int matchsize, | 49 | unsigned int matchsize, |
46 | unsigned int hook_mask) | 50 | unsigned int hook_mask) |
@@ -49,17 +53,23 @@ ipt_mac_checkentry(const char *tablename, | |||
49 | if (hook_mask | 53 | if (hook_mask |
50 | & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | 54 | & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) |
51 | | (1 << NF_IP_FORWARD))) { | 55 | | (1 << NF_IP_FORWARD))) { |
52 | printk("ipt_mac: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n"); | 56 | printk("xt_mac: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n"); |
53 | return 0; | 57 | return 0; |
54 | } | 58 | } |
55 | 59 | ||
56 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_mac_info))) | 60 | if (matchsize != XT_ALIGN(sizeof(struct xt_mac_info))) |
57 | return 0; | 61 | return 0; |
58 | 62 | ||
59 | return 1; | 63 | return 1; |
60 | } | 64 | } |
61 | 65 | ||
62 | static struct ipt_match mac_match = { | 66 | static struct xt_match mac_match = { |
67 | .name = "mac", | ||
68 | .match = &match, | ||
69 | .checkentry = &ipt_mac_checkentry, | ||
70 | .me = THIS_MODULE, | ||
71 | }; | ||
72 | static struct xt_match mac6_match = { | ||
63 | .name = "mac", | 73 | .name = "mac", |
64 | .match = &match, | 74 | .match = &match, |
65 | .checkentry = &ipt_mac_checkentry, | 75 | .checkentry = &ipt_mac_checkentry, |
@@ -68,12 +78,22 @@ static struct ipt_match mac_match = { | |||
68 | 78 | ||
69 | static int __init init(void) | 79 | static int __init init(void) |
70 | { | 80 | { |
71 | return ipt_register_match(&mac_match); | 81 | int ret; |
82 | ret = xt_register_match(AF_INET, &mac_match); | ||
83 | if (ret) | ||
84 | return ret; | ||
85 | |||
86 | ret = xt_register_match(AF_INET6, &mac6_match); | ||
87 | if (ret) | ||
88 | xt_unregister_match(AF_INET, &mac_match); | ||
89 | |||
90 | return ret; | ||
72 | } | 91 | } |
73 | 92 | ||
74 | static void __exit fini(void) | 93 | static void __exit fini(void) |
75 | { | 94 | { |
76 | ipt_unregister_match(&mac_match); | 95 | xt_unregister_match(AF_INET, &mac_match); |
96 | xt_unregister_match(AF_INET6, &mac6_match); | ||
77 | } | 97 | } |
78 | 98 | ||
79 | module_init(init); | 99 | module_init(init); |
diff --git a/net/ipv4/netfilter/ipt_mark.c b/net/netfilter/xt_mark.c index 00bef6cdd3f8..2a0ac62b72c8 100644 --- a/net/ipv4/netfilter/ipt_mark.c +++ b/net/netfilter/xt_mark.c | |||
@@ -10,12 +10,14 @@ | |||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/skbuff.h> | 11 | #include <linux/skbuff.h> |
12 | 12 | ||
13 | #include <linux/netfilter_ipv4/ipt_mark.h> | 13 | #include <linux/netfilter/xt_mark.h> |
14 | #include <linux/netfilter_ipv4/ip_tables.h> | 14 | #include <linux/netfilter/x_tables.h> |
15 | 15 | ||
16 | MODULE_LICENSE("GPL"); | 16 | MODULE_LICENSE("GPL"); |
17 | MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); | 17 | MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); |
18 | MODULE_DESCRIPTION("iptables mark matching module"); | 18 | MODULE_DESCRIPTION("iptables mark matching module"); |
19 | MODULE_ALIAS("ipt_mark"); | ||
20 | MODULE_ALIAS("ip6t_mark"); | ||
19 | 21 | ||
20 | static int | 22 | static int |
21 | match(const struct sk_buff *skb, | 23 | match(const struct sk_buff *skb, |
@@ -23,23 +25,24 @@ match(const struct sk_buff *skb, | |||
23 | const struct net_device *out, | 25 | const struct net_device *out, |
24 | const void *matchinfo, | 26 | const void *matchinfo, |
25 | int offset, | 27 | int offset, |
28 | unsigned int protoff, | ||
26 | int *hotdrop) | 29 | int *hotdrop) |
27 | { | 30 | { |
28 | const struct ipt_mark_info *info = matchinfo; | 31 | const struct xt_mark_info *info = matchinfo; |
29 | 32 | ||
30 | return ((skb->nfmark & info->mask) == info->mark) ^ info->invert; | 33 | return ((skb->nfmark & info->mask) == info->mark) ^ info->invert; |
31 | } | 34 | } |
32 | 35 | ||
33 | static int | 36 | static int |
34 | checkentry(const char *tablename, | 37 | checkentry(const char *tablename, |
35 | const struct ipt_ip *ip, | 38 | const void *entry, |
36 | void *matchinfo, | 39 | void *matchinfo, |
37 | unsigned int matchsize, | 40 | unsigned int matchsize, |
38 | unsigned int hook_mask) | 41 | unsigned int hook_mask) |
39 | { | 42 | { |
40 | struct ipt_mark_info *minfo = (struct ipt_mark_info *) matchinfo; | 43 | struct xt_mark_info *minfo = (struct xt_mark_info *) matchinfo; |
41 | 44 | ||
42 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_mark_info))) | 45 | if (matchsize != XT_ALIGN(sizeof(struct xt_mark_info))) |
43 | return 0; | 46 | return 0; |
44 | 47 | ||
45 | if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) { | 48 | if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) { |
@@ -50,7 +53,14 @@ checkentry(const char *tablename, | |||
50 | return 1; | 53 | return 1; |
51 | } | 54 | } |
52 | 55 | ||
53 | static struct ipt_match mark_match = { | 56 | static struct xt_match mark_match = { |
57 | .name = "mark", | ||
58 | .match = &match, | ||
59 | .checkentry = &checkentry, | ||
60 | .me = THIS_MODULE, | ||
61 | }; | ||
62 | |||
63 | static struct xt_match mark6_match = { | ||
54 | .name = "mark", | 64 | .name = "mark", |
55 | .match = &match, | 65 | .match = &match, |
56 | .checkentry = &checkentry, | 66 | .checkentry = &checkentry, |
@@ -59,12 +69,22 @@ static struct ipt_match mark_match = { | |||
59 | 69 | ||
60 | static int __init init(void) | 70 | static int __init init(void) |
61 | { | 71 | { |
62 | return ipt_register_match(&mark_match); | 72 | int ret; |
73 | ret = xt_register_match(AF_INET, &mark_match); | ||
74 | if (ret) | ||
75 | return ret; | ||
76 | |||
77 | ret = xt_register_match(AF_INET6, &mark6_match); | ||
78 | if (ret) | ||
79 | xt_unregister_match(AF_INET, &mark_match); | ||
80 | |||
81 | return ret; | ||
63 | } | 82 | } |
64 | 83 | ||
65 | static void __exit fini(void) | 84 | static void __exit fini(void) |
66 | { | 85 | { |
67 | ipt_unregister_match(&mark_match); | 86 | xt_unregister_match(AF_INET, &mark_match); |
87 | xt_unregister_match(AF_INET6, &mark6_match); | ||
68 | } | 88 | } |
69 | 89 | ||
70 | module_init(init); | 90 | module_init(init); |
diff --git a/net/ipv6/netfilter/ip6t_physdev.c b/net/netfilter/xt_physdev.c index 71515c86ece1..19bb57c14dfe 100644 --- a/net/ipv6/netfilter/ip6t_physdev.c +++ b/net/netfilter/xt_physdev.c | |||
@@ -10,8 +10,8 @@ | |||
10 | 10 | ||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/skbuff.h> | 12 | #include <linux/skbuff.h> |
13 | #include <linux/netfilter_ipv6/ip6t_physdev.h> | 13 | #include <linux/netfilter/xt_physdev.h> |
14 | #include <linux/netfilter_ipv6/ip6_tables.h> | 14 | #include <linux/netfilter/x_tables.h> |
15 | #include <linux/netfilter_bridge.h> | 15 | #include <linux/netfilter_bridge.h> |
16 | #define MATCH 1 | 16 | #define MATCH 1 |
17 | #define NOMATCH 0 | 17 | #define NOMATCH 0 |
@@ -19,6 +19,8 @@ | |||
19 | MODULE_LICENSE("GPL"); | 19 | MODULE_LICENSE("GPL"); |
20 | MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); | 20 | MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); |
21 | MODULE_DESCRIPTION("iptables bridge physical device match module"); | 21 | MODULE_DESCRIPTION("iptables bridge physical device match module"); |
22 | MODULE_ALIAS("ipt_physdev"); | ||
23 | MODULE_ALIAS("ip6t_physdev"); | ||
22 | 24 | ||
23 | static int | 25 | static int |
24 | match(const struct sk_buff *skb, | 26 | match(const struct sk_buff *skb, |
@@ -31,7 +33,7 @@ match(const struct sk_buff *skb, | |||
31 | { | 33 | { |
32 | int i; | 34 | int i; |
33 | static const char nulldevname[IFNAMSIZ]; | 35 | static const char nulldevname[IFNAMSIZ]; |
34 | const struct ip6t_physdev_info *info = matchinfo; | 36 | const struct xt_physdev_info *info = matchinfo; |
35 | unsigned int ret; | 37 | unsigned int ret; |
36 | const char *indev, *outdev; | 38 | const char *indev, *outdev; |
37 | struct nf_bridge_info *nf_bridge; | 39 | struct nf_bridge_info *nf_bridge; |
@@ -41,37 +43,37 @@ match(const struct sk_buff *skb, | |||
41 | * the destination device will be a bridge. */ | 43 | * the destination device will be a bridge. */ |
42 | if (!(nf_bridge = skb->nf_bridge)) { | 44 | if (!(nf_bridge = skb->nf_bridge)) { |
43 | /* Return MATCH if the invert flags of the used options are on */ | 45 | /* Return MATCH if the invert flags of the used options are on */ |
44 | if ((info->bitmask & IP6T_PHYSDEV_OP_BRIDGED) && | 46 | if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) && |
45 | !(info->invert & IP6T_PHYSDEV_OP_BRIDGED)) | 47 | !(info->invert & XT_PHYSDEV_OP_BRIDGED)) |
46 | return NOMATCH; | 48 | return NOMATCH; |
47 | if ((info->bitmask & IP6T_PHYSDEV_OP_ISIN) && | 49 | if ((info->bitmask & XT_PHYSDEV_OP_ISIN) && |
48 | !(info->invert & IP6T_PHYSDEV_OP_ISIN)) | 50 | !(info->invert & XT_PHYSDEV_OP_ISIN)) |
49 | return NOMATCH; | 51 | return NOMATCH; |
50 | if ((info->bitmask & IP6T_PHYSDEV_OP_ISOUT) && | 52 | if ((info->bitmask & XT_PHYSDEV_OP_ISOUT) && |
51 | !(info->invert & IP6T_PHYSDEV_OP_ISOUT)) | 53 | !(info->invert & XT_PHYSDEV_OP_ISOUT)) |
52 | return NOMATCH; | 54 | return NOMATCH; |
53 | if ((info->bitmask & IP6T_PHYSDEV_OP_IN) && | 55 | if ((info->bitmask & XT_PHYSDEV_OP_IN) && |
54 | !(info->invert & IP6T_PHYSDEV_OP_IN)) | 56 | !(info->invert & XT_PHYSDEV_OP_IN)) |
55 | return NOMATCH; | 57 | return NOMATCH; |
56 | if ((info->bitmask & IP6T_PHYSDEV_OP_OUT) && | 58 | if ((info->bitmask & XT_PHYSDEV_OP_OUT) && |
57 | !(info->invert & IP6T_PHYSDEV_OP_OUT)) | 59 | !(info->invert & XT_PHYSDEV_OP_OUT)) |
58 | return NOMATCH; | 60 | return NOMATCH; |
59 | return MATCH; | 61 | return MATCH; |
60 | } | 62 | } |
61 | 63 | ||
62 | /* This only makes sense in the FORWARD and POSTROUTING chains */ | 64 | /* This only makes sense in the FORWARD and POSTROUTING chains */ |
63 | if ((info->bitmask & IP6T_PHYSDEV_OP_BRIDGED) && | 65 | if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) && |
64 | (!!(nf_bridge->mask & BRNF_BRIDGED) ^ | 66 | (!!(nf_bridge->mask & BRNF_BRIDGED) ^ |
65 | !(info->invert & IP6T_PHYSDEV_OP_BRIDGED))) | 67 | !(info->invert & XT_PHYSDEV_OP_BRIDGED))) |
66 | return NOMATCH; | 68 | return NOMATCH; |
67 | 69 | ||
68 | if ((info->bitmask & IP6T_PHYSDEV_OP_ISIN && | 70 | if ((info->bitmask & XT_PHYSDEV_OP_ISIN && |
69 | (!nf_bridge->physindev ^ !!(info->invert & IP6T_PHYSDEV_OP_ISIN))) || | 71 | (!nf_bridge->physindev ^ !!(info->invert & XT_PHYSDEV_OP_ISIN))) || |
70 | (info->bitmask & IP6T_PHYSDEV_OP_ISOUT && | 72 | (info->bitmask & XT_PHYSDEV_OP_ISOUT && |
71 | (!nf_bridge->physoutdev ^ !!(info->invert & IP6T_PHYSDEV_OP_ISOUT)))) | 73 | (!nf_bridge->physoutdev ^ !!(info->invert & XT_PHYSDEV_OP_ISOUT)))) |
72 | return NOMATCH; | 74 | return NOMATCH; |
73 | 75 | ||
74 | if (!(info->bitmask & IP6T_PHYSDEV_OP_IN)) | 76 | if (!(info->bitmask & XT_PHYSDEV_OP_IN)) |
75 | goto match_outdev; | 77 | goto match_outdev; |
76 | indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; | 78 | indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; |
77 | for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { | 79 | for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { |
@@ -80,11 +82,11 @@ match(const struct sk_buff *skb, | |||
80 | & ((const unsigned int *)info->in_mask)[i]; | 82 | & ((const unsigned int *)info->in_mask)[i]; |
81 | } | 83 | } |
82 | 84 | ||
83 | if ((ret == 0) ^ !(info->invert & IP6T_PHYSDEV_OP_IN)) | 85 | if ((ret == 0) ^ !(info->invert & XT_PHYSDEV_OP_IN)) |
84 | return NOMATCH; | 86 | return NOMATCH; |
85 | 87 | ||
86 | match_outdev: | 88 | match_outdev: |
87 | if (!(info->bitmask & IP6T_PHYSDEV_OP_OUT)) | 89 | if (!(info->bitmask & XT_PHYSDEV_OP_OUT)) |
88 | return MATCH; | 90 | return MATCH; |
89 | outdev = nf_bridge->physoutdev ? | 91 | outdev = nf_bridge->physoutdev ? |
90 | nf_bridge->physoutdev->name : nulldevname; | 92 | nf_bridge->physoutdev->name : nulldevname; |
@@ -94,27 +96,34 @@ match_outdev: | |||
94 | & ((const unsigned int *)info->out_mask)[i]; | 96 | & ((const unsigned int *)info->out_mask)[i]; |
95 | } | 97 | } |
96 | 98 | ||
97 | return (ret != 0) ^ !(info->invert & IP6T_PHYSDEV_OP_OUT); | 99 | return (ret != 0) ^ !(info->invert & XT_PHYSDEV_OP_OUT); |
98 | } | 100 | } |
99 | 101 | ||
100 | static int | 102 | static int |
101 | checkentry(const char *tablename, | 103 | checkentry(const char *tablename, |
102 | const struct ip6t_ip6 *ip, | 104 | const void *ip, |
103 | void *matchinfo, | 105 | void *matchinfo, |
104 | unsigned int matchsize, | 106 | unsigned int matchsize, |
105 | unsigned int hook_mask) | 107 | unsigned int hook_mask) |
106 | { | 108 | { |
107 | const struct ip6t_physdev_info *info = matchinfo; | 109 | const struct xt_physdev_info *info = matchinfo; |
108 | 110 | ||
109 | if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_physdev_info))) | 111 | if (matchsize != XT_ALIGN(sizeof(struct xt_physdev_info))) |
110 | return 0; | 112 | return 0; |
111 | if (!(info->bitmask & IP6T_PHYSDEV_OP_MASK) || | 113 | if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || |
112 | info->bitmask & ~IP6T_PHYSDEV_OP_MASK) | 114 | info->bitmask & ~XT_PHYSDEV_OP_MASK) |
113 | return 0; | 115 | return 0; |
114 | return 1; | 116 | return 1; |
115 | } | 117 | } |
116 | 118 | ||
117 | static struct ip6t_match physdev_match = { | 119 | static struct xt_match physdev_match = { |
120 | .name = "physdev", | ||
121 | .match = &match, | ||
122 | .checkentry = &checkentry, | ||
123 | .me = THIS_MODULE, | ||
124 | }; | ||
125 | |||
126 | static struct xt_match physdev6_match = { | ||
118 | .name = "physdev", | 127 | .name = "physdev", |
119 | .match = &match, | 128 | .match = &match, |
120 | .checkentry = &checkentry, | 129 | .checkentry = &checkentry, |
@@ -123,12 +132,23 @@ static struct ip6t_match physdev_match = { | |||
123 | 132 | ||
124 | static int __init init(void) | 133 | static int __init init(void) |
125 | { | 134 | { |
126 | return ip6t_register_match(&physdev_match); | 135 | int ret; |
136 | |||
137 | ret = xt_register_match(AF_INET, &physdev_match); | ||
138 | if (ret < 0) | ||
139 | return ret; | ||
140 | |||
141 | ret = xt_register_match(AF_INET6, &physdev6_match); | ||
142 | if (ret < 0) | ||
143 | xt_unregister_match(AF_INET, &physdev_match); | ||
144 | |||
145 | return ret; | ||
127 | } | 146 | } |
128 | 147 | ||
129 | static void __exit fini(void) | 148 | static void __exit fini(void) |
130 | { | 149 | { |
131 | ip6t_unregister_match(&physdev_match); | 150 | xt_unregister_match(AF_INET, &physdev_match); |
151 | xt_unregister_match(AF_INET6, &physdev6_match); | ||
132 | } | 152 | } |
133 | 153 | ||
134 | module_init(init); | 154 | module_init(init); |
diff --git a/net/ipv4/netfilter/ipt_pkttype.c b/net/netfilter/xt_pkttype.c index 8ddb1dc5e5ae..ab1b2630f97d 100644 --- a/net/ipv4/netfilter/ipt_pkttype.c +++ b/net/netfilter/xt_pkttype.c | |||
@@ -10,60 +10,72 @@ | |||
10 | #include <linux/if_ether.h> | 10 | #include <linux/if_ether.h> |
11 | #include <linux/if_packet.h> | 11 | #include <linux/if_packet.h> |
12 | 12 | ||
13 | #include <linux/netfilter_ipv4/ipt_pkttype.h> | 13 | #include <linux/netfilter/xt_pkttype.h> |
14 | #include <linux/netfilter_ipv4/ip_tables.h> | 14 | #include <linux/netfilter/x_tables.h> |
15 | 15 | ||
16 | MODULE_LICENSE("GPL"); | 16 | MODULE_LICENSE("GPL"); |
17 | MODULE_AUTHOR("Michal Ludvig <michal@logix.cz>"); | 17 | MODULE_AUTHOR("Michal Ludvig <michal@logix.cz>"); |
18 | MODULE_DESCRIPTION("IP tables match to match on linklayer packet type"); | 18 | MODULE_DESCRIPTION("IP tables match to match on linklayer packet type"); |
19 | MODULE_ALIAS("ipt_pkttype"); | ||
20 | MODULE_ALIAS("ip6t_pkttype"); | ||
19 | 21 | ||
20 | static int match(const struct sk_buff *skb, | 22 | static int match(const struct sk_buff *skb, |
21 | const struct net_device *in, | 23 | const struct net_device *in, |
22 | const struct net_device *out, | 24 | const struct net_device *out, |
23 | const void *matchinfo, | 25 | const void *matchinfo, |
24 | int offset, | 26 | int offset, |
27 | unsigned int protoff, | ||
25 | int *hotdrop) | 28 | int *hotdrop) |
26 | { | 29 | { |
27 | const struct ipt_pkttype_info *info = matchinfo; | 30 | const struct xt_pkttype_info *info = matchinfo; |
28 | 31 | ||
29 | return (skb->pkt_type == info->pkttype) ^ info->invert; | 32 | return (skb->pkt_type == info->pkttype) ^ info->invert; |
30 | } | 33 | } |
31 | 34 | ||
32 | static int checkentry(const char *tablename, | 35 | static int checkentry(const char *tablename, |
33 | const struct ipt_ip *ip, | 36 | const void *ip, |
34 | void *matchinfo, | 37 | void *matchinfo, |
35 | unsigned int matchsize, | 38 | unsigned int matchsize, |
36 | unsigned int hook_mask) | 39 | unsigned int hook_mask) |
37 | { | 40 | { |
38 | /* | 41 | if (matchsize != XT_ALIGN(sizeof(struct xt_pkttype_info))) |
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; | 42 | return 0; |
48 | 43 | ||
49 | return 1; | 44 | return 1; |
50 | } | 45 | } |
51 | 46 | ||
52 | static struct ipt_match pkttype_match = { | 47 | static struct xt_match pkttype_match = { |
53 | .name = "pkttype", | 48 | .name = "pkttype", |
54 | .match = &match, | 49 | .match = &match, |
55 | .checkentry = &checkentry, | 50 | .checkentry = &checkentry, |
56 | .me = THIS_MODULE, | 51 | .me = THIS_MODULE, |
57 | }; | 52 | }; |
53 | static struct xt_match pkttype6_match = { | ||
54 | .name = "pkttype", | ||
55 | .match = &match, | ||
56 | .checkentry = &checkentry, | ||
57 | .me = THIS_MODULE, | ||
58 | }; | ||
59 | |||
58 | 60 | ||
59 | static int __init init(void) | 61 | static int __init init(void) |
60 | { | 62 | { |
61 | return ipt_register_match(&pkttype_match); | 63 | int ret; |
64 | ret = xt_register_match(AF_INET, &pkttype_match); | ||
65 | if (ret) | ||
66 | return ret; | ||
67 | |||
68 | ret = xt_register_match(AF_INET6, &pkttype6_match); | ||
69 | if (ret) | ||
70 | xt_unregister_match(AF_INET, &pkttype_match); | ||
71 | |||
72 | return ret; | ||
62 | } | 73 | } |
63 | 74 | ||
64 | static void __exit fini(void) | 75 | static void __exit fini(void) |
65 | { | 76 | { |
66 | ipt_unregister_match(&pkttype_match); | 77 | xt_unregister_match(AF_INET, &pkttype_match); |
78 | xt_unregister_match(AF_INET6, &pkttype6_match); | ||
67 | } | 79 | } |
68 | 80 | ||
69 | module_init(init); | 81 | module_init(init); |
diff --git a/net/ipv4/netfilter/ipt_realm.c b/net/netfilter/xt_realm.c index 54a6897ebaa6..2b7e1781d34d 100644 --- a/net/ipv4/netfilter/ipt_realm.c +++ b/net/netfilter/xt_realm.c | |||
@@ -14,12 +14,14 @@ | |||
14 | #include <linux/netdevice.h> | 14 | #include <linux/netdevice.h> |
15 | #include <net/route.h> | 15 | #include <net/route.h> |
16 | 16 | ||
17 | #include <linux/netfilter_ipv4/ipt_realm.h> | 17 | #include <linux/netfilter_ipv4.h> |
18 | #include <linux/netfilter_ipv4/ip_tables.h> | 18 | #include <linux/netfilter/xt_realm.h> |
19 | #include <linux/netfilter/x_tables.h> | ||
19 | 20 | ||
20 | MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>"); | 21 | MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>"); |
21 | MODULE_LICENSE("GPL"); | 22 | MODULE_LICENSE("GPL"); |
22 | MODULE_DESCRIPTION("iptables realm match"); | 23 | MODULE_DESCRIPTION("X_tables realm match"); |
24 | MODULE_ALIAS("ipt_realm"); | ||
23 | 25 | ||
24 | static int | 26 | static int |
25 | match(const struct sk_buff *skb, | 27 | match(const struct sk_buff *skb, |
@@ -27,16 +29,17 @@ match(const struct sk_buff *skb, | |||
27 | const struct net_device *out, | 29 | const struct net_device *out, |
28 | const void *matchinfo, | 30 | const void *matchinfo, |
29 | int offset, | 31 | int offset, |
32 | unsigned int protoff, | ||
30 | int *hotdrop) | 33 | int *hotdrop) |
31 | { | 34 | { |
32 | const struct ipt_realm_info *info = matchinfo; | 35 | const struct xt_realm_info *info = matchinfo; |
33 | struct dst_entry *dst = skb->dst; | 36 | struct dst_entry *dst = skb->dst; |
34 | 37 | ||
35 | return (info->id == (dst->tclassid & info->mask)) ^ info->invert; | 38 | return (info->id == (dst->tclassid & info->mask)) ^ info->invert; |
36 | } | 39 | } |
37 | 40 | ||
38 | static int check(const char *tablename, | 41 | static int check(const char *tablename, |
39 | const struct ipt_ip *ip, | 42 | const void *ip, |
40 | void *matchinfo, | 43 | void *matchinfo, |
41 | unsigned int matchsize, | 44 | unsigned int matchsize, |
42 | unsigned int hook_mask) | 45 | unsigned int hook_mask) |
@@ -44,18 +47,18 @@ static int check(const char *tablename, | |||
44 | if (hook_mask | 47 | if (hook_mask |
45 | & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) | | 48 | & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) | |
46 | (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN))) { | 49 | (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN))) { |
47 | printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, " | 50 | printk("xt_realm: only valid for POST_ROUTING, LOCAL_OUT, " |
48 | "LOCAL_IN or FORWARD.\n"); | 51 | "LOCAL_IN or FORWARD.\n"); |
49 | return 0; | 52 | return 0; |
50 | } | 53 | } |
51 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info))) { | 54 | if (matchsize != XT_ALIGN(sizeof(struct xt_realm_info))) { |
52 | printk("ipt_realm: invalid matchsize.\n"); | 55 | printk("xt_realm: invalid matchsize.\n"); |
53 | return 0; | 56 | return 0; |
54 | } | 57 | } |
55 | return 1; | 58 | return 1; |
56 | } | 59 | } |
57 | 60 | ||
58 | static struct ipt_match realm_match = { | 61 | static struct xt_match realm_match = { |
59 | .name = "realm", | 62 | .name = "realm", |
60 | .match = match, | 63 | .match = match, |
61 | .checkentry = check, | 64 | .checkentry = check, |
@@ -64,12 +67,12 @@ static struct ipt_match realm_match = { | |||
64 | 67 | ||
65 | static int __init init(void) | 68 | static int __init init(void) |
66 | { | 69 | { |
67 | return ipt_register_match(&realm_match); | 70 | return xt_register_match(AF_INET, &realm_match); |
68 | } | 71 | } |
69 | 72 | ||
70 | static void __exit fini(void) | 73 | static void __exit fini(void) |
71 | { | 74 | { |
72 | ipt_unregister_match(&realm_match); | 75 | xt_unregister_match(AF_INET, &realm_match); |
73 | } | 76 | } |
74 | 77 | ||
75 | module_init(init); | 78 | module_init(init); |
diff --git a/net/ipv4/netfilter/ipt_sctp.c b/net/netfilter/xt_sctp.c index fe2b327bcaa4..10fbfc5ba758 100644 --- a/net/ipv4/netfilter/ipt_sctp.c +++ b/net/netfilter/xt_sctp.c | |||
@@ -1,10 +1,18 @@ | |||
1 | #include <linux/module.h> | 1 | #include <linux/module.h> |
2 | #include <linux/skbuff.h> | 2 | #include <linux/skbuff.h> |
3 | #include <net/ip.h> | 3 | #include <net/ip.h> |
4 | #include <net/ipv6.h> | ||
4 | #include <linux/sctp.h> | 5 | #include <linux/sctp.h> |
5 | 6 | ||
7 | #include <linux/netfilter/x_tables.h> | ||
8 | #include <linux/netfilter/xt_sctp.h> | ||
6 | #include <linux/netfilter_ipv4/ip_tables.h> | 9 | #include <linux/netfilter_ipv4/ip_tables.h> |
7 | #include <linux/netfilter_ipv4/ipt_sctp.h> | 10 | #include <linux/netfilter_ipv6/ip6_tables.h> |
11 | |||
12 | MODULE_LICENSE("GPL"); | ||
13 | MODULE_AUTHOR("Kiran Kumar Immidi"); | ||
14 | MODULE_DESCRIPTION("Match for SCTP protocol packets"); | ||
15 | MODULE_ALIAS("ipt_sctp"); | ||
8 | 16 | ||
9 | #ifdef DEBUG_SCTP | 17 | #ifdef DEBUG_SCTP |
10 | #define duprintf(format, args...) printk(format , ## args) | 18 | #define duprintf(format, args...) printk(format , ## args) |
@@ -16,7 +24,7 @@ | |||
16 | || (!!((invflag) & (option)) ^ (cond))) | 24 | || (!!((invflag) & (option)) ^ (cond))) |
17 | 25 | ||
18 | static int | 26 | static int |
19 | match_flags(const struct ipt_sctp_flag_info *flag_info, | 27 | match_flags(const struct xt_sctp_flag_info *flag_info, |
20 | const int flag_count, | 28 | const int flag_count, |
21 | u_int8_t chunktype, | 29 | u_int8_t chunktype, |
22 | u_int8_t chunkflags) | 30 | u_int8_t chunkflags) |
@@ -32,15 +40,15 @@ match_flags(const struct ipt_sctp_flag_info *flag_info, | |||
32 | return 1; | 40 | return 1; |
33 | } | 41 | } |
34 | 42 | ||
35 | static int | 43 | static inline int |
36 | match_packet(const struct sk_buff *skb, | 44 | match_packet(const struct sk_buff *skb, |
45 | unsigned int offset, | ||
37 | const u_int32_t *chunkmap, | 46 | const u_int32_t *chunkmap, |
38 | int chunk_match_type, | 47 | int chunk_match_type, |
39 | const struct ipt_sctp_flag_info *flag_info, | 48 | const struct xt_sctp_flag_info *flag_info, |
40 | const int flag_count, | 49 | const int flag_count, |
41 | int *hotdrop) | 50 | int *hotdrop) |
42 | { | 51 | { |
43 | int offset; | ||
44 | u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)]; | 52 | u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)]; |
45 | sctp_chunkhdr_t _sch, *sch; | 53 | sctp_chunkhdr_t _sch, *sch; |
46 | 54 | ||
@@ -52,7 +60,6 @@ match_packet(const struct sk_buff *skb, | |||
52 | SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap); | 60 | SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap); |
53 | } | 61 | } |
54 | 62 | ||
55 | offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t); | ||
56 | do { | 63 | do { |
57 | sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch); | 64 | sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch); |
58 | if (sch == NULL) { | 65 | if (sch == NULL) { |
@@ -118,19 +125,20 @@ match(const struct sk_buff *skb, | |||
118 | const struct net_device *out, | 125 | const struct net_device *out, |
119 | const void *matchinfo, | 126 | const void *matchinfo, |
120 | int offset, | 127 | int offset, |
128 | unsigned int protoff, | ||
121 | int *hotdrop) | 129 | int *hotdrop) |
122 | { | 130 | { |
123 | const struct ipt_sctp_info *info; | 131 | const struct xt_sctp_info *info; |
124 | sctp_sctphdr_t _sh, *sh; | 132 | sctp_sctphdr_t _sh, *sh; |
125 | 133 | ||
126 | info = (const struct ipt_sctp_info *)matchinfo; | 134 | info = (const struct xt_sctp_info *)matchinfo; |
127 | 135 | ||
128 | if (offset) { | 136 | if (offset) { |
129 | duprintf("Dropping non-first fragment.. FIXME\n"); | 137 | duprintf("Dropping non-first fragment.. FIXME\n"); |
130 | return 0; | 138 | return 0; |
131 | } | 139 | } |
132 | 140 | ||
133 | sh = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_sh), &_sh); | 141 | sh = skb_header_pointer(skb, protoff, sizeof(_sh), &_sh); |
134 | if (sh == NULL) { | 142 | if (sh == NULL) { |
135 | duprintf("Dropping evil TCP offset=0 tinygram.\n"); | 143 | duprintf("Dropping evil TCP offset=0 tinygram.\n"); |
136 | *hotdrop = 1; | 144 | *hotdrop = 1; |
@@ -140,64 +148,103 @@ match(const struct sk_buff *skb, | |||
140 | 148 | ||
141 | return SCCHECK(((ntohs(sh->source) >= info->spts[0]) | 149 | return SCCHECK(((ntohs(sh->source) >= info->spts[0]) |
142 | && (ntohs(sh->source) <= info->spts[1])), | 150 | && (ntohs(sh->source) <= info->spts[1])), |
143 | IPT_SCTP_SRC_PORTS, info->flags, info->invflags) | 151 | XT_SCTP_SRC_PORTS, info->flags, info->invflags) |
144 | && SCCHECK(((ntohs(sh->dest) >= info->dpts[0]) | 152 | && SCCHECK(((ntohs(sh->dest) >= info->dpts[0]) |
145 | && (ntohs(sh->dest) <= info->dpts[1])), | 153 | && (ntohs(sh->dest) <= info->dpts[1])), |
146 | IPT_SCTP_DEST_PORTS, info->flags, info->invflags) | 154 | XT_SCTP_DEST_PORTS, info->flags, info->invflags) |
147 | && SCCHECK(match_packet(skb, info->chunkmap, info->chunk_match_type, | 155 | && SCCHECK(match_packet(skb, protoff, |
156 | info->chunkmap, info->chunk_match_type, | ||
148 | info->flag_info, info->flag_count, | 157 | info->flag_info, info->flag_count, |
149 | hotdrop), | 158 | hotdrop), |
150 | IPT_SCTP_CHUNK_TYPES, info->flags, info->invflags); | 159 | XT_SCTP_CHUNK_TYPES, info->flags, info->invflags); |
151 | } | 160 | } |
152 | 161 | ||
153 | static int | 162 | static int |
154 | checkentry(const char *tablename, | 163 | checkentry(const char *tablename, |
155 | const struct ipt_ip *ip, | 164 | const void *inf, |
165 | void *matchinfo, | ||
166 | unsigned int matchsize, | ||
167 | unsigned int hook_mask) | ||
168 | { | ||
169 | const struct xt_sctp_info *info; | ||
170 | const struct ipt_ip *ip = inf; | ||
171 | |||
172 | info = (const struct xt_sctp_info *)matchinfo; | ||
173 | |||
174 | return ip->proto == IPPROTO_SCTP | ||
175 | && !(ip->invflags & XT_INV_PROTO) | ||
176 | && matchsize == XT_ALIGN(sizeof(struct xt_sctp_info)) | ||
177 | && !(info->flags & ~XT_SCTP_VALID_FLAGS) | ||
178 | && !(info->invflags & ~XT_SCTP_VALID_FLAGS) | ||
179 | && !(info->invflags & ~info->flags) | ||
180 | && ((!(info->flags & XT_SCTP_CHUNK_TYPES)) || | ||
181 | (info->chunk_match_type & | ||
182 | (SCTP_CHUNK_MATCH_ALL | ||
183 | | SCTP_CHUNK_MATCH_ANY | ||
184 | | SCTP_CHUNK_MATCH_ONLY))); | ||
185 | } | ||
186 | |||
187 | static int | ||
188 | checkentry6(const char *tablename, | ||
189 | const void *inf, | ||
156 | void *matchinfo, | 190 | void *matchinfo, |
157 | unsigned int matchsize, | 191 | unsigned int matchsize, |
158 | unsigned int hook_mask) | 192 | unsigned int hook_mask) |
159 | { | 193 | { |
160 | const struct ipt_sctp_info *info; | 194 | const struct xt_sctp_info *info; |
195 | const struct ip6t_ip6 *ip = inf; | ||
161 | 196 | ||
162 | info = (const struct ipt_sctp_info *)matchinfo; | 197 | info = (const struct xt_sctp_info *)matchinfo; |
163 | 198 | ||
164 | return ip->proto == IPPROTO_SCTP | 199 | return ip->proto == IPPROTO_SCTP |
165 | && !(ip->invflags & IPT_INV_PROTO) | 200 | && !(ip->invflags & XT_INV_PROTO) |
166 | && matchsize == IPT_ALIGN(sizeof(struct ipt_sctp_info)) | 201 | && matchsize == XT_ALIGN(sizeof(struct xt_sctp_info)) |
167 | && !(info->flags & ~IPT_SCTP_VALID_FLAGS) | 202 | && !(info->flags & ~XT_SCTP_VALID_FLAGS) |
168 | && !(info->invflags & ~IPT_SCTP_VALID_FLAGS) | 203 | && !(info->invflags & ~XT_SCTP_VALID_FLAGS) |
169 | && !(info->invflags & ~info->flags) | 204 | && !(info->invflags & ~info->flags) |
170 | && ((!(info->flags & IPT_SCTP_CHUNK_TYPES)) || | 205 | && ((!(info->flags & XT_SCTP_CHUNK_TYPES)) || |
171 | (info->chunk_match_type & | 206 | (info->chunk_match_type & |
172 | (SCTP_CHUNK_MATCH_ALL | 207 | (SCTP_CHUNK_MATCH_ALL |
173 | | SCTP_CHUNK_MATCH_ANY | 208 | | SCTP_CHUNK_MATCH_ANY |
174 | | SCTP_CHUNK_MATCH_ONLY))); | 209 | | SCTP_CHUNK_MATCH_ONLY))); |
175 | } | 210 | } |
176 | 211 | ||
177 | static struct ipt_match sctp_match = | 212 | |
213 | static struct xt_match sctp_match = | ||
178 | { | 214 | { |
179 | .list = { NULL, NULL}, | ||
180 | .name = "sctp", | 215 | .name = "sctp", |
181 | .match = &match, | 216 | .match = &match, |
182 | .checkentry = &checkentry, | 217 | .checkentry = &checkentry, |
183 | .destroy = NULL, | 218 | .me = THIS_MODULE |
219 | }; | ||
220 | static struct xt_match sctp6_match = | ||
221 | { | ||
222 | .name = "sctp", | ||
223 | .match = &match, | ||
224 | .checkentry = &checkentry6, | ||
184 | .me = THIS_MODULE | 225 | .me = THIS_MODULE |
185 | }; | 226 | }; |
186 | 227 | ||
228 | |||
187 | static int __init init(void) | 229 | static int __init init(void) |
188 | { | 230 | { |
189 | return ipt_register_match(&sctp_match); | 231 | int ret; |
232 | ret = xt_register_match(AF_INET, &sctp_match); | ||
233 | if (ret) | ||
234 | return ret; | ||
235 | |||
236 | ret = xt_register_match(AF_INET6, &sctp6_match); | ||
237 | if (ret) | ||
238 | xt_unregister_match(AF_INET, &sctp_match); | ||
239 | |||
240 | return ret; | ||
190 | } | 241 | } |
191 | 242 | ||
192 | static void __exit fini(void) | 243 | static void __exit fini(void) |
193 | { | 244 | { |
194 | ipt_unregister_match(&sctp_match); | 245 | xt_unregister_match(AF_INET6, &sctp6_match); |
246 | xt_unregister_match(AF_INET, &sctp_match); | ||
195 | } | 247 | } |
196 | 248 | ||
197 | module_init(init); | 249 | module_init(init); |
198 | module_exit(fini); | 250 | module_exit(fini); |
199 | |||
200 | MODULE_LICENSE("GPL"); | ||
201 | MODULE_AUTHOR("Kiran Kumar Immidi"); | ||
202 | MODULE_DESCRIPTION("Match for SCTP protocol packets"); | ||
203 | |||
diff --git a/net/ipv4/netfilter/ipt_state.c b/net/netfilter/xt_state.c index 4d7f16b70cec..39ce808d40ef 100644 --- a/net/ipv4/netfilter/ipt_state.c +++ b/net/netfilter/xt_state.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* Kernel module to match connection tracking information. */ | 1 | /* Kernel module to match connection tracking information. */ |
2 | 2 | ||
3 | /* (C) 1999-2001 Paul `Rusty' Russell | 3 | /* (C) 1999-2001 Paul `Rusty' Russell |
4 | * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> | 4 | * (C) 2002-2005 Netfilter Core Team <coreteam@netfilter.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 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 | 7 | * it under the terms of the GNU General Public License version 2 as |
@@ -11,12 +11,14 @@ | |||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/skbuff.h> | 12 | #include <linux/skbuff.h> |
13 | #include <net/netfilter/nf_conntrack_compat.h> | 13 | #include <net/netfilter/nf_conntrack_compat.h> |
14 | #include <linux/netfilter_ipv4/ip_tables.h> | 14 | #include <linux/netfilter/x_tables.h> |
15 | #include <linux/netfilter_ipv4/ipt_state.h> | 15 | #include <linux/netfilter/xt_state.h> |
16 | 16 | ||
17 | MODULE_LICENSE("GPL"); | 17 | MODULE_LICENSE("GPL"); |
18 | MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>"); | 18 | MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>"); |
19 | MODULE_DESCRIPTION("iptables connection tracking state match module"); | 19 | MODULE_DESCRIPTION("ip[6]_tables connection tracking state match module"); |
20 | MODULE_ALIAS("ipt_state"); | ||
21 | MODULE_ALIAS("ip6t_state"); | ||
20 | 22 | ||
21 | static int | 23 | static int |
22 | match(const struct sk_buff *skb, | 24 | match(const struct sk_buff *skb, |
@@ -24,35 +26,43 @@ match(const struct sk_buff *skb, | |||
24 | const struct net_device *out, | 26 | const struct net_device *out, |
25 | const void *matchinfo, | 27 | const void *matchinfo, |
26 | int offset, | 28 | int offset, |
29 | unsigned int protoff, | ||
27 | int *hotdrop) | 30 | int *hotdrop) |
28 | { | 31 | { |
29 | const struct ipt_state_info *sinfo = matchinfo; | 32 | const struct xt_state_info *sinfo = matchinfo; |
30 | enum ip_conntrack_info ctinfo; | 33 | enum ip_conntrack_info ctinfo; |
31 | unsigned int statebit; | 34 | unsigned int statebit; |
32 | 35 | ||
33 | if (nf_ct_is_untracked(skb)) | 36 | if (nf_ct_is_untracked(skb)) |
34 | statebit = IPT_STATE_UNTRACKED; | 37 | statebit = XT_STATE_UNTRACKED; |
35 | else if (!nf_ct_get_ctinfo(skb, &ctinfo)) | 38 | else if (!nf_ct_get_ctinfo(skb, &ctinfo)) |
36 | statebit = IPT_STATE_INVALID; | 39 | statebit = XT_STATE_INVALID; |
37 | else | 40 | else |
38 | statebit = IPT_STATE_BIT(ctinfo); | 41 | statebit = XT_STATE_BIT(ctinfo); |
39 | 42 | ||
40 | return (sinfo->statemask & statebit); | 43 | return (sinfo->statemask & statebit); |
41 | } | 44 | } |
42 | 45 | ||
43 | static int check(const char *tablename, | 46 | static int check(const char *tablename, |
44 | const struct ipt_ip *ip, | 47 | const void *ip, |
45 | void *matchinfo, | 48 | void *matchinfo, |
46 | unsigned int matchsize, | 49 | unsigned int matchsize, |
47 | unsigned int hook_mask) | 50 | unsigned int hook_mask) |
48 | { | 51 | { |
49 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_state_info))) | 52 | if (matchsize != XT_ALIGN(sizeof(struct xt_state_info))) |
50 | return 0; | 53 | return 0; |
51 | 54 | ||
52 | return 1; | 55 | return 1; |
53 | } | 56 | } |
54 | 57 | ||
55 | static struct ipt_match state_match = { | 58 | static struct xt_match state_match = { |
59 | .name = "state", | ||
60 | .match = &match, | ||
61 | .checkentry = &check, | ||
62 | .me = THIS_MODULE, | ||
63 | }; | ||
64 | |||
65 | static struct xt_match state6_match = { | ||
56 | .name = "state", | 66 | .name = "state", |
57 | .match = &match, | 67 | .match = &match, |
58 | .checkentry = &check, | 68 | .checkentry = &check, |
@@ -61,13 +71,25 @@ static struct ipt_match state_match = { | |||
61 | 71 | ||
62 | static int __init init(void) | 72 | static int __init init(void) |
63 | { | 73 | { |
64 | need_ip_conntrack(); | 74 | int ret; |
65 | return ipt_register_match(&state_match); | 75 | |
76 | need_conntrack(); | ||
77 | |||
78 | ret = xt_register_match(AF_INET, &state_match); | ||
79 | if (ret < 0) | ||
80 | return ret; | ||
81 | |||
82 | ret = xt_register_match(AF_INET6, &state6_match); | ||
83 | if (ret < 0) | ||
84 | xt_unregister_match(AF_INET,&state_match); | ||
85 | |||
86 | return ret; | ||
66 | } | 87 | } |
67 | 88 | ||
68 | static void __exit fini(void) | 89 | static void __exit fini(void) |
69 | { | 90 | { |
70 | ipt_unregister_match(&state_match); | 91 | xt_unregister_match(AF_INET, &state_match); |
92 | xt_unregister_match(AF_INET6, &state6_match); | ||
71 | } | 93 | } |
72 | 94 | ||
73 | module_init(init); | 95 | module_init(init); |
diff --git a/net/ipv4/netfilter/ipt_string.c b/net/netfilter/xt_string.c index b5def204d798..7c7d5c8807d6 100644 --- a/net/ipv4/netfilter/ipt_string.c +++ b/net/netfilter/xt_string.c | |||
@@ -11,23 +11,26 @@ | |||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/skbuff.h> | 13 | #include <linux/skbuff.h> |
14 | #include <linux/netfilter_ipv4/ip_tables.h> | 14 | #include <linux/netfilter/x_tables.h> |
15 | #include <linux/netfilter_ipv4/ipt_string.h> | 15 | #include <linux/netfilter/xt_string.h> |
16 | #include <linux/textsearch.h> | 16 | #include <linux/textsearch.h> |
17 | 17 | ||
18 | MODULE_AUTHOR("Pablo Neira Ayuso <pablo@eurodev.net>"); | 18 | MODULE_AUTHOR("Pablo Neira Ayuso <pablo@eurodev.net>"); |
19 | MODULE_DESCRIPTION("IP tables string match module"); | 19 | MODULE_DESCRIPTION("IP tables string match module"); |
20 | MODULE_LICENSE("GPL"); | 20 | MODULE_LICENSE("GPL"); |
21 | MODULE_ALIAS("ipt_string"); | ||
22 | MODULE_ALIAS("ip6t_string"); | ||
21 | 23 | ||
22 | static int match(const struct sk_buff *skb, | 24 | static int match(const struct sk_buff *skb, |
23 | const struct net_device *in, | 25 | const struct net_device *in, |
24 | const struct net_device *out, | 26 | const struct net_device *out, |
25 | const void *matchinfo, | 27 | const void *matchinfo, |
26 | int offset, | 28 | int offset, |
29 | unsigned int protoff, | ||
27 | int *hotdrop) | 30 | int *hotdrop) |
28 | { | 31 | { |
29 | struct ts_state state; | 32 | struct ts_state state; |
30 | struct ipt_string_info *conf = (struct ipt_string_info *) matchinfo; | 33 | struct xt_string_info *conf = (struct xt_string_info *) matchinfo; |
31 | 34 | ||
32 | memset(&state, 0, sizeof(struct ts_state)); | 35 | memset(&state, 0, sizeof(struct ts_state)); |
33 | 36 | ||
@@ -36,18 +39,18 @@ static int match(const struct sk_buff *skb, | |||
36 | != UINT_MAX) && !conf->invert; | 39 | != UINT_MAX) && !conf->invert; |
37 | } | 40 | } |
38 | 41 | ||
39 | #define STRING_TEXT_PRIV(m) ((struct ipt_string_info *) m) | 42 | #define STRING_TEXT_PRIV(m) ((struct xt_string_info *) m) |
40 | 43 | ||
41 | static int checkentry(const char *tablename, | 44 | static int checkentry(const char *tablename, |
42 | const struct ipt_ip *ip, | 45 | const void *ip, |
43 | void *matchinfo, | 46 | void *matchinfo, |
44 | unsigned int matchsize, | 47 | unsigned int matchsize, |
45 | unsigned int hook_mask) | 48 | unsigned int hook_mask) |
46 | { | 49 | { |
47 | struct ipt_string_info *conf = matchinfo; | 50 | struct xt_string_info *conf = matchinfo; |
48 | struct ts_config *ts_conf; | 51 | struct ts_config *ts_conf; |
49 | 52 | ||
50 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_string_info))) | 53 | if (matchsize != XT_ALIGN(sizeof(struct xt_string_info))) |
51 | return 0; | 54 | return 0; |
52 | 55 | ||
53 | /* Damn, can't handle this case properly with iptables... */ | 56 | /* Damn, can't handle this case properly with iptables... */ |
@@ -69,7 +72,14 @@ static void destroy(void *matchinfo, unsigned int matchsize) | |||
69 | textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config); | 72 | textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config); |
70 | } | 73 | } |
71 | 74 | ||
72 | static struct ipt_match string_match = { | 75 | static struct xt_match string_match = { |
76 | .name = "string", | ||
77 | .match = match, | ||
78 | .checkentry = checkentry, | ||
79 | .destroy = destroy, | ||
80 | .me = THIS_MODULE | ||
81 | }; | ||
82 | static struct xt_match string6_match = { | ||
73 | .name = "string", | 83 | .name = "string", |
74 | .match = match, | 84 | .match = match, |
75 | .checkentry = checkentry, | 85 | .checkentry = checkentry, |
@@ -79,12 +89,22 @@ static struct ipt_match string_match = { | |||
79 | 89 | ||
80 | static int __init init(void) | 90 | static int __init init(void) |
81 | { | 91 | { |
82 | return ipt_register_match(&string_match); | 92 | int ret; |
93 | |||
94 | ret = xt_register_match(AF_INET, &string_match); | ||
95 | if (ret) | ||
96 | return ret; | ||
97 | ret = xt_register_match(AF_INET6, &string6_match); | ||
98 | if (ret) | ||
99 | xt_unregister_match(AF_INET, &string_match); | ||
100 | |||
101 | return ret; | ||
83 | } | 102 | } |
84 | 103 | ||
85 | static void __exit fini(void) | 104 | static void __exit fini(void) |
86 | { | 105 | { |
87 | ipt_unregister_match(&string_match); | 106 | xt_unregister_match(AF_INET, &string_match); |
107 | xt_unregister_match(AF_INET6, &string6_match); | ||
88 | } | 108 | } |
89 | 109 | ||
90 | module_init(init); | 110 | module_init(init); |
diff --git a/net/ipv4/netfilter/ipt_tcpmss.c b/net/netfilter/xt_tcpmss.c index 4dc9b16ab4a3..acf7f533e9f1 100644 --- a/net/ipv4/netfilter/ipt_tcpmss.c +++ b/net/netfilter/xt_tcpmss.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* Kernel module to match TCP MSS values. */ | 1 | /* Kernel module to match TCP MSS values. */ |
2 | 2 | ||
3 | /* Copyright (C) 2000 Marc Boucher <marc@mbsi.ca> | 3 | /* Copyright (C) 2000 Marc Boucher <marc@mbsi.ca> |
4 | * Portions (C) 2005 by Harald Welte <laforge@netfilter.org> | ||
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or modify | 6 | * 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 | * it under the terms of the GNU General Public License version 2 as |
@@ -11,19 +12,24 @@ | |||
11 | #include <linux/skbuff.h> | 12 | #include <linux/skbuff.h> |
12 | #include <net/tcp.h> | 13 | #include <net/tcp.h> |
13 | 14 | ||
14 | #include <linux/netfilter_ipv4/ipt_tcpmss.h> | 15 | #include <linux/netfilter/xt_tcpmss.h> |
16 | #include <linux/netfilter/x_tables.h> | ||
17 | |||
15 | #include <linux/netfilter_ipv4/ip_tables.h> | 18 | #include <linux/netfilter_ipv4/ip_tables.h> |
19 | #include <linux/netfilter_ipv6/ip6_tables.h> | ||
16 | 20 | ||
17 | #define TH_SYN 0x02 | 21 | #define TH_SYN 0x02 |
18 | 22 | ||
19 | MODULE_LICENSE("GPL"); | 23 | MODULE_LICENSE("GPL"); |
20 | MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); | 24 | MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); |
21 | MODULE_DESCRIPTION("iptables TCP MSS match module"); | 25 | MODULE_DESCRIPTION("iptables TCP MSS match module"); |
26 | MODULE_ALIAS("ipt_tcpmss"); | ||
22 | 27 | ||
23 | /* Returns 1 if the mss option is set and matched by the range, 0 otherwise */ | 28 | /* Returns 1 if the mss option is set and matched by the range, 0 otherwise */ |
24 | static inline int | 29 | static inline int |
25 | mssoption_match(u_int16_t min, u_int16_t max, | 30 | mssoption_match(u_int16_t min, u_int16_t max, |
26 | const struct sk_buff *skb, | 31 | const struct sk_buff *skb, |
32 | unsigned int protoff, | ||
27 | int invert, | 33 | int invert, |
28 | int *hotdrop) | 34 | int *hotdrop) |
29 | { | 35 | { |
@@ -33,8 +39,7 @@ mssoption_match(u_int16_t min, u_int16_t max, | |||
33 | unsigned int i, optlen; | 39 | unsigned int i, optlen; |
34 | 40 | ||
35 | /* If we don't have the whole header, drop packet. */ | 41 | /* If we don't have the whole header, drop packet. */ |
36 | th = skb_header_pointer(skb, skb->nh.iph->ihl * 4, | 42 | th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); |
37 | sizeof(_tcph), &_tcph); | ||
38 | if (th == NULL) | 43 | if (th == NULL) |
39 | goto dropit; | 44 | goto dropit; |
40 | 45 | ||
@@ -47,8 +52,7 @@ mssoption_match(u_int16_t min, u_int16_t max, | |||
47 | goto out; | 52 | goto out; |
48 | 53 | ||
49 | /* Truncated options. */ | 54 | /* Truncated options. */ |
50 | op = skb_header_pointer(skb, skb->nh.iph->ihl * 4 + sizeof(*th), | 55 | op = skb_header_pointer(skb, protoff + sizeof(*th), optlen, _opt); |
51 | optlen, _opt); | ||
52 | if (op == NULL) | 56 | if (op == NULL) |
53 | goto dropit; | 57 | goto dropit; |
54 | 58 | ||
@@ -79,22 +83,24 @@ match(const struct sk_buff *skb, | |||
79 | const struct net_device *out, | 83 | const struct net_device *out, |
80 | const void *matchinfo, | 84 | const void *matchinfo, |
81 | int offset, | 85 | int offset, |
86 | unsigned int protoff, | ||
82 | int *hotdrop) | 87 | int *hotdrop) |
83 | { | 88 | { |
84 | const struct ipt_tcpmss_match_info *info = matchinfo; | 89 | const struct xt_tcpmss_match_info *info = matchinfo; |
85 | 90 | ||
86 | return mssoption_match(info->mss_min, info->mss_max, skb, | 91 | return mssoption_match(info->mss_min, info->mss_max, skb, protoff, |
87 | info->invert, hotdrop); | 92 | info->invert, hotdrop); |
88 | } | 93 | } |
89 | 94 | ||
90 | static int | 95 | static int |
91 | checkentry(const char *tablename, | 96 | checkentry(const char *tablename, |
92 | const struct ipt_ip *ip, | 97 | const void *ipinfo, |
93 | void *matchinfo, | 98 | void *matchinfo, |
94 | unsigned int matchsize, | 99 | unsigned int matchsize, |
95 | unsigned int hook_mask) | 100 | unsigned int hook_mask) |
96 | { | 101 | { |
97 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_tcpmss_match_info))) | 102 | const struct ipt_ip *ip = ipinfo; |
103 | if (matchsize != XT_ALIGN(sizeof(struct xt_tcpmss_match_info))) | ||
98 | return 0; | 104 | return 0; |
99 | 105 | ||
100 | /* Must specify -p tcp */ | 106 | /* Must specify -p tcp */ |
@@ -106,21 +112,60 @@ checkentry(const char *tablename, | |||
106 | return 1; | 112 | return 1; |
107 | } | 113 | } |
108 | 114 | ||
109 | static struct ipt_match tcpmss_match = { | 115 | static int |
116 | checkentry6(const char *tablename, | ||
117 | const void *ipinfo, | ||
118 | void *matchinfo, | ||
119 | unsigned int matchsize, | ||
120 | unsigned int hook_mask) | ||
121 | { | ||
122 | const struct ip6t_ip6 *ip = ipinfo; | ||
123 | |||
124 | if (matchsize != XT_ALIGN(sizeof(struct xt_tcpmss_match_info))) | ||
125 | return 0; | ||
126 | |||
127 | /* Must specify -p tcp */ | ||
128 | if (ip->proto != IPPROTO_TCP || (ip->invflags & XT_INV_PROTO)) { | ||
129 | printk("tcpmss: Only works on TCP packets\n"); | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | return 1; | ||
134 | } | ||
135 | |||
136 | static struct xt_match tcpmss_match = { | ||
110 | .name = "tcpmss", | 137 | .name = "tcpmss", |
111 | .match = &match, | 138 | .match = &match, |
112 | .checkentry = &checkentry, | 139 | .checkentry = &checkentry, |
113 | .me = THIS_MODULE, | 140 | .me = THIS_MODULE, |
114 | }; | 141 | }; |
115 | 142 | ||
143 | static struct xt_match tcpmss6_match = { | ||
144 | .name = "tcpmss", | ||
145 | .match = &match, | ||
146 | .checkentry = &checkentry6, | ||
147 | .me = THIS_MODULE, | ||
148 | }; | ||
149 | |||
150 | |||
116 | static int __init init(void) | 151 | static int __init init(void) |
117 | { | 152 | { |
118 | return ipt_register_match(&tcpmss_match); | 153 | int ret; |
154 | ret = xt_register_match(AF_INET, &tcpmss_match); | ||
155 | if (ret) | ||
156 | return ret; | ||
157 | |||
158 | ret = xt_register_match(AF_INET6, &tcpmss6_match); | ||
159 | if (ret) | ||
160 | xt_unregister_match(AF_INET, &tcpmss_match); | ||
161 | |||
162 | return ret; | ||
119 | } | 163 | } |
120 | 164 | ||
121 | static void __exit fini(void) | 165 | static void __exit fini(void) |
122 | { | 166 | { |
123 | ipt_unregister_match(&tcpmss_match); | 167 | xt_unregister_match(AF_INET6, &tcpmss6_match); |
168 | xt_unregister_match(AF_INET, &tcpmss_match); | ||
124 | } | 169 | } |
125 | 170 | ||
126 | module_init(init); | 171 | module_init(init); |
diff --git a/net/netfilter/xt_tcpudp.c b/net/netfilter/xt_tcpudp.c new file mode 100644 index 000000000000..33f86fd6f3e6 --- /dev/null +++ b/net/netfilter/xt_tcpudp.c | |||
@@ -0,0 +1,333 @@ | |||
1 | #include <linux/types.h> | ||
2 | #include <linux/module.h> | ||
3 | #include <net/ip.h> | ||
4 | #include <net/ipv6.h> | ||
5 | #include <net/tcp.h> | ||
6 | #include <net/udp.h> | ||
7 | #include <linux/netfilter/x_tables.h> | ||
8 | #include <linux/netfilter/xt_tcpudp.h> | ||
9 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
10 | #include <linux/netfilter_ipv6/ip6_tables.h> | ||
11 | |||
12 | MODULE_DESCRIPTION("x_tables match for TCP and UDP, supports IPv4 and IPv6"); | ||
13 | MODULE_LICENSE("GPL"); | ||
14 | MODULE_ALIAS("xt_tcp"); | ||
15 | MODULE_ALIAS("xt_udp"); | ||
16 | MODULE_ALIAS("ipt_udp"); | ||
17 | MODULE_ALIAS("ipt_tcp"); | ||
18 | MODULE_ALIAS("ip6t_udp"); | ||
19 | MODULE_ALIAS("ip6t_tcp"); | ||
20 | |||
21 | #ifdef DEBUG_IP_FIREWALL_USER | ||
22 | #define duprintf(format, args...) printk(format , ## args) | ||
23 | #else | ||
24 | #define duprintf(format, args...) | ||
25 | #endif | ||
26 | |||
27 | |||
28 | /* Returns 1 if the port is matched by the range, 0 otherwise */ | ||
29 | static inline int | ||
30 | port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert) | ||
31 | { | ||
32 | int ret; | ||
33 | |||
34 | ret = (port >= min && port <= max) ^ invert; | ||
35 | return ret; | ||
36 | } | ||
37 | |||
38 | static int | ||
39 | tcp_find_option(u_int8_t option, | ||
40 | const struct sk_buff *skb, | ||
41 | unsigned int protoff, | ||
42 | unsigned int optlen, | ||
43 | int invert, | ||
44 | int *hotdrop) | ||
45 | { | ||
46 | /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ | ||
47 | u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; | ||
48 | unsigned int i; | ||
49 | |||
50 | duprintf("tcp_match: finding option\n"); | ||
51 | |||
52 | if (!optlen) | ||
53 | return invert; | ||
54 | |||
55 | /* If we don't have the whole header, drop packet. */ | ||
56 | op = skb_header_pointer(skb, protoff + sizeof(struct tcphdr), | ||
57 | optlen, _opt); | ||
58 | if (op == NULL) { | ||
59 | *hotdrop = 1; | ||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | for (i = 0; i < optlen; ) { | ||
64 | if (op[i] == option) return !invert; | ||
65 | if (op[i] < 2) i++; | ||
66 | else i += op[i+1]?:1; | ||
67 | } | ||
68 | |||
69 | return invert; | ||
70 | } | ||
71 | |||
72 | static int | ||
73 | tcp_match(const struct sk_buff *skb, | ||
74 | const struct net_device *in, | ||
75 | const struct net_device *out, | ||
76 | const void *matchinfo, | ||
77 | int offset, | ||
78 | unsigned int protoff, | ||
79 | int *hotdrop) | ||
80 | { | ||
81 | struct tcphdr _tcph, *th; | ||
82 | const struct xt_tcp *tcpinfo = matchinfo; | ||
83 | |||
84 | if (offset) { | ||
85 | /* To quote Alan: | ||
86 | |||
87 | Don't allow a fragment of TCP 8 bytes in. Nobody normal | ||
88 | causes this. Its a cracker trying to break in by doing a | ||
89 | flag overwrite to pass the direction checks. | ||
90 | */ | ||
91 | if (offset == 1) { | ||
92 | duprintf("Dropping evil TCP offset=1 frag.\n"); | ||
93 | *hotdrop = 1; | ||
94 | } | ||
95 | /* Must not be a fragment. */ | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | #define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) | ||
100 | |||
101 | th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); | ||
102 | if (th == NULL) { | ||
103 | /* We've been asked to examine this packet, and we | ||
104 | can't. Hence, no choice but to drop. */ | ||
105 | duprintf("Dropping evil TCP offset=0 tinygram.\n"); | ||
106 | *hotdrop = 1; | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1], | ||
111 | ntohs(th->source), | ||
112 | !!(tcpinfo->invflags & XT_TCP_INV_SRCPT))) | ||
113 | return 0; | ||
114 | if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1], | ||
115 | ntohs(th->dest), | ||
116 | !!(tcpinfo->invflags & XT_TCP_INV_DSTPT))) | ||
117 | return 0; | ||
118 | if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask) | ||
119 | == tcpinfo->flg_cmp, | ||
120 | XT_TCP_INV_FLAGS)) | ||
121 | return 0; | ||
122 | if (tcpinfo->option) { | ||
123 | if (th->doff * 4 < sizeof(_tcph)) { | ||
124 | *hotdrop = 1; | ||
125 | return 0; | ||
126 | } | ||
127 | if (!tcp_find_option(tcpinfo->option, skb, protoff, | ||
128 | th->doff*4 - sizeof(_tcph), | ||
129 | tcpinfo->invflags & XT_TCP_INV_OPTION, | ||
130 | hotdrop)) | ||
131 | return 0; | ||
132 | } | ||
133 | return 1; | ||
134 | } | ||
135 | |||
136 | /* Called when user tries to insert an entry of this type. */ | ||
137 | static int | ||
138 | tcp_checkentry(const char *tablename, | ||
139 | const void *info, | ||
140 | void *matchinfo, | ||
141 | unsigned int matchsize, | ||
142 | unsigned int hook_mask) | ||
143 | { | ||
144 | const struct ipt_ip *ip = info; | ||
145 | const struct xt_tcp *tcpinfo = matchinfo; | ||
146 | |||
147 | /* Must specify proto == TCP, and no unknown invflags */ | ||
148 | return ip->proto == IPPROTO_TCP | ||
149 | && !(ip->invflags & XT_INV_PROTO) | ||
150 | && matchsize == XT_ALIGN(sizeof(struct xt_tcp)) | ||
151 | && !(tcpinfo->invflags & ~XT_TCP_INV_MASK); | ||
152 | } | ||
153 | |||
154 | /* Called when user tries to insert an entry of this type. */ | ||
155 | static int | ||
156 | tcp6_checkentry(const char *tablename, | ||
157 | const void *entry, | ||
158 | void *matchinfo, | ||
159 | unsigned int matchsize, | ||
160 | unsigned int hook_mask) | ||
161 | { | ||
162 | const struct ip6t_ip6 *ipv6 = entry; | ||
163 | const struct xt_tcp *tcpinfo = matchinfo; | ||
164 | |||
165 | /* Must specify proto == TCP, and no unknown invflags */ | ||
166 | return ipv6->proto == IPPROTO_TCP | ||
167 | && !(ipv6->invflags & XT_INV_PROTO) | ||
168 | && matchsize == XT_ALIGN(sizeof(struct xt_tcp)) | ||
169 | && !(tcpinfo->invflags & ~XT_TCP_INV_MASK); | ||
170 | } | ||
171 | |||
172 | |||
173 | static int | ||
174 | udp_match(const struct sk_buff *skb, | ||
175 | const struct net_device *in, | ||
176 | const struct net_device *out, | ||
177 | const void *matchinfo, | ||
178 | int offset, | ||
179 | unsigned int protoff, | ||
180 | int *hotdrop) | ||
181 | { | ||
182 | struct udphdr _udph, *uh; | ||
183 | const struct xt_udp *udpinfo = matchinfo; | ||
184 | |||
185 | /* Must not be a fragment. */ | ||
186 | if (offset) | ||
187 | return 0; | ||
188 | |||
189 | uh = skb_header_pointer(skb, protoff, sizeof(_udph), &_udph); | ||
190 | if (uh == NULL) { | ||
191 | /* We've been asked to examine this packet, and we | ||
192 | can't. Hence, no choice but to drop. */ | ||
193 | duprintf("Dropping evil UDP tinygram.\n"); | ||
194 | *hotdrop = 1; | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | return port_match(udpinfo->spts[0], udpinfo->spts[1], | ||
199 | ntohs(uh->source), | ||
200 | !!(udpinfo->invflags & XT_UDP_INV_SRCPT)) | ||
201 | && port_match(udpinfo->dpts[0], udpinfo->dpts[1], | ||
202 | ntohs(uh->dest), | ||
203 | !!(udpinfo->invflags & XT_UDP_INV_DSTPT)); | ||
204 | } | ||
205 | |||
206 | /* Called when user tries to insert an entry of this type. */ | ||
207 | static int | ||
208 | udp_checkentry(const char *tablename, | ||
209 | const void *info, | ||
210 | void *matchinfo, | ||
211 | unsigned int matchinfosize, | ||
212 | unsigned int hook_mask) | ||
213 | { | ||
214 | const struct ipt_ip *ip = info; | ||
215 | const struct xt_udp *udpinfo = matchinfo; | ||
216 | |||
217 | /* Must specify proto == UDP, and no unknown invflags */ | ||
218 | if (ip->proto != IPPROTO_UDP || (ip->invflags & XT_INV_PROTO)) { | ||
219 | duprintf("ipt_udp: Protocol %u != %u\n", ip->proto, | ||
220 | IPPROTO_UDP); | ||
221 | return 0; | ||
222 | } | ||
223 | if (matchinfosize != XT_ALIGN(sizeof(struct xt_udp))) { | ||
224 | duprintf("ipt_udp: matchsize %u != %u\n", | ||
225 | matchinfosize, XT_ALIGN(sizeof(struct xt_udp))); | ||
226 | return 0; | ||
227 | } | ||
228 | if (udpinfo->invflags & ~XT_UDP_INV_MASK) { | ||
229 | duprintf("ipt_udp: unknown flags %X\n", | ||
230 | udpinfo->invflags); | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | return 1; | ||
235 | } | ||
236 | |||
237 | /* Called when user tries to insert an entry of this type. */ | ||
238 | static int | ||
239 | udp6_checkentry(const char *tablename, | ||
240 | const void *entry, | ||
241 | void *matchinfo, | ||
242 | unsigned int matchinfosize, | ||
243 | unsigned int hook_mask) | ||
244 | { | ||
245 | const struct ip6t_ip6 *ipv6 = entry; | ||
246 | const struct xt_udp *udpinfo = matchinfo; | ||
247 | |||
248 | /* Must specify proto == UDP, and no unknown invflags */ | ||
249 | if (ipv6->proto != IPPROTO_UDP || (ipv6->invflags & XT_INV_PROTO)) { | ||
250 | duprintf("ip6t_udp: Protocol %u != %u\n", ipv6->proto, | ||
251 | IPPROTO_UDP); | ||
252 | return 0; | ||
253 | } | ||
254 | if (matchinfosize != XT_ALIGN(sizeof(struct xt_udp))) { | ||
255 | duprintf("ip6t_udp: matchsize %u != %u\n", | ||
256 | matchinfosize, XT_ALIGN(sizeof(struct xt_udp))); | ||
257 | return 0; | ||
258 | } | ||
259 | if (udpinfo->invflags & ~XT_UDP_INV_MASK) { | ||
260 | duprintf("ip6t_udp: unknown flags %X\n", | ||
261 | udpinfo->invflags); | ||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | return 1; | ||
266 | } | ||
267 | |||
268 | static struct xt_match tcp_matchstruct = { | ||
269 | .name = "tcp", | ||
270 | .match = &tcp_match, | ||
271 | .checkentry = &tcp_checkentry, | ||
272 | .me = THIS_MODULE, | ||
273 | }; | ||
274 | static struct xt_match tcp6_matchstruct = { | ||
275 | .name = "tcp", | ||
276 | .match = &tcp_match, | ||
277 | .checkentry = &tcp6_checkentry, | ||
278 | .me = THIS_MODULE, | ||
279 | }; | ||
280 | |||
281 | static struct xt_match udp_matchstruct = { | ||
282 | .name = "udp", | ||
283 | .match = &udp_match, | ||
284 | .checkentry = &udp_checkentry, | ||
285 | .me = THIS_MODULE, | ||
286 | }; | ||
287 | static struct xt_match udp6_matchstruct = { | ||
288 | .name = "udp", | ||
289 | .match = &udp_match, | ||
290 | .checkentry = &udp6_checkentry, | ||
291 | .me = THIS_MODULE, | ||
292 | }; | ||
293 | |||
294 | static int __init init(void) | ||
295 | { | ||
296 | int ret; | ||
297 | ret = xt_register_match(AF_INET, &tcp_matchstruct); | ||
298 | if (ret) | ||
299 | return ret; | ||
300 | |||
301 | ret = xt_register_match(AF_INET6, &tcp6_matchstruct); | ||
302 | if (ret) | ||
303 | goto out_unreg_tcp; | ||
304 | |||
305 | ret = xt_register_match(AF_INET, &udp_matchstruct); | ||
306 | if (ret) | ||
307 | goto out_unreg_tcp6; | ||
308 | |||
309 | ret = xt_register_match(AF_INET6, &udp6_matchstruct); | ||
310 | if (ret) | ||
311 | goto out_unreg_udp; | ||
312 | |||
313 | return ret; | ||
314 | |||
315 | out_unreg_udp: | ||
316 | xt_unregister_match(AF_INET, &tcp_matchstruct); | ||
317 | out_unreg_tcp6: | ||
318 | xt_unregister_match(AF_INET6, &tcp6_matchstruct); | ||
319 | out_unreg_tcp: | ||
320 | xt_unregister_match(AF_INET, &tcp_matchstruct); | ||
321 | return ret; | ||
322 | } | ||
323 | |||
324 | static void __exit fini(void) | ||
325 | { | ||
326 | xt_unregister_match(AF_INET6, &udp6_matchstruct); | ||
327 | xt_unregister_match(AF_INET, &udp_matchstruct); | ||
328 | xt_unregister_match(AF_INET6, &tcp6_matchstruct); | ||
329 | xt_unregister_match(AF_INET, &tcp_matchstruct); | ||
330 | } | ||
331 | |||
332 | module_init(init); | ||
333 | module_exit(fini); | ||
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index b5001939b74b..39a22a3ffe78 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c | |||
@@ -62,7 +62,7 @@ ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook) | |||
62 | struct ipt_target *target; | 62 | struct ipt_target *target; |
63 | int ret = 0; | 63 | int ret = 0; |
64 | 64 | ||
65 | target = ipt_find_target(t->u.user.name, t->u.user.revision); | 65 | target = xt_find_target(AF_INET, t->u.user.name, t->u.user.revision); |
66 | if (!target) | 66 | if (!target) |
67 | return -ENOENT; | 67 | return -ENOENT; |
68 | 68 | ||