aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-10-08 12:50:38 -0400
committerDavid S. Miller <davem@davemloft.net>2008-10-08 12:50:38 -0400
commit364ae953a48152be11f1aa424cbfd943b7762b0d (patch)
tree6873b352af1aa2dd6baa223b951eff4d6e74b1ae /net
parent075f664689b40217539ebfe856fab73d302a15f1 (diff)
parentf39a9410ed0503278fd5edc559fa019051413039 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
Diffstat (limited to 'net')
-rw-r--r--net/bridge/br_netfilter.c4
-rw-r--r--net/bridge/netfilter/Kconfig30
-rw-r--r--net/bridge/netfilter/ebt_802_3.c47
-rw-r--r--net/bridge/netfilter/ebt_among.c85
-rw-r--r--net/bridge/netfilter/ebt_arp.c73
-rw-r--r--net/bridge/netfilter/ebt_arpreply.c49
-rw-r--r--net/bridge/netfilter/ebt_dnat.c57
-rw-r--r--net/bridge/netfilter/ebt_ip.c72
-rw-r--r--net/bridge/netfilter/ebt_ip6.c76
-rw-r--r--net/bridge/netfilter/ebt_limit.c45
-rw-r--r--net/bridge/netfilter/ebt_log.c57
-rw-r--r--net/bridge/netfilter/ebt_mark.c41
-rw-r--r--net/bridge/netfilter/ebt_mark_m.c45
-rw-r--r--net/bridge/netfilter/ebt_nflog.c44
-rw-r--r--net/bridge/netfilter/ebt_pkttype.c41
-rw-r--r--net/bridge/netfilter/ebt_redirect.c63
-rw-r--r--net/bridge/netfilter/ebt_snat.c52
-rw-r--r--net/bridge/netfilter/ebt_stp.c78
-rw-r--r--net/bridge/netfilter/ebt_ulog.c58
-rw-r--r--net/bridge/netfilter/ebt_vlan.c61
-rw-r--r--net/bridge/netfilter/ebtables.c313
-rw-r--r--net/core/net_namespace.c1
-rw-r--r--net/ipv4/netfilter.c7
-rw-r--r--net/ipv4/netfilter/Kconfig128
-rw-r--r--net/ipv4/netfilter/Makefile4
-rw-r--r--net/ipv4/netfilter/arp_tables.c116
-rw-r--r--net/ipv4/netfilter/arpt_mangle.c15
-rw-r--r--net/ipv4/netfilter/arptable_filter.c8
-rw-r--r--net/ipv4/netfilter/ip_tables.c177
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c29
-rw-r--r--net/ipv4/netfilter/ipt_ECN.c17
-rw-r--r--net/ipv4/netfilter/ipt_LOG.c21
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c30
-rw-r--r--net/ipv4/netfilter/ipt_NETMAP.c26
-rw-r--r--net/ipv4/netfilter/ipt_REDIRECT.c21
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c19
-rw-r--r--net/ipv4/netfilter/ipt_TTL.c15
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c23
-rw-r--r--net/ipv4/netfilter/ipt_addrtype.c35
-rw-r--r--net/ipv4/netfilter/ipt_ah.c24
-rw-r--r--net/ipv4/netfilter/ipt_ecn.c20
-rw-r--r--net/ipv4/netfilter/ipt_ttl.c9
-rw-r--r--net/ipv4/netfilter/iptable_filter.c6
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c10
-rw-r--r--net/ipv4/netfilter/iptable_raw.c4
-rw-r--r--net/ipv4/netfilter/iptable_security.c6
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c68
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c73
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c22
-rw-r--r--net/ipv4/netfilter/nf_defrag_ipv4.c96
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c72
-rw-r--r--net/ipv4/netfilter/nf_nat_helper.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_pptp.c3
-rw-r--r--net/ipv4/netfilter/nf_nat_rule.c92
-rw-r--r--net/ipv6/netfilter.c2
-rw-r--r--net/ipv6/netfilter/Kconfig77
-rw-r--r--net/ipv6/netfilter/ip6_tables.c173
-rw-r--r--net/ipv6/netfilter/ip6t_HL.c15
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c22
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c39
-rw-r--r--net/ipv6/netfilter/ip6t_ah.c21
-rw-r--r--net/ipv6/netfilter/ip6t_eui64.c11
-rw-r--r--net/ipv6/netfilter/ip6t_frag.c21
-rw-r--r--net/ipv6/netfilter/ip6t_hbh.c25
-rw-r--r--net/ipv6/netfilter/ip6t_hl.c9
-rw-r--r--net/ipv6/netfilter/ip6t_ipv6header.c16
-rw-r--r--net/ipv6/netfilter/ip6t_mh.c25
-rw-r--r--net/ipv6/netfilter/ip6t_rt.c21
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c6
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c31
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c20
-rw-r--r--net/ipv6/netfilter/ip6table_security.c6
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c24
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c19
-rw-r--r--net/netfilter/Kconfig236
-rw-r--r--net/netfilter/Makefile6
-rw-r--r--net/netfilter/core.c18
-rw-r--r--net/netfilter/nf_conntrack_acct.c100
-rw-r--r--net/netfilter/nf_conntrack_core.c344
-rw-r--r--net/netfilter/nf_conntrack_ecache.c26
-rw-r--r--net/netfilter/nf_conntrack_expect.c104
-rw-r--r--net/netfilter/nf_conntrack_ftp.c9
-rw-r--r--net/netfilter/nf_conntrack_h323_main.c6
-rw-r--r--net/netfilter/nf_conntrack_helper.c40
-rw-r--r--net/netfilter/nf_conntrack_netlink.c31
-rw-r--r--net/netfilter/nf_conntrack_pptp.c36
-rw-r--r--net/netfilter/nf_conntrack_proto.c10
-rw-r--r--net/netfilter/nf_conntrack_proto_dccp.c20
-rw-r--r--net/netfilter/nf_conntrack_proto_generic.c2
-rw-r--r--net/netfilter/nf_conntrack_proto_gre.c101
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c6
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c35
-rw-r--r--net/netfilter/nf_conntrack_proto_udp.c16
-rw-r--r--net/netfilter/nf_conntrack_proto_udplite.c20
-rw-r--r--net/netfilter/nf_conntrack_sip.c3
-rw-r--r--net/netfilter/nf_conntrack_standalone.c146
-rw-r--r--net/netfilter/nf_internals.h4
-rw-r--r--net/netfilter/nf_log.c18
-rw-r--r--net/netfilter/nf_queue.c22
-rw-r--r--net/netfilter/nf_sockopt.c18
-rw-r--r--net/netfilter/nf_tproxy_core.c96
-rw-r--r--net/netfilter/nfnetlink_log.c4
-rw-r--r--net/netfilter/x_tables.c145
-rw-r--r--net/netfilter/xt_CLASSIFY.c44
-rw-r--r--net/netfilter/xt_CONNMARK.c78
-rw-r--r--net/netfilter/xt_CONNSECMARK.c63
-rw-r--r--net/netfilter/xt_DSCP.c59
-rw-r--r--net/netfilter/xt_MARK.c76
-rw-r--r--net/netfilter/xt_NFLOG.c46
-rw-r--r--net/netfilter/xt_NFQUEUE.c10
-rw-r--r--net/netfilter/xt_NOTRACK.c30
-rw-r--r--net/netfilter/xt_RATEEST.c56
-rw-r--r--net/netfilter/xt_SECMARK.c52
-rw-r--r--net/netfilter/xt_TCPMSS.c38
-rw-r--r--net/netfilter/xt_TCPOPTSTRIP.c16
-rw-r--r--net/netfilter/xt_TPROXY.c102
-rw-r--r--net/netfilter/xt_TRACE.c30
-rw-r--r--net/netfilter/xt_comment.c31
-rw-r--r--net/netfilter/xt_connbytes.c56
-rw-r--r--net/netfilter/xt_connlimit.c80
-rw-r--r--net/netfilter/xt_connmark.c68
-rw-r--r--net/netfilter/xt_conntrack.c62
-rw-r--r--net/netfilter/xt_dccp.c27
-rw-r--r--net/netfilter/xt_dscp.c51
-rw-r--r--net/netfilter/xt_esp.c25
-rw-r--r--net/netfilter/xt_hashlimit.c104
-rw-r--r--net/netfilter/xt_helper.c54
-rw-r--r--net/netfilter/xt_iprange.c27
-rw-r--r--net/netfilter/xt_length.c18
-rw-r--r--net/netfilter/xt_limit.c54
-rw-r--r--net/netfilter/xt_mac.c41
-rw-r--r--net/netfilter/xt_mark.c46
-rw-r--r--net/netfilter/xt_multiport.c71
-rw-r--r--net/netfilter/xt_owner.c51
-rw-r--r--net/netfilter/xt_physdev.c49
-rw-r--r--net/netfilter/xt_pkttype.c37
-rw-r--r--net/netfilter/xt_policy.c34
-rw-r--r--net/netfilter/xt_quota.c43
-rw-r--r--net/netfilter/xt_rateest.c58
-rw-r--r--net/netfilter/xt_realm.c9
-rw-r--r--net/netfilter/xt_recent.c (renamed from net/ipv4/netfilter/ipt_recent.c)348
-rw-r--r--net/netfilter/xt_sctp.c27
-rw-r--r--net/netfilter/xt_socket.c185
-rw-r--r--net/netfilter/xt_state.c24
-rw-r--r--net/netfilter/xt_statistic.c45
-rw-r--r--net/netfilter/xt_string.c53
-rw-r--r--net/netfilter/xt_tcpmss.c17
-rw-r--r--net/netfilter/xt_tcpudp.c64
-rw-r--r--net/netfilter/xt_time.c41
-rw-r--r--net/netfilter/xt_u32.c33
-rw-r--r--net/sched/act_ipt.c46
151 files changed, 3795 insertions, 3679 deletions
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 6a9a6cd74b1e..a4abed5b4c44 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -657,7 +657,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
657{ 657{
658 struct nf_bridge_info *nf_bridge; 658 struct nf_bridge_info *nf_bridge;
659 struct net_device *parent; 659 struct net_device *parent;
660 int pf; 660 u_int8_t pf;
661 661
662 if (!skb->nf_bridge) 662 if (!skb->nf_bridge)
663 return NF_ACCEPT; 663 return NF_ACCEPT;
@@ -791,7 +791,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
791{ 791{
792 struct nf_bridge_info *nf_bridge = skb->nf_bridge; 792 struct nf_bridge_info *nf_bridge = skb->nf_bridge;
793 struct net_device *realoutdev = bridge_parent(skb->dev); 793 struct net_device *realoutdev = bridge_parent(skb->dev);
794 int pf; 794 u_int8_t pf;
795 795
796#ifdef CONFIG_NETFILTER_DEBUG 796#ifdef CONFIG_NETFILTER_DEBUG
797 /* Be very paranoid. This probably won't happen anymore, but let's 797 /* Be very paranoid. This probably won't happen anymore, but let's
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
index 909479794999..366d3e9d51f8 100644
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -2,21 +2,21 @@
2# Bridge netfilter configuration 2# Bridge netfilter configuration
3# 3#
4 4
5menu "Bridge: Netfilter Configuration" 5menuconfig BRIDGE_NF_EBTABLES
6 depends on BRIDGE && BRIDGE_NETFILTER
7
8config BRIDGE_NF_EBTABLES
9 tristate "Ethernet Bridge tables (ebtables) support" 6 tristate "Ethernet Bridge tables (ebtables) support"
7 select NETFILTER_XTABLES
10 help 8 help
11 ebtables is a general, extensible frame/packet identification 9 ebtables is a general, extensible frame/packet identification
12 framework. Say 'Y' or 'M' here if you want to do Ethernet 10 framework. Say 'Y' or 'M' here if you want to do Ethernet
13 filtering/NAT/brouting on the Ethernet bridge. 11 filtering/NAT/brouting on the Ethernet bridge.
12
13if BRIDGE_NF_EBTABLES
14
14# 15#
15# tables 16# tables
16# 17#
17config BRIDGE_EBT_BROUTE 18config BRIDGE_EBT_BROUTE
18 tristate "ebt: broute table support" 19 tristate "ebt: broute table support"
19 depends on BRIDGE_NF_EBTABLES
20 help 20 help
21 The ebtables broute table is used to define rules that decide between 21 The ebtables broute table is used to define rules that decide between
22 bridging and routing frames, giving Linux the functionality of a 22 bridging and routing frames, giving Linux the functionality of a
@@ -27,7 +27,6 @@ config BRIDGE_EBT_BROUTE
27 27
28config BRIDGE_EBT_T_FILTER 28config BRIDGE_EBT_T_FILTER
29 tristate "ebt: filter table support" 29 tristate "ebt: filter table support"
30 depends on BRIDGE_NF_EBTABLES
31 help 30 help
32 The ebtables filter table is used to define frame filtering rules at 31 The ebtables filter table is used to define frame filtering rules at
33 local input, forwarding and local output. See the man page for 32 local input, forwarding and local output. See the man page for
@@ -37,7 +36,6 @@ config BRIDGE_EBT_T_FILTER
37 36
38config BRIDGE_EBT_T_NAT 37config BRIDGE_EBT_T_NAT
39 tristate "ebt: nat table support" 38 tristate "ebt: nat table support"
40 depends on BRIDGE_NF_EBTABLES
41 help 39 help
42 The ebtables nat table is used to define rules that alter the MAC 40 The ebtables nat table is used to define rules that alter the MAC
43 source address (MAC SNAT) or the MAC destination address (MAC DNAT). 41 source address (MAC SNAT) or the MAC destination address (MAC DNAT).
@@ -49,7 +47,6 @@ config BRIDGE_EBT_T_NAT
49# 47#
50config BRIDGE_EBT_802_3 48config BRIDGE_EBT_802_3
51 tristate "ebt: 802.3 filter support" 49 tristate "ebt: 802.3 filter support"
52 depends on BRIDGE_NF_EBTABLES
53 help 50 help
54 This option adds matching support for 802.3 Ethernet frames. 51 This option adds matching support for 802.3 Ethernet frames.
55 52
@@ -57,7 +54,6 @@ config BRIDGE_EBT_802_3
57 54
58config BRIDGE_EBT_AMONG 55config BRIDGE_EBT_AMONG
59 tristate "ebt: among filter support" 56 tristate "ebt: among filter support"
60 depends on BRIDGE_NF_EBTABLES
61 help 57 help
62 This option adds the among match, which allows matching the MAC source 58 This option adds the among match, which allows matching the MAC source
63 and/or destination address on a list of addresses. Optionally, 59 and/or destination address on a list of addresses. Optionally,
@@ -67,7 +63,6 @@ config BRIDGE_EBT_AMONG
67 63
68config BRIDGE_EBT_ARP 64config BRIDGE_EBT_ARP
69 tristate "ebt: ARP filter support" 65 tristate "ebt: ARP filter support"
70 depends on BRIDGE_NF_EBTABLES
71 help 66 help
72 This option adds the ARP match, which allows ARP and RARP header field 67 This option adds the ARP match, which allows ARP and RARP header field
73 filtering. 68 filtering.
@@ -76,7 +71,6 @@ config BRIDGE_EBT_ARP
76 71
77config BRIDGE_EBT_IP 72config BRIDGE_EBT_IP
78 tristate "ebt: IP filter support" 73 tristate "ebt: IP filter support"
79 depends on BRIDGE_NF_EBTABLES
80 help 74 help
81 This option adds the IP match, which allows basic IP header field 75 This option adds the IP match, which allows basic IP header field
82 filtering. 76 filtering.
@@ -94,7 +88,6 @@ config BRIDGE_EBT_IP6
94 88
95config BRIDGE_EBT_LIMIT 89config BRIDGE_EBT_LIMIT
96 tristate "ebt: limit match support" 90 tristate "ebt: limit match support"
97 depends on BRIDGE_NF_EBTABLES
98 help 91 help
99 This option adds the limit match, which allows you to control 92 This option adds the limit match, which allows you to control
100 the rate at which a rule can be matched. This match is the 93 the rate at which a rule can be matched. This match is the
@@ -105,7 +98,6 @@ config BRIDGE_EBT_LIMIT
105 98
106config BRIDGE_EBT_MARK 99config BRIDGE_EBT_MARK
107 tristate "ebt: mark filter support" 100 tristate "ebt: mark filter support"
108 depends on BRIDGE_NF_EBTABLES
109 help 101 help
110 This option adds the mark match, which allows matching frames based on 102 This option adds the mark match, which allows matching frames based on
111 the 'nfmark' value in the frame. This can be set by the mark target. 103 the 'nfmark' value in the frame. This can be set by the mark target.
@@ -116,7 +108,6 @@ config BRIDGE_EBT_MARK
116 108
117config BRIDGE_EBT_PKTTYPE 109config BRIDGE_EBT_PKTTYPE
118 tristate "ebt: packet type filter support" 110 tristate "ebt: packet type filter support"
119 depends on BRIDGE_NF_EBTABLES
120 help 111 help
121 This option adds the packet type match, which allows matching on the 112 This option adds the packet type match, which allows matching on the
122 type of packet based on its Ethernet "class" (as determined by 113 type of packet based on its Ethernet "class" (as determined by
@@ -127,7 +118,6 @@ config BRIDGE_EBT_PKTTYPE
127 118
128config BRIDGE_EBT_STP 119config BRIDGE_EBT_STP
129 tristate "ebt: STP filter support" 120 tristate "ebt: STP filter support"
130 depends on BRIDGE_NF_EBTABLES
131 help 121 help
132 This option adds the Spanning Tree Protocol match, which 122 This option adds the Spanning Tree Protocol match, which
133 allows STP header field filtering. 123 allows STP header field filtering.
@@ -136,7 +126,6 @@ config BRIDGE_EBT_STP
136 126
137config BRIDGE_EBT_VLAN 127config BRIDGE_EBT_VLAN
138 tristate "ebt: 802.1Q VLAN filter support" 128 tristate "ebt: 802.1Q VLAN filter support"
139 depends on BRIDGE_NF_EBTABLES
140 help 129 help
141 This option adds the 802.1Q vlan match, which allows the filtering of 130 This option adds the 802.1Q vlan match, which allows the filtering of
142 802.1Q vlan fields. 131 802.1Q vlan fields.
@@ -156,7 +145,6 @@ config BRIDGE_EBT_ARPREPLY
156 145
157config BRIDGE_EBT_DNAT 146config BRIDGE_EBT_DNAT
158 tristate "ebt: dnat target support" 147 tristate "ebt: dnat target support"
159 depends on BRIDGE_NF_EBTABLES
160 help 148 help
161 This option adds the MAC DNAT target, which allows altering the MAC 149 This option adds the MAC DNAT target, which allows altering the MAC
162 destination address of frames. 150 destination address of frames.
@@ -165,7 +153,6 @@ config BRIDGE_EBT_DNAT
165 153
166config BRIDGE_EBT_MARK_T 154config BRIDGE_EBT_MARK_T
167 tristate "ebt: mark target support" 155 tristate "ebt: mark target support"
168 depends on BRIDGE_NF_EBTABLES
169 help 156 help
170 This option adds the mark target, which allows marking frames by 157 This option adds the mark target, which allows marking frames by
171 setting the 'nfmark' value in the frame. 158 setting the 'nfmark' value in the frame.
@@ -176,7 +163,6 @@ config BRIDGE_EBT_MARK_T
176 163
177config BRIDGE_EBT_REDIRECT 164config BRIDGE_EBT_REDIRECT
178 tristate "ebt: redirect target support" 165 tristate "ebt: redirect target support"
179 depends on BRIDGE_NF_EBTABLES
180 help 166 help
181 This option adds the MAC redirect target, which allows altering the MAC 167 This option adds the MAC redirect target, which allows altering the MAC
182 destination address of a frame to that of the device it arrived on. 168 destination address of a frame to that of the device it arrived on.
@@ -185,7 +171,6 @@ config BRIDGE_EBT_REDIRECT
185 171
186config BRIDGE_EBT_SNAT 172config BRIDGE_EBT_SNAT
187 tristate "ebt: snat target support" 173 tristate "ebt: snat target support"
188 depends on BRIDGE_NF_EBTABLES
189 help 174 help
190 This option adds the MAC SNAT target, which allows altering the MAC 175 This option adds the MAC SNAT target, which allows altering the MAC
191 source address of frames. 176 source address of frames.
@@ -196,7 +181,6 @@ config BRIDGE_EBT_SNAT
196# 181#
197config BRIDGE_EBT_LOG 182config BRIDGE_EBT_LOG
198 tristate "ebt: log support" 183 tristate "ebt: log support"
199 depends on BRIDGE_NF_EBTABLES
200 help 184 help
201 This option adds the log watcher, that you can use in any rule 185 This option adds the log watcher, that you can use in any rule
202 in any ebtables table. It records info about the frame header 186 in any ebtables table. It records info about the frame header
@@ -206,7 +190,6 @@ config BRIDGE_EBT_LOG
206 190
207config BRIDGE_EBT_ULOG 191config BRIDGE_EBT_ULOG
208 tristate "ebt: ulog support (OBSOLETE)" 192 tristate "ebt: ulog support (OBSOLETE)"
209 depends on BRIDGE_NF_EBTABLES
210 help 193 help
211 This option enables the old bridge-specific "ebt_ulog" implementation 194 This option enables the old bridge-specific "ebt_ulog" implementation
212 which has been obsoleted by the new "nfnetlink_log" code (see 195 which has been obsoleted by the new "nfnetlink_log" code (see
@@ -223,7 +206,6 @@ config BRIDGE_EBT_ULOG
223 206
224config BRIDGE_EBT_NFLOG 207config BRIDGE_EBT_NFLOG
225 tristate "ebt: nflog support" 208 tristate "ebt: nflog support"
226 depends on BRIDGE_NF_EBTABLES
227 help 209 help
228 This option enables the nflog watcher, which allows to LOG 210 This option enables the nflog watcher, which allows to LOG
229 messages through the netfilter logging API, which can use 211 messages through the netfilter logging API, which can use
@@ -235,4 +217,4 @@ config BRIDGE_EBT_NFLOG
235 217
236 To compile it as a module, choose M here. If unsure, say N. 218 To compile it as a module, choose M here. If unsure, say N.
237 219
238endmenu 220endif # BRIDGE_NF_EBTABLES
diff --git a/net/bridge/netfilter/ebt_802_3.c b/net/bridge/netfilter/ebt_802_3.c
index 98534025360f..bd91dc58d49b 100644
--- a/net/bridge/netfilter/ebt_802_3.c
+++ b/net/bridge/netfilter/ebt_802_3.c
@@ -7,64 +7,63 @@
7 * May 2003 7 * May 2003
8 * 8 *
9 */ 9 */
10 10#include <linux/module.h>
11#include <linux/netfilter/x_tables.h>
11#include <linux/netfilter_bridge/ebtables.h> 12#include <linux/netfilter_bridge/ebtables.h>
12#include <linux/netfilter_bridge/ebt_802_3.h> 13#include <linux/netfilter_bridge/ebt_802_3.h>
13#include <linux/module.h>
14 14
15static int ebt_filter_802_3(const struct sk_buff *skb, const struct net_device *in, 15static bool
16 const struct net_device *out, const void *data, unsigned int datalen) 16ebt_802_3_mt(const struct sk_buff *skb, const struct xt_match_param *par)
17{ 17{
18 const struct ebt_802_3_info *info = data; 18 const struct ebt_802_3_info *info = par->matchinfo;
19 const struct ebt_802_3_hdr *hdr = ebt_802_3_hdr(skb); 19 const struct ebt_802_3_hdr *hdr = ebt_802_3_hdr(skb);
20 __be16 type = hdr->llc.ui.ctrl & IS_UI ? hdr->llc.ui.type : hdr->llc.ni.type; 20 __be16 type = hdr->llc.ui.ctrl & IS_UI ? hdr->llc.ui.type : hdr->llc.ni.type;
21 21
22 if (info->bitmask & EBT_802_3_SAP) { 22 if (info->bitmask & EBT_802_3_SAP) {
23 if (FWINV(info->sap != hdr->llc.ui.ssap, EBT_802_3_SAP)) 23 if (FWINV(info->sap != hdr->llc.ui.ssap, EBT_802_3_SAP))
24 return EBT_NOMATCH; 24 return false;
25 if (FWINV(info->sap != hdr->llc.ui.dsap, EBT_802_3_SAP)) 25 if (FWINV(info->sap != hdr->llc.ui.dsap, EBT_802_3_SAP))
26 return EBT_NOMATCH; 26 return false;
27 } 27 }
28 28
29 if (info->bitmask & EBT_802_3_TYPE) { 29 if (info->bitmask & EBT_802_3_TYPE) {
30 if (!(hdr->llc.ui.dsap == CHECK_TYPE && hdr->llc.ui.ssap == CHECK_TYPE)) 30 if (!(hdr->llc.ui.dsap == CHECK_TYPE && hdr->llc.ui.ssap == CHECK_TYPE))
31 return EBT_NOMATCH; 31 return false;
32 if (FWINV(info->type != type, EBT_802_3_TYPE)) 32 if (FWINV(info->type != type, EBT_802_3_TYPE))
33 return EBT_NOMATCH; 33 return false;
34 } 34 }
35 35
36 return EBT_MATCH; 36 return true;
37} 37}
38 38
39static struct ebt_match filter_802_3; 39static bool ebt_802_3_mt_check(const struct xt_mtchk_param *par)
40static int ebt_802_3_check(const char *tablename, unsigned int hookmask,
41 const struct ebt_entry *e, void *data, unsigned int datalen)
42{ 40{
43 const struct ebt_802_3_info *info = data; 41 const struct ebt_802_3_info *info = par->matchinfo;
44 42
45 if (datalen < sizeof(struct ebt_802_3_info))
46 return -EINVAL;
47 if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK) 43 if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK)
48 return -EINVAL; 44 return false;
49 45
50 return 0; 46 return true;
51} 47}
52 48
53static struct ebt_match filter_802_3 __read_mostly = { 49static struct xt_match ebt_802_3_mt_reg __read_mostly = {
54 .name = EBT_802_3_MATCH, 50 .name = "802_3",
55 .match = ebt_filter_802_3, 51 .revision = 0,
56 .check = ebt_802_3_check, 52 .family = NFPROTO_BRIDGE,
53 .match = ebt_802_3_mt,
54 .checkentry = ebt_802_3_mt_check,
55 .matchsize = XT_ALIGN(sizeof(struct ebt_802_3_info)),
57 .me = THIS_MODULE, 56 .me = THIS_MODULE,
58}; 57};
59 58
60static int __init ebt_802_3_init(void) 59static int __init ebt_802_3_init(void)
61{ 60{
62 return ebt_register_match(&filter_802_3); 61 return xt_register_match(&ebt_802_3_mt_reg);
63} 62}
64 63
65static void __exit ebt_802_3_fini(void) 64static void __exit ebt_802_3_fini(void)
66{ 65{
67 ebt_unregister_match(&filter_802_3); 66 xt_unregister_match(&ebt_802_3_mt_reg);
68} 67}
69 68
70module_init(ebt_802_3_init); 69module_init(ebt_802_3_init);
diff --git a/net/bridge/netfilter/ebt_among.c b/net/bridge/netfilter/ebt_among.c
index 70b6dca5ea75..b595f091f35b 100644
--- a/net/bridge/netfilter/ebt_among.c
+++ b/net/bridge/netfilter/ebt_among.c
@@ -7,15 +7,15 @@
7 * August, 2003 7 * August, 2003
8 * 8 *
9 */ 9 */
10
11#include <linux/netfilter_bridge/ebtables.h>
12#include <linux/netfilter_bridge/ebt_among.h>
13#include <linux/ip.h> 10#include <linux/ip.h>
14#include <linux/if_arp.h> 11#include <linux/if_arp.h>
15#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/netfilter/x_tables.h>
14#include <linux/netfilter_bridge/ebtables.h>
15#include <linux/netfilter_bridge/ebt_among.h>
16 16
17static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh, 17static bool ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh,
18 const char *mac, __be32 ip) 18 const char *mac, __be32 ip)
19{ 19{
20 /* You may be puzzled as to how this code works. 20 /* You may be puzzled as to how this code works.
21 * Some tricks were used, refer to 21 * Some tricks were used, refer to
@@ -33,23 +33,19 @@ static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh,
33 if (ip) { 33 if (ip) {
34 for (i = start; i < limit; i++) { 34 for (i = start; i < limit; i++) {
35 p = &wh->pool[i]; 35 p = &wh->pool[i];
36 if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) { 36 if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0])
37 if (p->ip == 0 || p->ip == ip) { 37 if (p->ip == 0 || p->ip == ip)
38 return 1; 38 return true;
39 }
40 }
41 } 39 }
42 } else { 40 } else {
43 for (i = start; i < limit; i++) { 41 for (i = start; i < limit; i++) {
44 p = &wh->pool[i]; 42 p = &wh->pool[i];
45 if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) { 43 if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0])
46 if (p->ip == 0) { 44 if (p->ip == 0)
47 return 1; 45 return true;
48 }
49 }
50 } 46 }
51 } 47 }
52 return 0; 48 return false;
53} 49}
54 50
55static int ebt_mac_wormhash_check_integrity(const struct ebt_mac_wormhash 51static int ebt_mac_wormhash_check_integrity(const struct ebt_mac_wormhash
@@ -131,12 +127,10 @@ static int get_ip_src(const struct sk_buff *skb, __be32 *addr)
131 return 0; 127 return 0;
132} 128}
133 129
134static int ebt_filter_among(const struct sk_buff *skb, 130static bool
135 const struct net_device *in, 131ebt_among_mt(const struct sk_buff *skb, const struct xt_match_param *par)
136 const struct net_device *out, const void *data,
137 unsigned int datalen)
138{ 132{
139 const struct ebt_among_info *info = data; 133 const struct ebt_among_info *info = par->matchinfo;
140 const char *dmac, *smac; 134 const char *dmac, *smac;
141 const struct ebt_mac_wormhash *wh_dst, *wh_src; 135 const struct ebt_mac_wormhash *wh_dst, *wh_src;
142 __be32 dip = 0, sip = 0; 136 __be32 dip = 0, sip = 0;
@@ -147,41 +141,41 @@ static int ebt_filter_among(const struct sk_buff *skb,
147 if (wh_src) { 141 if (wh_src) {
148 smac = eth_hdr(skb)->h_source; 142 smac = eth_hdr(skb)->h_source;
149 if (get_ip_src(skb, &sip)) 143 if (get_ip_src(skb, &sip))
150 return EBT_NOMATCH; 144 return false;
151 if (!(info->bitmask & EBT_AMONG_SRC_NEG)) { 145 if (!(info->bitmask & EBT_AMONG_SRC_NEG)) {
152 /* we match only if it contains */ 146 /* we match only if it contains */
153 if (!ebt_mac_wormhash_contains(wh_src, smac, sip)) 147 if (!ebt_mac_wormhash_contains(wh_src, smac, sip))
154 return EBT_NOMATCH; 148 return false;
155 } else { 149 } else {
156 /* we match only if it DOES NOT contain */ 150 /* we match only if it DOES NOT contain */
157 if (ebt_mac_wormhash_contains(wh_src, smac, sip)) 151 if (ebt_mac_wormhash_contains(wh_src, smac, sip))
158 return EBT_NOMATCH; 152 return false;
159 } 153 }
160 } 154 }
161 155
162 if (wh_dst) { 156 if (wh_dst) {
163 dmac = eth_hdr(skb)->h_dest; 157 dmac = eth_hdr(skb)->h_dest;
164 if (get_ip_dst(skb, &dip)) 158 if (get_ip_dst(skb, &dip))
165 return EBT_NOMATCH; 159 return false;
166 if (!(info->bitmask & EBT_AMONG_DST_NEG)) { 160 if (!(info->bitmask & EBT_AMONG_DST_NEG)) {
167 /* we match only if it contains */ 161 /* we match only if it contains */
168 if (!ebt_mac_wormhash_contains(wh_dst, dmac, dip)) 162 if (!ebt_mac_wormhash_contains(wh_dst, dmac, dip))
169 return EBT_NOMATCH; 163 return false;
170 } else { 164 } else {
171 /* we match only if it DOES NOT contain */ 165 /* we match only if it DOES NOT contain */
172 if (ebt_mac_wormhash_contains(wh_dst, dmac, dip)) 166 if (ebt_mac_wormhash_contains(wh_dst, dmac, dip))
173 return EBT_NOMATCH; 167 return false;
174 } 168 }
175 } 169 }
176 170
177 return EBT_MATCH; 171 return true;
178} 172}
179 173
180static int ebt_among_check(const char *tablename, unsigned int hookmask, 174static bool ebt_among_mt_check(const struct xt_mtchk_param *par)
181 const struct ebt_entry *e, void *data,
182 unsigned int datalen)
183{ 175{
184 const struct ebt_among_info *info = data; 176 const struct ebt_among_info *info = par->matchinfo;
177 const struct ebt_entry_match *em =
178 container_of(par->matchinfo, const struct ebt_entry_match, data);
185 int expected_length = sizeof(struct ebt_among_info); 179 int expected_length = sizeof(struct ebt_among_info);
186 const struct ebt_mac_wormhash *wh_dst, *wh_src; 180 const struct ebt_mac_wormhash *wh_dst, *wh_src;
187 int err; 181 int err;
@@ -191,42 +185,45 @@ static int ebt_among_check(const char *tablename, unsigned int hookmask,
191 expected_length += ebt_mac_wormhash_size(wh_dst); 185 expected_length += ebt_mac_wormhash_size(wh_dst);
192 expected_length += ebt_mac_wormhash_size(wh_src); 186 expected_length += ebt_mac_wormhash_size(wh_src);
193 187
194 if (datalen != EBT_ALIGN(expected_length)) { 188 if (em->match_size != EBT_ALIGN(expected_length)) {
195 printk(KERN_WARNING 189 printk(KERN_WARNING
196 "ebtables: among: wrong size: %d " 190 "ebtables: among: wrong size: %d "
197 "against expected %d, rounded to %Zd\n", 191 "against expected %d, rounded to %Zd\n",
198 datalen, expected_length, 192 em->match_size, expected_length,
199 EBT_ALIGN(expected_length)); 193 EBT_ALIGN(expected_length));
200 return -EINVAL; 194 return false;
201 } 195 }
202 if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) { 196 if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) {
203 printk(KERN_WARNING 197 printk(KERN_WARNING
204 "ebtables: among: dst integrity fail: %x\n", -err); 198 "ebtables: among: dst integrity fail: %x\n", -err);
205 return -EINVAL; 199 return false;
206 } 200 }
207 if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) { 201 if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) {
208 printk(KERN_WARNING 202 printk(KERN_WARNING
209 "ebtables: among: src integrity fail: %x\n", -err); 203 "ebtables: among: src integrity fail: %x\n", -err);
210 return -EINVAL; 204 return false;
211 } 205 }
212 return 0; 206 return true;
213} 207}
214 208
215static struct ebt_match filter_among __read_mostly = { 209static struct xt_match ebt_among_mt_reg __read_mostly = {
216 .name = EBT_AMONG_MATCH, 210 .name = "among",
217 .match = ebt_filter_among, 211 .revision = 0,
218 .check = ebt_among_check, 212 .family = NFPROTO_BRIDGE,
213 .match = ebt_among_mt,
214 .checkentry = ebt_among_mt_check,
215 .matchsize = -1, /* special case */
219 .me = THIS_MODULE, 216 .me = THIS_MODULE,
220}; 217};
221 218
222static int __init ebt_among_init(void) 219static int __init ebt_among_init(void)
223{ 220{
224 return ebt_register_match(&filter_among); 221 return xt_register_match(&ebt_among_mt_reg);
225} 222}
226 223
227static void __exit ebt_among_fini(void) 224static void __exit ebt_among_fini(void)
228{ 225{
229 ebt_unregister_match(&filter_among); 226 xt_unregister_match(&ebt_among_mt_reg);
230} 227}
231 228
232module_init(ebt_among_init); 229module_init(ebt_among_init);
diff --git a/net/bridge/netfilter/ebt_arp.c b/net/bridge/netfilter/ebt_arp.c
index 7c535be75665..b7ad60419f9a 100644
--- a/net/bridge/netfilter/ebt_arp.c
+++ b/net/bridge/netfilter/ebt_arp.c
@@ -8,58 +8,58 @@
8 * April, 2002 8 * April, 2002
9 * 9 *
10 */ 10 */
11
12#include <linux/netfilter_bridge/ebtables.h>
13#include <linux/netfilter_bridge/ebt_arp.h>
14#include <linux/if_arp.h> 11#include <linux/if_arp.h>
15#include <linux/if_ether.h> 12#include <linux/if_ether.h>
16#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/netfilter/x_tables.h>
15#include <linux/netfilter_bridge/ebtables.h>
16#include <linux/netfilter_bridge/ebt_arp.h>
17 17
18static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in, 18static bool
19 const struct net_device *out, const void *data, unsigned int datalen) 19ebt_arp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
20{ 20{
21 const struct ebt_arp_info *info = data; 21 const struct ebt_arp_info *info = par->matchinfo;
22 const struct arphdr *ah; 22 const struct arphdr *ah;
23 struct arphdr _arph; 23 struct arphdr _arph;
24 24
25 ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph); 25 ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
26 if (ah == NULL) 26 if (ah == NULL)
27 return EBT_NOMATCH; 27 return false;
28 if (info->bitmask & EBT_ARP_OPCODE && FWINV(info->opcode != 28 if (info->bitmask & EBT_ARP_OPCODE && FWINV(info->opcode !=
29 ah->ar_op, EBT_ARP_OPCODE)) 29 ah->ar_op, EBT_ARP_OPCODE))
30 return EBT_NOMATCH; 30 return false;
31 if (info->bitmask & EBT_ARP_HTYPE && FWINV(info->htype != 31 if (info->bitmask & EBT_ARP_HTYPE && FWINV(info->htype !=
32 ah->ar_hrd, EBT_ARP_HTYPE)) 32 ah->ar_hrd, EBT_ARP_HTYPE))
33 return EBT_NOMATCH; 33 return false;
34 if (info->bitmask & EBT_ARP_PTYPE && FWINV(info->ptype != 34 if (info->bitmask & EBT_ARP_PTYPE && FWINV(info->ptype !=
35 ah->ar_pro, EBT_ARP_PTYPE)) 35 ah->ar_pro, EBT_ARP_PTYPE))
36 return EBT_NOMATCH; 36 return false;
37 37
38 if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_GRAT)) { 38 if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_GRAT)) {
39 const __be32 *sap, *dap; 39 const __be32 *sap, *dap;
40 __be32 saddr, daddr; 40 __be32 saddr, daddr;
41 41
42 if (ah->ar_pln != sizeof(__be32) || ah->ar_pro != htons(ETH_P_IP)) 42 if (ah->ar_pln != sizeof(__be32) || ah->ar_pro != htons(ETH_P_IP))
43 return EBT_NOMATCH; 43 return false;
44 sap = skb_header_pointer(skb, sizeof(struct arphdr) + 44 sap = skb_header_pointer(skb, sizeof(struct arphdr) +
45 ah->ar_hln, sizeof(saddr), 45 ah->ar_hln, sizeof(saddr),
46 &saddr); 46 &saddr);
47 if (sap == NULL) 47 if (sap == NULL)
48 return EBT_NOMATCH; 48 return false;
49 dap = skb_header_pointer(skb, sizeof(struct arphdr) + 49 dap = skb_header_pointer(skb, sizeof(struct arphdr) +
50 2*ah->ar_hln+sizeof(saddr), 50 2*ah->ar_hln+sizeof(saddr),
51 sizeof(daddr), &daddr); 51 sizeof(daddr), &daddr);
52 if (dap == NULL) 52 if (dap == NULL)
53 return EBT_NOMATCH; 53 return false;
54 if (info->bitmask & EBT_ARP_SRC_IP && 54 if (info->bitmask & EBT_ARP_SRC_IP &&
55 FWINV(info->saddr != (*sap & info->smsk), EBT_ARP_SRC_IP)) 55 FWINV(info->saddr != (*sap & info->smsk), EBT_ARP_SRC_IP))
56 return EBT_NOMATCH; 56 return false;
57 if (info->bitmask & EBT_ARP_DST_IP && 57 if (info->bitmask & EBT_ARP_DST_IP &&
58 FWINV(info->daddr != (*dap & info->dmsk), EBT_ARP_DST_IP)) 58 FWINV(info->daddr != (*dap & info->dmsk), EBT_ARP_DST_IP))
59 return EBT_NOMATCH; 59 return false;
60 if (info->bitmask & EBT_ARP_GRAT && 60 if (info->bitmask & EBT_ARP_GRAT &&
61 FWINV(*dap != *sap, EBT_ARP_GRAT)) 61 FWINV(*dap != *sap, EBT_ARP_GRAT))
62 return EBT_NOMATCH; 62 return false;
63 } 63 }
64 64
65 if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) { 65 if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) {
@@ -68,18 +68,18 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
68 uint8_t verdict, i; 68 uint8_t verdict, i;
69 69
70 if (ah->ar_hln != ETH_ALEN || ah->ar_hrd != htons(ARPHRD_ETHER)) 70 if (ah->ar_hln != ETH_ALEN || ah->ar_hrd != htons(ARPHRD_ETHER))
71 return EBT_NOMATCH; 71 return false;
72 if (info->bitmask & EBT_ARP_SRC_MAC) { 72 if (info->bitmask & EBT_ARP_SRC_MAC) {
73 mp = skb_header_pointer(skb, sizeof(struct arphdr), 73 mp = skb_header_pointer(skb, sizeof(struct arphdr),
74 sizeof(_mac), &_mac); 74 sizeof(_mac), &_mac);
75 if (mp == NULL) 75 if (mp == NULL)
76 return EBT_NOMATCH; 76 return false;
77 verdict = 0; 77 verdict = 0;
78 for (i = 0; i < 6; i++) 78 for (i = 0; i < 6; i++)
79 verdict |= (mp[i] ^ info->smaddr[i]) & 79 verdict |= (mp[i] ^ info->smaddr[i]) &
80 info->smmsk[i]; 80 info->smmsk[i];
81 if (FWINV(verdict != 0, EBT_ARP_SRC_MAC)) 81 if (FWINV(verdict != 0, EBT_ARP_SRC_MAC))
82 return EBT_NOMATCH; 82 return false;
83 } 83 }
84 84
85 if (info->bitmask & EBT_ARP_DST_MAC) { 85 if (info->bitmask & EBT_ARP_DST_MAC) {
@@ -87,50 +87,51 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
87 ah->ar_hln + ah->ar_pln, 87 ah->ar_hln + ah->ar_pln,
88 sizeof(_mac), &_mac); 88 sizeof(_mac), &_mac);
89 if (mp == NULL) 89 if (mp == NULL)
90 return EBT_NOMATCH; 90 return false;
91 verdict = 0; 91 verdict = 0;
92 for (i = 0; i < 6; i++) 92 for (i = 0; i < 6; i++)
93 verdict |= (mp[i] ^ info->dmaddr[i]) & 93 verdict |= (mp[i] ^ info->dmaddr[i]) &
94 info->dmmsk[i]; 94 info->dmmsk[i];
95 if (FWINV(verdict != 0, EBT_ARP_DST_MAC)) 95 if (FWINV(verdict != 0, EBT_ARP_DST_MAC))
96 return EBT_NOMATCH; 96 return false;
97 } 97 }
98 } 98 }
99 99
100 return EBT_MATCH; 100 return true;
101} 101}
102 102
103static int ebt_arp_check(const char *tablename, unsigned int hookmask, 103static bool ebt_arp_mt_check(const struct xt_mtchk_param *par)
104 const struct ebt_entry *e, void *data, unsigned int datalen)
105{ 104{
106 const struct ebt_arp_info *info = data; 105 const struct ebt_arp_info *info = par->matchinfo;
106 const struct ebt_entry *e = par->entryinfo;
107 107
108 if (datalen != EBT_ALIGN(sizeof(struct ebt_arp_info)))
109 return -EINVAL;
110 if ((e->ethproto != htons(ETH_P_ARP) && 108 if ((e->ethproto != htons(ETH_P_ARP) &&
111 e->ethproto != htons(ETH_P_RARP)) || 109 e->ethproto != htons(ETH_P_RARP)) ||
112 e->invflags & EBT_IPROTO) 110 e->invflags & EBT_IPROTO)
113 return -EINVAL; 111 return false;
114 if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK) 112 if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK)
115 return -EINVAL; 113 return false;
116 return 0; 114 return true;
117} 115}
118 116
119static struct ebt_match filter_arp __read_mostly = { 117static struct xt_match ebt_arp_mt_reg __read_mostly = {
120 .name = EBT_ARP_MATCH, 118 .name = "arp",
121 .match = ebt_filter_arp, 119 .revision = 0,
122 .check = ebt_arp_check, 120 .family = NFPROTO_BRIDGE,
121 .match = ebt_arp_mt,
122 .checkentry = ebt_arp_mt_check,
123 .matchsize = XT_ALIGN(sizeof(struct ebt_arp_info)),
123 .me = THIS_MODULE, 124 .me = THIS_MODULE,
124}; 125};
125 126
126static int __init ebt_arp_init(void) 127static int __init ebt_arp_init(void)
127{ 128{
128 return ebt_register_match(&filter_arp); 129 return xt_register_match(&ebt_arp_mt_reg);
129} 130}
130 131
131static void __exit ebt_arp_fini(void) 132static void __exit ebt_arp_fini(void)
132{ 133{
133 ebt_unregister_match(&filter_arp); 134 xt_unregister_match(&ebt_arp_mt_reg);
134} 135}
135 136
136module_init(ebt_arp_init); 137module_init(ebt_arp_init);
diff --git a/net/bridge/netfilter/ebt_arpreply.c b/net/bridge/netfilter/ebt_arpreply.c
index 0c4279590fc7..76584cd72e57 100644
--- a/net/bridge/netfilter/ebt_arpreply.c
+++ b/net/bridge/netfilter/ebt_arpreply.c
@@ -8,18 +8,17 @@
8 * August, 2003 8 * August, 2003
9 * 9 *
10 */ 10 */
11
12#include <linux/netfilter_bridge/ebtables.h>
13#include <linux/netfilter_bridge/ebt_arpreply.h>
14#include <linux/if_arp.h> 11#include <linux/if_arp.h>
15#include <net/arp.h> 12#include <net/arp.h>
16#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/netfilter/x_tables.h>
15#include <linux/netfilter_bridge/ebtables.h>
16#include <linux/netfilter_bridge/ebt_arpreply.h>
17 17
18static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr, 18static unsigned int
19 const struct net_device *in, const struct net_device *out, 19ebt_arpreply_tg(struct sk_buff *skb, const struct xt_target_param *par)
20 const void *data, unsigned int datalen)
21{ 20{
22 struct ebt_arpreply_info *info = (void *)data; 21 const struct ebt_arpreply_info *info = par->targinfo;
23 const __be32 *siptr, *diptr; 22 const __be32 *siptr, *diptr;
24 __be32 _sip, _dip; 23 __be32 _sip, _dip;
25 const struct arphdr *ap; 24 const struct arphdr *ap;
@@ -52,45 +51,45 @@ static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr,
52 if (diptr == NULL) 51 if (diptr == NULL)
53 return EBT_DROP; 52 return EBT_DROP;
54 53
55 arp_send(ARPOP_REPLY, ETH_P_ARP, *siptr, (struct net_device *)in, 54 arp_send(ARPOP_REPLY, ETH_P_ARP, *siptr, (struct net_device *)par->in,
56 *diptr, shp, info->mac, shp); 55 *diptr, shp, info->mac, shp);
57 56
58 return info->target; 57 return info->target;
59} 58}
60 59
61static int ebt_target_reply_check(const char *tablename, unsigned int hookmask, 60static bool ebt_arpreply_tg_check(const struct xt_tgchk_param *par)
62 const struct ebt_entry *e, void *data, unsigned int datalen)
63{ 61{
64 const struct ebt_arpreply_info *info = data; 62 const struct ebt_arpreply_info *info = par->targinfo;
63 const struct ebt_entry *e = par->entryinfo;
65 64
66 if (datalen != EBT_ALIGN(sizeof(struct ebt_arpreply_info)))
67 return -EINVAL;
68 if (BASE_CHAIN && info->target == EBT_RETURN) 65 if (BASE_CHAIN && info->target == EBT_RETURN)
69 return -EINVAL; 66 return false;
70 if (e->ethproto != htons(ETH_P_ARP) || 67 if (e->ethproto != htons(ETH_P_ARP) ||
71 e->invflags & EBT_IPROTO) 68 e->invflags & EBT_IPROTO)
72 return -EINVAL; 69 return false;
73 CLEAR_BASE_CHAIN_BIT; 70 return true;
74 if (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING))
75 return -EINVAL;
76 return 0;
77} 71}
78 72
79static struct ebt_target reply_target __read_mostly = { 73static struct xt_target ebt_arpreply_tg_reg __read_mostly = {
80 .name = EBT_ARPREPLY_TARGET, 74 .name = "arpreply",
81 .target = ebt_target_reply, 75 .revision = 0,
82 .check = ebt_target_reply_check, 76 .family = NFPROTO_BRIDGE,
77 .table = "nat",
78 .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING),
79 .target = ebt_arpreply_tg,
80 .checkentry = ebt_arpreply_tg_check,
81 .targetsize = XT_ALIGN(sizeof(struct ebt_arpreply_info)),
83 .me = THIS_MODULE, 82 .me = THIS_MODULE,
84}; 83};
85 84
86static int __init ebt_arpreply_init(void) 85static int __init ebt_arpreply_init(void)
87{ 86{
88 return ebt_register_target(&reply_target); 87 return xt_register_target(&ebt_arpreply_tg_reg);
89} 88}
90 89
91static void __exit ebt_arpreply_fini(void) 90static void __exit ebt_arpreply_fini(void)
92{ 91{
93 ebt_unregister_target(&reply_target); 92 xt_unregister_target(&ebt_arpreply_tg_reg);
94} 93}
95 94
96module_init(ebt_arpreply_init); 95module_init(ebt_arpreply_init);
diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c
index ca64c1cc1b47..6b49ea9e31fb 100644
--- a/net/bridge/netfilter/ebt_dnat.c
+++ b/net/bridge/netfilter/ebt_dnat.c
@@ -7,18 +7,17 @@
7 * June, 2002 7 * June, 2002
8 * 8 *
9 */ 9 */
10 10#include <linux/module.h>
11#include <net/sock.h>
11#include <linux/netfilter.h> 12#include <linux/netfilter.h>
13#include <linux/netfilter/x_tables.h>
12#include <linux/netfilter_bridge/ebtables.h> 14#include <linux/netfilter_bridge/ebtables.h>
13#include <linux/netfilter_bridge/ebt_nat.h> 15#include <linux/netfilter_bridge/ebt_nat.h>
14#include <linux/module.h>
15#include <net/sock.h>
16 16
17static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr, 17static unsigned int
18 const struct net_device *in, const struct net_device *out, 18ebt_dnat_tg(struct sk_buff *skb, const struct xt_target_param *par)
19 const void *data, unsigned int datalen)
20{ 19{
21 const struct ebt_nat_info *info = data; 20 const struct ebt_nat_info *info = par->targinfo;
22 21
23 if (!skb_make_writable(skb, 0)) 22 if (!skb_make_writable(skb, 0))
24 return EBT_DROP; 23 return EBT_DROP;
@@ -27,40 +26,46 @@ static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr,
27 return info->target; 26 return info->target;
28} 27}
29 28
30static int ebt_target_dnat_check(const char *tablename, unsigned int hookmask, 29static bool ebt_dnat_tg_check(const struct xt_tgchk_param *par)
31 const struct ebt_entry *e, void *data, unsigned int datalen)
32{ 30{
33 const struct ebt_nat_info *info = data; 31 const struct ebt_nat_info *info = par->targinfo;
32 unsigned int hook_mask;
34 33
35 if (BASE_CHAIN && info->target == EBT_RETURN) 34 if (BASE_CHAIN && info->target == EBT_RETURN)
36 return -EINVAL; 35 return false;
37 CLEAR_BASE_CHAIN_BIT; 36
38 if ( (strcmp(tablename, "nat") || 37 hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
39 (hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))) && 38 if ((strcmp(par->table, "nat") != 0 ||
40 (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) ) 39 (hook_mask & ~((1 << NF_BR_PRE_ROUTING) |
41 return -EINVAL; 40 (1 << NF_BR_LOCAL_OUT)))) &&
42 if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info))) 41 (strcmp(par->table, "broute") != 0 ||
43 return -EINVAL; 42 hook_mask & ~(1 << NF_BR_BROUTING)))
43 return false;
44 if (INVALID_TARGET) 44 if (INVALID_TARGET)
45 return -EINVAL; 45 return false;
46 return 0; 46 return true;
47} 47}
48 48
49static struct ebt_target dnat __read_mostly = { 49static struct xt_target ebt_dnat_tg_reg __read_mostly = {
50 .name = EBT_DNAT_TARGET, 50 .name = "dnat",
51 .target = ebt_target_dnat, 51 .revision = 0,
52 .check = ebt_target_dnat_check, 52 .family = NFPROTO_BRIDGE,
53 .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING) |
54 (1 << NF_BR_LOCAL_OUT) | (1 << NF_BR_BROUTING),
55 .target = ebt_dnat_tg,
56 .checkentry = ebt_dnat_tg_check,
57 .targetsize = XT_ALIGN(sizeof(struct ebt_nat_info)),
53 .me = THIS_MODULE, 58 .me = THIS_MODULE,
54}; 59};
55 60
56static int __init ebt_dnat_init(void) 61static int __init ebt_dnat_init(void)
57{ 62{
58 return ebt_register_target(&dnat); 63 return xt_register_target(&ebt_dnat_tg_reg);
59} 64}
60 65
61static void __exit ebt_dnat_fini(void) 66static void __exit ebt_dnat_fini(void)
62{ 67{
63 ebt_unregister_target(&dnat); 68 xt_unregister_target(&ebt_dnat_tg_reg);
64} 69}
65 70
66module_init(ebt_dnat_init); 71module_init(ebt_dnat_init);
diff --git a/net/bridge/netfilter/ebt_ip.c b/net/bridge/netfilter/ebt_ip.c
index 65caa00dcf2a..d771bbfbcbe6 100644
--- a/net/bridge/netfilter/ebt_ip.c
+++ b/net/bridge/netfilter/ebt_ip.c
@@ -11,24 +11,23 @@
11 * Innominate Security Technologies AG <mhopf@innominate.com> 11 * Innominate Security Technologies AG <mhopf@innominate.com>
12 * September, 2002 12 * September, 2002
13 */ 13 */
14
15#include <linux/netfilter_bridge/ebtables.h>
16#include <linux/netfilter_bridge/ebt_ip.h>
17#include <linux/ip.h> 14#include <linux/ip.h>
18#include <net/ip.h> 15#include <net/ip.h>
19#include <linux/in.h> 16#include <linux/in.h>
20#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/netfilter/x_tables.h>
19#include <linux/netfilter_bridge/ebtables.h>
20#include <linux/netfilter_bridge/ebt_ip.h>
21 21
22struct tcpudphdr { 22struct tcpudphdr {
23 __be16 src; 23 __be16 src;
24 __be16 dst; 24 __be16 dst;
25}; 25};
26 26
27static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in, 27static bool
28 const struct net_device *out, const void *data, 28ebt_ip_mt(const struct sk_buff *skb, const struct xt_match_param *par)
29 unsigned int datalen)
30{ 29{
31 const struct ebt_ip_info *info = data; 30 const struct ebt_ip_info *info = par->matchinfo;
32 const struct iphdr *ih; 31 const struct iphdr *ih;
33 struct iphdr _iph; 32 struct iphdr _iph;
34 const struct tcpudphdr *pptr; 33 const struct tcpudphdr *pptr;
@@ -36,92 +35,93 @@ static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in,
36 35
37 ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph); 36 ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
38 if (ih == NULL) 37 if (ih == NULL)
39 return EBT_NOMATCH; 38 return false;
40 if (info->bitmask & EBT_IP_TOS && 39 if (info->bitmask & EBT_IP_TOS &&
41 FWINV(info->tos != ih->tos, EBT_IP_TOS)) 40 FWINV(info->tos != ih->tos, EBT_IP_TOS))
42 return EBT_NOMATCH; 41 return false;
43 if (info->bitmask & EBT_IP_SOURCE && 42 if (info->bitmask & EBT_IP_SOURCE &&
44 FWINV((ih->saddr & info->smsk) != 43 FWINV((ih->saddr & info->smsk) !=
45 info->saddr, EBT_IP_SOURCE)) 44 info->saddr, EBT_IP_SOURCE))
46 return EBT_NOMATCH; 45 return false;
47 if ((info->bitmask & EBT_IP_DEST) && 46 if ((info->bitmask & EBT_IP_DEST) &&
48 FWINV((ih->daddr & info->dmsk) != 47 FWINV((ih->daddr & info->dmsk) !=
49 info->daddr, EBT_IP_DEST)) 48 info->daddr, EBT_IP_DEST))
50 return EBT_NOMATCH; 49 return false;
51 if (info->bitmask & EBT_IP_PROTO) { 50 if (info->bitmask & EBT_IP_PROTO) {
52 if (FWINV(info->protocol != ih->protocol, EBT_IP_PROTO)) 51 if (FWINV(info->protocol != ih->protocol, EBT_IP_PROTO))
53 return EBT_NOMATCH; 52 return false;
54 if (!(info->bitmask & EBT_IP_DPORT) && 53 if (!(info->bitmask & EBT_IP_DPORT) &&
55 !(info->bitmask & EBT_IP_SPORT)) 54 !(info->bitmask & EBT_IP_SPORT))
56 return EBT_MATCH; 55 return true;
57 if (ntohs(ih->frag_off) & IP_OFFSET) 56 if (ntohs(ih->frag_off) & IP_OFFSET)
58 return EBT_NOMATCH; 57 return false;
59 pptr = skb_header_pointer(skb, ih->ihl*4, 58 pptr = skb_header_pointer(skb, ih->ihl*4,
60 sizeof(_ports), &_ports); 59 sizeof(_ports), &_ports);
61 if (pptr == NULL) 60 if (pptr == NULL)
62 return EBT_NOMATCH; 61 return false;
63 if (info->bitmask & EBT_IP_DPORT) { 62 if (info->bitmask & EBT_IP_DPORT) {
64 u32 dst = ntohs(pptr->dst); 63 u32 dst = ntohs(pptr->dst);
65 if (FWINV(dst < info->dport[0] || 64 if (FWINV(dst < info->dport[0] ||
66 dst > info->dport[1], 65 dst > info->dport[1],
67 EBT_IP_DPORT)) 66 EBT_IP_DPORT))
68 return EBT_NOMATCH; 67 return false;
69 } 68 }
70 if (info->bitmask & EBT_IP_SPORT) { 69 if (info->bitmask & EBT_IP_SPORT) {
71 u32 src = ntohs(pptr->src); 70 u32 src = ntohs(pptr->src);
72 if (FWINV(src < info->sport[0] || 71 if (FWINV(src < info->sport[0] ||
73 src > info->sport[1], 72 src > info->sport[1],
74 EBT_IP_SPORT)) 73 EBT_IP_SPORT))
75 return EBT_NOMATCH; 74 return false;
76 } 75 }
77 } 76 }
78 return EBT_MATCH; 77 return true;
79} 78}
80 79
81static int ebt_ip_check(const char *tablename, unsigned int hookmask, 80static bool ebt_ip_mt_check(const struct xt_mtchk_param *par)
82 const struct ebt_entry *e, void *data, unsigned int datalen)
83{ 81{
84 const struct ebt_ip_info *info = data; 82 const struct ebt_ip_info *info = par->matchinfo;
83 const struct ebt_entry *e = par->entryinfo;
85 84
86 if (datalen != EBT_ALIGN(sizeof(struct ebt_ip_info)))
87 return -EINVAL;
88 if (e->ethproto != htons(ETH_P_IP) || 85 if (e->ethproto != htons(ETH_P_IP) ||
89 e->invflags & EBT_IPROTO) 86 e->invflags & EBT_IPROTO)
90 return -EINVAL; 87 return false;
91 if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK) 88 if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK)
92 return -EINVAL; 89 return false;
93 if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) { 90 if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) {
94 if (info->invflags & EBT_IP_PROTO) 91 if (info->invflags & EBT_IP_PROTO)
95 return -EINVAL; 92 return false;
96 if (info->protocol != IPPROTO_TCP && 93 if (info->protocol != IPPROTO_TCP &&
97 info->protocol != IPPROTO_UDP && 94 info->protocol != IPPROTO_UDP &&
98 info->protocol != IPPROTO_UDPLITE && 95 info->protocol != IPPROTO_UDPLITE &&
99 info->protocol != IPPROTO_SCTP && 96 info->protocol != IPPROTO_SCTP &&
100 info->protocol != IPPROTO_DCCP) 97 info->protocol != IPPROTO_DCCP)
101 return -EINVAL; 98 return false;
102 } 99 }
103 if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1]) 100 if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1])
104 return -EINVAL; 101 return false;
105 if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1]) 102 if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1])
106 return -EINVAL; 103 return false;
107 return 0; 104 return true;
108} 105}
109 106
110static struct ebt_match filter_ip __read_mostly = { 107static struct xt_match ebt_ip_mt_reg __read_mostly = {
111 .name = EBT_IP_MATCH, 108 .name = "ip",
112 .match = ebt_filter_ip, 109 .revision = 0,
113 .check = ebt_ip_check, 110 .family = NFPROTO_BRIDGE,
111 .match = ebt_ip_mt,
112 .checkentry = ebt_ip_mt_check,
113 .matchsize = XT_ALIGN(sizeof(struct ebt_ip_info)),
114 .me = THIS_MODULE, 114 .me = THIS_MODULE,
115}; 115};
116 116
117static int __init ebt_ip_init(void) 117static int __init ebt_ip_init(void)
118{ 118{
119 return ebt_register_match(&filter_ip); 119 return xt_register_match(&ebt_ip_mt_reg);
120} 120}
121 121
122static void __exit ebt_ip_fini(void) 122static void __exit ebt_ip_fini(void)
123{ 123{
124 ebt_unregister_match(&filter_ip); 124 xt_unregister_match(&ebt_ip_mt_reg);
125} 125}
126 126
127module_init(ebt_ip_init); 127module_init(ebt_ip_init);
diff --git a/net/bridge/netfilter/ebt_ip6.c b/net/bridge/netfilter/ebt_ip6.c
index 36efb3a75249..784a6573876c 100644
--- a/net/bridge/netfilter/ebt_ip6.c
+++ b/net/bridge/netfilter/ebt_ip6.c
@@ -13,26 +13,24 @@
13 * 13 *
14 * Jan, 2008 14 * Jan, 2008
15 */ 15 */
16
17#include <linux/netfilter_bridge/ebtables.h>
18#include <linux/netfilter_bridge/ebt_ip6.h>
19#include <linux/ipv6.h> 16#include <linux/ipv6.h>
20#include <net/ipv6.h> 17#include <net/ipv6.h>
21#include <linux/in.h> 18#include <linux/in.h>
22#include <linux/module.h> 19#include <linux/module.h>
23#include <net/dsfield.h> 20#include <net/dsfield.h>
21#include <linux/netfilter/x_tables.h>
22#include <linux/netfilter_bridge/ebtables.h>
23#include <linux/netfilter_bridge/ebt_ip6.h>
24 24
25struct tcpudphdr { 25struct tcpudphdr {
26 __be16 src; 26 __be16 src;
27 __be16 dst; 27 __be16 dst;
28}; 28};
29 29
30static int ebt_filter_ip6(const struct sk_buff *skb, 30static bool
31 const struct net_device *in, 31ebt_ip6_mt(const struct sk_buff *skb, const struct xt_match_param *par)
32 const struct net_device *out, const void *data,
33 unsigned int datalen)
34{ 32{
35 const struct ebt_ip6_info *info = (struct ebt_ip6_info *)data; 33 const struct ebt_ip6_info *info = par->matchinfo;
36 const struct ipv6hdr *ih6; 34 const struct ipv6hdr *ih6;
37 struct ipv6hdr _ip6h; 35 struct ipv6hdr _ip6h;
38 const struct tcpudphdr *pptr; 36 const struct tcpudphdr *pptr;
@@ -42,100 +40,100 @@ static int ebt_filter_ip6(const struct sk_buff *skb,
42 40
43 ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h); 41 ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h);
44 if (ih6 == NULL) 42 if (ih6 == NULL)
45 return EBT_NOMATCH; 43 return false;
46 if (info->bitmask & EBT_IP6_TCLASS && 44 if (info->bitmask & EBT_IP6_TCLASS &&
47 FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS)) 45 FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS))
48 return EBT_NOMATCH; 46 return false;
49 for (i = 0; i < 4; i++) 47 for (i = 0; i < 4; i++)
50 tmp_addr.in6_u.u6_addr32[i] = ih6->saddr.in6_u.u6_addr32[i] & 48 tmp_addr.in6_u.u6_addr32[i] = ih6->saddr.in6_u.u6_addr32[i] &
51 info->smsk.in6_u.u6_addr32[i]; 49 info->smsk.in6_u.u6_addr32[i];
52 if (info->bitmask & EBT_IP6_SOURCE && 50 if (info->bitmask & EBT_IP6_SOURCE &&
53 FWINV((ipv6_addr_cmp(&tmp_addr, &info->saddr) != 0), 51 FWINV((ipv6_addr_cmp(&tmp_addr, &info->saddr) != 0),
54 EBT_IP6_SOURCE)) 52 EBT_IP6_SOURCE))
55 return EBT_NOMATCH; 53 return false;
56 for (i = 0; i < 4; i++) 54 for (i = 0; i < 4; i++)
57 tmp_addr.in6_u.u6_addr32[i] = ih6->daddr.in6_u.u6_addr32[i] & 55 tmp_addr.in6_u.u6_addr32[i] = ih6->daddr.in6_u.u6_addr32[i] &
58 info->dmsk.in6_u.u6_addr32[i]; 56 info->dmsk.in6_u.u6_addr32[i];
59 if (info->bitmask & EBT_IP6_DEST && 57 if (info->bitmask & EBT_IP6_DEST &&
60 FWINV((ipv6_addr_cmp(&tmp_addr, &info->daddr) != 0), EBT_IP6_DEST)) 58 FWINV((ipv6_addr_cmp(&tmp_addr, &info->daddr) != 0), EBT_IP6_DEST))
61 return EBT_NOMATCH; 59 return false;
62 if (info->bitmask & EBT_IP6_PROTO) { 60 if (info->bitmask & EBT_IP6_PROTO) {
63 uint8_t nexthdr = ih6->nexthdr; 61 uint8_t nexthdr = ih6->nexthdr;
64 int offset_ph; 62 int offset_ph;
65 63
66 offset_ph = ipv6_skip_exthdr(skb, sizeof(_ip6h), &nexthdr); 64 offset_ph = ipv6_skip_exthdr(skb, sizeof(_ip6h), &nexthdr);
67 if (offset_ph == -1) 65 if (offset_ph == -1)
68 return EBT_NOMATCH; 66 return false;
69 if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO)) 67 if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO))
70 return EBT_NOMATCH; 68 return false;
71 if (!(info->bitmask & EBT_IP6_DPORT) && 69 if (!(info->bitmask & EBT_IP6_DPORT) &&
72 !(info->bitmask & EBT_IP6_SPORT)) 70 !(info->bitmask & EBT_IP6_SPORT))
73 return EBT_MATCH; 71 return true;
74 pptr = skb_header_pointer(skb, offset_ph, sizeof(_ports), 72 pptr = skb_header_pointer(skb, offset_ph, sizeof(_ports),
75 &_ports); 73 &_ports);
76 if (pptr == NULL) 74 if (pptr == NULL)
77 return EBT_NOMATCH; 75 return false;
78 if (info->bitmask & EBT_IP6_DPORT) { 76 if (info->bitmask & EBT_IP6_DPORT) {
79 u32 dst = ntohs(pptr->dst); 77 u32 dst = ntohs(pptr->dst);
80 if (FWINV(dst < info->dport[0] || 78 if (FWINV(dst < info->dport[0] ||
81 dst > info->dport[1], EBT_IP6_DPORT)) 79 dst > info->dport[1], EBT_IP6_DPORT))
82 return EBT_NOMATCH; 80 return false;
83 } 81 }
84 if (info->bitmask & EBT_IP6_SPORT) { 82 if (info->bitmask & EBT_IP6_SPORT) {
85 u32 src = ntohs(pptr->src); 83 u32 src = ntohs(pptr->src);
86 if (FWINV(src < info->sport[0] || 84 if (FWINV(src < info->sport[0] ||
87 src > info->sport[1], EBT_IP6_SPORT)) 85 src > info->sport[1], EBT_IP6_SPORT))
88 return EBT_NOMATCH; 86 return false;
89 } 87 }
90 return EBT_MATCH; 88 return true;
91 } 89 }
92 return EBT_MATCH; 90 return true;
93} 91}
94 92
95static int ebt_ip6_check(const char *tablename, unsigned int hookmask, 93static bool ebt_ip6_mt_check(const struct xt_mtchk_param *par)
96 const struct ebt_entry *e, void *data, unsigned int datalen)
97{ 94{
98 struct ebt_ip6_info *info = (struct ebt_ip6_info *)data; 95 const struct ebt_entry *e = par->entryinfo;
96 struct ebt_ip6_info *info = par->matchinfo;
99 97
100 if (datalen != EBT_ALIGN(sizeof(struct ebt_ip6_info)))
101 return -EINVAL;
102 if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO) 98 if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO)
103 return -EINVAL; 99 return false;
104 if (info->bitmask & ~EBT_IP6_MASK || info->invflags & ~EBT_IP6_MASK) 100 if (info->bitmask & ~EBT_IP6_MASK || info->invflags & ~EBT_IP6_MASK)
105 return -EINVAL; 101 return false;
106 if (info->bitmask & (EBT_IP6_DPORT | EBT_IP6_SPORT)) { 102 if (info->bitmask & (EBT_IP6_DPORT | EBT_IP6_SPORT)) {
107 if (info->invflags & EBT_IP6_PROTO) 103 if (info->invflags & EBT_IP6_PROTO)
108 return -EINVAL; 104 return false;
109 if (info->protocol != IPPROTO_TCP && 105 if (info->protocol != IPPROTO_TCP &&
110 info->protocol != IPPROTO_UDP && 106 info->protocol != IPPROTO_UDP &&
111 info->protocol != IPPROTO_UDPLITE && 107 info->protocol != IPPROTO_UDPLITE &&
112 info->protocol != IPPROTO_SCTP && 108 info->protocol != IPPROTO_SCTP &&
113 info->protocol != IPPROTO_DCCP) 109 info->protocol != IPPROTO_DCCP)
114 return -EINVAL; 110 return false;
115 } 111 }
116 if (info->bitmask & EBT_IP6_DPORT && info->dport[0] > info->dport[1]) 112 if (info->bitmask & EBT_IP6_DPORT && info->dport[0] > info->dport[1])
117 return -EINVAL; 113 return false;
118 if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1]) 114 if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1])
119 return -EINVAL; 115 return false;
120 return 0; 116 return true;
121} 117}
122 118
123static struct ebt_match filter_ip6 = 119static struct xt_match ebt_ip6_mt_reg __read_mostly = {
124{ 120 .name = "ip6",
125 .name = EBT_IP6_MATCH, 121 .revision = 0,
126 .match = ebt_filter_ip6, 122 .family = NFPROTO_BRIDGE,
127 .check = ebt_ip6_check, 123 .match = ebt_ip6_mt,
124 .checkentry = ebt_ip6_mt_check,
125 .matchsize = XT_ALIGN(sizeof(struct ebt_ip6_info)),
128 .me = THIS_MODULE, 126 .me = THIS_MODULE,
129}; 127};
130 128
131static int __init ebt_ip6_init(void) 129static int __init ebt_ip6_init(void)
132{ 130{
133 return ebt_register_match(&filter_ip6); 131 return xt_register_match(&ebt_ip6_mt_reg);
134} 132}
135 133
136static void __exit ebt_ip6_fini(void) 134static void __exit ebt_ip6_fini(void)
137{ 135{
138 ebt_unregister_match(&filter_ip6); 136 xt_unregister_match(&ebt_ip6_mt_reg);
139} 137}
140 138
141module_init(ebt_ip6_init); 139module_init(ebt_ip6_init);
diff --git a/net/bridge/netfilter/ebt_limit.c b/net/bridge/netfilter/ebt_limit.c
index 8cbdc01c253e..f7bd9192ff0c 100644
--- a/net/bridge/netfilter/ebt_limit.c
+++ b/net/bridge/netfilter/ebt_limit.c
@@ -10,13 +10,12 @@
10 * September, 2003 10 * September, 2003
11 * 11 *
12 */ 12 */
13
14#include <linux/netfilter_bridge/ebtables.h>
15#include <linux/netfilter_bridge/ebt_limit.h>
16#include <linux/module.h> 13#include <linux/module.h>
17
18#include <linux/netdevice.h> 14#include <linux/netdevice.h>
19#include <linux/spinlock.h> 15#include <linux/spinlock.h>
16#include <linux/netfilter/x_tables.h>
17#include <linux/netfilter_bridge/ebtables.h>
18#include <linux/netfilter_bridge/ebt_limit.h>
20 19
21static DEFINE_SPINLOCK(limit_lock); 20static DEFINE_SPINLOCK(limit_lock);
22 21
@@ -31,11 +30,10 @@ static DEFINE_SPINLOCK(limit_lock);
31 30
32#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ) 31#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
33 32
34static int ebt_limit_match(const struct sk_buff *skb, 33static bool
35 const struct net_device *in, const struct net_device *out, 34ebt_limit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
36 const void *data, unsigned int datalen)
37{ 35{
38 struct ebt_limit_info *info = (struct ebt_limit_info *)data; 36 struct ebt_limit_info *info = (void *)par->matchinfo;
39 unsigned long now = jiffies; 37 unsigned long now = jiffies;
40 38
41 spin_lock_bh(&limit_lock); 39 spin_lock_bh(&limit_lock);
@@ -47,11 +45,11 @@ static int ebt_limit_match(const struct sk_buff *skb,
47 /* We're not limited. */ 45 /* We're not limited. */
48 info->credit -= info->cost; 46 info->credit -= info->cost;
49 spin_unlock_bh(&limit_lock); 47 spin_unlock_bh(&limit_lock);
50 return EBT_MATCH; 48 return true;
51 } 49 }
52 50
53 spin_unlock_bh(&limit_lock); 51 spin_unlock_bh(&limit_lock);
54 return EBT_NOMATCH; 52 return false;
55} 53}
56 54
57/* Precision saver. */ 55/* Precision saver. */
@@ -66,20 +64,16 @@ user2credits(u_int32_t user)
66 return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE; 64 return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE;
67} 65}
68 66
69static int ebt_limit_check(const char *tablename, unsigned int hookmask, 67static bool ebt_limit_mt_check(const struct xt_mtchk_param *par)
70 const struct ebt_entry *e, void *data, unsigned int datalen)
71{ 68{
72 struct ebt_limit_info *info = data; 69 struct ebt_limit_info *info = par->matchinfo;
73
74 if (datalen != EBT_ALIGN(sizeof(struct ebt_limit_info)))
75 return -EINVAL;
76 70
77 /* Check for overflow. */ 71 /* Check for overflow. */
78 if (info->burst == 0 || 72 if (info->burst == 0 ||
79 user2credits(info->avg * info->burst) < user2credits(info->avg)) { 73 user2credits(info->avg * info->burst) < user2credits(info->avg)) {
80 printk("Overflow in ebt_limit, try lower: %u/%u\n", 74 printk("Overflow in ebt_limit, try lower: %u/%u\n",
81 info->avg, info->burst); 75 info->avg, info->burst);
82 return -EINVAL; 76 return false;
83 } 77 }
84 78
85 /* User avg in seconds * EBT_LIMIT_SCALE: convert to jiffies * 128. */ 79 /* User avg in seconds * EBT_LIMIT_SCALE: convert to jiffies * 128. */
@@ -87,24 +81,27 @@ static int ebt_limit_check(const char *tablename, unsigned int hookmask,
87 info->credit = user2credits(info->avg * info->burst); 81 info->credit = user2credits(info->avg * info->burst);
88 info->credit_cap = user2credits(info->avg * info->burst); 82 info->credit_cap = user2credits(info->avg * info->burst);
89 info->cost = user2credits(info->avg); 83 info->cost = user2credits(info->avg);
90 return 0; 84 return true;
91} 85}
92 86
93static struct ebt_match ebt_limit_reg __read_mostly = { 87static struct xt_match ebt_limit_mt_reg __read_mostly = {
94 .name = EBT_LIMIT_MATCH, 88 .name = "limit",
95 .match = ebt_limit_match, 89 .revision = 0,
96 .check = ebt_limit_check, 90 .family = NFPROTO_BRIDGE,
91 .match = ebt_limit_mt,
92 .checkentry = ebt_limit_mt_check,
93 .matchsize = XT_ALIGN(sizeof(struct ebt_limit_info)),
97 .me = THIS_MODULE, 94 .me = THIS_MODULE,
98}; 95};
99 96
100static int __init ebt_limit_init(void) 97static int __init ebt_limit_init(void)
101{ 98{
102 return ebt_register_match(&ebt_limit_reg); 99 return xt_register_match(&ebt_limit_mt_reg);
103} 100}
104 101
105static void __exit ebt_limit_fini(void) 102static void __exit ebt_limit_fini(void)
106{ 103{
107 ebt_unregister_match(&ebt_limit_reg); 104 xt_unregister_match(&ebt_limit_mt_reg);
108} 105}
109 106
110module_init(ebt_limit_init); 107module_init(ebt_limit_init);
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index 2f430d4ae911..3d33c608906a 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -8,10 +8,6 @@
8 * April, 2002 8 * April, 2002
9 * 9 *
10 */ 10 */
11
12#include <linux/netfilter_bridge/ebtables.h>
13#include <linux/netfilter_bridge/ebt_log.h>
14#include <linux/netfilter.h>
15#include <linux/module.h> 11#include <linux/module.h>
16#include <linux/ip.h> 12#include <linux/ip.h>
17#include <linux/in.h> 13#include <linux/in.h>
@@ -21,22 +17,23 @@
21#include <linux/ipv6.h> 17#include <linux/ipv6.h>
22#include <net/ipv6.h> 18#include <net/ipv6.h>
23#include <linux/in6.h> 19#include <linux/in6.h>
20#include <linux/netfilter/x_tables.h>
21#include <linux/netfilter_bridge/ebtables.h>
22#include <linux/netfilter_bridge/ebt_log.h>
23#include <linux/netfilter.h>
24 24
25static DEFINE_SPINLOCK(ebt_log_lock); 25static DEFINE_SPINLOCK(ebt_log_lock);
26 26
27static int ebt_log_check(const char *tablename, unsigned int hookmask, 27static bool ebt_log_tg_check(const struct xt_tgchk_param *par)
28 const struct ebt_entry *e, void *data, unsigned int datalen)
29{ 28{
30 struct ebt_log_info *info = data; 29 struct ebt_log_info *info = par->targinfo;
31 30
32 if (datalen != EBT_ALIGN(sizeof(struct ebt_log_info)))
33 return -EINVAL;
34 if (info->bitmask & ~EBT_LOG_MASK) 31 if (info->bitmask & ~EBT_LOG_MASK)
35 return -EINVAL; 32 return false;
36 if (info->loglevel >= 8) 33 if (info->loglevel >= 8)
37 return -EINVAL; 34 return false;
38 info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0'; 35 info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0';
39 return 0; 36 return true;
40} 37}
41 38
42struct tcpudphdr 39struct tcpudphdr
@@ -84,7 +81,7 @@ print_ports(const struct sk_buff *skb, uint8_t protocol, int offset)
84 81
85#define myNIPQUAD(a) a[0], a[1], a[2], a[3] 82#define myNIPQUAD(a) a[0], a[1], a[2], a[3]
86static void 83static void
87ebt_log_packet(unsigned int pf, unsigned int hooknum, 84ebt_log_packet(u_int8_t pf, unsigned int hooknum,
88 const struct sk_buff *skb, const struct net_device *in, 85 const struct sk_buff *skb, const struct net_device *in,
89 const struct net_device *out, const struct nf_loginfo *loginfo, 86 const struct net_device *out, const struct nf_loginfo *loginfo,
90 const char *prefix) 87 const char *prefix)
@@ -194,11 +191,10 @@ out:
194 191
195} 192}
196 193
197static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, 194static unsigned int
198 const struct net_device *in, const struct net_device *out, 195ebt_log_tg(struct sk_buff *skb, const struct xt_target_param *par)
199 const void *data, unsigned int datalen)
200{ 196{
201 const struct ebt_log_info *info = data; 197 const struct ebt_log_info *info = par->targinfo;
202 struct nf_loginfo li; 198 struct nf_loginfo li;
203 199
204 li.type = NF_LOG_TYPE_LOG; 200 li.type = NF_LOG_TYPE_LOG;
@@ -206,18 +202,21 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
206 li.u.log.logflags = info->bitmask; 202 li.u.log.logflags = info->bitmask;
207 203
208 if (info->bitmask & EBT_LOG_NFLOG) 204 if (info->bitmask & EBT_LOG_NFLOG)
209 nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, 205 nf_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in,
210 "%s", info->prefix); 206 par->out, &li, "%s", info->prefix);
211 else 207 else
212 ebt_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, 208 ebt_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in,
213 info->prefix); 209 par->out, &li, info->prefix);
210 return EBT_CONTINUE;
214} 211}
215 212
216static struct ebt_watcher log = 213static struct xt_target ebt_log_tg_reg __read_mostly = {
217{ 214 .name = "log",
218 .name = EBT_LOG_WATCHER, 215 .revision = 0,
219 .watcher = ebt_log, 216 .family = NFPROTO_BRIDGE,
220 .check = ebt_log_check, 217 .target = ebt_log_tg,
218 .checkentry = ebt_log_tg_check,
219 .targetsize = XT_ALIGN(sizeof(struct ebt_log_info)),
221 .me = THIS_MODULE, 220 .me = THIS_MODULE,
222}; 221};
223 222
@@ -231,17 +230,17 @@ static int __init ebt_log_init(void)
231{ 230{
232 int ret; 231 int ret;
233 232
234 ret = ebt_register_watcher(&log); 233 ret = xt_register_target(&ebt_log_tg_reg);
235 if (ret < 0) 234 if (ret < 0)
236 return ret; 235 return ret;
237 nf_log_register(PF_BRIDGE, &ebt_log_logger); 236 nf_log_register(NFPROTO_BRIDGE, &ebt_log_logger);
238 return 0; 237 return 0;
239} 238}
240 239
241static void __exit ebt_log_fini(void) 240static void __exit ebt_log_fini(void)
242{ 241{
243 nf_log_unregister(&ebt_log_logger); 242 nf_log_unregister(&ebt_log_logger);
244 ebt_unregister_watcher(&log); 243 xt_unregister_target(&ebt_log_tg_reg);
245} 244}
246 245
247module_init(ebt_log_init); 246module_init(ebt_log_init);
diff --git a/net/bridge/netfilter/ebt_mark.c b/net/bridge/netfilter/ebt_mark.c
index 36723f47db0a..2fee7e8e2e93 100644
--- a/net/bridge/netfilter/ebt_mark.c
+++ b/net/bridge/netfilter/ebt_mark.c
@@ -13,15 +13,15 @@
13 * Marking a frame doesn't really change anything in the frame anyway. 13 * Marking a frame doesn't really change anything in the frame anyway.
14 */ 14 */
15 15
16#include <linux/module.h>
17#include <linux/netfilter/x_tables.h>
16#include <linux/netfilter_bridge/ebtables.h> 18#include <linux/netfilter_bridge/ebtables.h>
17#include <linux/netfilter_bridge/ebt_mark_t.h> 19#include <linux/netfilter_bridge/ebt_mark_t.h>
18#include <linux/module.h>
19 20
20static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr, 21static unsigned int
21 const struct net_device *in, const struct net_device *out, 22ebt_mark_tg(struct sk_buff *skb, const struct xt_target_param *par)
22 const void *data, unsigned int datalen)
23{ 23{
24 const struct ebt_mark_t_info *info = data; 24 const struct ebt_mark_t_info *info = par->targinfo;
25 int action = info->target & -16; 25 int action = info->target & -16;
26 26
27 if (action == MARK_SET_VALUE) 27 if (action == MARK_SET_VALUE)
@@ -36,42 +36,41 @@ static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr,
36 return info->target | ~EBT_VERDICT_BITS; 36 return info->target | ~EBT_VERDICT_BITS;
37} 37}
38 38
39static int ebt_target_mark_check(const char *tablename, unsigned int hookmask, 39static bool ebt_mark_tg_check(const struct xt_tgchk_param *par)
40 const struct ebt_entry *e, void *data, unsigned int datalen)
41{ 40{
42 const struct ebt_mark_t_info *info = data; 41 const struct ebt_mark_t_info *info = par->targinfo;
43 int tmp; 42 int tmp;
44 43
45 if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info)))
46 return -EINVAL;
47 tmp = info->target | ~EBT_VERDICT_BITS; 44 tmp = info->target | ~EBT_VERDICT_BITS;
48 if (BASE_CHAIN && tmp == EBT_RETURN) 45 if (BASE_CHAIN && tmp == EBT_RETURN)
49 return -EINVAL; 46 return false;
50 CLEAR_BASE_CHAIN_BIT;
51 if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) 47 if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
52 return -EINVAL; 48 return false;
53 tmp = info->target & ~EBT_VERDICT_BITS; 49 tmp = info->target & ~EBT_VERDICT_BITS;
54 if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE && 50 if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE &&
55 tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE) 51 tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE)
56 return -EINVAL; 52 return false;
57 return 0; 53 return true;
58} 54}
59 55
60static struct ebt_target mark_target __read_mostly = { 56static struct xt_target ebt_mark_tg_reg __read_mostly = {
61 .name = EBT_MARK_TARGET, 57 .name = "mark",
62 .target = ebt_target_mark, 58 .revision = 0,
63 .check = ebt_target_mark_check, 59 .family = NFPROTO_BRIDGE,
60 .target = ebt_mark_tg,
61 .checkentry = ebt_mark_tg_check,
62 .targetsize = XT_ALIGN(sizeof(struct ebt_mark_t_info)),
64 .me = THIS_MODULE, 63 .me = THIS_MODULE,
65}; 64};
66 65
67static int __init ebt_mark_init(void) 66static int __init ebt_mark_init(void)
68{ 67{
69 return ebt_register_target(&mark_target); 68 return xt_register_target(&ebt_mark_tg_reg);
70} 69}
71 70
72static void __exit ebt_mark_fini(void) 71static void __exit ebt_mark_fini(void)
73{ 72{
74 ebt_unregister_target(&mark_target); 73 xt_unregister_target(&ebt_mark_tg_reg);
75} 74}
76 75
77module_init(ebt_mark_init); 76module_init(ebt_mark_init);
diff --git a/net/bridge/netfilter/ebt_mark_m.c b/net/bridge/netfilter/ebt_mark_m.c
index 9b0a4543861f..ea570f214b1d 100644
--- a/net/bridge/netfilter/ebt_mark_m.c
+++ b/net/bridge/netfilter/ebt_mark_m.c
@@ -7,53 +7,52 @@
7 * July, 2002 7 * July, 2002
8 * 8 *
9 */ 9 */
10 10#include <linux/module.h>
11#include <linux/netfilter/x_tables.h>
11#include <linux/netfilter_bridge/ebtables.h> 12#include <linux/netfilter_bridge/ebtables.h>
12#include <linux/netfilter_bridge/ebt_mark_m.h> 13#include <linux/netfilter_bridge/ebt_mark_m.h>
13#include <linux/module.h>
14 14
15static int ebt_filter_mark(const struct sk_buff *skb, 15static bool
16 const struct net_device *in, const struct net_device *out, const void *data, 16ebt_mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
17 unsigned int datalen)
18{ 17{
19 const struct ebt_mark_m_info *info = data; 18 const struct ebt_mark_m_info *info = par->matchinfo;
20 19
21 if (info->bitmask & EBT_MARK_OR) 20 if (info->bitmask & EBT_MARK_OR)
22 return !(!!(skb->mark & info->mask) ^ info->invert); 21 return !!(skb->mark & info->mask) ^ info->invert;
23 return !(((skb->mark & info->mask) == info->mark) ^ info->invert); 22 return ((skb->mark & info->mask) == info->mark) ^ info->invert;
24} 23}
25 24
26static int ebt_mark_check(const char *tablename, unsigned int hookmask, 25static bool ebt_mark_mt_check(const struct xt_mtchk_param *par)
27 const struct ebt_entry *e, void *data, unsigned int datalen)
28{ 26{
29 const struct ebt_mark_m_info *info = data; 27 const struct ebt_mark_m_info *info = par->matchinfo;
30 28
31 if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_m_info)))
32 return -EINVAL;
33 if (info->bitmask & ~EBT_MARK_MASK) 29 if (info->bitmask & ~EBT_MARK_MASK)
34 return -EINVAL; 30 return false;
35 if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND)) 31 if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND))
36 return -EINVAL; 32 return false;
37 if (!info->bitmask) 33 if (!info->bitmask)
38 return -EINVAL; 34 return false;
39 return 0; 35 return true;
40} 36}
41 37
42static struct ebt_match filter_mark __read_mostly = { 38static struct xt_match ebt_mark_mt_reg __read_mostly = {
43 .name = EBT_MARK_MATCH, 39 .name = "mark_m",
44 .match = ebt_filter_mark, 40 .revision = 0,
45 .check = ebt_mark_check, 41 .family = NFPROTO_BRIDGE,
42 .match = ebt_mark_mt,
43 .checkentry = ebt_mark_mt_check,
44 .matchsize = XT_ALIGN(sizeof(struct ebt_mark_m_info)),
46 .me = THIS_MODULE, 45 .me = THIS_MODULE,
47}; 46};
48 47
49static int __init ebt_mark_m_init(void) 48static int __init ebt_mark_m_init(void)
50{ 49{
51 return ebt_register_match(&filter_mark); 50 return xt_register_match(&ebt_mark_mt_reg);
52} 51}
53 52
54static void __exit ebt_mark_m_fini(void) 53static void __exit ebt_mark_m_fini(void)
55{ 54{
56 ebt_unregister_match(&filter_mark); 55 xt_unregister_match(&ebt_mark_mt_reg);
57} 56}
58 57
59module_init(ebt_mark_m_init); 58module_init(ebt_mark_m_init);
diff --git a/net/bridge/netfilter/ebt_nflog.c b/net/bridge/netfilter/ebt_nflog.c
index 8e799aa9e560..2a63d996dd4e 100644
--- a/net/bridge/netfilter/ebt_nflog.c
+++ b/net/bridge/netfilter/ebt_nflog.c
@@ -14,17 +14,15 @@
14 14
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/spinlock.h> 16#include <linux/spinlock.h>
17#include <linux/netfilter/x_tables.h>
17#include <linux/netfilter_bridge/ebtables.h> 18#include <linux/netfilter_bridge/ebtables.h>
18#include <linux/netfilter_bridge/ebt_nflog.h> 19#include <linux/netfilter_bridge/ebt_nflog.h>
19#include <net/netfilter/nf_log.h> 20#include <net/netfilter/nf_log.h>
20 21
21static void ebt_nflog(const struct sk_buff *skb, 22static unsigned int
22 unsigned int hooknr, 23ebt_nflog_tg(struct sk_buff *skb, const struct xt_target_param *par)
23 const struct net_device *in,
24 const struct net_device *out,
25 const void *data, unsigned int datalen)
26{ 24{
27 struct ebt_nflog_info *info = (struct ebt_nflog_info *)data; 25 const struct ebt_nflog_info *info = par->targinfo;
28 struct nf_loginfo li; 26 struct nf_loginfo li;
29 27
30 li.type = NF_LOG_TYPE_ULOG; 28 li.type = NF_LOG_TYPE_ULOG;
@@ -32,39 +30,39 @@ static void ebt_nflog(const struct sk_buff *skb,
32 li.u.ulog.group = info->group; 30 li.u.ulog.group = info->group;
33 li.u.ulog.qthreshold = info->threshold; 31 li.u.ulog.qthreshold = info->threshold;
34 32
35 nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, "%s", info->prefix); 33 nf_log_packet(PF_BRIDGE, par->hooknum, skb, par->in, par->out,
34 &li, "%s", info->prefix);
35 return EBT_CONTINUE;
36} 36}
37 37
38static int ebt_nflog_check(const char *tablename, 38static bool ebt_nflog_tg_check(const struct xt_tgchk_param *par)
39 unsigned int hookmask,
40 const struct ebt_entry *e,
41 void *data, unsigned int datalen)
42{ 39{
43 struct ebt_nflog_info *info = (struct ebt_nflog_info *)data; 40 struct ebt_nflog_info *info = par->targinfo;
44 41
45 if (datalen != EBT_ALIGN(sizeof(struct ebt_nflog_info)))
46 return -EINVAL;
47 if (info->flags & ~EBT_NFLOG_MASK) 42 if (info->flags & ~EBT_NFLOG_MASK)
48 return -EINVAL; 43 return false;
49 info->prefix[EBT_NFLOG_PREFIX_SIZE - 1] = '\0'; 44 info->prefix[EBT_NFLOG_PREFIX_SIZE - 1] = '\0';
50 return 0; 45 return true;
51} 46}
52 47
53static struct ebt_watcher nflog __read_mostly = { 48static struct xt_target ebt_nflog_tg_reg __read_mostly = {
54 .name = EBT_NFLOG_WATCHER, 49 .name = "nflog",
55 .watcher = ebt_nflog, 50 .revision = 0,
56 .check = ebt_nflog_check, 51 .family = NFPROTO_BRIDGE,
57 .me = THIS_MODULE, 52 .target = ebt_nflog_tg,
53 .checkentry = ebt_nflog_tg_check,
54 .targetsize = XT_ALIGN(sizeof(struct ebt_nflog_info)),
55 .me = THIS_MODULE,
58}; 56};
59 57
60static int __init ebt_nflog_init(void) 58static int __init ebt_nflog_init(void)
61{ 59{
62 return ebt_register_watcher(&nflog); 60 return xt_register_target(&ebt_nflog_tg_reg);
63} 61}
64 62
65static void __exit ebt_nflog_fini(void) 63static void __exit ebt_nflog_fini(void)
66{ 64{
67 ebt_unregister_watcher(&nflog); 65 xt_unregister_target(&ebt_nflog_tg_reg);
68} 66}
69 67
70module_init(ebt_nflog_init); 68module_init(ebt_nflog_init);
diff --git a/net/bridge/netfilter/ebt_pkttype.c b/net/bridge/netfilter/ebt_pkttype.c
index 676db32df3d1..883e96e2a542 100644
--- a/net/bridge/netfilter/ebt_pkttype.c
+++ b/net/bridge/netfilter/ebt_pkttype.c
@@ -7,50 +7,47 @@
7 * April, 2003 7 * April, 2003
8 * 8 *
9 */ 9 */
10 10#include <linux/module.h>
11#include <linux/netfilter/x_tables.h>
11#include <linux/netfilter_bridge/ebtables.h> 12#include <linux/netfilter_bridge/ebtables.h>
12#include <linux/netfilter_bridge/ebt_pkttype.h> 13#include <linux/netfilter_bridge/ebt_pkttype.h>
13#include <linux/module.h>
14 14
15static int ebt_filter_pkttype(const struct sk_buff *skb, 15static bool
16 const struct net_device *in, 16ebt_pkttype_mt(const struct sk_buff *skb, const struct xt_match_param *par)
17 const struct net_device *out,
18 const void *data,
19 unsigned int datalen)
20{ 17{
21 const struct ebt_pkttype_info *info = data; 18 const struct ebt_pkttype_info *info = par->matchinfo;
22 19
23 return (skb->pkt_type != info->pkt_type) ^ info->invert; 20 return (skb->pkt_type == info->pkt_type) ^ info->invert;
24} 21}
25 22
26static int ebt_pkttype_check(const char *tablename, unsigned int hookmask, 23static bool ebt_pkttype_mt_check(const struct xt_mtchk_param *par)
27 const struct ebt_entry *e, void *data, unsigned int datalen)
28{ 24{
29 const struct ebt_pkttype_info *info = data; 25 const struct ebt_pkttype_info *info = par->matchinfo;
30 26
31 if (datalen != EBT_ALIGN(sizeof(struct ebt_pkttype_info)))
32 return -EINVAL;
33 if (info->invert != 0 && info->invert != 1) 27 if (info->invert != 0 && info->invert != 1)
34 return -EINVAL; 28 return false;
35 /* Allow any pkt_type value */ 29 /* Allow any pkt_type value */
36 return 0; 30 return true;
37} 31}
38 32
39static struct ebt_match filter_pkttype __read_mostly = { 33static struct xt_match ebt_pkttype_mt_reg __read_mostly = {
40 .name = EBT_PKTTYPE_MATCH, 34 .name = "pkttype",
41 .match = ebt_filter_pkttype, 35 .revision = 0,
42 .check = ebt_pkttype_check, 36 .family = NFPROTO_BRIDGE,
37 .match = ebt_pkttype_mt,
38 .checkentry = ebt_pkttype_mt_check,
39 .matchsize = XT_ALIGN(sizeof(struct ebt_pkttype_info)),
43 .me = THIS_MODULE, 40 .me = THIS_MODULE,
44}; 41};
45 42
46static int __init ebt_pkttype_init(void) 43static int __init ebt_pkttype_init(void)
47{ 44{
48 return ebt_register_match(&filter_pkttype); 45 return xt_register_match(&ebt_pkttype_mt_reg);
49} 46}
50 47
51static void __exit ebt_pkttype_fini(void) 48static void __exit ebt_pkttype_fini(void)
52{ 49{
53 ebt_unregister_match(&filter_pkttype); 50 xt_unregister_match(&ebt_pkttype_mt_reg);
54} 51}
55 52
56module_init(ebt_pkttype_init); 53module_init(ebt_pkttype_init);
diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c
index b8afe850cf1e..c8a49f7a57ba 100644
--- a/net/bridge/netfilter/ebt_redirect.c
+++ b/net/bridge/netfilter/ebt_redirect.c
@@ -7,65 +7,70 @@
7 * April, 2002 7 * April, 2002
8 * 8 *
9 */ 9 */
10
11#include <linux/netfilter.h>
12#include <linux/netfilter_bridge/ebtables.h>
13#include <linux/netfilter_bridge/ebt_redirect.h>
14#include <linux/module.h> 10#include <linux/module.h>
15#include <net/sock.h> 11#include <net/sock.h>
16#include "../br_private.h" 12#include "../br_private.h"
13#include <linux/netfilter.h>
14#include <linux/netfilter/x_tables.h>
15#include <linux/netfilter_bridge/ebtables.h>
16#include <linux/netfilter_bridge/ebt_redirect.h>
17 17
18static int ebt_target_redirect(struct sk_buff *skb, unsigned int hooknr, 18static unsigned int
19 const struct net_device *in, const struct net_device *out, 19ebt_redirect_tg(struct sk_buff *skb, const struct xt_target_param *par)
20 const void *data, unsigned int datalen)
21{ 20{
22 const struct ebt_redirect_info *info = data; 21 const struct ebt_redirect_info *info = par->targinfo;
23 22
24 if (!skb_make_writable(skb, 0)) 23 if (!skb_make_writable(skb, 0))
25 return EBT_DROP; 24 return EBT_DROP;
26 25
27 if (hooknr != NF_BR_BROUTING) 26 if (par->hooknum != NF_BR_BROUTING)
28 memcpy(eth_hdr(skb)->h_dest, 27 memcpy(eth_hdr(skb)->h_dest,
29 in->br_port->br->dev->dev_addr, ETH_ALEN); 28 par->in->br_port->br->dev->dev_addr, ETH_ALEN);
30 else 29 else
31 memcpy(eth_hdr(skb)->h_dest, in->dev_addr, ETH_ALEN); 30 memcpy(eth_hdr(skb)->h_dest, par->in->dev_addr, ETH_ALEN);
32 skb->pkt_type = PACKET_HOST; 31 skb->pkt_type = PACKET_HOST;
33 return info->target; 32 return info->target;
34} 33}
35 34
36static int ebt_target_redirect_check(const char *tablename, unsigned int hookmask, 35static bool ebt_redirect_tg_check(const struct xt_tgchk_param *par)
37 const struct ebt_entry *e, void *data, unsigned int datalen)
38{ 36{
39 const struct ebt_redirect_info *info = data; 37 const struct ebt_redirect_info *info = par->targinfo;
38 unsigned int hook_mask;
40 39
41 if (datalen != EBT_ALIGN(sizeof(struct ebt_redirect_info)))
42 return -EINVAL;
43 if (BASE_CHAIN && info->target == EBT_RETURN) 40 if (BASE_CHAIN && info->target == EBT_RETURN)
44 return -EINVAL; 41 return false;
45 CLEAR_BASE_CHAIN_BIT; 42
46 if ( (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) && 43 hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
47 (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) ) 44 if ((strcmp(par->table, "nat") != 0 ||
48 return -EINVAL; 45 hook_mask & ~(1 << NF_BR_PRE_ROUTING)) &&
46 (strcmp(par->table, "broute") != 0 ||
47 hook_mask & ~(1 << NF_BR_BROUTING)))
48 return false;
49 if (INVALID_TARGET) 49 if (INVALID_TARGET)
50 return -EINVAL; 50 return false;
51 return 0; 51 return true;
52} 52}
53 53
54static struct ebt_target redirect_target __read_mostly = { 54static struct xt_target ebt_redirect_tg_reg __read_mostly = {
55 .name = EBT_REDIRECT_TARGET, 55 .name = "redirect",
56 .target = ebt_target_redirect, 56 .revision = 0,
57 .check = ebt_target_redirect_check, 57 .family = NFPROTO_BRIDGE,
58 .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING) |
59 (1 << NF_BR_BROUTING),
60 .target = ebt_redirect_tg,
61 .checkentry = ebt_redirect_tg_check,
62 .targetsize = XT_ALIGN(sizeof(struct ebt_redirect_info)),
58 .me = THIS_MODULE, 63 .me = THIS_MODULE,
59}; 64};
60 65
61static int __init ebt_redirect_init(void) 66static int __init ebt_redirect_init(void)
62{ 67{
63 return ebt_register_target(&redirect_target); 68 return xt_register_target(&ebt_redirect_tg_reg);
64} 69}
65 70
66static void __exit ebt_redirect_fini(void) 71static void __exit ebt_redirect_fini(void)
67{ 72{
68 ebt_unregister_target(&redirect_target); 73 xt_unregister_target(&ebt_redirect_tg_reg);
69} 74}
70 75
71module_init(ebt_redirect_init); 76module_init(ebt_redirect_init);
diff --git a/net/bridge/netfilter/ebt_snat.c b/net/bridge/netfilter/ebt_snat.c
index 5425333dda03..8d04d4c302bd 100644
--- a/net/bridge/netfilter/ebt_snat.c
+++ b/net/bridge/netfilter/ebt_snat.c
@@ -7,20 +7,19 @@
7 * June, 2002 7 * June, 2002
8 * 8 *
9 */ 9 */
10
11#include <linux/netfilter.h>
12#include <linux/netfilter_bridge/ebtables.h>
13#include <linux/netfilter_bridge/ebt_nat.h>
14#include <linux/module.h> 10#include <linux/module.h>
15#include <net/sock.h> 11#include <net/sock.h>
16#include <linux/if_arp.h> 12#include <linux/if_arp.h>
17#include <net/arp.h> 13#include <net/arp.h>
14#include <linux/netfilter.h>
15#include <linux/netfilter/x_tables.h>
16#include <linux/netfilter_bridge/ebtables.h>
17#include <linux/netfilter_bridge/ebt_nat.h>
18 18
19static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr, 19static unsigned int
20 const struct net_device *in, const struct net_device *out, 20ebt_snat_tg(struct sk_buff *skb, const struct xt_target_param *par)
21 const void *data, unsigned int datalen)
22{ 21{
23 const struct ebt_nat_info *info = data; 22 const struct ebt_nat_info *info = par->targinfo;
24 23
25 if (!skb_make_writable(skb, 0)) 24 if (!skb_make_writable(skb, 0))
26 return EBT_DROP; 25 return EBT_DROP;
@@ -43,46 +42,43 @@ out:
43 return info->target | ~EBT_VERDICT_BITS; 42 return info->target | ~EBT_VERDICT_BITS;
44} 43}
45 44
46static int ebt_target_snat_check(const char *tablename, unsigned int hookmask, 45static bool ebt_snat_tg_check(const struct xt_tgchk_param *par)
47 const struct ebt_entry *e, void *data, unsigned int datalen)
48{ 46{
49 const struct ebt_nat_info *info = data; 47 const struct ebt_nat_info *info = par->targinfo;
50 int tmp; 48 int tmp;
51 49
52 if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info)))
53 return -EINVAL;
54 tmp = info->target | ~EBT_VERDICT_BITS; 50 tmp = info->target | ~EBT_VERDICT_BITS;
55 if (BASE_CHAIN && tmp == EBT_RETURN) 51 if (BASE_CHAIN && tmp == EBT_RETURN)
56 return -EINVAL; 52 return false;
57 CLEAR_BASE_CHAIN_BIT;
58 if (strcmp(tablename, "nat"))
59 return -EINVAL;
60 if (hookmask & ~(1 << NF_BR_POST_ROUTING))
61 return -EINVAL;
62 53
63 if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) 54 if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
64 return -EINVAL; 55 return false;
65 tmp = info->target | EBT_VERDICT_BITS; 56 tmp = info->target | EBT_VERDICT_BITS;
66 if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT) 57 if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT)
67 return -EINVAL; 58 return false;
68 return 0; 59 return true;
69} 60}
70 61
71static struct ebt_target snat __read_mostly = { 62static struct xt_target ebt_snat_tg_reg __read_mostly = {
72 .name = EBT_SNAT_TARGET, 63 .name = "snat",
73 .target = ebt_target_snat, 64 .revision = 0,
74 .check = ebt_target_snat_check, 65 .family = NFPROTO_BRIDGE,
66 .table = "nat",
67 .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_POST_ROUTING),
68 .target = ebt_snat_tg,
69 .checkentry = ebt_snat_tg_check,
70 .targetsize = XT_ALIGN(sizeof(struct ebt_nat_info)),
75 .me = THIS_MODULE, 71 .me = THIS_MODULE,
76}; 72};
77 73
78static int __init ebt_snat_init(void) 74static int __init ebt_snat_init(void)
79{ 75{
80 return ebt_register_target(&snat); 76 return xt_register_target(&ebt_snat_tg_reg);
81} 77}
82 78
83static void __exit ebt_snat_fini(void) 79static void __exit ebt_snat_fini(void)
84{ 80{
85 ebt_unregister_target(&snat); 81 xt_unregister_target(&ebt_snat_tg_reg);
86} 82}
87 83
88module_init(ebt_snat_init); 84module_init(ebt_snat_init);
diff --git a/net/bridge/netfilter/ebt_stp.c b/net/bridge/netfilter/ebt_stp.c
index 40f36d37607d..48527e621626 100644
--- a/net/bridge/netfilter/ebt_stp.c
+++ b/net/bridge/netfilter/ebt_stp.c
@@ -7,11 +7,11 @@
7 * 7 *
8 * July, 2003 8 * July, 2003
9 */ 9 */
10
11#include <linux/netfilter_bridge/ebtables.h>
12#include <linux/netfilter_bridge/ebt_stp.h>
13#include <linux/etherdevice.h> 10#include <linux/etherdevice.h>
14#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/netfilter/x_tables.h>
13#include <linux/netfilter_bridge/ebtables.h>
14#include <linux/netfilter_bridge/ebt_stp.h>
15 15
16#define BPDU_TYPE_CONFIG 0 16#define BPDU_TYPE_CONFIG 0
17#define BPDU_TYPE_TCN 0x80 17#define BPDU_TYPE_TCN 0x80
@@ -40,7 +40,7 @@ struct stp_config_pdu {
40#define NR16(p) (p[0] << 8 | p[1]) 40#define NR16(p) (p[0] << 8 | p[1])
41#define NR32(p) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]) 41#define NR32(p) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3])
42 42
43static int ebt_filter_config(const struct ebt_stp_info *info, 43static bool ebt_filter_config(const struct ebt_stp_info *info,
44 const struct stp_config_pdu *stpc) 44 const struct stp_config_pdu *stpc)
45{ 45{
46 const struct ebt_stp_config_info *c; 46 const struct ebt_stp_config_info *c;
@@ -51,12 +51,12 @@ static int ebt_filter_config(const struct ebt_stp_info *info,
51 c = &info->config; 51 c = &info->config;
52 if ((info->bitmask & EBT_STP_FLAGS) && 52 if ((info->bitmask & EBT_STP_FLAGS) &&
53 FWINV(c->flags != stpc->flags, EBT_STP_FLAGS)) 53 FWINV(c->flags != stpc->flags, EBT_STP_FLAGS))
54 return EBT_NOMATCH; 54 return false;
55 if (info->bitmask & EBT_STP_ROOTPRIO) { 55 if (info->bitmask & EBT_STP_ROOTPRIO) {
56 v16 = NR16(stpc->root); 56 v16 = NR16(stpc->root);
57 if (FWINV(v16 < c->root_priol || 57 if (FWINV(v16 < c->root_priol ||
58 v16 > c->root_priou, EBT_STP_ROOTPRIO)) 58 v16 > c->root_priou, EBT_STP_ROOTPRIO))
59 return EBT_NOMATCH; 59 return false;
60 } 60 }
61 if (info->bitmask & EBT_STP_ROOTADDR) { 61 if (info->bitmask & EBT_STP_ROOTADDR) {
62 verdict = 0; 62 verdict = 0;
@@ -64,19 +64,19 @@ static int ebt_filter_config(const struct ebt_stp_info *info,
64 verdict |= (stpc->root[2+i] ^ c->root_addr[i]) & 64 verdict |= (stpc->root[2+i] ^ c->root_addr[i]) &
65 c->root_addrmsk[i]; 65 c->root_addrmsk[i];
66 if (FWINV(verdict != 0, EBT_STP_ROOTADDR)) 66 if (FWINV(verdict != 0, EBT_STP_ROOTADDR))
67 return EBT_NOMATCH; 67 return false;
68 } 68 }
69 if (info->bitmask & EBT_STP_ROOTCOST) { 69 if (info->bitmask & EBT_STP_ROOTCOST) {
70 v32 = NR32(stpc->root_cost); 70 v32 = NR32(stpc->root_cost);
71 if (FWINV(v32 < c->root_costl || 71 if (FWINV(v32 < c->root_costl ||
72 v32 > c->root_costu, EBT_STP_ROOTCOST)) 72 v32 > c->root_costu, EBT_STP_ROOTCOST))
73 return EBT_NOMATCH; 73 return false;
74 } 74 }
75 if (info->bitmask & EBT_STP_SENDERPRIO) { 75 if (info->bitmask & EBT_STP_SENDERPRIO) {
76 v16 = NR16(stpc->sender); 76 v16 = NR16(stpc->sender);
77 if (FWINV(v16 < c->sender_priol || 77 if (FWINV(v16 < c->sender_priol ||
78 v16 > c->sender_priou, EBT_STP_SENDERPRIO)) 78 v16 > c->sender_priou, EBT_STP_SENDERPRIO))
79 return EBT_NOMATCH; 79 return false;
80 } 80 }
81 if (info->bitmask & EBT_STP_SENDERADDR) { 81 if (info->bitmask & EBT_STP_SENDERADDR) {
82 verdict = 0; 82 verdict = 0;
@@ -84,60 +84,60 @@ static int ebt_filter_config(const struct ebt_stp_info *info,
84 verdict |= (stpc->sender[2+i] ^ c->sender_addr[i]) & 84 verdict |= (stpc->sender[2+i] ^ c->sender_addr[i]) &
85 c->sender_addrmsk[i]; 85 c->sender_addrmsk[i];
86 if (FWINV(verdict != 0, EBT_STP_SENDERADDR)) 86 if (FWINV(verdict != 0, EBT_STP_SENDERADDR))
87 return EBT_NOMATCH; 87 return false;
88 } 88 }
89 if (info->bitmask & EBT_STP_PORT) { 89 if (info->bitmask & EBT_STP_PORT) {
90 v16 = NR16(stpc->port); 90 v16 = NR16(stpc->port);
91 if (FWINV(v16 < c->portl || 91 if (FWINV(v16 < c->portl ||
92 v16 > c->portu, EBT_STP_PORT)) 92 v16 > c->portu, EBT_STP_PORT))
93 return EBT_NOMATCH; 93 return false;
94 } 94 }
95 if (info->bitmask & EBT_STP_MSGAGE) { 95 if (info->bitmask & EBT_STP_MSGAGE) {
96 v16 = NR16(stpc->msg_age); 96 v16 = NR16(stpc->msg_age);
97 if (FWINV(v16 < c->msg_agel || 97 if (FWINV(v16 < c->msg_agel ||
98 v16 > c->msg_ageu, EBT_STP_MSGAGE)) 98 v16 > c->msg_ageu, EBT_STP_MSGAGE))
99 return EBT_NOMATCH; 99 return false;
100 } 100 }
101 if (info->bitmask & EBT_STP_MAXAGE) { 101 if (info->bitmask & EBT_STP_MAXAGE) {
102 v16 = NR16(stpc->max_age); 102 v16 = NR16(stpc->max_age);
103 if (FWINV(v16 < c->max_agel || 103 if (FWINV(v16 < c->max_agel ||
104 v16 > c->max_ageu, EBT_STP_MAXAGE)) 104 v16 > c->max_ageu, EBT_STP_MAXAGE))
105 return EBT_NOMATCH; 105 return false;
106 } 106 }
107 if (info->bitmask & EBT_STP_HELLOTIME) { 107 if (info->bitmask & EBT_STP_HELLOTIME) {
108 v16 = NR16(stpc->hello_time); 108 v16 = NR16(stpc->hello_time);
109 if (FWINV(v16 < c->hello_timel || 109 if (FWINV(v16 < c->hello_timel ||
110 v16 > c->hello_timeu, EBT_STP_HELLOTIME)) 110 v16 > c->hello_timeu, EBT_STP_HELLOTIME))
111 return EBT_NOMATCH; 111 return false;
112 } 112 }
113 if (info->bitmask & EBT_STP_FWDD) { 113 if (info->bitmask & EBT_STP_FWDD) {
114 v16 = NR16(stpc->forward_delay); 114 v16 = NR16(stpc->forward_delay);
115 if (FWINV(v16 < c->forward_delayl || 115 if (FWINV(v16 < c->forward_delayl ||
116 v16 > c->forward_delayu, EBT_STP_FWDD)) 116 v16 > c->forward_delayu, EBT_STP_FWDD))
117 return EBT_NOMATCH; 117 return false;
118 } 118 }
119 return EBT_MATCH; 119 return true;
120} 120}
121 121
122static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in, 122static bool
123 const struct net_device *out, const void *data, unsigned int datalen) 123ebt_stp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
124{ 124{
125 const struct ebt_stp_info *info = data; 125 const struct ebt_stp_info *info = par->matchinfo;
126 const struct stp_header *sp; 126 const struct stp_header *sp;
127 struct stp_header _stph; 127 struct stp_header _stph;
128 const uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00}; 128 const uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00};
129 129
130 sp = skb_header_pointer(skb, 0, sizeof(_stph), &_stph); 130 sp = skb_header_pointer(skb, 0, sizeof(_stph), &_stph);
131 if (sp == NULL) 131 if (sp == NULL)
132 return EBT_NOMATCH; 132 return false;
133 133
134 /* The stp code only considers these */ 134 /* The stp code only considers these */
135 if (memcmp(sp, header, sizeof(header))) 135 if (memcmp(sp, header, sizeof(header)))
136 return EBT_NOMATCH; 136 return false;
137 137
138 if (info->bitmask & EBT_STP_TYPE 138 if (info->bitmask & EBT_STP_TYPE
139 && FWINV(info->type != sp->type, EBT_STP_TYPE)) 139 && FWINV(info->type != sp->type, EBT_STP_TYPE))
140 return EBT_NOMATCH; 140 return false;
141 141
142 if (sp->type == BPDU_TYPE_CONFIG && 142 if (sp->type == BPDU_TYPE_CONFIG &&
143 info->bitmask & EBT_STP_CONFIG_MASK) { 143 info->bitmask & EBT_STP_CONFIG_MASK) {
@@ -147,48 +147,48 @@ static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in
147 st = skb_header_pointer(skb, sizeof(_stph), 147 st = skb_header_pointer(skb, sizeof(_stph),
148 sizeof(_stpc), &_stpc); 148 sizeof(_stpc), &_stpc);
149 if (st == NULL) 149 if (st == NULL)
150 return EBT_NOMATCH; 150 return false;
151 return ebt_filter_config(info, st); 151 return ebt_filter_config(info, st);
152 } 152 }
153 return EBT_MATCH; 153 return true;
154} 154}
155 155
156static int ebt_stp_check(const char *tablename, unsigned int hookmask, 156static bool ebt_stp_mt_check(const struct xt_mtchk_param *par)
157 const struct ebt_entry *e, void *data, unsigned int datalen)
158{ 157{
159 const struct ebt_stp_info *info = data; 158 const struct ebt_stp_info *info = par->matchinfo;
160 const unsigned int len = EBT_ALIGN(sizeof(struct ebt_stp_info));
161 const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00}; 159 const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00};
162 const uint8_t msk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 160 const uint8_t msk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
161 const struct ebt_entry *e = par->entryinfo;
163 162
164 if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK || 163 if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK ||
165 !(info->bitmask & EBT_STP_MASK)) 164 !(info->bitmask & EBT_STP_MASK))
166 return -EINVAL; 165 return false;
167 if (datalen != len)
168 return -EINVAL;
169 /* Make sure the match only receives stp frames */ 166 /* Make sure the match only receives stp frames */
170 if (compare_ether_addr(e->destmac, bridge_ula) || 167 if (compare_ether_addr(e->destmac, bridge_ula) ||
171 compare_ether_addr(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC)) 168 compare_ether_addr(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC))
172 return -EINVAL; 169 return false;
173 170
174 return 0; 171 return true;
175} 172}
176 173
177static struct ebt_match filter_stp __read_mostly = { 174static struct xt_match ebt_stp_mt_reg __read_mostly = {
178 .name = EBT_STP_MATCH, 175 .name = "stp",
179 .match = ebt_filter_stp, 176 .revision = 0,
180 .check = ebt_stp_check, 177 .family = NFPROTO_BRIDGE,
178 .match = ebt_stp_mt,
179 .checkentry = ebt_stp_mt_check,
180 .matchsize = XT_ALIGN(sizeof(struct ebt_stp_info)),
181 .me = THIS_MODULE, 181 .me = THIS_MODULE,
182}; 182};
183 183
184static int __init ebt_stp_init(void) 184static int __init ebt_stp_init(void)
185{ 185{
186 return ebt_register_match(&filter_stp); 186 return xt_register_match(&ebt_stp_mt_reg);
187} 187}
188 188
189static void __exit ebt_stp_fini(void) 189static void __exit ebt_stp_fini(void)
190{ 190{
191 ebt_unregister_match(&filter_stp); 191 xt_unregister_match(&ebt_stp_mt_reg);
192} 192}
193 193
194module_init(ebt_stp_init); 194module_init(ebt_stp_init);
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index 2d4c9ef909fc..2c6d6823e703 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -36,6 +36,7 @@
36#include <linux/timer.h> 36#include <linux/timer.h>
37#include <linux/netlink.h> 37#include <linux/netlink.h>
38#include <linux/netdevice.h> 38#include <linux/netdevice.h>
39#include <linux/netfilter/x_tables.h>
39#include <linux/netfilter_bridge/ebtables.h> 40#include <linux/netfilter_bridge/ebtables.h>
40#include <linux/netfilter_bridge/ebt_ulog.h> 41#include <linux/netfilter_bridge/ebt_ulog.h>
41#include <net/netfilter/nf_log.h> 42#include <net/netfilter/nf_log.h>
@@ -223,7 +224,7 @@ alloc_failure:
223} 224}
224 225
225/* this function is registered with the netfilter core */ 226/* this function is registered with the netfilter core */
226static void ebt_log_packet(unsigned int pf, unsigned int hooknum, 227static void ebt_log_packet(u_int8_t pf, unsigned int hooknum,
227 const struct sk_buff *skb, const struct net_device *in, 228 const struct sk_buff *skb, const struct net_device *in,
228 const struct net_device *out, const struct nf_loginfo *li, 229 const struct net_device *out, const struct nf_loginfo *li,
229 const char *prefix) 230 const char *prefix)
@@ -245,24 +246,20 @@ static void ebt_log_packet(unsigned int pf, unsigned int hooknum,
245 ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); 246 ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
246} 247}
247 248
248static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr, 249static unsigned int
249 const struct net_device *in, const struct net_device *out, 250ebt_ulog_tg(struct sk_buff *skb, const struct xt_target_param *par)
250 const void *data, unsigned int datalen)
251{ 251{
252 const struct ebt_ulog_info *uloginfo = data; 252 ebt_ulog_packet(par->hooknum, skb, par->in, par->out,
253 253 par->targinfo, NULL);
254 ebt_ulog_packet(hooknr, skb, in, out, uloginfo, NULL); 254 return EBT_CONTINUE;
255} 255}
256 256
257 257static bool ebt_ulog_tg_check(const struct xt_tgchk_param *par)
258static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
259 const struct ebt_entry *e, void *data, unsigned int datalen)
260{ 258{
261 struct ebt_ulog_info *uloginfo = data; 259 struct ebt_ulog_info *uloginfo = par->targinfo;
262 260
263 if (datalen != EBT_ALIGN(sizeof(struct ebt_ulog_info)) || 261 if (uloginfo->nlgroup > 31)
264 uloginfo->nlgroup > 31) 262 return false;
265 return -EINVAL;
266 263
267 uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0'; 264 uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0';
268 265
@@ -272,27 +269,31 @@ static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
272 return 0; 269 return 0;
273} 270}
274 271
275static struct ebt_watcher ulog __read_mostly = { 272static struct xt_target ebt_ulog_tg_reg __read_mostly = {
276 .name = EBT_ULOG_WATCHER, 273 .name = "ulog",
277 .watcher = ebt_ulog, 274 .revision = 0,
278 .check = ebt_ulog_check, 275 .family = NFPROTO_BRIDGE,
276 .target = ebt_ulog_tg,
277 .checkentry = ebt_ulog_tg_check,
278 .targetsize = XT_ALIGN(sizeof(struct ebt_ulog_info)),
279 .me = THIS_MODULE, 279 .me = THIS_MODULE,
280}; 280};
281 281
282static const struct nf_logger ebt_ulog_logger = { 282static const struct nf_logger ebt_ulog_logger = {
283 .name = EBT_ULOG_WATCHER, 283 .name = "ulog",
284 .logfn = &ebt_log_packet, 284 .logfn = &ebt_log_packet,
285 .me = THIS_MODULE, 285 .me = THIS_MODULE,
286}; 286};
287 287
288static int __init ebt_ulog_init(void) 288static int __init ebt_ulog_init(void)
289{ 289{
290 int i, ret = 0; 290 bool ret = true;
291 int i;
291 292
292 if (nlbufsiz >= 128*1024) { 293 if (nlbufsiz >= 128*1024) {
293 printk(KERN_NOTICE "ebt_ulog: Netlink buffer has to be <= 128kB," 294 printk(KERN_NOTICE "ebt_ulog: Netlink buffer has to be <= 128kB,"
294 " please try a smaller nlbufsiz parameter.\n"); 295 " please try a smaller nlbufsiz parameter.\n");
295 return -EINVAL; 296 return false;
296 } 297 }
297 298
298 /* initialize ulog_buffers */ 299 /* initialize ulog_buffers */
@@ -304,13 +305,16 @@ static int __init ebt_ulog_init(void)
304 ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG, 305 ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG,
305 EBT_ULOG_MAXNLGROUPS, NULL, NULL, 306 EBT_ULOG_MAXNLGROUPS, NULL, NULL,
306 THIS_MODULE); 307 THIS_MODULE);
307 if (!ebtulognl) 308 if (!ebtulognl) {
308 ret = -ENOMEM; 309 printk(KERN_WARNING KBUILD_MODNAME ": out of memory trying to "
309 else if ((ret = ebt_register_watcher(&ulog))) 310 "call netlink_kernel_create\n");
311 ret = false;
312 } else if (xt_register_target(&ebt_ulog_tg_reg) != 0) {
310 netlink_kernel_release(ebtulognl); 313 netlink_kernel_release(ebtulognl);
314 }
311 315
312 if (ret == 0) 316 if (ret)
313 nf_log_register(PF_BRIDGE, &ebt_ulog_logger); 317 nf_log_register(NFPROTO_BRIDGE, &ebt_ulog_logger);
314 318
315 return ret; 319 return ret;
316} 320}
@@ -321,7 +325,7 @@ static void __exit ebt_ulog_fini(void)
321 int i; 325 int i;
322 326
323 nf_log_unregister(&ebt_ulog_logger); 327 nf_log_unregister(&ebt_ulog_logger);
324 ebt_unregister_watcher(&ulog); 328 xt_unregister_target(&ebt_ulog_tg_reg);
325 for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) { 329 for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
326 ub = &ulog_buffers[i]; 330 ub = &ulog_buffers[i];
327 if (timer_pending(&ub->timer)) 331 if (timer_pending(&ub->timer))
diff --git a/net/bridge/netfilter/ebt_vlan.c b/net/bridge/netfilter/ebt_vlan.c
index ab60b0dade80..3dddd489328e 100644
--- a/net/bridge/netfilter/ebt_vlan.c
+++ b/net/bridge/netfilter/ebt_vlan.c
@@ -22,6 +22,7 @@
22#include <linux/if_vlan.h> 22#include <linux/if_vlan.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/moduleparam.h> 24#include <linux/moduleparam.h>
25#include <linux/netfilter/x_tables.h>
25#include <linux/netfilter_bridge/ebtables.h> 26#include <linux/netfilter_bridge/ebtables.h>
26#include <linux/netfilter_bridge/ebt_vlan.h> 27#include <linux/netfilter_bridge/ebt_vlan.h>
27 28
@@ -37,15 +38,12 @@ MODULE_LICENSE("GPL");
37 38
38#define DEBUG_MSG(args...) if (debug) printk (KERN_DEBUG "ebt_vlan: " args) 39#define DEBUG_MSG(args...) if (debug) printk (KERN_DEBUG "ebt_vlan: " args)
39#define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_ 40#define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_
40#define EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return EBT_NOMATCH;} 41#define EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return false; }
41 42
42static int 43static bool
43ebt_filter_vlan(const struct sk_buff *skb, 44ebt_vlan_mt(const struct sk_buff *skb, const struct xt_match_param *par)
44 const struct net_device *in,
45 const struct net_device *out,
46 const void *data, unsigned int datalen)
47{ 45{
48 const struct ebt_vlan_info *info = data; 46 const struct ebt_vlan_info *info = par->matchinfo;
49 const struct vlan_hdr *fp; 47 const struct vlan_hdr *fp;
50 struct vlan_hdr _frame; 48 struct vlan_hdr _frame;
51 49
@@ -57,7 +55,7 @@ ebt_filter_vlan(const struct sk_buff *skb,
57 55
58 fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame); 56 fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame);
59 if (fp == NULL) 57 if (fp == NULL)
60 return EBT_NOMATCH; 58 return false;
61 59
62 /* Tag Control Information (TCI) consists of the following elements: 60 /* Tag Control Information (TCI) consists of the following elements:
63 * - User_priority. The user_priority field is three bits in length, 61 * - User_priority. The user_priority field is three bits in length,
@@ -83,30 +81,20 @@ ebt_filter_vlan(const struct sk_buff *skb,
83 if (GET_BITMASK(EBT_VLAN_ENCAP)) 81 if (GET_BITMASK(EBT_VLAN_ENCAP))
84 EXIT_ON_MISMATCH(encap, EBT_VLAN_ENCAP); 82 EXIT_ON_MISMATCH(encap, EBT_VLAN_ENCAP);
85 83
86 return EBT_MATCH; 84 return true;
87} 85}
88 86
89static int 87static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par)
90ebt_check_vlan(const char *tablename,
91 unsigned int hooknr,
92 const struct ebt_entry *e, void *data, unsigned int datalen)
93{ 88{
94 struct ebt_vlan_info *info = data; 89 struct ebt_vlan_info *info = par->matchinfo;
95 90 const struct ebt_entry *e = par->entryinfo;
96 /* Parameters buffer overflow check */
97 if (datalen != EBT_ALIGN(sizeof(struct ebt_vlan_info))) {
98 DEBUG_MSG
99 ("passed size %d is not eq to ebt_vlan_info (%Zd)\n",
100 datalen, sizeof(struct ebt_vlan_info));
101 return -EINVAL;
102 }
103 91
104 /* Is it 802.1Q frame checked? */ 92 /* Is it 802.1Q frame checked? */
105 if (e->ethproto != htons(ETH_P_8021Q)) { 93 if (e->ethproto != htons(ETH_P_8021Q)) {
106 DEBUG_MSG 94 DEBUG_MSG
107 ("passed entry proto %2.4X is not 802.1Q (8100)\n", 95 ("passed entry proto %2.4X is not 802.1Q (8100)\n",
108 (unsigned short) ntohs(e->ethproto)); 96 (unsigned short) ntohs(e->ethproto));
109 return -EINVAL; 97 return false;
110 } 98 }
111 99
112 /* Check for bitmask range 100 /* Check for bitmask range
@@ -114,14 +102,14 @@ ebt_check_vlan(const char *tablename,
114 if (info->bitmask & ~EBT_VLAN_MASK) { 102 if (info->bitmask & ~EBT_VLAN_MASK) {
115 DEBUG_MSG("bitmask %2X is out of mask (%2X)\n", 103 DEBUG_MSG("bitmask %2X is out of mask (%2X)\n",
116 info->bitmask, EBT_VLAN_MASK); 104 info->bitmask, EBT_VLAN_MASK);
117 return -EINVAL; 105 return false;
118 } 106 }
119 107
120 /* Check for inversion flags range */ 108 /* Check for inversion flags range */
121 if (info->invflags & ~EBT_VLAN_MASK) { 109 if (info->invflags & ~EBT_VLAN_MASK) {
122 DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n", 110 DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n",
123 info->invflags, EBT_VLAN_MASK); 111 info->invflags, EBT_VLAN_MASK);
124 return -EINVAL; 112 return false;
125 } 113 }
126 114
127 /* Reserved VLAN ID (VID) values 115 /* Reserved VLAN ID (VID) values
@@ -136,7 +124,7 @@ ebt_check_vlan(const char *tablename,
136 DEBUG_MSG 124 DEBUG_MSG
137 ("id %d is out of range (1-4096)\n", 125 ("id %d is out of range (1-4096)\n",
138 info->id); 126 info->id);
139 return -EINVAL; 127 return false;
140 } 128 }
141 /* Note: This is valid VLAN-tagged frame point. 129 /* Note: This is valid VLAN-tagged frame point.
142 * Any value of user_priority are acceptable, 130 * Any value of user_priority are acceptable,
@@ -151,7 +139,7 @@ ebt_check_vlan(const char *tablename,
151 if ((unsigned char) info->prio > 7) { 139 if ((unsigned char) info->prio > 7) {
152 DEBUG_MSG("prio %d is out of range (0-7)\n", 140 DEBUG_MSG("prio %d is out of range (0-7)\n",
153 info->prio); 141 info->prio);
154 return -EINVAL; 142 return false;
155 } 143 }
156 } 144 }
157 /* Check for encapsulated proto range - it is possible to be 145 /* Check for encapsulated proto range - it is possible to be
@@ -162,17 +150,20 @@ ebt_check_vlan(const char *tablename,
162 DEBUG_MSG 150 DEBUG_MSG
163 ("encap frame length %d is less than minimal\n", 151 ("encap frame length %d is less than minimal\n",
164 ntohs(info->encap)); 152 ntohs(info->encap));
165 return -EINVAL; 153 return false;
166 } 154 }
167 } 155 }
168 156
169 return 0; 157 return true;
170} 158}
171 159
172static struct ebt_match filter_vlan __read_mostly = { 160static struct xt_match ebt_vlan_mt_reg __read_mostly = {
173 .name = EBT_VLAN_MATCH, 161 .name = "vlan",
174 .match = ebt_filter_vlan, 162 .revision = 0,
175 .check = ebt_check_vlan, 163 .family = NFPROTO_BRIDGE,
164 .match = ebt_vlan_mt,
165 .checkentry = ebt_vlan_mt_check,
166 .matchsize = XT_ALIGN(sizeof(struct ebt_vlan_info)),
176 .me = THIS_MODULE, 167 .me = THIS_MODULE,
177}; 168};
178 169
@@ -181,12 +172,12 @@ static int __init ebt_vlan_init(void)
181 DEBUG_MSG("ebtables 802.1Q extension module v" 172 DEBUG_MSG("ebtables 802.1Q extension module v"
182 MODULE_VERS "\n"); 173 MODULE_VERS "\n");
183 DEBUG_MSG("module debug=%d\n", !!debug); 174 DEBUG_MSG("module debug=%d\n", !!debug);
184 return ebt_register_match(&filter_vlan); 175 return xt_register_match(&ebt_vlan_mt_reg);
185} 176}
186 177
187static void __exit ebt_vlan_fini(void) 178static void __exit ebt_vlan_fini(void)
188{ 179{
189 ebt_unregister_match(&filter_vlan); 180 xt_unregister_match(&ebt_vlan_mt_reg);
190} 181}
191 182
192module_init(ebt_vlan_init); 183module_init(ebt_vlan_init);
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 32afff859e4a..5bb88eb0aad4 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -19,6 +19,7 @@
19#include <linux/kmod.h> 19#include <linux/kmod.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/vmalloc.h> 21#include <linux/vmalloc.h>
22#include <linux/netfilter/x_tables.h>
22#include <linux/netfilter_bridge/ebtables.h> 23#include <linux/netfilter_bridge/ebtables.h>
23#include <linux/spinlock.h> 24#include <linux/spinlock.h>
24#include <linux/mutex.h> 25#include <linux/mutex.h>
@@ -55,29 +56,31 @@
55 56
56static DEFINE_MUTEX(ebt_mutex); 57static DEFINE_MUTEX(ebt_mutex);
57static LIST_HEAD(ebt_tables); 58static LIST_HEAD(ebt_tables);
58static LIST_HEAD(ebt_targets);
59static LIST_HEAD(ebt_matches);
60static LIST_HEAD(ebt_watchers);
61 59
62static struct ebt_target ebt_standard_target = 60static struct xt_target ebt_standard_target = {
63{ {NULL, NULL}, EBT_STANDARD_TARGET, NULL, NULL, NULL, NULL}; 61 .name = "standard",
62 .revision = 0,
63 .family = NFPROTO_BRIDGE,
64 .targetsize = sizeof(int),
65};
64 66
65static inline int ebt_do_watcher (struct ebt_entry_watcher *w, 67static inline int
66 const struct sk_buff *skb, unsigned int hooknr, const struct net_device *in, 68ebt_do_watcher(const struct ebt_entry_watcher *w, struct sk_buff *skb,
67 const struct net_device *out) 69 struct xt_target_param *par)
68{ 70{
69 w->u.watcher->watcher(skb, hooknr, in, out, w->data, 71 par->target = w->u.watcher;
70 w->watcher_size); 72 par->targinfo = w->data;
73 w->u.watcher->target(skb, par);
71 /* watchers don't give a verdict */ 74 /* watchers don't give a verdict */
72 return 0; 75 return 0;
73} 76}
74 77
75static inline int ebt_do_match (struct ebt_entry_match *m, 78static inline int ebt_do_match (struct ebt_entry_match *m,
76 const struct sk_buff *skb, const struct net_device *in, 79 const struct sk_buff *skb, struct xt_match_param *par)
77 const struct net_device *out)
78{ 80{
79 return m->u.match->match(skb, in, out, m->data, 81 par->match = m->u.match;
80 m->match_size); 82 par->matchinfo = m->data;
83 return m->u.match->match(skb, par);
81} 84}
82 85
83static inline int ebt_dev_check(char *entry, const struct net_device *device) 86static inline int ebt_dev_check(char *entry, const struct net_device *device)
@@ -153,6 +156,15 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
153 struct ebt_entries *chaininfo; 156 struct ebt_entries *chaininfo;
154 char *base; 157 char *base;
155 struct ebt_table_info *private; 158 struct ebt_table_info *private;
159 bool hotdrop = false;
160 struct xt_match_param mtpar;
161 struct xt_target_param tgpar;
162
163 mtpar.family = tgpar.family = NFPROTO_BRIDGE;
164 mtpar.in = tgpar.in = in;
165 mtpar.out = tgpar.out = out;
166 mtpar.hotdrop = &hotdrop;
167 tgpar.hooknum = hook;
156 168
157 read_lock_bh(&table->lock); 169 read_lock_bh(&table->lock);
158 private = table->private; 170 private = table->private;
@@ -173,8 +185,12 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
173 if (ebt_basic_match(point, eth_hdr(skb), in, out)) 185 if (ebt_basic_match(point, eth_hdr(skb), in, out))
174 goto letscontinue; 186 goto letscontinue;
175 187
176 if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, in, out) != 0) 188 if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, &mtpar) != 0)
177 goto letscontinue; 189 goto letscontinue;
190 if (hotdrop) {
191 read_unlock_bh(&table->lock);
192 return NF_DROP;
193 }
178 194
179 /* increase counter */ 195 /* increase counter */
180 (*(counter_base + i)).pcnt++; 196 (*(counter_base + i)).pcnt++;
@@ -182,17 +198,18 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
182 198
183 /* these should only watch: not modify, nor tell us 199 /* these should only watch: not modify, nor tell us
184 what to do with the packet */ 200 what to do with the packet */
185 EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, hook, in, 201 EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, &tgpar);
186 out);
187 202
188 t = (struct ebt_entry_target *) 203 t = (struct ebt_entry_target *)
189 (((char *)point) + point->target_offset); 204 (((char *)point) + point->target_offset);
190 /* standard target */ 205 /* standard target */
191 if (!t->u.target->target) 206 if (!t->u.target->target)
192 verdict = ((struct ebt_standard_target *)t)->verdict; 207 verdict = ((struct ebt_standard_target *)t)->verdict;
193 else 208 else {
194 verdict = t->u.target->target(skb, hook, 209 tgpar.target = t->u.target;
195 in, out, t->data, t->target_size); 210 tgpar.targinfo = t->data;
211 verdict = t->u.target->target(skb, &tgpar);
212 }
196 if (verdict == EBT_ACCEPT) { 213 if (verdict == EBT_ACCEPT) {
197 read_unlock_bh(&table->lock); 214 read_unlock_bh(&table->lock);
198 return NF_ACCEPT; 215 return NF_ACCEPT;
@@ -312,80 +329,71 @@ find_table_lock(const char *name, int *error, struct mutex *mutex)
312 return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex); 329 return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex);
313} 330}
314 331
315static inline struct ebt_match *
316find_match_lock(const char *name, int *error, struct mutex *mutex)
317{
318 return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex);
319}
320
321static inline struct ebt_watcher *
322find_watcher_lock(const char *name, int *error, struct mutex *mutex)
323{
324 return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex);
325}
326
327static inline struct ebt_target *
328find_target_lock(const char *name, int *error, struct mutex *mutex)
329{
330 return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex);
331}
332
333static inline int 332static inline int
334ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e, 333ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par,
335 const char *name, unsigned int hookmask, unsigned int *cnt) 334 unsigned int *cnt)
336{ 335{
337 struct ebt_match *match; 336 const struct ebt_entry *e = par->entryinfo;
337 struct xt_match *match;
338 size_t left = ((char *)e + e->watchers_offset) - (char *)m; 338 size_t left = ((char *)e + e->watchers_offset) - (char *)m;
339 int ret; 339 int ret;
340 340
341 if (left < sizeof(struct ebt_entry_match) || 341 if (left < sizeof(struct ebt_entry_match) ||
342 left - sizeof(struct ebt_entry_match) < m->match_size) 342 left - sizeof(struct ebt_entry_match) < m->match_size)
343 return -EINVAL; 343 return -EINVAL;
344 match = find_match_lock(m->u.name, &ret, &ebt_mutex); 344
345 if (!match) 345 match = try_then_request_module(xt_find_match(NFPROTO_BRIDGE,
346 return ret; 346 m->u.name, 0), "ebt_%s", m->u.name);
347 m->u.match = match; 347 if (IS_ERR(match))
348 if (!try_module_get(match->me)) { 348 return PTR_ERR(match);
349 mutex_unlock(&ebt_mutex); 349 if (match == NULL)
350 return -ENOENT; 350 return -ENOENT;
351 } 351 m->u.match = match;
352 mutex_unlock(&ebt_mutex); 352
353 if (match->check && 353 par->match = match;
354 match->check(name, hookmask, e, m->data, m->match_size) != 0) { 354 par->matchinfo = m->data;
355 BUGPRINT("match->check failed\n"); 355 ret = xt_check_match(par, m->match_size,
356 e->ethproto, e->invflags & EBT_IPROTO);
357 if (ret < 0) {
356 module_put(match->me); 358 module_put(match->me);
357 return -EINVAL; 359 return ret;
358 } 360 }
361
359 (*cnt)++; 362 (*cnt)++;
360 return 0; 363 return 0;
361} 364}
362 365
363static inline int 366static inline int
364ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e, 367ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par,
365 const char *name, unsigned int hookmask, unsigned int *cnt) 368 unsigned int *cnt)
366{ 369{
367 struct ebt_watcher *watcher; 370 const struct ebt_entry *e = par->entryinfo;
371 struct xt_target *watcher;
368 size_t left = ((char *)e + e->target_offset) - (char *)w; 372 size_t left = ((char *)e + e->target_offset) - (char *)w;
369 int ret; 373 int ret;
370 374
371 if (left < sizeof(struct ebt_entry_watcher) || 375 if (left < sizeof(struct ebt_entry_watcher) ||
372 left - sizeof(struct ebt_entry_watcher) < w->watcher_size) 376 left - sizeof(struct ebt_entry_watcher) < w->watcher_size)
373 return -EINVAL; 377 return -EINVAL;
374 watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex); 378
375 if (!watcher) 379 watcher = try_then_request_module(
376 return ret; 380 xt_find_target(NFPROTO_BRIDGE, w->u.name, 0),
377 w->u.watcher = watcher; 381 "ebt_%s", w->u.name);
378 if (!try_module_get(watcher->me)) { 382 if (IS_ERR(watcher))
379 mutex_unlock(&ebt_mutex); 383 return PTR_ERR(watcher);
384 if (watcher == NULL)
380 return -ENOENT; 385 return -ENOENT;
381 } 386 w->u.watcher = watcher;
382 mutex_unlock(&ebt_mutex); 387
383 if (watcher->check && 388 par->target = watcher;
384 watcher->check(name, hookmask, e, w->data, w->watcher_size) != 0) { 389 par->targinfo = w->data;
385 BUGPRINT("watcher->check failed\n"); 390 ret = xt_check_target(par, w->watcher_size,
391 e->ethproto, e->invflags & EBT_IPROTO);
392 if (ret < 0) {
386 module_put(watcher->me); 393 module_put(watcher->me);
387 return -EINVAL; 394 return ret;
388 } 395 }
396
389 (*cnt)++; 397 (*cnt)++;
390 return 0; 398 return 0;
391} 399}
@@ -558,30 +566,41 @@ ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo,
558static inline int 566static inline int
559ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i) 567ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i)
560{ 568{
569 struct xt_mtdtor_param par;
570
561 if (i && (*i)-- == 0) 571 if (i && (*i)-- == 0)
562 return 1; 572 return 1;
563 if (m->u.match->destroy)
564 m->u.match->destroy(m->data, m->match_size);
565 module_put(m->u.match->me);
566 573
574 par.match = m->u.match;
575 par.matchinfo = m->data;
576 par.family = NFPROTO_BRIDGE;
577 if (par.match->destroy != NULL)
578 par.match->destroy(&par);
579 module_put(par.match->me);
567 return 0; 580 return 0;
568} 581}
569 582
570static inline int 583static inline int
571ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i) 584ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i)
572{ 585{
586 struct xt_tgdtor_param par;
587
573 if (i && (*i)-- == 0) 588 if (i && (*i)-- == 0)
574 return 1; 589 return 1;
575 if (w->u.watcher->destroy)
576 w->u.watcher->destroy(w->data, w->watcher_size);
577 module_put(w->u.watcher->me);
578 590
591 par.target = w->u.watcher;
592 par.targinfo = w->data;
593 par.family = NFPROTO_BRIDGE;
594 if (par.target->destroy != NULL)
595 par.target->destroy(&par);
596 module_put(par.target->me);
579 return 0; 597 return 0;
580} 598}
581 599
582static inline int 600static inline int
583ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt) 601ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
584{ 602{
603 struct xt_tgdtor_param par;
585 struct ebt_entry_target *t; 604 struct ebt_entry_target *t;
586 605
587 if (e->bitmask == 0) 606 if (e->bitmask == 0)
@@ -592,10 +611,13 @@ ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
592 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL); 611 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL);
593 EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL); 612 EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL);
594 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); 613 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
595 if (t->u.target->destroy)
596 t->u.target->destroy(t->data, t->target_size);
597 module_put(t->u.target->me);
598 614
615 par.target = t->u.target;
616 par.targinfo = t->data;
617 par.family = NFPROTO_BRIDGE;
618 if (par.target->destroy != NULL)
619 par.target->destroy(&par);
620 module_put(par.target->me);
599 return 0; 621 return 0;
600} 622}
601 623
@@ -605,10 +627,12 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
605 struct ebt_cl_stack *cl_s, unsigned int udc_cnt) 627 struct ebt_cl_stack *cl_s, unsigned int udc_cnt)
606{ 628{
607 struct ebt_entry_target *t; 629 struct ebt_entry_target *t;
608 struct ebt_target *target; 630 struct xt_target *target;
609 unsigned int i, j, hook = 0, hookmask = 0; 631 unsigned int i, j, hook = 0, hookmask = 0;
610 size_t gap; 632 size_t gap;
611 int ret; 633 int ret;
634 struct xt_mtchk_param mtpar;
635 struct xt_tgchk_param tgpar;
612 636
613 /* don't mess with the struct ebt_entries */ 637 /* don't mess with the struct ebt_entries */
614 if (e->bitmask == 0) 638 if (e->bitmask == 0)
@@ -649,24 +673,31 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
649 hookmask = cl_s[i - 1].hookmask; 673 hookmask = cl_s[i - 1].hookmask;
650 } 674 }
651 i = 0; 675 i = 0;
652 ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i); 676
677 mtpar.table = tgpar.table = name;
678 mtpar.entryinfo = tgpar.entryinfo = e;
679 mtpar.hook_mask = tgpar.hook_mask = hookmask;
680 mtpar.family = tgpar.family = NFPROTO_BRIDGE;
681 ret = EBT_MATCH_ITERATE(e, ebt_check_match, &mtpar, &i);
653 if (ret != 0) 682 if (ret != 0)
654 goto cleanup_matches; 683 goto cleanup_matches;
655 j = 0; 684 j = 0;
656 ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j); 685 ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, &tgpar, &j);
657 if (ret != 0) 686 if (ret != 0)
658 goto cleanup_watchers; 687 goto cleanup_watchers;
659 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); 688 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
660 gap = e->next_offset - e->target_offset; 689 gap = e->next_offset - e->target_offset;
661 target = find_target_lock(t->u.name, &ret, &ebt_mutex); 690
662 if (!target) 691 target = try_then_request_module(
692 xt_find_target(NFPROTO_BRIDGE, t->u.name, 0),
693 "ebt_%s", t->u.name);
694 if (IS_ERR(target)) {
695 ret = PTR_ERR(target);
663 goto cleanup_watchers; 696 goto cleanup_watchers;
664 if (!try_module_get(target->me)) { 697 } else if (target == NULL) {
665 mutex_unlock(&ebt_mutex);
666 ret = -ENOENT; 698 ret = -ENOENT;
667 goto cleanup_watchers; 699 goto cleanup_watchers;
668 } 700 }
669 mutex_unlock(&ebt_mutex);
670 701
671 t->u.target = target; 702 t->u.target = target;
672 if (t->u.target == &ebt_standard_target) { 703 if (t->u.target == &ebt_standard_target) {
@@ -681,13 +712,20 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
681 ret = -EFAULT; 712 ret = -EFAULT;
682 goto cleanup_watchers; 713 goto cleanup_watchers;
683 } 714 }
684 } else if (t->target_size > gap - sizeof(struct ebt_entry_target) || 715 } else if (t->target_size > gap - sizeof(struct ebt_entry_target)) {
685 (t->u.target->check &&
686 t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){
687 module_put(t->u.target->me); 716 module_put(t->u.target->me);
688 ret = -EFAULT; 717 ret = -EFAULT;
689 goto cleanup_watchers; 718 goto cleanup_watchers;
690 } 719 }
720
721 tgpar.target = target;
722 tgpar.targinfo = t->data;
723 ret = xt_check_target(&tgpar, t->target_size,
724 e->ethproto, e->invflags & EBT_IPROTO);
725 if (ret < 0) {
726 module_put(target->me);
727 goto cleanup_watchers;
728 }
691 (*cnt)++; 729 (*cnt)++;
692 return 0; 730 return 0;
693cleanup_watchers: 731cleanup_watchers:
@@ -1068,87 +1106,6 @@ free_newinfo:
1068 return ret; 1106 return ret;
1069} 1107}
1070 1108
1071int ebt_register_target(struct ebt_target *target)
1072{
1073 struct ebt_target *t;
1074 int ret;
1075
1076 ret = mutex_lock_interruptible(&ebt_mutex);
1077 if (ret != 0)
1078 return ret;
1079 list_for_each_entry(t, &ebt_targets, list) {
1080 if (strcmp(t->name, target->name) == 0) {
1081 mutex_unlock(&ebt_mutex);
1082 return -EEXIST;
1083 }
1084 }
1085 list_add(&target->list, &ebt_targets);
1086 mutex_unlock(&ebt_mutex);
1087
1088 return 0;
1089}
1090
1091void ebt_unregister_target(struct ebt_target *target)
1092{
1093 mutex_lock(&ebt_mutex);
1094 list_del(&target->list);
1095 mutex_unlock(&ebt_mutex);
1096}
1097
1098int ebt_register_match(struct ebt_match *match)
1099{
1100 struct ebt_match *m;
1101 int ret;
1102
1103 ret = mutex_lock_interruptible(&ebt_mutex);
1104 if (ret != 0)
1105 return ret;
1106 list_for_each_entry(m, &ebt_matches, list) {
1107 if (strcmp(m->name, match->name) == 0) {
1108 mutex_unlock(&ebt_mutex);
1109 return -EEXIST;
1110 }
1111 }
1112 list_add(&match->list, &ebt_matches);
1113 mutex_unlock(&ebt_mutex);
1114
1115 return 0;
1116}
1117
1118void ebt_unregister_match(struct ebt_match *match)
1119{
1120 mutex_lock(&ebt_mutex);
1121 list_del(&match->list);
1122 mutex_unlock(&ebt_mutex);
1123}
1124
1125int ebt_register_watcher(struct ebt_watcher *watcher)
1126{
1127 struct ebt_watcher *w;
1128 int ret;
1129
1130 ret = mutex_lock_interruptible(&ebt_mutex);
1131 if (ret != 0)
1132 return ret;
1133 list_for_each_entry(w, &ebt_watchers, list) {
1134 if (strcmp(w->name, watcher->name) == 0) {
1135 mutex_unlock(&ebt_mutex);
1136 return -EEXIST;
1137 }
1138 }
1139 list_add(&watcher->list, &ebt_watchers);
1140 mutex_unlock(&ebt_mutex);
1141
1142 return 0;
1143}
1144
1145void ebt_unregister_watcher(struct ebt_watcher *watcher)
1146{
1147 mutex_lock(&ebt_mutex);
1148 list_del(&watcher->list);
1149 mutex_unlock(&ebt_mutex);
1150}
1151
1152int ebt_register_table(struct ebt_table *table) 1109int ebt_register_table(struct ebt_table *table)
1153{ 1110{
1154 struct ebt_table_info *newinfo; 1111 struct ebt_table_info *newinfo;
@@ -1518,11 +1475,14 @@ static int __init ebtables_init(void)
1518{ 1475{
1519 int ret; 1476 int ret;
1520 1477
1521 mutex_lock(&ebt_mutex); 1478 ret = xt_register_target(&ebt_standard_target);
1522 list_add(&ebt_standard_target.list, &ebt_targets); 1479 if (ret < 0)
1523 mutex_unlock(&ebt_mutex); 1480 return ret;
1524 if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0) 1481 ret = nf_register_sockopt(&ebt_sockopts);
1482 if (ret < 0) {
1483 xt_unregister_target(&ebt_standard_target);
1525 return ret; 1484 return ret;
1485 }
1526 1486
1527 printk(KERN_INFO "Ebtables v2.0 registered\n"); 1487 printk(KERN_INFO "Ebtables v2.0 registered\n");
1528 return 0; 1488 return 0;
@@ -1531,17 +1491,12 @@ static int __init ebtables_init(void)
1531static void __exit ebtables_fini(void) 1491static void __exit ebtables_fini(void)
1532{ 1492{
1533 nf_unregister_sockopt(&ebt_sockopts); 1493 nf_unregister_sockopt(&ebt_sockopts);
1494 xt_unregister_target(&ebt_standard_target);
1534 printk(KERN_INFO "Ebtables v2.0 unregistered\n"); 1495 printk(KERN_INFO "Ebtables v2.0 unregistered\n");
1535} 1496}
1536 1497
1537EXPORT_SYMBOL(ebt_register_table); 1498EXPORT_SYMBOL(ebt_register_table);
1538EXPORT_SYMBOL(ebt_unregister_table); 1499EXPORT_SYMBOL(ebt_unregister_table);
1539EXPORT_SYMBOL(ebt_register_match);
1540EXPORT_SYMBOL(ebt_unregister_match);
1541EXPORT_SYMBOL(ebt_register_watcher);
1542EXPORT_SYMBOL(ebt_unregister_watcher);
1543EXPORT_SYMBOL(ebt_register_target);
1544EXPORT_SYMBOL(ebt_unregister_target);
1545EXPORT_SYMBOL(ebt_do_table); 1500EXPORT_SYMBOL(ebt_do_table);
1546module_init(ebtables_init); 1501module_init(ebtables_init);
1547module_exit(ebtables_fini); 1502module_exit(ebtables_fini);
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 7c52fe277b62..b0dc818a91d7 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -18,6 +18,7 @@ static struct list_head *first_device = &pernet_list;
18static DEFINE_MUTEX(net_mutex); 18static DEFINE_MUTEX(net_mutex);
19 19
20LIST_HEAD(net_namespace_list); 20LIST_HEAD(net_namespace_list);
21EXPORT_SYMBOL_GPL(net_namespace_list);
21 22
22struct net init_net; 23struct net init_net;
23EXPORT_SYMBOL(init_net); 24EXPORT_SYMBOL(init_net);
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index 01671ad51ed3..6efdb70b3eb2 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -12,6 +12,7 @@
12/* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */ 12/* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
13int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) 13int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
14{ 14{
15 struct net *net = dev_net(skb->dst->dev);
15 const struct iphdr *iph = ip_hdr(skb); 16 const struct iphdr *iph = ip_hdr(skb);
16 struct rtable *rt; 17 struct rtable *rt;
17 struct flowi fl = {}; 18 struct flowi fl = {};
@@ -19,7 +20,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
19 unsigned int hh_len; 20 unsigned int hh_len;
20 unsigned int type; 21 unsigned int type;
21 22
22 type = inet_addr_type(&init_net, iph->saddr); 23 type = inet_addr_type(net, iph->saddr);
23 if (skb->sk && inet_sk(skb->sk)->transparent) 24 if (skb->sk && inet_sk(skb->sk)->transparent)
24 type = RTN_LOCAL; 25 type = RTN_LOCAL;
25 if (addr_type == RTN_UNSPEC) 26 if (addr_type == RTN_UNSPEC)
@@ -36,7 +37,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
36 fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; 37 fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
37 fl.mark = skb->mark; 38 fl.mark = skb->mark;
38 fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; 39 fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
39 if (ip_route_output_key(&init_net, &rt, &fl) != 0) 40 if (ip_route_output_key(net, &rt, &fl) != 0)
40 return -1; 41 return -1;
41 42
42 /* Drop old route. */ 43 /* Drop old route. */
@@ -46,7 +47,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
46 /* non-local src, find valid iif to satisfy 47 /* non-local src, find valid iif to satisfy
47 * rp-filter when calling ip_route_input. */ 48 * rp-filter when calling ip_route_input. */
48 fl.nl_u.ip4_u.daddr = iph->saddr; 49 fl.nl_u.ip4_u.daddr = iph->saddr;
49 if (ip_route_output_key(&init_net, &rt, &fl) != 0) 50 if (ip_route_output_key(net, &rt, &fl) != 0)
50 return -1; 51 return -1;
51 52
52 odst = skb->dst; 53 odst = skb->dst;
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 90eb7cb47e77..3816e1dc9295 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -5,10 +5,15 @@
5menu "IP: Netfilter Configuration" 5menu "IP: Netfilter Configuration"
6 depends on INET && NETFILTER 6 depends on INET && NETFILTER
7 7
8config NF_DEFRAG_IPV4
9 tristate
10 default n
11
8config NF_CONNTRACK_IPV4 12config NF_CONNTRACK_IPV4
9 tristate "IPv4 connection tracking support (required for NAT)" 13 tristate "IPv4 connection tracking support (required for NAT)"
10 depends on NF_CONNTRACK 14 depends on NF_CONNTRACK
11 default m if NETFILTER_ADVANCED=n 15 default m if NETFILTER_ADVANCED=n
16 select NF_DEFRAG_IPV4
12 ---help--- 17 ---help---
13 Connection tracking keeps a record of what packets have passed 18 Connection tracking keeps a record of what packets have passed
14 through your machine, in order to figure out how they are related 19 through your machine, in order to figure out how they are related
@@ -56,23 +61,30 @@ config IP_NF_IPTABLES
56 61
57 To compile it as a module, choose M here. If unsure, say N. 62 To compile it as a module, choose M here. If unsure, say N.
58 63
64if IP_NF_IPTABLES
65
59# The matches. 66# The matches.
60config IP_NF_MATCH_RECENT 67config IP_NF_MATCH_ADDRTYPE
61 tristate '"recent" match support' 68 tristate '"addrtype" address type match support'
62 depends on IP_NF_IPTABLES
63 depends on NETFILTER_ADVANCED 69 depends on NETFILTER_ADVANCED
64 help 70 help
65 This match is used for creating one or many lists of recently 71 This option allows you to match what routing thinks of an address,
66 used addresses and then matching against that/those list(s). 72 eg. UNICAST, LOCAL, BROADCAST, ...
67 73
68 Short options are available by using 'iptables -m recent -h' 74 If you want to compile it as a module, say M here and read
69 Official Website: <http://snowman.net/projects/ipt_recent/> 75 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
76
77config IP_NF_MATCH_AH
78 tristate '"ah" match support'
79 depends on NETFILTER_ADVANCED
80 help
81 This match extension allows you to match a range of SPIs
82 inside AH header of IPSec packets.
70 83
71 To compile it as a module, choose M here. If unsure, say N. 84 To compile it as a module, choose M here. If unsure, say N.
72 85
73config IP_NF_MATCH_ECN 86config IP_NF_MATCH_ECN
74 tristate '"ecn" match support' 87 tristate '"ecn" match support'
75 depends on IP_NF_IPTABLES
76 depends on NETFILTER_ADVANCED 88 depends on NETFILTER_ADVANCED
77 help 89 help
78 This option adds a `ECN' match, which allows you to match against 90 This option adds a `ECN' match, which allows you to match against
@@ -80,19 +92,8 @@ config IP_NF_MATCH_ECN
80 92
81 To compile it as a module, choose M here. If unsure, say N. 93 To compile it as a module, choose M here. If unsure, say N.
82 94
83config IP_NF_MATCH_AH
84 tristate '"ah" match support'
85 depends on IP_NF_IPTABLES
86 depends on NETFILTER_ADVANCED
87 help
88 This match extension allows you to match a range of SPIs
89 inside AH header of IPSec packets.
90
91 To compile it as a module, choose M here. If unsure, say N.
92
93config IP_NF_MATCH_TTL 95config IP_NF_MATCH_TTL
94 tristate '"ttl" match support' 96 tristate '"ttl" match support'
95 depends on IP_NF_IPTABLES
96 depends on NETFILTER_ADVANCED 97 depends on NETFILTER_ADVANCED
97 help 98 help
98 This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user 99 This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user
@@ -100,21 +101,9 @@ config IP_NF_MATCH_TTL
100 101
101 To compile it as a module, choose M here. If unsure, say N. 102 To compile it as a module, choose M here. If unsure, say N.
102 103
103config IP_NF_MATCH_ADDRTYPE
104 tristate '"addrtype" address type match support'
105 depends on IP_NF_IPTABLES
106 depends on NETFILTER_ADVANCED
107 help
108 This option allows you to match what routing thinks of an address,
109 eg. UNICAST, LOCAL, BROADCAST, ...
110
111 If you want to compile it as a module, say M here and read
112 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
113
114# `filter', generic and specific targets 104# `filter', generic and specific targets
115config IP_NF_FILTER 105config IP_NF_FILTER
116 tristate "Packet filtering" 106 tristate "Packet filtering"
117 depends on IP_NF_IPTABLES
118 default m if NETFILTER_ADVANCED=n 107 default m if NETFILTER_ADVANCED=n
119 help 108 help
120 Packet filtering defines a table `filter', which has a series of 109 Packet filtering defines a table `filter', which has a series of
@@ -136,7 +125,6 @@ config IP_NF_TARGET_REJECT
136 125
137config IP_NF_TARGET_LOG 126config IP_NF_TARGET_LOG
138 tristate "LOG target support" 127 tristate "LOG target support"
139 depends on IP_NF_IPTABLES
140 default m if NETFILTER_ADVANCED=n 128 default m if NETFILTER_ADVANCED=n
141 help 129 help
142 This option adds a `LOG' target, which allows you to create rules in 130 This option adds a `LOG' target, which allows you to create rules in
@@ -146,7 +134,6 @@ config IP_NF_TARGET_LOG
146 134
147config IP_NF_TARGET_ULOG 135config IP_NF_TARGET_ULOG
148 tristate "ULOG target support" 136 tristate "ULOG target support"
149 depends on IP_NF_IPTABLES
150 default m if NETFILTER_ADVANCED=n 137 default m if NETFILTER_ADVANCED=n
151 ---help--- 138 ---help---
152 139
@@ -167,7 +154,7 @@ config IP_NF_TARGET_ULOG
167# NAT + specific targets: nf_conntrack 154# NAT + specific targets: nf_conntrack
168config NF_NAT 155config NF_NAT
169 tristate "Full NAT" 156 tristate "Full NAT"
170 depends on IP_NF_IPTABLES && NF_CONNTRACK_IPV4 157 depends on NF_CONNTRACK_IPV4
171 default m if NETFILTER_ADVANCED=n 158 default m if NETFILTER_ADVANCED=n
172 help 159 help
173 The Full NAT option allows masquerading, port forwarding and other 160 The Full NAT option allows masquerading, port forwarding and other
@@ -194,26 +181,26 @@ config IP_NF_TARGET_MASQUERADE
194 181
195 To compile it as a module, choose M here. If unsure, say N. 182 To compile it as a module, choose M here. If unsure, say N.
196 183
197config IP_NF_TARGET_REDIRECT 184config IP_NF_TARGET_NETMAP
198 tristate "REDIRECT target support" 185 tristate "NETMAP target support"
199 depends on NF_NAT 186 depends on NF_NAT
200 depends on NETFILTER_ADVANCED 187 depends on NETFILTER_ADVANCED
201 help 188 help
202 REDIRECT is a special case of NAT: all incoming connections are 189 NETMAP is an implementation of static 1:1 NAT mapping of network
203 mapped onto the incoming interface's address, causing the packets to 190 addresses. It maps the network address part, while keeping the host
204 come to the local machine instead of passing through. This is 191 address part intact.
205 useful for transparent proxies.
206 192
207 To compile it as a module, choose M here. If unsure, say N. 193 To compile it as a module, choose M here. If unsure, say N.
208 194
209config IP_NF_TARGET_NETMAP 195config IP_NF_TARGET_REDIRECT
210 tristate "NETMAP target support" 196 tristate "REDIRECT target support"
211 depends on NF_NAT 197 depends on NF_NAT
212 depends on NETFILTER_ADVANCED 198 depends on NETFILTER_ADVANCED
213 help 199 help
214 NETMAP is an implementation of static 1:1 NAT mapping of network 200 REDIRECT is a special case of NAT: all incoming connections are
215 addresses. It maps the network address part, while keeping the host 201 mapped onto the incoming interface's address, causing the packets to
216 address part intact. 202 come to the local machine instead of passing through. This is
203 useful for transparent proxies.
217 204
218 To compile it as a module, choose M here. If unsure, say N. 205 To compile it as a module, choose M here. If unsure, say N.
219 206
@@ -262,44 +249,43 @@ config NF_NAT_PROTO_SCTP
262 249
263config NF_NAT_FTP 250config NF_NAT_FTP
264 tristate 251 tristate
265 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT 252 depends on NF_CONNTRACK && NF_NAT
266 default NF_NAT && NF_CONNTRACK_FTP 253 default NF_NAT && NF_CONNTRACK_FTP
267 254
268config NF_NAT_IRC 255config NF_NAT_IRC
269 tristate 256 tristate
270 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT 257 depends on NF_CONNTRACK && NF_NAT
271 default NF_NAT && NF_CONNTRACK_IRC 258 default NF_NAT && NF_CONNTRACK_IRC
272 259
273config NF_NAT_TFTP 260config NF_NAT_TFTP
274 tristate 261 tristate
275 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT 262 depends on NF_CONNTRACK && NF_NAT
276 default NF_NAT && NF_CONNTRACK_TFTP 263 default NF_NAT && NF_CONNTRACK_TFTP
277 264
278config NF_NAT_AMANDA 265config NF_NAT_AMANDA
279 tristate 266 tristate
280 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT 267 depends on NF_CONNTRACK && NF_NAT
281 default NF_NAT && NF_CONNTRACK_AMANDA 268 default NF_NAT && NF_CONNTRACK_AMANDA
282 269
283config NF_NAT_PPTP 270config NF_NAT_PPTP
284 tristate 271 tristate
285 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT 272 depends on NF_CONNTRACK && NF_NAT
286 default NF_NAT && NF_CONNTRACK_PPTP 273 default NF_NAT && NF_CONNTRACK_PPTP
287 select NF_NAT_PROTO_GRE 274 select NF_NAT_PROTO_GRE
288 275
289config NF_NAT_H323 276config NF_NAT_H323
290 tristate 277 tristate
291 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT 278 depends on NF_CONNTRACK && NF_NAT
292 default NF_NAT && NF_CONNTRACK_H323 279 default NF_NAT && NF_CONNTRACK_H323
293 280
294config NF_NAT_SIP 281config NF_NAT_SIP
295 tristate 282 tristate
296 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT 283 depends on NF_CONNTRACK && NF_NAT
297 default NF_NAT && NF_CONNTRACK_SIP 284 default NF_NAT && NF_CONNTRACK_SIP
298 285
299# mangle + specific targets 286# mangle + specific targets
300config IP_NF_MANGLE 287config IP_NF_MANGLE
301 tristate "Packet mangling" 288 tristate "Packet mangling"
302 depends on IP_NF_IPTABLES
303 default m if NETFILTER_ADVANCED=n 289 default m if NETFILTER_ADVANCED=n
304 help 290 help
305 This option adds a `mangle' table to iptables: see the man page for 291 This option adds a `mangle' table to iptables: see the man page for
@@ -308,6 +294,19 @@ config IP_NF_MANGLE
308 294
309 To compile it as a module, choose M here. If unsure, say N. 295 To compile it as a module, choose M here. If unsure, say N.
310 296
297config IP_NF_TARGET_CLUSTERIP
298 tristate "CLUSTERIP target support (EXPERIMENTAL)"
299 depends on IP_NF_MANGLE && EXPERIMENTAL
300 depends on NF_CONNTRACK_IPV4
301 depends on NETFILTER_ADVANCED
302 select NF_CONNTRACK_MARK
303 help
304 The CLUSTERIP target allows you to build load-balancing clusters of
305 network servers without having a dedicated load-balancing
306 router/server/switch.
307
308 To compile it as a module, choose M here. If unsure, say N.
309
311config IP_NF_TARGET_ECN 310config IP_NF_TARGET_ECN
312 tristate "ECN target support" 311 tristate "ECN target support"
313 depends on IP_NF_MANGLE 312 depends on IP_NF_MANGLE
@@ -338,23 +337,9 @@ config IP_NF_TARGET_TTL
338 337
339 To compile it as a module, choose M here. If unsure, say N. 338 To compile it as a module, choose M here. If unsure, say N.
340 339
341config IP_NF_TARGET_CLUSTERIP
342 tristate "CLUSTERIP target support (EXPERIMENTAL)"
343 depends on IP_NF_MANGLE && EXPERIMENTAL
344 depends on NF_CONNTRACK_IPV4
345 depends on NETFILTER_ADVANCED
346 select NF_CONNTRACK_MARK
347 help
348 The CLUSTERIP target allows you to build load-balancing clusters of
349 network servers without having a dedicated load-balancing
350 router/server/switch.
351
352 To compile it as a module, choose M here. If unsure, say N.
353
354# raw + specific targets 340# raw + specific targets
355config IP_NF_RAW 341config IP_NF_RAW
356 tristate 'raw table support (required for NOTRACK/TRACE)' 342 tristate 'raw table support (required for NOTRACK/TRACE)'
357 depends on IP_NF_IPTABLES
358 depends on NETFILTER_ADVANCED 343 depends on NETFILTER_ADVANCED
359 help 344 help
360 This option adds a `raw' table to iptables. This table is the very 345 This option adds a `raw' table to iptables. This table is the very
@@ -367,7 +352,6 @@ config IP_NF_RAW
367# security table for MAC policy 352# security table for MAC policy
368config IP_NF_SECURITY 353config IP_NF_SECURITY
369 tristate "Security table" 354 tristate "Security table"
370 depends on IP_NF_IPTABLES
371 depends on SECURITY 355 depends on SECURITY
372 depends on NETFILTER_ADVANCED 356 depends on NETFILTER_ADVANCED
373 help 357 help
@@ -376,6 +360,8 @@ config IP_NF_SECURITY
376 360
377 If unsure, say N. 361 If unsure, say N.
378 362
363endif # IP_NF_IPTABLES
364
379# ARP tables 365# ARP tables
380config IP_NF_ARPTABLES 366config IP_NF_ARPTABLES
381 tristate "ARP tables support" 367 tristate "ARP tables support"
@@ -388,9 +374,10 @@ config IP_NF_ARPTABLES
388 374
389 To compile it as a module, choose M here. If unsure, say N. 375 To compile it as a module, choose M here. If unsure, say N.
390 376
377if IP_NF_ARPTABLES
378
391config IP_NF_ARPFILTER 379config IP_NF_ARPFILTER
392 tristate "ARP packet filtering" 380 tristate "ARP packet filtering"
393 depends on IP_NF_ARPTABLES
394 help 381 help
395 ARP packet filtering defines a table `filter', which has a series of 382 ARP packet filtering defines a table `filter', which has a series of
396 rules for simple ARP packet filtering at local input and 383 rules for simple ARP packet filtering at local input and
@@ -401,10 +388,11 @@ config IP_NF_ARPFILTER
401 388
402config IP_NF_ARP_MANGLE 389config IP_NF_ARP_MANGLE
403 tristate "ARP payload mangling" 390 tristate "ARP payload mangling"
404 depends on IP_NF_ARPTABLES
405 help 391 help
406 Allows altering the ARP packet payload: source and destination 392 Allows altering the ARP packet payload: source and destination
407 hardware and network addresses. 393 hardware and network addresses.
408 394
395endif # IP_NF_ARPTABLES
396
409endmenu 397endmenu
410 398
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 3f31291f37ce..5f9b650d90fc 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -18,6 +18,9 @@ obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
18 18
19obj-$(CONFIG_NF_NAT) += nf_nat.o 19obj-$(CONFIG_NF_NAT) += nf_nat.o
20 20
21# defrag
22obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o
23
21# NAT helpers (nf_conntrack) 24# NAT helpers (nf_conntrack)
22obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o 25obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
23obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o 26obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
@@ -48,7 +51,6 @@ obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o
48obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o 51obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
49obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o 52obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
50obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o 53obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
51obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
52obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o 54obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
53 55
54# targets 56# targets
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 03e83a65aec5..8d70d29f1ccf 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -200,15 +200,12 @@ static inline int arp_checkentry(const struct arpt_arp *arp)
200 return 1; 200 return 1;
201} 201}
202 202
203static unsigned int arpt_error(struct sk_buff *skb, 203static unsigned int
204 const struct net_device *in, 204arpt_error(struct sk_buff *skb, const struct xt_target_param *par)
205 const struct net_device *out,
206 unsigned int hooknum,
207 const struct xt_target *target,
208 const void *targinfo)
209{ 205{
210 if (net_ratelimit()) 206 if (net_ratelimit())
211 printk("arp_tables: error: '%s'\n", (char *)targinfo); 207 printk("arp_tables: error: '%s'\n",
208 (const char *)par->targinfo);
212 209
213 return NF_DROP; 210 return NF_DROP;
214} 211}
@@ -232,6 +229,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
232 const char *indev, *outdev; 229 const char *indev, *outdev;
233 void *table_base; 230 void *table_base;
234 const struct xt_table_info *private; 231 const struct xt_table_info *private;
232 struct xt_target_param tgpar;
235 233
236 if (!pskb_may_pull(skb, arp_hdr_len(skb->dev))) 234 if (!pskb_may_pull(skb, arp_hdr_len(skb->dev)))
237 return NF_DROP; 235 return NF_DROP;
@@ -245,6 +243,11 @@ unsigned int arpt_do_table(struct sk_buff *skb,
245 e = get_entry(table_base, private->hook_entry[hook]); 243 e = get_entry(table_base, private->hook_entry[hook]);
246 back = get_entry(table_base, private->underflow[hook]); 244 back = get_entry(table_base, private->underflow[hook]);
247 245
246 tgpar.in = in;
247 tgpar.out = out;
248 tgpar.hooknum = hook;
249 tgpar.family = NFPROTO_ARP;
250
248 arp = arp_hdr(skb); 251 arp = arp_hdr(skb);
249 do { 252 do {
250 if (arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) { 253 if (arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) {
@@ -290,11 +293,10 @@ unsigned int arpt_do_table(struct sk_buff *skb,
290 /* Targets which reenter must return 293 /* Targets which reenter must return
291 * abs. verdicts 294 * abs. verdicts
292 */ 295 */
296 tgpar.target = t->u.kernel.target;
297 tgpar.targinfo = t->data;
293 verdict = t->u.kernel.target->target(skb, 298 verdict = t->u.kernel.target->target(skb,
294 in, out, 299 &tgpar);
295 hook,
296 t->u.kernel.target,
297 t->data);
298 300
299 /* Target might have changed stuff. */ 301 /* Target might have changed stuff. */
300 arp = arp_hdr(skb); 302 arp = arp_hdr(skb);
@@ -456,23 +458,24 @@ static inline int check_entry(struct arpt_entry *e, const char *name)
456 458
457static inline int check_target(struct arpt_entry *e, const char *name) 459static inline int check_target(struct arpt_entry *e, const char *name)
458{ 460{
459 struct arpt_entry_target *t; 461 struct arpt_entry_target *t = arpt_get_target(e);
460 struct xt_target *target;
461 int ret; 462 int ret;
462 463 struct xt_tgchk_param par = {
463 t = arpt_get_target(e); 464 .table = name,
464 target = t->u.kernel.target; 465 .entryinfo = e,
465 466 .target = t->u.kernel.target,
466 ret = xt_check_target(target, NF_ARP, t->u.target_size - sizeof(*t), 467 .targinfo = t->data,
467 name, e->comefrom, 0, 0); 468 .hook_mask = e->comefrom,
468 if (!ret && t->u.kernel.target->checkentry 469 .family = NFPROTO_ARP,
469 && !t->u.kernel.target->checkentry(name, e, target, t->data, 470 };
470 e->comefrom)) { 471
472 ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false);
473 if (ret < 0) {
471 duprintf("arp_tables: check failed for `%s'.\n", 474 duprintf("arp_tables: check failed for `%s'.\n",
472 t->u.kernel.target->name); 475 t->u.kernel.target->name);
473 ret = -EINVAL; 476 return ret;
474 } 477 }
475 return ret; 478 return 0;
476} 479}
477 480
478static inline int 481static inline int
@@ -488,7 +491,8 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size,
488 return ret; 491 return ret;
489 492
490 t = arpt_get_target(e); 493 t = arpt_get_target(e);
491 target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, 494 target = try_then_request_module(xt_find_target(NFPROTO_ARP,
495 t->u.user.name,
492 t->u.user.revision), 496 t->u.user.revision),
493 "arpt_%s", t->u.user.name); 497 "arpt_%s", t->u.user.name);
494 if (IS_ERR(target) || !target) { 498 if (IS_ERR(target) || !target) {
@@ -554,15 +558,19 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
554 558
555static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i) 559static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i)
556{ 560{
561 struct xt_tgdtor_param par;
557 struct arpt_entry_target *t; 562 struct arpt_entry_target *t;
558 563
559 if (i && (*i)-- == 0) 564 if (i && (*i)-- == 0)
560 return 1; 565 return 1;
561 566
562 t = arpt_get_target(e); 567 t = arpt_get_target(e);
563 if (t->u.kernel.target->destroy) 568 par.target = t->u.kernel.target;
564 t->u.kernel.target->destroy(t->u.kernel.target, t->data); 569 par.targinfo = t->data;
565 module_put(t->u.kernel.target->me); 570 par.family = NFPROTO_ARP;
571 if (par.target->destroy != NULL)
572 par.target->destroy(&par);
573 module_put(par.target->me);
566 return 0; 574 return 0;
567} 575}
568 576
@@ -788,7 +796,7 @@ static void compat_standard_from_user(void *dst, void *src)
788 int v = *(compat_int_t *)src; 796 int v = *(compat_int_t *)src;
789 797
790 if (v > 0) 798 if (v > 0)
791 v += xt_compat_calc_jump(NF_ARP, v); 799 v += xt_compat_calc_jump(NFPROTO_ARP, v);
792 memcpy(dst, &v, sizeof(v)); 800 memcpy(dst, &v, sizeof(v));
793} 801}
794 802
@@ -797,7 +805,7 @@ static int compat_standard_to_user(void __user *dst, void *src)
797 compat_int_t cv = *(int *)src; 805 compat_int_t cv = *(int *)src;
798 806
799 if (cv > 0) 807 if (cv > 0)
800 cv -= xt_compat_calc_jump(NF_ARP, cv); 808 cv -= xt_compat_calc_jump(NFPROTO_ARP, cv);
801 return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0; 809 return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0;
802} 810}
803 811
@@ -815,7 +823,7 @@ static int compat_calc_entry(struct arpt_entry *e,
815 t = arpt_get_target(e); 823 t = arpt_get_target(e);
816 off += xt_compat_target_offset(t->u.kernel.target); 824 off += xt_compat_target_offset(t->u.kernel.target);
817 newinfo->size -= off; 825 newinfo->size -= off;
818 ret = xt_compat_add_offset(NF_ARP, entry_offset, off); 826 ret = xt_compat_add_offset(NFPROTO_ARP, entry_offset, off);
819 if (ret) 827 if (ret)
820 return ret; 828 return ret;
821 829
@@ -866,9 +874,9 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
866 name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; 874 name[ARPT_TABLE_MAXNAMELEN-1] = '\0';
867#ifdef CONFIG_COMPAT 875#ifdef CONFIG_COMPAT
868 if (compat) 876 if (compat)
869 xt_compat_lock(NF_ARP); 877 xt_compat_lock(NFPROTO_ARP);
870#endif 878#endif
871 t = try_then_request_module(xt_find_table_lock(net, NF_ARP, name), 879 t = try_then_request_module(xt_find_table_lock(net, NFPROTO_ARP, name),
872 "arptable_%s", name); 880 "arptable_%s", name);
873 if (t && !IS_ERR(t)) { 881 if (t && !IS_ERR(t)) {
874 struct arpt_getinfo info; 882 struct arpt_getinfo info;
@@ -878,7 +886,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
878 if (compat) { 886 if (compat) {
879 struct xt_table_info tmp; 887 struct xt_table_info tmp;
880 ret = compat_table_info(private, &tmp); 888 ret = compat_table_info(private, &tmp);
881 xt_compat_flush_offsets(NF_ARP); 889 xt_compat_flush_offsets(NFPROTO_ARP);
882 private = &tmp; 890 private = &tmp;
883 } 891 }
884#endif 892#endif
@@ -901,7 +909,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
901 ret = t ? PTR_ERR(t) : -ENOENT; 909 ret = t ? PTR_ERR(t) : -ENOENT;
902#ifdef CONFIG_COMPAT 910#ifdef CONFIG_COMPAT
903 if (compat) 911 if (compat)
904 xt_compat_unlock(NF_ARP); 912 xt_compat_unlock(NFPROTO_ARP);
905#endif 913#endif
906 return ret; 914 return ret;
907} 915}
@@ -925,7 +933,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr,
925 return -EINVAL; 933 return -EINVAL;
926 } 934 }
927 935
928 t = xt_find_table_lock(net, NF_ARP, get.name); 936 t = xt_find_table_lock(net, NFPROTO_ARP, get.name);
929 if (t && !IS_ERR(t)) { 937 if (t && !IS_ERR(t)) {
930 const struct xt_table_info *private = t->private; 938 const struct xt_table_info *private = t->private;
931 939
@@ -967,7 +975,7 @@ static int __do_replace(struct net *net, const char *name,
967 goto out; 975 goto out;
968 } 976 }
969 977
970 t = try_then_request_module(xt_find_table_lock(net, NF_ARP, name), 978 t = try_then_request_module(xt_find_table_lock(net, NFPROTO_ARP, name),
971 "arptable_%s", name); 979 "arptable_%s", name);
972 if (!t || IS_ERR(t)) { 980 if (!t || IS_ERR(t)) {
973 ret = t ? PTR_ERR(t) : -ENOENT; 981 ret = t ? PTR_ERR(t) : -ENOENT;
@@ -1134,7 +1142,7 @@ static int do_add_counters(struct net *net, void __user *user, unsigned int len,
1134 goto free; 1142 goto free;
1135 } 1143 }
1136 1144
1137 t = xt_find_table_lock(net, NF_ARP, name); 1145 t = xt_find_table_lock(net, NFPROTO_ARP, name);
1138 if (!t || IS_ERR(t)) { 1146 if (!t || IS_ERR(t)) {
1139 ret = t ? PTR_ERR(t) : -ENOENT; 1147 ret = t ? PTR_ERR(t) : -ENOENT;
1140 goto free; 1148 goto free;
@@ -1218,7 +1226,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
1218 entry_offset = (void *)e - (void *)base; 1226 entry_offset = (void *)e - (void *)base;
1219 1227
1220 t = compat_arpt_get_target(e); 1228 t = compat_arpt_get_target(e);
1221 target = try_then_request_module(xt_find_target(NF_ARP, 1229 target = try_then_request_module(xt_find_target(NFPROTO_ARP,
1222 t->u.user.name, 1230 t->u.user.name,
1223 t->u.user.revision), 1231 t->u.user.revision),
1224 "arpt_%s", t->u.user.name); 1232 "arpt_%s", t->u.user.name);
@@ -1232,7 +1240,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
1232 1240
1233 off += xt_compat_target_offset(target); 1241 off += xt_compat_target_offset(target);
1234 *size += off; 1242 *size += off;
1235 ret = xt_compat_add_offset(NF_ARP, entry_offset, off); 1243 ret = xt_compat_add_offset(NFPROTO_ARP, entry_offset, off);
1236 if (ret) 1244 if (ret)
1237 goto release_target; 1245 goto release_target;
1238 1246
@@ -1333,7 +1341,7 @@ static int translate_compat_table(const char *name,
1333 1341
1334 duprintf("translate_compat_table: size %u\n", info->size); 1342 duprintf("translate_compat_table: size %u\n", info->size);
1335 j = 0; 1343 j = 0;
1336 xt_compat_lock(NF_ARP); 1344 xt_compat_lock(NFPROTO_ARP);
1337 /* Walk through entries, checking offsets. */ 1345 /* Walk through entries, checking offsets. */
1338 ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, 1346 ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size,
1339 check_compat_entry_size_and_hooks, 1347 check_compat_entry_size_and_hooks,
@@ -1383,8 +1391,8 @@ static int translate_compat_table(const char *name,
1383 ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, 1391 ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size,
1384 compat_copy_entry_from_user, 1392 compat_copy_entry_from_user,
1385 &pos, &size, name, newinfo, entry1); 1393 &pos, &size, name, newinfo, entry1);
1386 xt_compat_flush_offsets(NF_ARP); 1394 xt_compat_flush_offsets(NFPROTO_ARP);
1387 xt_compat_unlock(NF_ARP); 1395 xt_compat_unlock(NFPROTO_ARP);
1388 if (ret) 1396 if (ret)
1389 goto free_newinfo; 1397 goto free_newinfo;
1390 1398
@@ -1420,8 +1428,8 @@ out:
1420 COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); 1428 COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
1421 return ret; 1429 return ret;
1422out_unlock: 1430out_unlock:
1423 xt_compat_flush_offsets(NF_ARP); 1431 xt_compat_flush_offsets(NFPROTO_ARP);
1424 xt_compat_unlock(NF_ARP); 1432 xt_compat_unlock(NFPROTO_ARP);
1425 goto out; 1433 goto out;
1426} 1434}
1427 1435
@@ -1607,8 +1615,8 @@ static int compat_get_entries(struct net *net,
1607 return -EINVAL; 1615 return -EINVAL;
1608 } 1616 }
1609 1617
1610 xt_compat_lock(NF_ARP); 1618 xt_compat_lock(NFPROTO_ARP);
1611 t = xt_find_table_lock(net, NF_ARP, get.name); 1619 t = xt_find_table_lock(net, NFPROTO_ARP, get.name);
1612 if (t && !IS_ERR(t)) { 1620 if (t && !IS_ERR(t)) {
1613 const struct xt_table_info *private = t->private; 1621 const struct xt_table_info *private = t->private;
1614 struct xt_table_info info; 1622 struct xt_table_info info;
@@ -1623,13 +1631,13 @@ static int compat_get_entries(struct net *net,
1623 private->size, get.size); 1631 private->size, get.size);
1624 ret = -EAGAIN; 1632 ret = -EAGAIN;
1625 } 1633 }
1626 xt_compat_flush_offsets(NF_ARP); 1634 xt_compat_flush_offsets(NFPROTO_ARP);
1627 module_put(t->me); 1635 module_put(t->me);
1628 xt_table_unlock(t); 1636 xt_table_unlock(t);
1629 } else 1637 } else
1630 ret = t ? PTR_ERR(t) : -ENOENT; 1638 ret = t ? PTR_ERR(t) : -ENOENT;
1631 1639
1632 xt_compat_unlock(NF_ARP); 1640 xt_compat_unlock(NFPROTO_ARP);
1633 return ret; 1641 return ret;
1634} 1642}
1635 1643
@@ -1709,7 +1717,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
1709 break; 1717 break;
1710 } 1718 }
1711 1719
1712 try_then_request_module(xt_find_revision(NF_ARP, rev.name, 1720 try_then_request_module(xt_find_revision(NFPROTO_ARP, rev.name,
1713 rev.revision, 1, &ret), 1721 rev.revision, 1, &ret),
1714 "arpt_%s", rev.name); 1722 "arpt_%s", rev.name);
1715 break; 1723 break;
@@ -1787,7 +1795,7 @@ void arpt_unregister_table(struct xt_table *table)
1787static struct xt_target arpt_standard_target __read_mostly = { 1795static struct xt_target arpt_standard_target __read_mostly = {
1788 .name = ARPT_STANDARD_TARGET, 1796 .name = ARPT_STANDARD_TARGET,
1789 .targetsize = sizeof(int), 1797 .targetsize = sizeof(int),
1790 .family = NF_ARP, 1798 .family = NFPROTO_ARP,
1791#ifdef CONFIG_COMPAT 1799#ifdef CONFIG_COMPAT
1792 .compatsize = sizeof(compat_int_t), 1800 .compatsize = sizeof(compat_int_t),
1793 .compat_from_user = compat_standard_from_user, 1801 .compat_from_user = compat_standard_from_user,
@@ -1799,7 +1807,7 @@ static struct xt_target arpt_error_target __read_mostly = {
1799 .name = ARPT_ERROR_TARGET, 1807 .name = ARPT_ERROR_TARGET,
1800 .target = arpt_error, 1808 .target = arpt_error,
1801 .targetsize = ARPT_FUNCTION_MAXNAMELEN, 1809 .targetsize = ARPT_FUNCTION_MAXNAMELEN,
1802 .family = NF_ARP, 1810 .family = NFPROTO_ARP,
1803}; 1811};
1804 1812
1805static struct nf_sockopt_ops arpt_sockopts = { 1813static struct nf_sockopt_ops arpt_sockopts = {
@@ -1821,12 +1829,12 @@ static struct nf_sockopt_ops arpt_sockopts = {
1821 1829
1822static int __net_init arp_tables_net_init(struct net *net) 1830static int __net_init arp_tables_net_init(struct net *net)
1823{ 1831{
1824 return xt_proto_init(net, NF_ARP); 1832 return xt_proto_init(net, NFPROTO_ARP);
1825} 1833}
1826 1834
1827static void __net_exit arp_tables_net_exit(struct net *net) 1835static void __net_exit arp_tables_net_exit(struct net *net)
1828{ 1836{
1829 xt_proto_fini(net, NF_ARP); 1837 xt_proto_fini(net, NFPROTO_ARP);
1830} 1838}
1831 1839
1832static struct pernet_operations arp_tables_net_ops = { 1840static struct pernet_operations arp_tables_net_ops = {
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c
index a385959d2655..b0d5b1d0a769 100644
--- a/net/ipv4/netfilter/arpt_mangle.c
+++ b/net/ipv4/netfilter/arpt_mangle.c
@@ -9,12 +9,9 @@ MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
9MODULE_DESCRIPTION("arptables arp payload mangle target"); 9MODULE_DESCRIPTION("arptables arp payload mangle target");
10 10
11static unsigned int 11static unsigned int
12target(struct sk_buff *skb, 12target(struct sk_buff *skb, const struct xt_target_param *par)
13 const struct net_device *in, const struct net_device *out,
14 unsigned int hooknum, const struct xt_target *target,
15 const void *targinfo)
16{ 13{
17 const struct arpt_mangle *mangle = targinfo; 14 const struct arpt_mangle *mangle = par->targinfo;
18 const struct arphdr *arp; 15 const struct arphdr *arp;
19 unsigned char *arpptr; 16 unsigned char *arpptr;
20 int pln, hln; 17 int pln, hln;
@@ -57,11 +54,9 @@ target(struct sk_buff *skb,
57 return mangle->target; 54 return mangle->target;
58} 55}
59 56
60static bool 57static bool checkentry(const struct xt_tgchk_param *par)
61checkentry(const char *tablename, const void *e, const struct xt_target *target,
62 void *targinfo, unsigned int hook_mask)
63{ 58{
64 const struct arpt_mangle *mangle = targinfo; 59 const struct arpt_mangle *mangle = par->targinfo;
65 60
66 if (mangle->flags & ~ARPT_MANGLE_MASK || 61 if (mangle->flags & ~ARPT_MANGLE_MASK ||
67 !(mangle->flags & ARPT_MANGLE_MASK)) 62 !(mangle->flags & ARPT_MANGLE_MASK))
@@ -75,7 +70,7 @@ checkentry(const char *tablename, const void *e, const struct xt_target *target,
75 70
76static struct xt_target arpt_mangle_reg __read_mostly = { 71static struct xt_target arpt_mangle_reg __read_mostly = {
77 .name = "mangle", 72 .name = "mangle",
78 .family = NF_ARP, 73 .family = NFPROTO_ARP,
79 .target = target, 74 .target = target,
80 .targetsize = sizeof(struct arpt_mangle), 75 .targetsize = sizeof(struct arpt_mangle),
81 .checkentry = checkentry, 76 .checkentry = checkentry,
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
index 082f5dd3156c..bee3d117661a 100644
--- a/net/ipv4/netfilter/arptable_filter.c
+++ b/net/ipv4/netfilter/arptable_filter.c
@@ -51,7 +51,7 @@ static struct xt_table packet_filter = {
51 .lock = __RW_LOCK_UNLOCKED(packet_filter.lock), 51 .lock = __RW_LOCK_UNLOCKED(packet_filter.lock),
52 .private = NULL, 52 .private = NULL,
53 .me = THIS_MODULE, 53 .me = THIS_MODULE,
54 .af = NF_ARP, 54 .af = NFPROTO_ARP,
55}; 55};
56 56
57/* The work comes in here from netfilter.c */ 57/* The work comes in here from netfilter.c */
@@ -89,21 +89,21 @@ static struct nf_hook_ops arpt_ops[] __read_mostly = {
89 { 89 {
90 .hook = arpt_in_hook, 90 .hook = arpt_in_hook,
91 .owner = THIS_MODULE, 91 .owner = THIS_MODULE,
92 .pf = NF_ARP, 92 .pf = NFPROTO_ARP,
93 .hooknum = NF_ARP_IN, 93 .hooknum = NF_ARP_IN,
94 .priority = NF_IP_PRI_FILTER, 94 .priority = NF_IP_PRI_FILTER,
95 }, 95 },
96 { 96 {
97 .hook = arpt_out_hook, 97 .hook = arpt_out_hook,
98 .owner = THIS_MODULE, 98 .owner = THIS_MODULE,
99 .pf = NF_ARP, 99 .pf = NFPROTO_ARP,
100 .hooknum = NF_ARP_OUT, 100 .hooknum = NF_ARP_OUT,
101 .priority = NF_IP_PRI_FILTER, 101 .priority = NF_IP_PRI_FILTER,
102 }, 102 },
103 { 103 {
104 .hook = arpt_forward_hook, 104 .hook = arpt_forward_hook,
105 .owner = THIS_MODULE, 105 .owner = THIS_MODULE,
106 .pf = NF_ARP, 106 .pf = NFPROTO_ARP,
107 .hooknum = NF_ARP_FORWARD, 107 .hooknum = NF_ARP_FORWARD,
108 .priority = NF_IP_PRI_FILTER, 108 .priority = NF_IP_PRI_FILTER,
109 }, 109 },
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 4e7c719445c2..213fb27debc1 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -171,31 +171,25 @@ ip_checkentry(const struct ipt_ip *ip)
171} 171}
172 172
173static unsigned int 173static unsigned int
174ipt_error(struct sk_buff *skb, 174ipt_error(struct sk_buff *skb, const struct xt_target_param *par)
175 const struct net_device *in,
176 const struct net_device *out,
177 unsigned int hooknum,
178 const struct xt_target *target,
179 const void *targinfo)
180{ 175{
181 if (net_ratelimit()) 176 if (net_ratelimit())
182 printk("ip_tables: error: `%s'\n", (char *)targinfo); 177 printk("ip_tables: error: `%s'\n",
178 (const char *)par->targinfo);
183 179
184 return NF_DROP; 180 return NF_DROP;
185} 181}
186 182
187/* Performance critical - called for every packet */ 183/* Performance critical - called for every packet */
188static inline bool 184static inline bool
189do_match(struct ipt_entry_match *m, 185do_match(struct ipt_entry_match *m, const struct sk_buff *skb,
190 const struct sk_buff *skb, 186 struct xt_match_param *par)
191 const struct net_device *in,
192 const struct net_device *out,
193 int offset,
194 bool *hotdrop)
195{ 187{
188 par->match = m->u.kernel.match;
189 par->matchinfo = m->data;
190
196 /* Stop iteration if it doesn't match */ 191 /* Stop iteration if it doesn't match */
197 if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data, 192 if (!m->u.kernel.match->match(skb, par))
198 offset, ip_hdrlen(skb), hotdrop))
199 return true; 193 return true;
200 else 194 else
201 return false; 195 return false;
@@ -326,7 +320,6 @@ ipt_do_table(struct sk_buff *skb,
326 struct xt_table *table) 320 struct xt_table *table)
327{ 321{
328 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); 322 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
329 u_int16_t offset;
330 const struct iphdr *ip; 323 const struct iphdr *ip;
331 u_int16_t datalen; 324 u_int16_t datalen;
332 bool hotdrop = false; 325 bool hotdrop = false;
@@ -336,6 +329,8 @@ ipt_do_table(struct sk_buff *skb,
336 void *table_base; 329 void *table_base;
337 struct ipt_entry *e, *back; 330 struct ipt_entry *e, *back;
338 struct xt_table_info *private; 331 struct xt_table_info *private;
332 struct xt_match_param mtpar;
333 struct xt_target_param tgpar;
339 334
340 /* Initialization */ 335 /* Initialization */
341 ip = ip_hdr(skb); 336 ip = ip_hdr(skb);
@@ -348,7 +343,13 @@ ipt_do_table(struct sk_buff *skb,
348 * things we don't know, ie. tcp syn flag or ports). If the 343 * things we don't know, ie. tcp syn flag or ports). If the
349 * rule is also a fragment-specific rule, non-fragments won't 344 * rule is also a fragment-specific rule, non-fragments won't
350 * match it. */ 345 * match it. */
351 offset = ntohs(ip->frag_off) & IP_OFFSET; 346 mtpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
347 mtpar.thoff = ip_hdrlen(skb);
348 mtpar.hotdrop = &hotdrop;
349 mtpar.in = tgpar.in = in;
350 mtpar.out = tgpar.out = out;
351 mtpar.family = tgpar.family = NFPROTO_IPV4;
352 tgpar.hooknum = hook;
352 353
353 read_lock_bh(&table->lock); 354 read_lock_bh(&table->lock);
354 IP_NF_ASSERT(table->valid_hooks & (1 << hook)); 355 IP_NF_ASSERT(table->valid_hooks & (1 << hook));
@@ -362,12 +363,11 @@ ipt_do_table(struct sk_buff *skb,
362 do { 363 do {
363 IP_NF_ASSERT(e); 364 IP_NF_ASSERT(e);
364 IP_NF_ASSERT(back); 365 IP_NF_ASSERT(back);
365 if (ip_packet_match(ip, indev, outdev, &e->ip, offset)) { 366 if (ip_packet_match(ip, indev, outdev,
367 &e->ip, mtpar.fragoff)) {
366 struct ipt_entry_target *t; 368 struct ipt_entry_target *t;
367 369
368 if (IPT_MATCH_ITERATE(e, do_match, 370 if (IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0)
369 skb, in, out,
370 offset, &hotdrop) != 0)
371 goto no_match; 371 goto no_match;
372 372
373 ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); 373 ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1);
@@ -413,16 +413,14 @@ ipt_do_table(struct sk_buff *skb,
413 } else { 413 } else {
414 /* Targets which reenter must return 414 /* Targets which reenter must return
415 abs. verdicts */ 415 abs. verdicts */
416 tgpar.target = t->u.kernel.target;
417 tgpar.targinfo = t->data;
416#ifdef CONFIG_NETFILTER_DEBUG 418#ifdef CONFIG_NETFILTER_DEBUG
417 ((struct ipt_entry *)table_base)->comefrom 419 ((struct ipt_entry *)table_base)->comefrom
418 = 0xeeeeeeec; 420 = 0xeeeeeeec;
419#endif 421#endif
420 verdict = t->u.kernel.target->target(skb, 422 verdict = t->u.kernel.target->target(skb,
421 in, out, 423 &tgpar);
422 hook,
423 t->u.kernel.target,
424 t->data);
425
426#ifdef CONFIG_NETFILTER_DEBUG 424#ifdef CONFIG_NETFILTER_DEBUG
427 if (((struct ipt_entry *)table_base)->comefrom 425 if (((struct ipt_entry *)table_base)->comefrom
428 != 0xeeeeeeec 426 != 0xeeeeeeec
@@ -575,12 +573,17 @@ mark_source_chains(struct xt_table_info *newinfo,
575static int 573static int
576cleanup_match(struct ipt_entry_match *m, unsigned int *i) 574cleanup_match(struct ipt_entry_match *m, unsigned int *i)
577{ 575{
576 struct xt_mtdtor_param par;
577
578 if (i && (*i)-- == 0) 578 if (i && (*i)-- == 0)
579 return 1; 579 return 1;
580 580
581 if (m->u.kernel.match->destroy) 581 par.match = m->u.kernel.match;
582 m->u.kernel.match->destroy(m->u.kernel.match, m->data); 582 par.matchinfo = m->data;
583 module_put(m->u.kernel.match->me); 583 par.family = NFPROTO_IPV4;
584 if (par.match->destroy != NULL)
585 par.match->destroy(&par);
586 module_put(par.match->me);
584 return 0; 587 return 0;
585} 588}
586 589
@@ -606,34 +609,28 @@ check_entry(struct ipt_entry *e, const char *name)
606} 609}
607 610
608static int 611static int
609check_match(struct ipt_entry_match *m, const char *name, 612check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par,
610 const struct ipt_ip *ip, 613 unsigned int *i)
611 unsigned int hookmask, unsigned int *i)
612{ 614{
613 struct xt_match *match; 615 const struct ipt_ip *ip = par->entryinfo;
614 int ret; 616 int ret;
615 617
616 match = m->u.kernel.match; 618 par->match = m->u.kernel.match;
617 ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m), 619 par->matchinfo = m->data;
618 name, hookmask, ip->proto, 620
619 ip->invflags & IPT_INV_PROTO); 621 ret = xt_check_match(par, m->u.match_size - sizeof(*m),
620 if (!ret && m->u.kernel.match->checkentry 622 ip->proto, ip->invflags & IPT_INV_PROTO);
621 && !m->u.kernel.match->checkentry(name, ip, match, m->data, 623 if (ret < 0) {
622 hookmask)) {
623 duprintf("ip_tables: check failed for `%s'.\n", 624 duprintf("ip_tables: check failed for `%s'.\n",
624 m->u.kernel.match->name); 625 par.match->name);
625 ret = -EINVAL; 626 return ret;
626 } 627 }
627 if (!ret) 628 ++*i;
628 (*i)++; 629 return 0;
629 return ret;
630} 630}
631 631
632static int 632static int
633find_check_match(struct ipt_entry_match *m, 633find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par,
634 const char *name,
635 const struct ipt_ip *ip,
636 unsigned int hookmask,
637 unsigned int *i) 634 unsigned int *i)
638{ 635{
639 struct xt_match *match; 636 struct xt_match *match;
@@ -648,7 +645,7 @@ find_check_match(struct ipt_entry_match *m,
648 } 645 }
649 m->u.kernel.match = match; 646 m->u.kernel.match = match;
650 647
651 ret = check_match(m, name, ip, hookmask, i); 648 ret = check_match(m, par, i);
652 if (ret) 649 if (ret)
653 goto err; 650 goto err;
654 651
@@ -660,23 +657,25 @@ err:
660 657
661static int check_target(struct ipt_entry *e, const char *name) 658static int check_target(struct ipt_entry *e, const char *name)
662{ 659{
663 struct ipt_entry_target *t; 660 struct ipt_entry_target *t = ipt_get_target(e);
664 struct xt_target *target; 661 struct xt_tgchk_param par = {
662 .table = name,
663 .entryinfo = e,
664 .target = t->u.kernel.target,
665 .targinfo = t->data,
666 .hook_mask = e->comefrom,
667 .family = NFPROTO_IPV4,
668 };
665 int ret; 669 int ret;
666 670
667 t = ipt_get_target(e); 671 ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
668 target = t->u.kernel.target; 672 e->ip.proto, e->ip.invflags & IPT_INV_PROTO);
669 ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), 673 if (ret < 0) {
670 name, e->comefrom, e->ip.proto,
671 e->ip.invflags & IPT_INV_PROTO);
672 if (!ret && t->u.kernel.target->checkentry
673 && !t->u.kernel.target->checkentry(name, e, target, t->data,
674 e->comefrom)) {
675 duprintf("ip_tables: check failed for `%s'.\n", 674 duprintf("ip_tables: check failed for `%s'.\n",
676 t->u.kernel.target->name); 675 t->u.kernel.target->name);
677 ret = -EINVAL; 676 return ret;
678 } 677 }
679 return ret; 678 return 0;
680} 679}
681 680
682static int 681static int
@@ -687,14 +686,18 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size,
687 struct xt_target *target; 686 struct xt_target *target;
688 int ret; 687 int ret;
689 unsigned int j; 688 unsigned int j;
689 struct xt_mtchk_param mtpar;
690 690
691 ret = check_entry(e, name); 691 ret = check_entry(e, name);
692 if (ret) 692 if (ret)
693 return ret; 693 return ret;
694 694
695 j = 0; 695 j = 0;
696 ret = IPT_MATCH_ITERATE(e, find_check_match, name, &e->ip, 696 mtpar.table = name;
697 e->comefrom, &j); 697 mtpar.entryinfo = &e->ip;
698 mtpar.hook_mask = e->comefrom;
699 mtpar.family = NFPROTO_IPV4;
700 ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
698 if (ret != 0) 701 if (ret != 0)
699 goto cleanup_matches; 702 goto cleanup_matches;
700 703
@@ -769,6 +772,7 @@ check_entry_size_and_hooks(struct ipt_entry *e,
769static int 772static int
770cleanup_entry(struct ipt_entry *e, unsigned int *i) 773cleanup_entry(struct ipt_entry *e, unsigned int *i)
771{ 774{
775 struct xt_tgdtor_param par;
772 struct ipt_entry_target *t; 776 struct ipt_entry_target *t;
773 777
774 if (i && (*i)-- == 0) 778 if (i && (*i)-- == 0)
@@ -777,9 +781,13 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i)
777 /* Cleanup all matches */ 781 /* Cleanup all matches */
778 IPT_MATCH_ITERATE(e, cleanup_match, NULL); 782 IPT_MATCH_ITERATE(e, cleanup_match, NULL);
779 t = ipt_get_target(e); 783 t = ipt_get_target(e);
780 if (t->u.kernel.target->destroy) 784
781 t->u.kernel.target->destroy(t->u.kernel.target, t->data); 785 par.target = t->u.kernel.target;
782 module_put(t->u.kernel.target->me); 786 par.targinfo = t->data;
787 par.family = NFPROTO_IPV4;
788 if (par.target->destroy != NULL)
789 par.target->destroy(&par);
790 module_put(par.target->me);
783 return 0; 791 return 0;
784} 792}
785 793
@@ -1648,12 +1656,16 @@ static int
1648compat_check_entry(struct ipt_entry *e, const char *name, 1656compat_check_entry(struct ipt_entry *e, const char *name,
1649 unsigned int *i) 1657 unsigned int *i)
1650{ 1658{
1659 struct xt_mtchk_param mtpar;
1651 unsigned int j; 1660 unsigned int j;
1652 int ret; 1661 int ret;
1653 1662
1654 j = 0; 1663 j = 0;
1655 ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, 1664 mtpar.table = name;
1656 e->comefrom, &j); 1665 mtpar.entryinfo = &e->ip;
1666 mtpar.hook_mask = e->comefrom;
1667 mtpar.family = NFPROTO_IPV4;
1668 ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j);
1657 if (ret) 1669 if (ret)
1658 goto cleanup_matches; 1670 goto cleanup_matches;
1659 1671
@@ -2121,30 +2133,23 @@ icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
2121} 2133}
2122 2134
2123static bool 2135static bool
2124icmp_match(const struct sk_buff *skb, 2136icmp_match(const struct sk_buff *skb, const struct xt_match_param *par)
2125 const struct net_device *in,
2126 const struct net_device *out,
2127 const struct xt_match *match,
2128 const void *matchinfo,
2129 int offset,
2130 unsigned int protoff,
2131 bool *hotdrop)
2132{ 2137{
2133 const struct icmphdr *ic; 2138 const struct icmphdr *ic;
2134 struct icmphdr _icmph; 2139 struct icmphdr _icmph;
2135 const struct ipt_icmp *icmpinfo = matchinfo; 2140 const struct ipt_icmp *icmpinfo = par->matchinfo;
2136 2141
2137 /* Must not be a fragment. */ 2142 /* Must not be a fragment. */
2138 if (offset) 2143 if (par->fragoff != 0)
2139 return false; 2144 return false;
2140 2145
2141 ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph); 2146 ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph);
2142 if (ic == NULL) { 2147 if (ic == NULL) {
2143 /* We've been asked to examine this packet, and we 2148 /* We've been asked to examine this packet, and we
2144 * can't. Hence, no choice but to drop. 2149 * can't. Hence, no choice but to drop.
2145 */ 2150 */
2146 duprintf("Dropping evil ICMP tinygram.\n"); 2151 duprintf("Dropping evil ICMP tinygram.\n");
2147 *hotdrop = true; 2152 *par->hotdrop = true;
2148 return false; 2153 return false;
2149 } 2154 }
2150 2155
@@ -2155,15 +2160,9 @@ icmp_match(const struct sk_buff *skb,
2155 !!(icmpinfo->invflags&IPT_ICMP_INV)); 2160 !!(icmpinfo->invflags&IPT_ICMP_INV));
2156} 2161}
2157 2162
2158/* Called when user tries to insert an entry of this type. */ 2163static bool icmp_checkentry(const struct xt_mtchk_param *par)
2159static bool
2160icmp_checkentry(const char *tablename,
2161 const void *entry,
2162 const struct xt_match *match,
2163 void *matchinfo,
2164 unsigned int hook_mask)
2165{ 2164{
2166 const struct ipt_icmp *icmpinfo = matchinfo; 2165 const struct ipt_icmp *icmpinfo = par->matchinfo;
2167 2166
2168 /* Must specify no unknown invflags */ 2167 /* Must specify no unknown invflags */
2169 return !(icmpinfo->invflags & ~IPT_ICMP_INV); 2168 return !(icmpinfo->invflags & ~IPT_ICMP_INV);
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index fafe8ebb4c55..7ac1677419a9 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -281,11 +281,9 @@ clusterip_responsible(const struct clusterip_config *config, u_int32_t hash)
281 ***********************************************************************/ 281 ***********************************************************************/
282 282
283static unsigned int 283static unsigned int
284clusterip_tg(struct sk_buff *skb, const struct net_device *in, 284clusterip_tg(struct sk_buff *skb, const struct xt_target_param *par)
285 const struct net_device *out, unsigned int hooknum,
286 const struct xt_target *target, const void *targinfo)
287{ 285{
288 const struct ipt_clusterip_tgt_info *cipinfo = targinfo; 286 const struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
289 struct nf_conn *ct; 287 struct nf_conn *ct;
290 enum ip_conntrack_info ctinfo; 288 enum ip_conntrack_info ctinfo;
291 u_int32_t hash; 289 u_int32_t hash;
@@ -349,13 +347,10 @@ clusterip_tg(struct sk_buff *skb, const struct net_device *in,
349 return XT_CONTINUE; 347 return XT_CONTINUE;
350} 348}
351 349
352static bool 350static bool clusterip_tg_check(const struct xt_tgchk_param *par)
353clusterip_tg_check(const char *tablename, const void *e_void,
354 const struct xt_target *target, void *targinfo,
355 unsigned int hook_mask)
356{ 351{
357 struct ipt_clusterip_tgt_info *cipinfo = targinfo; 352 struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
358 const struct ipt_entry *e = e_void; 353 const struct ipt_entry *e = par->entryinfo;
359 354
360 struct clusterip_config *config; 355 struct clusterip_config *config;
361 356
@@ -406,9 +401,9 @@ clusterip_tg_check(const char *tablename, const void *e_void,
406 } 401 }
407 cipinfo->config = config; 402 cipinfo->config = config;
408 403
409 if (nf_ct_l3proto_try_module_get(target->family) < 0) { 404 if (nf_ct_l3proto_try_module_get(par->target->family) < 0) {
410 printk(KERN_WARNING "can't load conntrack support for " 405 printk(KERN_WARNING "can't load conntrack support for "
411 "proto=%u\n", target->family); 406 "proto=%u\n", par->target->family);
412 return false; 407 return false;
413 } 408 }
414 409
@@ -416,9 +411,9 @@ clusterip_tg_check(const char *tablename, const void *e_void,
416} 411}
417 412
418/* drop reference count of cluster config when rule is deleted */ 413/* drop reference count of cluster config when rule is deleted */
419static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo) 414static void clusterip_tg_destroy(const struct xt_tgdtor_param *par)
420{ 415{
421 const struct ipt_clusterip_tgt_info *cipinfo = targinfo; 416 const struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
422 417
423 /* if no more entries are referencing the config, remove it 418 /* if no more entries are referencing the config, remove it
424 * from the list and destroy the proc entry */ 419 * from the list and destroy the proc entry */
@@ -426,7 +421,7 @@ static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo)
426 421
427 clusterip_config_put(cipinfo->config); 422 clusterip_config_put(cipinfo->config);
428 423
429 nf_ct_l3proto_module_put(target->family); 424 nf_ct_l3proto_module_put(par->target->family);
430} 425}
431 426
432#ifdef CONFIG_COMPAT 427#ifdef CONFIG_COMPAT
@@ -445,7 +440,7 @@ struct compat_ipt_clusterip_tgt_info
445 440
446static struct xt_target clusterip_tg_reg __read_mostly = { 441static struct xt_target clusterip_tg_reg __read_mostly = {
447 .name = "CLUSTERIP", 442 .name = "CLUSTERIP",
448 .family = AF_INET, 443 .family = NFPROTO_IPV4,
449 .target = clusterip_tg, 444 .target = clusterip_tg,
450 .checkentry = clusterip_tg_check, 445 .checkentry = clusterip_tg_check,
451 .destroy = clusterip_tg_destroy, 446 .destroy = clusterip_tg_destroy,
@@ -546,7 +541,7 @@ arp_mangle(unsigned int hook,
546 541
547static struct nf_hook_ops cip_arp_ops __read_mostly = { 542static struct nf_hook_ops cip_arp_ops __read_mostly = {
548 .hook = arp_mangle, 543 .hook = arp_mangle,
549 .pf = NF_ARP, 544 .pf = NFPROTO_ARP,
550 .hooknum = NF_ARP_OUT, 545 .hooknum = NF_ARP_OUT,
551 .priority = -1 546 .priority = -1
552}; 547};
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c
index d60139c134ca..f7e2fa0974dc 100644
--- a/net/ipv4/netfilter/ipt_ECN.c
+++ b/net/ipv4/netfilter/ipt_ECN.c
@@ -77,11 +77,9 @@ set_ect_tcp(struct sk_buff *skb, const struct ipt_ECN_info *einfo)
77} 77}
78 78
79static unsigned int 79static unsigned int
80ecn_tg(struct sk_buff *skb, const struct net_device *in, 80ecn_tg(struct sk_buff *skb, const struct xt_target_param *par)
81 const struct net_device *out, unsigned int hooknum,
82 const struct xt_target *target, const void *targinfo)
83{ 81{
84 const struct ipt_ECN_info *einfo = targinfo; 82 const struct ipt_ECN_info *einfo = par->targinfo;
85 83
86 if (einfo->operation & IPT_ECN_OP_SET_IP) 84 if (einfo->operation & IPT_ECN_OP_SET_IP)
87 if (!set_ect_ip(skb, einfo)) 85 if (!set_ect_ip(skb, einfo))
@@ -95,13 +93,10 @@ ecn_tg(struct sk_buff *skb, const struct net_device *in,
95 return XT_CONTINUE; 93 return XT_CONTINUE;
96} 94}
97 95
98static bool 96static bool ecn_tg_check(const struct xt_tgchk_param *par)
99ecn_tg_check(const char *tablename, const void *e_void,
100 const struct xt_target *target, void *targinfo,
101 unsigned int hook_mask)
102{ 97{
103 const struct ipt_ECN_info *einfo = targinfo; 98 const struct ipt_ECN_info *einfo = par->targinfo;
104 const struct ipt_entry *e = e_void; 99 const struct ipt_entry *e = par->entryinfo;
105 100
106 if (einfo->operation & IPT_ECN_OP_MASK) { 101 if (einfo->operation & IPT_ECN_OP_MASK) {
107 printk(KERN_WARNING "ECN: unsupported ECN operation %x\n", 102 printk(KERN_WARNING "ECN: unsupported ECN operation %x\n",
@@ -124,7 +119,7 @@ ecn_tg_check(const char *tablename, const void *e_void,
124 119
125static struct xt_target ecn_tg_reg __read_mostly = { 120static struct xt_target ecn_tg_reg __read_mostly = {
126 .name = "ECN", 121 .name = "ECN",
127 .family = AF_INET, 122 .family = NFPROTO_IPV4,
128 .target = ecn_tg, 123 .target = ecn_tg,
129 .targetsize = sizeof(struct ipt_ECN_info), 124 .targetsize = sizeof(struct ipt_ECN_info),
130 .table = "mangle", 125 .table = "mangle",
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
index 0af14137137b..fc6ce04a3e35 100644
--- a/net/ipv4/netfilter/ipt_LOG.c
+++ b/net/ipv4/netfilter/ipt_LOG.c
@@ -375,7 +375,7 @@ static struct nf_loginfo default_loginfo = {
375}; 375};
376 376
377static void 377static void
378ipt_log_packet(unsigned int pf, 378ipt_log_packet(u_int8_t pf,
379 unsigned int hooknum, 379 unsigned int hooknum,
380 const struct sk_buff *skb, 380 const struct sk_buff *skb,
381 const struct net_device *in, 381 const struct net_device *in,
@@ -426,28 +426,23 @@ ipt_log_packet(unsigned int pf,
426} 426}
427 427
428static unsigned int 428static unsigned int
429log_tg(struct sk_buff *skb, const struct net_device *in, 429log_tg(struct sk_buff *skb, const struct xt_target_param *par)
430 const struct net_device *out, unsigned int hooknum,
431 const struct xt_target *target, const void *targinfo)
432{ 430{
433 const struct ipt_log_info *loginfo = targinfo; 431 const struct ipt_log_info *loginfo = par->targinfo;
434 struct nf_loginfo li; 432 struct nf_loginfo li;
435 433
436 li.type = NF_LOG_TYPE_LOG; 434 li.type = NF_LOG_TYPE_LOG;
437 li.u.log.level = loginfo->level; 435 li.u.log.level = loginfo->level;
438 li.u.log.logflags = loginfo->logflags; 436 li.u.log.logflags = loginfo->logflags;
439 437
440 ipt_log_packet(PF_INET, hooknum, skb, in, out, &li, 438 ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in, par->out, &li,
441 loginfo->prefix); 439 loginfo->prefix);
442 return XT_CONTINUE; 440 return XT_CONTINUE;
443} 441}
444 442
445static bool 443static bool log_tg_check(const struct xt_tgchk_param *par)
446log_tg_check(const char *tablename, const void *e,
447 const struct xt_target *target, void *targinfo,
448 unsigned int hook_mask)
449{ 444{
450 const struct ipt_log_info *loginfo = targinfo; 445 const struct ipt_log_info *loginfo = par->targinfo;
451 446
452 if (loginfo->level >= 8) { 447 if (loginfo->level >= 8) {
453 pr_debug("LOG: level %u >= 8\n", loginfo->level); 448 pr_debug("LOG: level %u >= 8\n", loginfo->level);
@@ -463,7 +458,7 @@ log_tg_check(const char *tablename, const void *e,
463 458
464static struct xt_target log_tg_reg __read_mostly = { 459static struct xt_target log_tg_reg __read_mostly = {
465 .name = "LOG", 460 .name = "LOG",
466 .family = AF_INET, 461 .family = NFPROTO_IPV4,
467 .target = log_tg, 462 .target = log_tg,
468 .targetsize = sizeof(struct ipt_log_info), 463 .targetsize = sizeof(struct ipt_log_info),
469 .checkentry = log_tg_check, 464 .checkentry = log_tg_check,
@@ -483,7 +478,7 @@ static int __init log_tg_init(void)
483 ret = xt_register_target(&log_tg_reg); 478 ret = xt_register_target(&log_tg_reg);
484 if (ret < 0) 479 if (ret < 0)
485 return ret; 480 return ret;
486 nf_log_register(PF_INET, &ipt_log_logger); 481 nf_log_register(NFPROTO_IPV4, &ipt_log_logger);
487 return 0; 482 return 0;
488} 483}
489 484
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index 0841aefaa503..f389f60cb105 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -31,12 +31,9 @@ MODULE_DESCRIPTION("Xtables: automatic-address SNAT");
31static DEFINE_RWLOCK(masq_lock); 31static DEFINE_RWLOCK(masq_lock);
32 32
33/* FIXME: Multiple targets. --RR */ 33/* FIXME: Multiple targets. --RR */
34static bool 34static bool masquerade_tg_check(const struct xt_tgchk_param *par)
35masquerade_tg_check(const char *tablename, const void *e,
36 const struct xt_target *target, void *targinfo,
37 unsigned int hook_mask)
38{ 35{
39 const struct nf_nat_multi_range_compat *mr = targinfo; 36 const struct nf_nat_multi_range_compat *mr = par->targinfo;
40 37
41 if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { 38 if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
42 pr_debug("masquerade_check: bad MAP_IPS.\n"); 39 pr_debug("masquerade_check: bad MAP_IPS.\n");
@@ -50,9 +47,7 @@ masquerade_tg_check(const char *tablename, const void *e,
50} 47}
51 48
52static unsigned int 49static unsigned int
53masquerade_tg(struct sk_buff *skb, const struct net_device *in, 50masquerade_tg(struct sk_buff *skb, const struct xt_target_param *par)
54 const struct net_device *out, unsigned int hooknum,
55 const struct xt_target *target, const void *targinfo)
56{ 51{
57 struct nf_conn *ct; 52 struct nf_conn *ct;
58 struct nf_conn_nat *nat; 53 struct nf_conn_nat *nat;
@@ -62,7 +57,7 @@ masquerade_tg(struct sk_buff *skb, const struct net_device *in,
62 const struct rtable *rt; 57 const struct rtable *rt;
63 __be32 newsrc; 58 __be32 newsrc;
64 59
65 NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING); 60 NF_CT_ASSERT(par->hooknum == NF_INET_POST_ROUTING);
66 61
67 ct = nf_ct_get(skb, &ctinfo); 62 ct = nf_ct_get(skb, &ctinfo);
68 nat = nfct_nat(ct); 63 nat = nfct_nat(ct);
@@ -76,16 +71,16 @@ masquerade_tg(struct sk_buff *skb, const struct net_device *in,
76 if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip == 0) 71 if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip == 0)
77 return NF_ACCEPT; 72 return NF_ACCEPT;
78 73
79 mr = targinfo; 74 mr = par->targinfo;
80 rt = skb->rtable; 75 rt = skb->rtable;
81 newsrc = inet_select_addr(out, rt->rt_gateway, RT_SCOPE_UNIVERSE); 76 newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE);
82 if (!newsrc) { 77 if (!newsrc) {
83 printk("MASQUERADE: %s ate my IP address\n", out->name); 78 printk("MASQUERADE: %s ate my IP address\n", par->out->name);
84 return NF_DROP; 79 return NF_DROP;
85 } 80 }
86 81
87 write_lock_bh(&masq_lock); 82 write_lock_bh(&masq_lock);
88 nat->masq_index = out->ifindex; 83 nat->masq_index = par->out->ifindex;
89 write_unlock_bh(&masq_lock); 84 write_unlock_bh(&masq_lock);
90 85
91 /* Transfer from original range. */ 86 /* Transfer from original range. */
@@ -119,9 +114,7 @@ static int masq_device_event(struct notifier_block *this,
119 void *ptr) 114 void *ptr)
120{ 115{
121 const struct net_device *dev = ptr; 116 const struct net_device *dev = ptr;
122 117 struct net *net = dev_net(dev);
123 if (!net_eq(dev_net(dev), &init_net))
124 return NOTIFY_DONE;
125 118
126 if (event == NETDEV_DOWN) { 119 if (event == NETDEV_DOWN) {
127 /* Device was downed. Search entire table for 120 /* Device was downed. Search entire table for
@@ -129,7 +122,8 @@ static int masq_device_event(struct notifier_block *this,
129 and forget them. */ 122 and forget them. */
130 NF_CT_ASSERT(dev->ifindex != 0); 123 NF_CT_ASSERT(dev->ifindex != 0);
131 124
132 nf_ct_iterate_cleanup(device_cmp, (void *)(long)dev->ifindex); 125 nf_ct_iterate_cleanup(net, device_cmp,
126 (void *)(long)dev->ifindex);
133 } 127 }
134 128
135 return NOTIFY_DONE; 129 return NOTIFY_DONE;
@@ -153,7 +147,7 @@ static struct notifier_block masq_inet_notifier = {
153 147
154static struct xt_target masquerade_tg_reg __read_mostly = { 148static struct xt_target masquerade_tg_reg __read_mostly = {
155 .name = "MASQUERADE", 149 .name = "MASQUERADE",
156 .family = AF_INET, 150 .family = NFPROTO_IPV4,
157 .target = masquerade_tg, 151 .target = masquerade_tg,
158 .targetsize = sizeof(struct nf_nat_multi_range_compat), 152 .targetsize = sizeof(struct nf_nat_multi_range_compat),
159 .table = "nat", 153 .table = "nat",
diff --git a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c
index 6739abfd1521..7c29582d4ec8 100644
--- a/net/ipv4/netfilter/ipt_NETMAP.c
+++ b/net/ipv4/netfilter/ipt_NETMAP.c
@@ -22,12 +22,9 @@ MODULE_LICENSE("GPL");
22MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>"); 22MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>");
23MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets"); 23MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets");
24 24
25static bool 25static bool netmap_tg_check(const struct xt_tgchk_param *par)
26netmap_tg_check(const char *tablename, const void *e,
27 const struct xt_target *target, void *targinfo,
28 unsigned int hook_mask)
29{ 26{
30 const struct nf_nat_multi_range_compat *mr = targinfo; 27 const struct nf_nat_multi_range_compat *mr = par->targinfo;
31 28
32 if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) { 29 if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) {
33 pr_debug("NETMAP:check: bad MAP_IPS.\n"); 30 pr_debug("NETMAP:check: bad MAP_IPS.\n");
@@ -41,24 +38,23 @@ netmap_tg_check(const char *tablename, const void *e,
41} 38}
42 39
43static unsigned int 40static unsigned int
44netmap_tg(struct sk_buff *skb, const struct net_device *in, 41netmap_tg(struct sk_buff *skb, const struct xt_target_param *par)
45 const struct net_device *out, unsigned int hooknum,
46 const struct xt_target *target, const void *targinfo)
47{ 42{
48 struct nf_conn *ct; 43 struct nf_conn *ct;
49 enum ip_conntrack_info ctinfo; 44 enum ip_conntrack_info ctinfo;
50 __be32 new_ip, netmask; 45 __be32 new_ip, netmask;
51 const struct nf_nat_multi_range_compat *mr = targinfo; 46 const struct nf_nat_multi_range_compat *mr = par->targinfo;
52 struct nf_nat_range newrange; 47 struct nf_nat_range newrange;
53 48
54 NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING 49 NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING ||
55 || hooknum == NF_INET_POST_ROUTING 50 par->hooknum == NF_INET_POST_ROUTING ||
56 || hooknum == NF_INET_LOCAL_OUT); 51 par->hooknum == NF_INET_LOCAL_OUT);
57 ct = nf_ct_get(skb, &ctinfo); 52 ct = nf_ct_get(skb, &ctinfo);
58 53
59 netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip); 54 netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip);
60 55
61 if (hooknum == NF_INET_PRE_ROUTING || hooknum == NF_INET_LOCAL_OUT) 56 if (par->hooknum == NF_INET_PRE_ROUTING ||
57 par->hooknum == NF_INET_LOCAL_OUT)
62 new_ip = ip_hdr(skb)->daddr & ~netmask; 58 new_ip = ip_hdr(skb)->daddr & ~netmask;
63 else 59 else
64 new_ip = ip_hdr(skb)->saddr & ~netmask; 60 new_ip = ip_hdr(skb)->saddr & ~netmask;
@@ -70,12 +66,12 @@ netmap_tg(struct sk_buff *skb, const struct net_device *in,
70 mr->range[0].min, mr->range[0].max }); 66 mr->range[0].min, mr->range[0].max });
71 67
72 /* Hand modified range to generic setup. */ 68 /* Hand modified range to generic setup. */
73 return nf_nat_setup_info(ct, &newrange, HOOK2MANIP(hooknum)); 69 return nf_nat_setup_info(ct, &newrange, HOOK2MANIP(par->hooknum));
74} 70}
75 71
76static struct xt_target netmap_tg_reg __read_mostly = { 72static struct xt_target netmap_tg_reg __read_mostly = {
77 .name = "NETMAP", 73 .name = "NETMAP",
78 .family = AF_INET, 74 .family = NFPROTO_IPV4,
79 .target = netmap_tg, 75 .target = netmap_tg,
80 .targetsize = sizeof(struct nf_nat_multi_range_compat), 76 .targetsize = sizeof(struct nf_nat_multi_range_compat),
81 .table = "nat", 77 .table = "nat",
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c
index 5c6292449d13..698e5e78685b 100644
--- a/net/ipv4/netfilter/ipt_REDIRECT.c
+++ b/net/ipv4/netfilter/ipt_REDIRECT.c
@@ -26,12 +26,9 @@ MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
26MODULE_DESCRIPTION("Xtables: Connection redirection to localhost"); 26MODULE_DESCRIPTION("Xtables: Connection redirection to localhost");
27 27
28/* FIXME: Take multiple ranges --RR */ 28/* FIXME: Take multiple ranges --RR */
29static bool 29static bool redirect_tg_check(const struct xt_tgchk_param *par)
30redirect_tg_check(const char *tablename, const void *e,
31 const struct xt_target *target, void *targinfo,
32 unsigned int hook_mask)
33{ 30{
34 const struct nf_nat_multi_range_compat *mr = targinfo; 31 const struct nf_nat_multi_range_compat *mr = par->targinfo;
35 32
36 if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { 33 if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
37 pr_debug("redirect_check: bad MAP_IPS.\n"); 34 pr_debug("redirect_check: bad MAP_IPS.\n");
@@ -45,24 +42,22 @@ redirect_tg_check(const char *tablename, const void *e,
45} 42}
46 43
47static unsigned int 44static unsigned int
48redirect_tg(struct sk_buff *skb, const struct net_device *in, 45redirect_tg(struct sk_buff *skb, const struct xt_target_param *par)
49 const struct net_device *out, unsigned int hooknum,
50 const struct xt_target *target, const void *targinfo)
51{ 46{
52 struct nf_conn *ct; 47 struct nf_conn *ct;
53 enum ip_conntrack_info ctinfo; 48 enum ip_conntrack_info ctinfo;
54 __be32 newdst; 49 __be32 newdst;
55 const struct nf_nat_multi_range_compat *mr = targinfo; 50 const struct nf_nat_multi_range_compat *mr = par->targinfo;
56 struct nf_nat_range newrange; 51 struct nf_nat_range newrange;
57 52
58 NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING 53 NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING ||
59 || hooknum == NF_INET_LOCAL_OUT); 54 par->hooknum == NF_INET_LOCAL_OUT);
60 55
61 ct = nf_ct_get(skb, &ctinfo); 56 ct = nf_ct_get(skb, &ctinfo);
62 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); 57 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
63 58
64 /* Local packets: make them go to loopback */ 59 /* Local packets: make them go to loopback */
65 if (hooknum == NF_INET_LOCAL_OUT) 60 if (par->hooknum == NF_INET_LOCAL_OUT)
66 newdst = htonl(0x7F000001); 61 newdst = htonl(0x7F000001);
67 else { 62 else {
68 struct in_device *indev; 63 struct in_device *indev;
@@ -92,7 +87,7 @@ redirect_tg(struct sk_buff *skb, const struct net_device *in,
92 87
93static struct xt_target redirect_tg_reg __read_mostly = { 88static struct xt_target redirect_tg_reg __read_mostly = {
94 .name = "REDIRECT", 89 .name = "REDIRECT",
95 .family = AF_INET, 90 .family = NFPROTO_IPV4,
96 .target = redirect_tg, 91 .target = redirect_tg,
97 .targetsize = sizeof(struct nf_nat_multi_range_compat), 92 .targetsize = sizeof(struct nf_nat_multi_range_compat),
98 .table = "nat", 93 .table = "nat",
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 2639872849da..0b4b6e0ff2b9 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -136,11 +136,9 @@ static inline void send_unreach(struct sk_buff *skb_in, int code)
136} 136}
137 137
138static unsigned int 138static unsigned int
139reject_tg(struct sk_buff *skb, const struct net_device *in, 139reject_tg(struct sk_buff *skb, const struct xt_target_param *par)
140 const struct net_device *out, unsigned int hooknum,
141 const struct xt_target *target, const void *targinfo)
142{ 140{
143 const struct ipt_reject_info *reject = targinfo; 141 const struct ipt_reject_info *reject = par->targinfo;
144 142
145 /* WARNING: This code causes reentry within iptables. 143 /* WARNING: This code causes reentry within iptables.
146 This means that the iptables jump stack is now crap. We 144 This means that the iptables jump stack is now crap. We
@@ -168,7 +166,7 @@ reject_tg(struct sk_buff *skb, const struct net_device *in,
168 send_unreach(skb, ICMP_PKT_FILTERED); 166 send_unreach(skb, ICMP_PKT_FILTERED);
169 break; 167 break;
170 case IPT_TCP_RESET: 168 case IPT_TCP_RESET:
171 send_reset(skb, hooknum); 169 send_reset(skb, par->hooknum);
172 case IPT_ICMP_ECHOREPLY: 170 case IPT_ICMP_ECHOREPLY:
173 /* Doesn't happen. */ 171 /* Doesn't happen. */
174 break; 172 break;
@@ -177,13 +175,10 @@ reject_tg(struct sk_buff *skb, const struct net_device *in,
177 return NF_DROP; 175 return NF_DROP;
178} 176}
179 177
180static bool 178static bool reject_tg_check(const struct xt_tgchk_param *par)
181reject_tg_check(const char *tablename, const void *e_void,
182 const struct xt_target *target, void *targinfo,
183 unsigned int hook_mask)
184{ 179{
185 const struct ipt_reject_info *rejinfo = targinfo; 180 const struct ipt_reject_info *rejinfo = par->targinfo;
186 const struct ipt_entry *e = e_void; 181 const struct ipt_entry *e = par->entryinfo;
187 182
188 if (rejinfo->with == IPT_ICMP_ECHOREPLY) { 183 if (rejinfo->with == IPT_ICMP_ECHOREPLY) {
189 printk("ipt_REJECT: ECHOREPLY no longer supported.\n"); 184 printk("ipt_REJECT: ECHOREPLY no longer supported.\n");
@@ -201,7 +196,7 @@ reject_tg_check(const char *tablename, const void *e_void,
201 196
202static struct xt_target reject_tg_reg __read_mostly = { 197static struct xt_target reject_tg_reg __read_mostly = {
203 .name = "REJECT", 198 .name = "REJECT",
204 .family = AF_INET, 199 .family = NFPROTO_IPV4,
205 .target = reject_tg, 200 .target = reject_tg,
206 .targetsize = sizeof(struct ipt_reject_info), 201 .targetsize = sizeof(struct ipt_reject_info),
207 .table = "filter", 202 .table = "filter",
diff --git a/net/ipv4/netfilter/ipt_TTL.c b/net/ipv4/netfilter/ipt_TTL.c
index 30eed65e7338..6d76aae90cc0 100644
--- a/net/ipv4/netfilter/ipt_TTL.c
+++ b/net/ipv4/netfilter/ipt_TTL.c
@@ -20,12 +20,10 @@ MODULE_DESCRIPTION("Xtables: IPv4 TTL field modification target");
20MODULE_LICENSE("GPL"); 20MODULE_LICENSE("GPL");
21 21
22static unsigned int 22static unsigned int
23ttl_tg(struct sk_buff *skb, const struct net_device *in, 23ttl_tg(struct sk_buff *skb, const struct xt_target_param *par)
24 const struct net_device *out, unsigned int hooknum,
25 const struct xt_target *target, const void *targinfo)
26{ 24{
27 struct iphdr *iph; 25 struct iphdr *iph;
28 const struct ipt_TTL_info *info = targinfo; 26 const struct ipt_TTL_info *info = par->targinfo;
29 int new_ttl; 27 int new_ttl;
30 28
31 if (!skb_make_writable(skb, skb->len)) 29 if (!skb_make_writable(skb, skb->len))
@@ -61,12 +59,9 @@ ttl_tg(struct sk_buff *skb, const struct net_device *in,
61 return XT_CONTINUE; 59 return XT_CONTINUE;
62} 60}
63 61
64static bool 62static bool ttl_tg_check(const struct xt_tgchk_param *par)
65ttl_tg_check(const char *tablename, const void *e,
66 const struct xt_target *target, void *targinfo,
67 unsigned int hook_mask)
68{ 63{
69 const struct ipt_TTL_info *info = targinfo; 64 const struct ipt_TTL_info *info = par->targinfo;
70 65
71 if (info->mode > IPT_TTL_MAXMODE) { 66 if (info->mode > IPT_TTL_MAXMODE) {
72 printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n", 67 printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n",
@@ -80,7 +75,7 @@ ttl_tg_check(const char *tablename, const void *e,
80 75
81static struct xt_target ttl_tg_reg __read_mostly = { 76static struct xt_target ttl_tg_reg __read_mostly = {
82 .name = "TTL", 77 .name = "TTL",
83 .family = AF_INET, 78 .family = NFPROTO_IPV4,
84 .target = ttl_tg, 79 .target = ttl_tg,
85 .targetsize = sizeof(struct ipt_TTL_info), 80 .targetsize = sizeof(struct ipt_TTL_info),
86 .table = "mangle", 81 .table = "mangle",
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index b192756c6d0d..18a2826b57c6 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -281,18 +281,14 @@ alloc_failure:
281} 281}
282 282
283static unsigned int 283static unsigned int
284ulog_tg(struct sk_buff *skb, const struct net_device *in, 284ulog_tg(struct sk_buff *skb, const struct xt_target_param *par)
285 const struct net_device *out, unsigned int hooknum,
286 const struct xt_target *target, const void *targinfo)
287{ 285{
288 struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo; 286 ipt_ulog_packet(par->hooknum, skb, par->in, par->out,
289 287 par->targinfo, NULL);
290 ipt_ulog_packet(hooknum, skb, in, out, loginfo, NULL);
291
292 return XT_CONTINUE; 288 return XT_CONTINUE;
293} 289}
294 290
295static void ipt_logfn(unsigned int pf, 291static void ipt_logfn(u_int8_t pf,
296 unsigned int hooknum, 292 unsigned int hooknum,
297 const struct sk_buff *skb, 293 const struct sk_buff *skb,
298 const struct net_device *in, 294 const struct net_device *in,
@@ -317,12 +313,9 @@ static void ipt_logfn(unsigned int pf,
317 ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); 313 ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
318} 314}
319 315
320static bool 316static bool ulog_tg_check(const struct xt_tgchk_param *par)
321ulog_tg_check(const char *tablename, const void *e,
322 const struct xt_target *target, void *targinfo,
323 unsigned int hookmask)
324{ 317{
325 const struct ipt_ulog_info *loginfo = targinfo; 318 const struct ipt_ulog_info *loginfo = par->targinfo;
326 319
327 if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') { 320 if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') {
328 pr_debug("ipt_ULOG: prefix term %i\n", 321 pr_debug("ipt_ULOG: prefix term %i\n",
@@ -374,7 +367,7 @@ static int ulog_tg_compat_to_user(void __user *dst, void *src)
374 367
375static struct xt_target ulog_tg_reg __read_mostly = { 368static struct xt_target ulog_tg_reg __read_mostly = {
376 .name = "ULOG", 369 .name = "ULOG",
377 .family = AF_INET, 370 .family = NFPROTO_IPV4,
378 .target = ulog_tg, 371 .target = ulog_tg,
379 .targetsize = sizeof(struct ipt_ulog_info), 372 .targetsize = sizeof(struct ipt_ulog_info),
380 .checkentry = ulog_tg_check, 373 .checkentry = ulog_tg_check,
@@ -419,7 +412,7 @@ static int __init ulog_tg_init(void)
419 return ret; 412 return ret;
420 } 413 }
421 if (nflog) 414 if (nflog)
422 nf_log_register(PF_INET, &ipt_ulog_logger); 415 nf_log_register(NFPROTO_IPV4, &ipt_ulog_logger);
423 416
424 return 0; 417 return 0;
425} 418}
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
index 462a22c97877..88762f02779d 100644
--- a/net/ipv4/netfilter/ipt_addrtype.c
+++ b/net/ipv4/netfilter/ipt_addrtype.c
@@ -30,12 +30,9 @@ static inline bool match_type(const struct net_device *dev, __be32 addr,
30} 30}
31 31
32static bool 32static bool
33addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in, 33addrtype_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
34 const struct net_device *out, const struct xt_match *match,
35 const void *matchinfo, int offset, unsigned int protoff,
36 bool *hotdrop)
37{ 34{
38 const struct ipt_addrtype_info *info = matchinfo; 35 const struct ipt_addrtype_info *info = par->matchinfo;
39 const struct iphdr *iph = ip_hdr(skb); 36 const struct iphdr *iph = ip_hdr(skb);
40 bool ret = true; 37 bool ret = true;
41 38
@@ -50,20 +47,17 @@ addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in,
50} 47}
51 48
52static bool 49static bool
53addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in, 50addrtype_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
54 const struct net_device *out, const struct xt_match *match,
55 const void *matchinfo, int offset, unsigned int protoff,
56 bool *hotdrop)
57{ 51{
58 const struct ipt_addrtype_info_v1 *info = matchinfo; 52 const struct ipt_addrtype_info_v1 *info = par->matchinfo;
59 const struct iphdr *iph = ip_hdr(skb); 53 const struct iphdr *iph = ip_hdr(skb);
60 const struct net_device *dev = NULL; 54 const struct net_device *dev = NULL;
61 bool ret = true; 55 bool ret = true;
62 56
63 if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) 57 if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN)
64 dev = in; 58 dev = par->in;
65 else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) 59 else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT)
66 dev = out; 60 dev = par->out;
67 61
68 if (info->source) 62 if (info->source)
69 ret &= match_type(dev, iph->saddr, info->source) ^ 63 ret &= match_type(dev, iph->saddr, info->source) ^
@@ -74,12 +68,9 @@ addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in,
74 return ret; 68 return ret;
75} 69}
76 70
77static bool 71static bool addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)
78addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void,
79 const struct xt_match *match, void *matchinfo,
80 unsigned int hook_mask)
81{ 72{
82 struct ipt_addrtype_info_v1 *info = matchinfo; 73 struct ipt_addrtype_info_v1 *info = par->matchinfo;
83 74
84 if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN && 75 if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN &&
85 info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { 76 info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
@@ -88,14 +79,16 @@ addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void,
88 return false; 79 return false;
89 } 80 }
90 81
91 if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN) && 82 if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |
83 (1 << NF_INET_LOCAL_IN)) &&
92 info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { 84 info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
93 printk(KERN_ERR "ipt_addrtype: output interface limitation " 85 printk(KERN_ERR "ipt_addrtype: output interface limitation "
94 "not valid in PRE_ROUTING and INPUT\n"); 86 "not valid in PRE_ROUTING and INPUT\n");
95 return false; 87 return false;
96 } 88 }
97 89
98 if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT) && 90 if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) |
91 (1 << NF_INET_LOCAL_OUT)) &&
99 info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { 92 info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
100 printk(KERN_ERR "ipt_addrtype: input interface limitation " 93 printk(KERN_ERR "ipt_addrtype: input interface limitation "
101 "not valid in POST_ROUTING and OUTPUT\n"); 94 "not valid in POST_ROUTING and OUTPUT\n");
@@ -108,14 +101,14 @@ addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void,
108static struct xt_match addrtype_mt_reg[] __read_mostly = { 101static struct xt_match addrtype_mt_reg[] __read_mostly = {
109 { 102 {
110 .name = "addrtype", 103 .name = "addrtype",
111 .family = AF_INET, 104 .family = NFPROTO_IPV4,
112 .match = addrtype_mt_v0, 105 .match = addrtype_mt_v0,
113 .matchsize = sizeof(struct ipt_addrtype_info), 106 .matchsize = sizeof(struct ipt_addrtype_info),
114 .me = THIS_MODULE 107 .me = THIS_MODULE
115 }, 108 },
116 { 109 {
117 .name = "addrtype", 110 .name = "addrtype",
118 .family = AF_INET, 111 .family = NFPROTO_IPV4,
119 .revision = 1, 112 .revision = 1,
120 .match = addrtype_mt_v1, 113 .match = addrtype_mt_v1,
121 .checkentry = addrtype_mt_checkentry_v1, 114 .checkentry = addrtype_mt_checkentry_v1,
diff --git a/net/ipv4/netfilter/ipt_ah.c b/net/ipv4/netfilter/ipt_ah.c
index e977989629c7..0104c0b399de 100644
--- a/net/ipv4/netfilter/ipt_ah.c
+++ b/net/ipv4/netfilter/ipt_ah.c
@@ -36,27 +36,23 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
36 return r; 36 return r;
37} 37}
38 38
39static bool 39static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par)
40ah_mt(const struct sk_buff *skb, const struct net_device *in,
41 const struct net_device *out, const struct xt_match *match,
42 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
43{ 40{
44 struct ip_auth_hdr _ahdr; 41 struct ip_auth_hdr _ahdr;
45 const struct ip_auth_hdr *ah; 42 const struct ip_auth_hdr *ah;
46 const struct ipt_ah *ahinfo = matchinfo; 43 const struct ipt_ah *ahinfo = par->matchinfo;
47 44
48 /* Must not be a fragment. */ 45 /* Must not be a fragment. */
49 if (offset) 46 if (par->fragoff != 0)
50 return false; 47 return false;
51 48
52 ah = skb_header_pointer(skb, protoff, 49 ah = skb_header_pointer(skb, par->thoff, sizeof(_ahdr), &_ahdr);
53 sizeof(_ahdr), &_ahdr);
54 if (ah == NULL) { 50 if (ah == NULL) {
55 /* We've been asked to examine this packet, and we 51 /* We've been asked to examine this packet, and we
56 * can't. Hence, no choice but to drop. 52 * can't. Hence, no choice but to drop.
57 */ 53 */
58 duprintf("Dropping evil AH tinygram.\n"); 54 duprintf("Dropping evil AH tinygram.\n");
59 *hotdrop = true; 55 *par->hotdrop = true;
60 return 0; 56 return 0;
61 } 57 }
62 58
@@ -65,13 +61,9 @@ ah_mt(const struct sk_buff *skb, const struct net_device *in,
65 !!(ahinfo->invflags & IPT_AH_INV_SPI)); 61 !!(ahinfo->invflags & IPT_AH_INV_SPI));
66} 62}
67 63
68/* Called when user tries to insert an entry of this type. */ 64static bool ah_mt_check(const struct xt_mtchk_param *par)
69static bool
70ah_mt_check(const char *tablename, const void *ip_void,
71 const struct xt_match *match, void *matchinfo,
72 unsigned int hook_mask)
73{ 65{
74 const struct ipt_ah *ahinfo = matchinfo; 66 const struct ipt_ah *ahinfo = par->matchinfo;
75 67
76 /* Must specify no unknown invflags */ 68 /* Must specify no unknown invflags */
77 if (ahinfo->invflags & ~IPT_AH_INV_MASK) { 69 if (ahinfo->invflags & ~IPT_AH_INV_MASK) {
@@ -83,7 +75,7 @@ ah_mt_check(const char *tablename, const void *ip_void,
83 75
84static struct xt_match ah_mt_reg __read_mostly = { 76static struct xt_match ah_mt_reg __read_mostly = {
85 .name = "ah", 77 .name = "ah",
86 .family = AF_INET, 78 .family = NFPROTO_IPV4,
87 .match = ah_mt, 79 .match = ah_mt,
88 .matchsize = sizeof(struct ipt_ah), 80 .matchsize = sizeof(struct ipt_ah),
89 .proto = IPPROTO_AH, 81 .proto = IPPROTO_AH,
diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c
index 749de8284ce5..6289b64144c6 100644
--- a/net/ipv4/netfilter/ipt_ecn.c
+++ b/net/ipv4/netfilter/ipt_ecn.c
@@ -67,12 +67,9 @@ static inline bool match_tcp(const struct sk_buff *skb,
67 return true; 67 return true;
68} 68}
69 69
70static bool 70static bool ecn_mt(const struct sk_buff *skb, const struct xt_match_param *par)
71ecn_mt(const struct sk_buff *skb, const struct net_device *in,
72 const struct net_device *out, const struct xt_match *match,
73 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
74{ 71{
75 const struct ipt_ecn_info *info = matchinfo; 72 const struct ipt_ecn_info *info = par->matchinfo;
76 73
77 if (info->operation & IPT_ECN_OP_MATCH_IP) 74 if (info->operation & IPT_ECN_OP_MATCH_IP)
78 if (!match_ip(skb, info)) 75 if (!match_ip(skb, info))
@@ -81,20 +78,17 @@ ecn_mt(const struct sk_buff *skb, const struct net_device *in,
81 if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) { 78 if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) {
82 if (ip_hdr(skb)->protocol != IPPROTO_TCP) 79 if (ip_hdr(skb)->protocol != IPPROTO_TCP)
83 return false; 80 return false;
84 if (!match_tcp(skb, info, hotdrop)) 81 if (!match_tcp(skb, info, par->hotdrop))
85 return false; 82 return false;
86 } 83 }
87 84
88 return true; 85 return true;
89} 86}
90 87
91static bool 88static bool ecn_mt_check(const struct xt_mtchk_param *par)
92ecn_mt_check(const char *tablename, const void *ip_void,
93 const struct xt_match *match, void *matchinfo,
94 unsigned int hook_mask)
95{ 89{
96 const struct ipt_ecn_info *info = matchinfo; 90 const struct ipt_ecn_info *info = par->matchinfo;
97 const struct ipt_ip *ip = ip_void; 91 const struct ipt_ip *ip = par->entryinfo;
98 92
99 if (info->operation & IPT_ECN_OP_MATCH_MASK) 93 if (info->operation & IPT_ECN_OP_MATCH_MASK)
100 return false; 94 return false;
@@ -114,7 +108,7 @@ ecn_mt_check(const char *tablename, const void *ip_void,
114 108
115static struct xt_match ecn_mt_reg __read_mostly = { 109static struct xt_match ecn_mt_reg __read_mostly = {
116 .name = "ecn", 110 .name = "ecn",
117 .family = AF_INET, 111 .family = NFPROTO_IPV4,
118 .match = ecn_mt, 112 .match = ecn_mt,
119 .matchsize = sizeof(struct ipt_ecn_info), 113 .matchsize = sizeof(struct ipt_ecn_info),
120 .checkentry = ecn_mt_check, 114 .checkentry = ecn_mt_check,
diff --git a/net/ipv4/netfilter/ipt_ttl.c b/net/ipv4/netfilter/ipt_ttl.c
index e0b8caeb710c..297f1cbf4ff5 100644
--- a/net/ipv4/netfilter/ipt_ttl.c
+++ b/net/ipv4/netfilter/ipt_ttl.c
@@ -18,12 +18,9 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
18MODULE_DESCRIPTION("Xtables: IPv4 TTL field match"); 18MODULE_DESCRIPTION("Xtables: IPv4 TTL field match");
19MODULE_LICENSE("GPL"); 19MODULE_LICENSE("GPL");
20 20
21static bool 21static bool ttl_mt(const struct sk_buff *skb, const struct xt_match_param *par)
22ttl_mt(const struct sk_buff *skb, const struct net_device *in,
23 const struct net_device *out, const struct xt_match *match,
24 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
25{ 22{
26 const struct ipt_ttl_info *info = matchinfo; 23 const struct ipt_ttl_info *info = par->matchinfo;
27 const u8 ttl = ip_hdr(skb)->ttl; 24 const u8 ttl = ip_hdr(skb)->ttl;
28 25
29 switch (info->mode) { 26 switch (info->mode) {
@@ -46,7 +43,7 @@ ttl_mt(const struct sk_buff *skb, const struct net_device *in,
46 43
47static struct xt_match ttl_mt_reg __read_mostly = { 44static struct xt_match ttl_mt_reg __read_mostly = {
48 .name = "ttl", 45 .name = "ttl",
49 .family = AF_INET, 46 .family = NFPROTO_IPV4,
50 .match = ttl_mt, 47 .match = ttl_mt,
51 .matchsize = sizeof(struct ipt_ttl_info), 48 .matchsize = sizeof(struct ipt_ttl_info),
52 .me = THIS_MODULE, 49 .me = THIS_MODULE,
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
index 1ea677dcf845..c9224310ebae 100644
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -70,7 +70,7 @@ ipt_local_in_hook(unsigned int hook,
70 int (*okfn)(struct sk_buff *)) 70 int (*okfn)(struct sk_buff *))
71{ 71{
72 return ipt_do_table(skb, hook, in, out, 72 return ipt_do_table(skb, hook, in, out,
73 nf_local_in_net(in, out)->ipv4.iptable_filter); 73 dev_net(in)->ipv4.iptable_filter);
74} 74}
75 75
76static unsigned int 76static unsigned int
@@ -81,7 +81,7 @@ ipt_hook(unsigned int hook,
81 int (*okfn)(struct sk_buff *)) 81 int (*okfn)(struct sk_buff *))
82{ 82{
83 return ipt_do_table(skb, hook, in, out, 83 return ipt_do_table(skb, hook, in, out,
84 nf_forward_net(in, out)->ipv4.iptable_filter); 84 dev_net(in)->ipv4.iptable_filter);
85} 85}
86 86
87static unsigned int 87static unsigned int
@@ -101,7 +101,7 @@ ipt_local_out_hook(unsigned int hook,
101 } 101 }
102 102
103 return ipt_do_table(skb, hook, in, out, 103 return ipt_do_table(skb, hook, in, out,
104 nf_local_out_net(in, out)->ipv4.iptable_filter); 104 dev_net(out)->ipv4.iptable_filter);
105} 105}
106 106
107static struct nf_hook_ops ipt_ops[] __read_mostly = { 107static struct nf_hook_ops ipt_ops[] __read_mostly = {
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index da59182f2226..69f2c4287146 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -81,7 +81,7 @@ ipt_pre_routing_hook(unsigned int hook,
81 int (*okfn)(struct sk_buff *)) 81 int (*okfn)(struct sk_buff *))
82{ 82{
83 return ipt_do_table(skb, hook, in, out, 83 return ipt_do_table(skb, hook, in, out,
84 nf_pre_routing_net(in, out)->ipv4.iptable_mangle); 84 dev_net(in)->ipv4.iptable_mangle);
85} 85}
86 86
87static unsigned int 87static unsigned int
@@ -92,7 +92,7 @@ ipt_post_routing_hook(unsigned int hook,
92 int (*okfn)(struct sk_buff *)) 92 int (*okfn)(struct sk_buff *))
93{ 93{
94 return ipt_do_table(skb, hook, in, out, 94 return ipt_do_table(skb, hook, in, out,
95 nf_post_routing_net(in, out)->ipv4.iptable_mangle); 95 dev_net(out)->ipv4.iptable_mangle);
96} 96}
97 97
98static unsigned int 98static unsigned int
@@ -103,7 +103,7 @@ ipt_local_in_hook(unsigned int hook,
103 int (*okfn)(struct sk_buff *)) 103 int (*okfn)(struct sk_buff *))
104{ 104{
105 return ipt_do_table(skb, hook, in, out, 105 return ipt_do_table(skb, hook, in, out,
106 nf_local_in_net(in, out)->ipv4.iptable_mangle); 106 dev_net(in)->ipv4.iptable_mangle);
107} 107}
108 108
109static unsigned int 109static unsigned int
@@ -114,7 +114,7 @@ ipt_forward_hook(unsigned int hook,
114 int (*okfn)(struct sk_buff *)) 114 int (*okfn)(struct sk_buff *))
115{ 115{
116 return ipt_do_table(skb, hook, in, out, 116 return ipt_do_table(skb, hook, in, out,
117 nf_forward_net(in, out)->ipv4.iptable_mangle); 117 dev_net(in)->ipv4.iptable_mangle);
118} 118}
119 119
120static unsigned int 120static unsigned int
@@ -147,7 +147,7 @@ ipt_local_hook(unsigned int hook,
147 tos = iph->tos; 147 tos = iph->tos;
148 148
149 ret = ipt_do_table(skb, hook, in, out, 149 ret = ipt_do_table(skb, hook, in, out,
150 nf_local_out_net(in, out)->ipv4.iptable_mangle); 150 dev_net(out)->ipv4.iptable_mangle);
151 /* Reroute for ANY change. */ 151 /* Reroute for ANY change. */
152 if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) { 152 if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) {
153 iph = ip_hdr(skb); 153 iph = ip_hdr(skb);
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index fddce7754b72..8faebfe638f1 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -53,7 +53,7 @@ ipt_hook(unsigned int hook,
53 int (*okfn)(struct sk_buff *)) 53 int (*okfn)(struct sk_buff *))
54{ 54{
55 return ipt_do_table(skb, hook, in, out, 55 return ipt_do_table(skb, hook, in, out,
56 nf_pre_routing_net(in, out)->ipv4.iptable_raw); 56 dev_net(in)->ipv4.iptable_raw);
57} 57}
58 58
59static unsigned int 59static unsigned int
@@ -72,7 +72,7 @@ ipt_local_hook(unsigned int hook,
72 return NF_ACCEPT; 72 return NF_ACCEPT;
73 } 73 }
74 return ipt_do_table(skb, hook, in, out, 74 return ipt_do_table(skb, hook, in, out,
75 nf_local_out_net(in, out)->ipv4.iptable_raw); 75 dev_net(out)->ipv4.iptable_raw);
76} 76}
77 77
78/* 'raw' is the very first table. */ 78/* 'raw' is the very first table. */
diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c
index db6d312128e1..36f3be3cc428 100644
--- a/net/ipv4/netfilter/iptable_security.c
+++ b/net/ipv4/netfilter/iptable_security.c
@@ -73,7 +73,7 @@ ipt_local_in_hook(unsigned int hook,
73 int (*okfn)(struct sk_buff *)) 73 int (*okfn)(struct sk_buff *))
74{ 74{
75 return ipt_do_table(skb, hook, in, out, 75 return ipt_do_table(skb, hook, in, out,
76 nf_local_in_net(in, out)->ipv4.iptable_security); 76 dev_net(in)->ipv4.iptable_security);
77} 77}
78 78
79static unsigned int 79static unsigned int
@@ -84,7 +84,7 @@ ipt_forward_hook(unsigned int hook,
84 int (*okfn)(struct sk_buff *)) 84 int (*okfn)(struct sk_buff *))
85{ 85{
86 return ipt_do_table(skb, hook, in, out, 86 return ipt_do_table(skb, hook, in, out,
87 nf_forward_net(in, out)->ipv4.iptable_security); 87 dev_net(in)->ipv4.iptable_security);
88} 88}
89 89
90static unsigned int 90static unsigned int
@@ -103,7 +103,7 @@ ipt_local_out_hook(unsigned int hook,
103 return NF_ACCEPT; 103 return NF_ACCEPT;
104 } 104 }
105 return ipt_do_table(skb, hook, in, out, 105 return ipt_do_table(skb, hook, in, out,
106 nf_local_out_net(in, out)->ipv4.iptable_security); 106 dev_net(out)->ipv4.iptable_security);
107} 107}
108 108
109static struct nf_hook_ops ipt_ops[] __read_mostly = { 109static struct nf_hook_ops ipt_ops[] __read_mostly = {
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 5a955c440364..4a7c35275396 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -1,3 +1,4 @@
1
1/* (C) 1999-2001 Paul `Rusty' Russell 2/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 3 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 * 4 *
@@ -24,6 +25,7 @@
24#include <net/netfilter/nf_conntrack_core.h> 25#include <net/netfilter/nf_conntrack_core.h>
25#include <net/netfilter/ipv4/nf_conntrack_ipv4.h> 26#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
26#include <net/netfilter/nf_nat_helper.h> 27#include <net/netfilter/nf_nat_helper.h>
28#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
27 29
28int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, 30int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,
29 struct nf_conn *ct, 31 struct nf_conn *ct,
@@ -63,23 +65,6 @@ static int ipv4_print_tuple(struct seq_file *s,
63 NIPQUAD(tuple->dst.u3.ip)); 65 NIPQUAD(tuple->dst.u3.ip));
64} 66}
65 67
66/* Returns new sk_buff, or NULL */
67static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
68{
69 int err;
70
71 skb_orphan(skb);
72
73 local_bh_disable();
74 err = ip_defrag(skb, user);
75 local_bh_enable();
76
77 if (!err)
78 ip_send_check(ip_hdr(skb));
79
80 return err;
81}
82
83static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, 68static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
84 unsigned int *dataoff, u_int8_t *protonum) 69 unsigned int *dataoff, u_int8_t *protonum)
85{ 70{
@@ -144,35 +129,13 @@ out:
144 return nf_conntrack_confirm(skb); 129 return nf_conntrack_confirm(skb);
145} 130}
146 131
147static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
148 struct sk_buff *skb,
149 const struct net_device *in,
150 const struct net_device *out,
151 int (*okfn)(struct sk_buff *))
152{
153 /* Previously seen (loopback)? Ignore. Do this before
154 fragment check. */
155 if (skb->nfct)
156 return NF_ACCEPT;
157
158 /* Gather fragments. */
159 if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
160 if (nf_ct_ipv4_gather_frags(skb,
161 hooknum == NF_INET_PRE_ROUTING ?
162 IP_DEFRAG_CONNTRACK_IN :
163 IP_DEFRAG_CONNTRACK_OUT))
164 return NF_STOLEN;
165 }
166 return NF_ACCEPT;
167}
168
169static unsigned int ipv4_conntrack_in(unsigned int hooknum, 132static unsigned int ipv4_conntrack_in(unsigned int hooknum,
170 struct sk_buff *skb, 133 struct sk_buff *skb,
171 const struct net_device *in, 134 const struct net_device *in,
172 const struct net_device *out, 135 const struct net_device *out,
173 int (*okfn)(struct sk_buff *)) 136 int (*okfn)(struct sk_buff *))
174{ 137{
175 return nf_conntrack_in(PF_INET, hooknum, skb); 138 return nf_conntrack_in(dev_net(in), PF_INET, hooknum, skb);
176} 139}
177 140
178static unsigned int ipv4_conntrack_local(unsigned int hooknum, 141static unsigned int ipv4_conntrack_local(unsigned int hooknum,
@@ -188,20 +151,13 @@ static unsigned int ipv4_conntrack_local(unsigned int hooknum,
188 printk("ipt_hook: happy cracking.\n"); 151 printk("ipt_hook: happy cracking.\n");
189 return NF_ACCEPT; 152 return NF_ACCEPT;
190 } 153 }
191 return nf_conntrack_in(PF_INET, hooknum, skb); 154 return nf_conntrack_in(dev_net(out), PF_INET, hooknum, skb);
192} 155}
193 156
194/* Connection tracking may drop packets, but never alters them, so 157/* Connection tracking may drop packets, but never alters them, so
195 make it the first hook. */ 158 make it the first hook. */
196static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = { 159static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
197 { 160 {
198 .hook = ipv4_conntrack_defrag,
199 .owner = THIS_MODULE,
200 .pf = PF_INET,
201 .hooknum = NF_INET_PRE_ROUTING,
202 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
203 },
204 {
205 .hook = ipv4_conntrack_in, 161 .hook = ipv4_conntrack_in,
206 .owner = THIS_MODULE, 162 .owner = THIS_MODULE,
207 .pf = PF_INET, 163 .pf = PF_INET,
@@ -209,13 +165,6 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
209 .priority = NF_IP_PRI_CONNTRACK, 165 .priority = NF_IP_PRI_CONNTRACK,
210 }, 166 },
211 { 167 {
212 .hook = ipv4_conntrack_defrag,
213 .owner = THIS_MODULE,
214 .pf = PF_INET,
215 .hooknum = NF_INET_LOCAL_OUT,
216 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
217 },
218 {
219 .hook = ipv4_conntrack_local, 168 .hook = ipv4_conntrack_local,
220 .owner = THIS_MODULE, 169 .owner = THIS_MODULE,
221 .pf = PF_INET, 170 .pf = PF_INET,
@@ -254,7 +203,7 @@ static ctl_table ip_ct_sysctl_table[] = {
254 { 203 {
255 .ctl_name = NET_IPV4_NF_CONNTRACK_COUNT, 204 .ctl_name = NET_IPV4_NF_CONNTRACK_COUNT,
256 .procname = "ip_conntrack_count", 205 .procname = "ip_conntrack_count",
257 .data = &nf_conntrack_count, 206 .data = &init_net.ct.count,
258 .maxlen = sizeof(int), 207 .maxlen = sizeof(int),
259 .mode = 0444, 208 .mode = 0444,
260 .proc_handler = &proc_dointvec, 209 .proc_handler = &proc_dointvec,
@@ -270,7 +219,7 @@ static ctl_table ip_ct_sysctl_table[] = {
270 { 219 {
271 .ctl_name = NET_IPV4_NF_CONNTRACK_CHECKSUM, 220 .ctl_name = NET_IPV4_NF_CONNTRACK_CHECKSUM,
272 .procname = "ip_conntrack_checksum", 221 .procname = "ip_conntrack_checksum",
273 .data = &nf_conntrack_checksum, 222 .data = &init_net.ct.sysctl_checksum,
274 .maxlen = sizeof(int), 223 .maxlen = sizeof(int),
275 .mode = 0644, 224 .mode = 0644,
276 .proc_handler = &proc_dointvec, 225 .proc_handler = &proc_dointvec,
@@ -278,7 +227,7 @@ static ctl_table ip_ct_sysctl_table[] = {
278 { 227 {
279 .ctl_name = NET_IPV4_NF_CONNTRACK_LOG_INVALID, 228 .ctl_name = NET_IPV4_NF_CONNTRACK_LOG_INVALID,
280 .procname = "ip_conntrack_log_invalid", 229 .procname = "ip_conntrack_log_invalid",
281 .data = &nf_ct_log_invalid, 230 .data = &init_net.ct.sysctl_log_invalid,
282 .maxlen = sizeof(unsigned int), 231 .maxlen = sizeof(unsigned int),
283 .mode = 0644, 232 .mode = 0644,
284 .proc_handler = &proc_dointvec_minmax, 233 .proc_handler = &proc_dointvec_minmax,
@@ -323,7 +272,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
323 return -EINVAL; 272 return -EINVAL;
324 } 273 }
325 274
326 h = nf_conntrack_find_get(&tuple); 275 h = nf_conntrack_find_get(sock_net(sk), &tuple);
327 if (h) { 276 if (h) {
328 struct sockaddr_in sin; 277 struct sockaddr_in sin;
329 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h); 278 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
@@ -422,6 +371,7 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
422 int ret = 0; 371 int ret = 0;
423 372
424 need_conntrack(); 373 need_conntrack();
374 nf_defrag_ipv4_enable();
425 375
426 ret = nf_register_sockopt(&so_getorigdst); 376 ret = nf_register_sockopt(&so_getorigdst);
427 if (ret < 0) { 377 if (ret < 0) {
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
index 3a020720e40b..313ebf00ee36 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
@@ -21,18 +21,20 @@
21#include <net/netfilter/nf_conntrack_acct.h> 21#include <net/netfilter/nf_conntrack_acct.h>
22 22
23struct ct_iter_state { 23struct ct_iter_state {
24 struct seq_net_private p;
24 unsigned int bucket; 25 unsigned int bucket;
25}; 26};
26 27
27static struct hlist_node *ct_get_first(struct seq_file *seq) 28static struct hlist_node *ct_get_first(struct seq_file *seq)
28{ 29{
30 struct net *net = seq_file_net(seq);
29 struct ct_iter_state *st = seq->private; 31 struct ct_iter_state *st = seq->private;
30 struct hlist_node *n; 32 struct hlist_node *n;
31 33
32 for (st->bucket = 0; 34 for (st->bucket = 0;
33 st->bucket < nf_conntrack_htable_size; 35 st->bucket < nf_conntrack_htable_size;
34 st->bucket++) { 36 st->bucket++) {
35 n = rcu_dereference(nf_conntrack_hash[st->bucket].first); 37 n = rcu_dereference(net->ct.hash[st->bucket].first);
36 if (n) 38 if (n)
37 return n; 39 return n;
38 } 40 }
@@ -42,13 +44,14 @@ static struct hlist_node *ct_get_first(struct seq_file *seq)
42static struct hlist_node *ct_get_next(struct seq_file *seq, 44static struct hlist_node *ct_get_next(struct seq_file *seq,
43 struct hlist_node *head) 45 struct hlist_node *head)
44{ 46{
47 struct net *net = seq_file_net(seq);
45 struct ct_iter_state *st = seq->private; 48 struct ct_iter_state *st = seq->private;
46 49
47 head = rcu_dereference(head->next); 50 head = rcu_dereference(head->next);
48 while (head == NULL) { 51 while (head == NULL) {
49 if (++st->bucket >= nf_conntrack_htable_size) 52 if (++st->bucket >= nf_conntrack_htable_size)
50 return NULL; 53 return NULL;
51 head = rcu_dereference(nf_conntrack_hash[st->bucket].first); 54 head = rcu_dereference(net->ct.hash[st->bucket].first);
52 } 55 }
53 return head; 56 return head;
54} 57}
@@ -158,8 +161,8 @@ static const struct seq_operations ct_seq_ops = {
158 161
159static int ct_open(struct inode *inode, struct file *file) 162static int ct_open(struct inode *inode, struct file *file)
160{ 163{
161 return seq_open_private(file, &ct_seq_ops, 164 return seq_open_net(inode, file, &ct_seq_ops,
162 sizeof(struct ct_iter_state)); 165 sizeof(struct ct_iter_state));
163} 166}
164 167
165static const struct file_operations ct_file_ops = { 168static const struct file_operations ct_file_ops = {
@@ -167,21 +170,23 @@ static const struct file_operations ct_file_ops = {
167 .open = ct_open, 170 .open = ct_open,
168 .read = seq_read, 171 .read = seq_read,
169 .llseek = seq_lseek, 172 .llseek = seq_lseek,
170 .release = seq_release_private, 173 .release = seq_release_net,
171}; 174};
172 175
173/* expects */ 176/* expects */
174struct ct_expect_iter_state { 177struct ct_expect_iter_state {
178 struct seq_net_private p;
175 unsigned int bucket; 179 unsigned int bucket;
176}; 180};
177 181
178static struct hlist_node *ct_expect_get_first(struct seq_file *seq) 182static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
179{ 183{
184 struct net *net = seq_file_net(seq);
180 struct ct_expect_iter_state *st = seq->private; 185 struct ct_expect_iter_state *st = seq->private;
181 struct hlist_node *n; 186 struct hlist_node *n;
182 187
183 for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) { 188 for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
184 n = rcu_dereference(nf_ct_expect_hash[st->bucket].first); 189 n = rcu_dereference(net->ct.expect_hash[st->bucket].first);
185 if (n) 190 if (n)
186 return n; 191 return n;
187 } 192 }
@@ -191,13 +196,14 @@ static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
191static struct hlist_node *ct_expect_get_next(struct seq_file *seq, 196static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
192 struct hlist_node *head) 197 struct hlist_node *head)
193{ 198{
199 struct net *net = seq_file_net(seq);
194 struct ct_expect_iter_state *st = seq->private; 200 struct ct_expect_iter_state *st = seq->private;
195 201
196 head = rcu_dereference(head->next); 202 head = rcu_dereference(head->next);
197 while (head == NULL) { 203 while (head == NULL) {
198 if (++st->bucket >= nf_ct_expect_hsize) 204 if (++st->bucket >= nf_ct_expect_hsize)
199 return NULL; 205 return NULL;
200 head = rcu_dereference(nf_ct_expect_hash[st->bucket].first); 206 head = rcu_dereference(net->ct.expect_hash[st->bucket].first);
201 } 207 }
202 return head; 208 return head;
203} 209}
@@ -265,8 +271,8 @@ static const struct seq_operations exp_seq_ops = {
265 271
266static int exp_open(struct inode *inode, struct file *file) 272static int exp_open(struct inode *inode, struct file *file)
267{ 273{
268 return seq_open_private(file, &exp_seq_ops, 274 return seq_open_net(inode, file, &exp_seq_ops,
269 sizeof(struct ct_expect_iter_state)); 275 sizeof(struct ct_expect_iter_state));
270} 276}
271 277
272static const struct file_operations ip_exp_file_ops = { 278static const struct file_operations ip_exp_file_ops = {
@@ -274,11 +280,12 @@ static const struct file_operations ip_exp_file_ops = {
274 .open = exp_open, 280 .open = exp_open,
275 .read = seq_read, 281 .read = seq_read,
276 .llseek = seq_lseek, 282 .llseek = seq_lseek,
277 .release = seq_release_private, 283 .release = seq_release_net,
278}; 284};
279 285
280static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) 286static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
281{ 287{
288 struct net *net = seq_file_net(seq);
282 int cpu; 289 int cpu;
283 290
284 if (*pos == 0) 291 if (*pos == 0)
@@ -288,7 +295,7 @@ static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
288 if (!cpu_possible(cpu)) 295 if (!cpu_possible(cpu))
289 continue; 296 continue;
290 *pos = cpu+1; 297 *pos = cpu+1;
291 return &per_cpu(nf_conntrack_stat, cpu); 298 return per_cpu_ptr(net->ct.stat, cpu);
292 } 299 }
293 300
294 return NULL; 301 return NULL;
@@ -296,13 +303,14 @@ static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
296 303
297static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) 304static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
298{ 305{
306 struct net *net = seq_file_net(seq);
299 int cpu; 307 int cpu;
300 308
301 for (cpu = *pos; cpu < NR_CPUS; ++cpu) { 309 for (cpu = *pos; cpu < NR_CPUS; ++cpu) {
302 if (!cpu_possible(cpu)) 310 if (!cpu_possible(cpu))
303 continue; 311 continue;
304 *pos = cpu+1; 312 *pos = cpu+1;
305 return &per_cpu(nf_conntrack_stat, cpu); 313 return per_cpu_ptr(net->ct.stat, cpu);
306 } 314 }
307 315
308 return NULL; 316 return NULL;
@@ -314,7 +322,8 @@ static void ct_cpu_seq_stop(struct seq_file *seq, void *v)
314 322
315static int ct_cpu_seq_show(struct seq_file *seq, void *v) 323static int ct_cpu_seq_show(struct seq_file *seq, void *v)
316{ 324{
317 unsigned int nr_conntracks = atomic_read(&nf_conntrack_count); 325 struct net *net = seq_file_net(seq);
326 unsigned int nr_conntracks = atomic_read(&net->ct.count);
318 const struct ip_conntrack_stat *st = v; 327 const struct ip_conntrack_stat *st = v;
319 328
320 if (v == SEQ_START_TOKEN) { 329 if (v == SEQ_START_TOKEN) {
@@ -354,7 +363,8 @@ static const struct seq_operations ct_cpu_seq_ops = {
354 363
355static int ct_cpu_seq_open(struct inode *inode, struct file *file) 364static int ct_cpu_seq_open(struct inode *inode, struct file *file)
356{ 365{
357 return seq_open(file, &ct_cpu_seq_ops); 366 return seq_open_net(inode, file, &ct_cpu_seq_ops,
367 sizeof(struct seq_net_private));
358} 368}
359 369
360static const struct file_operations ct_cpu_seq_fops = { 370static const struct file_operations ct_cpu_seq_fops = {
@@ -362,39 +372,54 @@ static const struct file_operations ct_cpu_seq_fops = {
362 .open = ct_cpu_seq_open, 372 .open = ct_cpu_seq_open,
363 .read = seq_read, 373 .read = seq_read,
364 .llseek = seq_lseek, 374 .llseek = seq_lseek,
365 .release = seq_release, 375 .release = seq_release_net,
366}; 376};
367 377
368int __init nf_conntrack_ipv4_compat_init(void) 378static int __net_init ip_conntrack_net_init(struct net *net)
369{ 379{
370 struct proc_dir_entry *proc, *proc_exp, *proc_stat; 380 struct proc_dir_entry *proc, *proc_exp, *proc_stat;
371 381
372 proc = proc_net_fops_create(&init_net, "ip_conntrack", 0440, &ct_file_ops); 382 proc = proc_net_fops_create(net, "ip_conntrack", 0440, &ct_file_ops);
373 if (!proc) 383 if (!proc)
374 goto err1; 384 goto err1;
375 385
376 proc_exp = proc_net_fops_create(&init_net, "ip_conntrack_expect", 0440, 386 proc_exp = proc_net_fops_create(net, "ip_conntrack_expect", 0440,
377 &ip_exp_file_ops); 387 &ip_exp_file_ops);
378 if (!proc_exp) 388 if (!proc_exp)
379 goto err2; 389 goto err2;
380 390
381 proc_stat = proc_create("ip_conntrack", S_IRUGO, 391 proc_stat = proc_create("ip_conntrack", S_IRUGO,
382 init_net.proc_net_stat, &ct_cpu_seq_fops); 392 net->proc_net_stat, &ct_cpu_seq_fops);
383 if (!proc_stat) 393 if (!proc_stat)
384 goto err3; 394 goto err3;
385 return 0; 395 return 0;
386 396
387err3: 397err3:
388 proc_net_remove(&init_net, "ip_conntrack_expect"); 398 proc_net_remove(net, "ip_conntrack_expect");
389err2: 399err2:
390 proc_net_remove(&init_net, "ip_conntrack"); 400 proc_net_remove(net, "ip_conntrack");
391err1: 401err1:
392 return -ENOMEM; 402 return -ENOMEM;
393} 403}
394 404
405static void __net_exit ip_conntrack_net_exit(struct net *net)
406{
407 remove_proc_entry("ip_conntrack", net->proc_net_stat);
408 proc_net_remove(net, "ip_conntrack_expect");
409 proc_net_remove(net, "ip_conntrack");
410}
411
412static struct pernet_operations ip_conntrack_net_ops = {
413 .init = ip_conntrack_net_init,
414 .exit = ip_conntrack_net_exit,
415};
416
417int __init nf_conntrack_ipv4_compat_init(void)
418{
419 return register_pernet_subsys(&ip_conntrack_net_ops);
420}
421
395void __exit nf_conntrack_ipv4_compat_fini(void) 422void __exit nf_conntrack_ipv4_compat_fini(void)
396{ 423{
397 remove_proc_entry("ip_conntrack", init_net.proc_net_stat); 424 unregister_pernet_subsys(&ip_conntrack_net_ops);
398 proc_net_remove(&init_net, "ip_conntrack_expect");
399 proc_net_remove(&init_net, "ip_conntrack");
400} 425}
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 97791048fa9b..4e8879220222 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -79,7 +79,7 @@ static int icmp_packet(struct nf_conn *ct,
79 const struct sk_buff *skb, 79 const struct sk_buff *skb,
80 unsigned int dataoff, 80 unsigned int dataoff,
81 enum ip_conntrack_info ctinfo, 81 enum ip_conntrack_info ctinfo,
82 int pf, 82 u_int8_t pf,
83 unsigned int hooknum) 83 unsigned int hooknum)
84{ 84{
85 /* Try to delete connection immediately after all replies: 85 /* Try to delete connection immediately after all replies:
@@ -91,7 +91,7 @@ static int icmp_packet(struct nf_conn *ct,
91 nf_ct_kill_acct(ct, ctinfo, skb); 91 nf_ct_kill_acct(ct, ctinfo, skb);
92 } else { 92 } else {
93 atomic_inc(&ct->proto.icmp.count); 93 atomic_inc(&ct->proto.icmp.count);
94 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb); 94 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct);
95 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout); 95 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout);
96 } 96 }
97 97
@@ -123,7 +123,7 @@ static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb,
123 123
124/* Returns conntrack if it dealt with ICMP, and filled in skb fields */ 124/* Returns conntrack if it dealt with ICMP, and filled in skb fields */
125static int 125static int
126icmp_error_message(struct sk_buff *skb, 126icmp_error_message(struct net *net, struct sk_buff *skb,
127 enum ip_conntrack_info *ctinfo, 127 enum ip_conntrack_info *ctinfo,
128 unsigned int hooknum) 128 unsigned int hooknum)
129{ 129{
@@ -155,7 +155,7 @@ icmp_error_message(struct sk_buff *skb,
155 155
156 *ctinfo = IP_CT_RELATED; 156 *ctinfo = IP_CT_RELATED;
157 157
158 h = nf_conntrack_find_get(&innertuple); 158 h = nf_conntrack_find_get(net, &innertuple);
159 if (!h) { 159 if (!h) {
160 pr_debug("icmp_error_message: no match\n"); 160 pr_debug("icmp_error_message: no match\n");
161 return -NF_ACCEPT; 161 return -NF_ACCEPT;
@@ -172,8 +172,8 @@ icmp_error_message(struct sk_buff *skb,
172 172
173/* Small and modified version of icmp_rcv */ 173/* Small and modified version of icmp_rcv */
174static int 174static int
175icmp_error(struct sk_buff *skb, unsigned int dataoff, 175icmp_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
176 enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum) 176 enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum)
177{ 177{
178 const struct icmphdr *icmph; 178 const struct icmphdr *icmph;
179 struct icmphdr _ih; 179 struct icmphdr _ih;
@@ -181,16 +181,16 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
181 /* Not enough header? */ 181 /* Not enough header? */
182 icmph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_ih), &_ih); 182 icmph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_ih), &_ih);
183 if (icmph == NULL) { 183 if (icmph == NULL) {
184 if (LOG_INVALID(IPPROTO_ICMP)) 184 if (LOG_INVALID(net, IPPROTO_ICMP))
185 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, 185 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
186 "nf_ct_icmp: short packet "); 186 "nf_ct_icmp: short packet ");
187 return -NF_ACCEPT; 187 return -NF_ACCEPT;
188 } 188 }
189 189
190 /* See ip_conntrack_proto_tcp.c */ 190 /* See ip_conntrack_proto_tcp.c */
191 if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && 191 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
192 nf_ip_checksum(skb, hooknum, dataoff, 0)) { 192 nf_ip_checksum(skb, hooknum, dataoff, 0)) {
193 if (LOG_INVALID(IPPROTO_ICMP)) 193 if (LOG_INVALID(net, IPPROTO_ICMP))
194 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, 194 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
195 "nf_ct_icmp: bad HW ICMP checksum "); 195 "nf_ct_icmp: bad HW ICMP checksum ");
196 return -NF_ACCEPT; 196 return -NF_ACCEPT;
@@ -203,7 +203,7 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
203 * discarded. 203 * discarded.
204 */ 204 */
205 if (icmph->type > NR_ICMP_TYPES) { 205 if (icmph->type > NR_ICMP_TYPES) {
206 if (LOG_INVALID(IPPROTO_ICMP)) 206 if (LOG_INVALID(net, IPPROTO_ICMP))
207 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, 207 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
208 "nf_ct_icmp: invalid ICMP type "); 208 "nf_ct_icmp: invalid ICMP type ");
209 return -NF_ACCEPT; 209 return -NF_ACCEPT;
@@ -217,7 +217,7 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
217 && icmph->type != ICMP_REDIRECT) 217 && icmph->type != ICMP_REDIRECT)
218 return NF_ACCEPT; 218 return NF_ACCEPT;
219 219
220 return icmp_error_message(skb, ctinfo, hooknum); 220 return icmp_error_message(net, skb, ctinfo, hooknum);
221} 221}
222 222
223#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 223#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c
new file mode 100644
index 000000000000..aa2c50a180f7
--- /dev/null
+++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
@@ -0,0 +1,96 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/types.h>
10#include <linux/ip.h>
11#include <linux/netfilter.h>
12#include <linux/module.h>
13#include <linux/skbuff.h>
14#include <net/route.h>
15#include <net/ip.h>
16
17#include <linux/netfilter_ipv4.h>
18#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
19
20/* Returns new sk_buff, or NULL */
21static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
22{
23 int err;
24
25 skb_orphan(skb);
26
27 local_bh_disable();
28 err = ip_defrag(skb, user);
29 local_bh_enable();
30
31 if (!err)
32 ip_send_check(ip_hdr(skb));
33
34 return err;
35}
36
37static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
38 struct sk_buff *skb,
39 const struct net_device *in,
40 const struct net_device *out,
41 int (*okfn)(struct sk_buff *))
42{
43#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
44 /* Previously seen (loopback)? Ignore. Do this before
45 fragment check. */
46 if (skb->nfct)
47 return NF_ACCEPT;
48#endif
49
50 /* Gather fragments. */
51 if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
52 if (nf_ct_ipv4_gather_frags(skb,
53 hooknum == NF_INET_PRE_ROUTING ?
54 IP_DEFRAG_CONNTRACK_IN :
55 IP_DEFRAG_CONNTRACK_OUT))
56 return NF_STOLEN;
57 }
58 return NF_ACCEPT;
59}
60
61static struct nf_hook_ops ipv4_defrag_ops[] = {
62 {
63 .hook = ipv4_conntrack_defrag,
64 .owner = THIS_MODULE,
65 .pf = PF_INET,
66 .hooknum = NF_INET_PRE_ROUTING,
67 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
68 },
69 {
70 .hook = ipv4_conntrack_defrag,
71 .owner = THIS_MODULE,
72 .pf = PF_INET,
73 .hooknum = NF_INET_LOCAL_OUT,
74 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
75 },
76};
77
78static int __init nf_defrag_init(void)
79{
80 return nf_register_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
81}
82
83static void __exit nf_defrag_fini(void)
84{
85 nf_unregister_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
86}
87
88void nf_defrag_ipv4_enable(void)
89{
90}
91EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable);
92
93module_init(nf_defrag_init);
94module_exit(nf_defrag_fini);
95
96MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 6c6a3cba8d50..2ac9eaf1a8c9 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -37,9 +37,6 @@ static struct nf_conntrack_l3proto *l3proto __read_mostly;
37 37
38/* Calculated at init based on memory size */ 38/* Calculated at init based on memory size */
39static unsigned int nf_nat_htable_size __read_mostly; 39static unsigned int nf_nat_htable_size __read_mostly;
40static int nf_nat_vmalloced;
41
42static struct hlist_head *bysource __read_mostly;
43 40
44#define MAX_IP_NAT_PROTO 256 41#define MAX_IP_NAT_PROTO 256
45static const struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO] 42static const struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO]
@@ -145,7 +142,8 @@ same_src(const struct nf_conn *ct,
145 142
146/* Only called for SRC manip */ 143/* Only called for SRC manip */
147static int 144static int
148find_appropriate_src(const struct nf_conntrack_tuple *tuple, 145find_appropriate_src(struct net *net,
146 const struct nf_conntrack_tuple *tuple,
149 struct nf_conntrack_tuple *result, 147 struct nf_conntrack_tuple *result,
150 const struct nf_nat_range *range) 148 const struct nf_nat_range *range)
151{ 149{
@@ -155,7 +153,7 @@ find_appropriate_src(const struct nf_conntrack_tuple *tuple,
155 const struct hlist_node *n; 153 const struct hlist_node *n;
156 154
157 rcu_read_lock(); 155 rcu_read_lock();
158 hlist_for_each_entry_rcu(nat, n, &bysource[h], bysource) { 156 hlist_for_each_entry_rcu(nat, n, &net->ipv4.nat_bysource[h], bysource) {
159 ct = nat->ct; 157 ct = nat->ct;
160 if (same_src(ct, tuple)) { 158 if (same_src(ct, tuple)) {
161 /* Copy source part from reply tuple. */ 159 /* Copy source part from reply tuple. */
@@ -231,6 +229,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
231 struct nf_conn *ct, 229 struct nf_conn *ct,
232 enum nf_nat_manip_type maniptype) 230 enum nf_nat_manip_type maniptype)
233{ 231{
232 struct net *net = nf_ct_net(ct);
234 const struct nf_nat_protocol *proto; 233 const struct nf_nat_protocol *proto;
235 234
236 /* 1) If this srcip/proto/src-proto-part is currently mapped, 235 /* 1) If this srcip/proto/src-proto-part is currently mapped,
@@ -242,7 +241,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
242 manips not an issue. */ 241 manips not an issue. */
243 if (maniptype == IP_NAT_MANIP_SRC && 242 if (maniptype == IP_NAT_MANIP_SRC &&
244 !(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) { 243 !(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) {
245 if (find_appropriate_src(orig_tuple, tuple, range)) { 244 if (find_appropriate_src(net, orig_tuple, tuple, range)) {
246 pr_debug("get_unique_tuple: Found current src map\n"); 245 pr_debug("get_unique_tuple: Found current src map\n");
247 if (!nf_nat_used_tuple(tuple, ct)) 246 if (!nf_nat_used_tuple(tuple, ct))
248 return; 247 return;
@@ -283,6 +282,7 @@ nf_nat_setup_info(struct nf_conn *ct,
283 const struct nf_nat_range *range, 282 const struct nf_nat_range *range,
284 enum nf_nat_manip_type maniptype) 283 enum nf_nat_manip_type maniptype)
285{ 284{
285 struct net *net = nf_ct_net(ct);
286 struct nf_conntrack_tuple curr_tuple, new_tuple; 286 struct nf_conntrack_tuple curr_tuple, new_tuple;
287 struct nf_conn_nat *nat; 287 struct nf_conn_nat *nat;
288 int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK); 288 int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK);
@@ -334,7 +334,8 @@ nf_nat_setup_info(struct nf_conn *ct,
334 /* nf_conntrack_alter_reply might re-allocate exntension aera */ 334 /* nf_conntrack_alter_reply might re-allocate exntension aera */
335 nat = nfct_nat(ct); 335 nat = nfct_nat(ct);
336 nat->ct = ct; 336 nat->ct = ct;
337 hlist_add_head_rcu(&nat->bysource, &bysource[srchash]); 337 hlist_add_head_rcu(&nat->bysource,
338 &net->ipv4.nat_bysource[srchash]);
338 spin_unlock_bh(&nf_nat_lock); 339 spin_unlock_bh(&nf_nat_lock);
339 } 340 }
340 341
@@ -583,6 +584,40 @@ static struct nf_ct_ext_type nat_extend __read_mostly = {
583 .flags = NF_CT_EXT_F_PREALLOC, 584 .flags = NF_CT_EXT_F_PREALLOC,
584}; 585};
585 586
587static int __net_init nf_nat_net_init(struct net *net)
588{
589 net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
590 &net->ipv4.nat_vmalloced);
591 if (!net->ipv4.nat_bysource)
592 return -ENOMEM;
593 return 0;
594}
595
596/* Clear NAT section of all conntracks, in case we're loaded again. */
597static int clean_nat(struct nf_conn *i, void *data)
598{
599 struct nf_conn_nat *nat = nfct_nat(i);
600
601 if (!nat)
602 return 0;
603 memset(nat, 0, sizeof(*nat));
604 i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST);
605 return 0;
606}
607
608static void __net_exit nf_nat_net_exit(struct net *net)
609{
610 nf_ct_iterate_cleanup(net, &clean_nat, NULL);
611 synchronize_rcu();
612 nf_ct_free_hashtable(net->ipv4.nat_bysource, net->ipv4.nat_vmalloced,
613 nf_nat_htable_size);
614}
615
616static struct pernet_operations nf_nat_net_ops = {
617 .init = nf_nat_net_init,
618 .exit = nf_nat_net_exit,
619};
620
586static int __init nf_nat_init(void) 621static int __init nf_nat_init(void)
587{ 622{
588 size_t i; 623 size_t i;
@@ -599,12 +634,9 @@ static int __init nf_nat_init(void)
599 /* Leave them the same for the moment. */ 634 /* Leave them the same for the moment. */
600 nf_nat_htable_size = nf_conntrack_htable_size; 635 nf_nat_htable_size = nf_conntrack_htable_size;
601 636
602 bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size, 637 ret = register_pernet_subsys(&nf_nat_net_ops);
603 &nf_nat_vmalloced); 638 if (ret < 0)
604 if (!bysource) {
605 ret = -ENOMEM;
606 goto cleanup_extend; 639 goto cleanup_extend;
607 }
608 640
609 /* Sew in builtin protocols. */ 641 /* Sew in builtin protocols. */
610 spin_lock_bh(&nf_nat_lock); 642 spin_lock_bh(&nf_nat_lock);
@@ -629,23 +661,9 @@ static int __init nf_nat_init(void)
629 return ret; 661 return ret;
630} 662}
631 663
632/* Clear NAT section of all conntracks, in case we're loaded again. */
633static int clean_nat(struct nf_conn *i, void *data)
634{
635 struct nf_conn_nat *nat = nfct_nat(i);
636
637 if (!nat)
638 return 0;
639 memset(nat, 0, sizeof(*nat));
640 i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST);
641 return 0;
642}
643
644static void __exit nf_nat_cleanup(void) 664static void __exit nf_nat_cleanup(void)
645{ 665{
646 nf_ct_iterate_cleanup(&clean_nat, NULL); 666 unregister_pernet_subsys(&nf_nat_net_ops);
647 synchronize_rcu();
648 nf_ct_free_hashtable(bysource, nf_nat_vmalloced, nf_nat_htable_size);
649 nf_ct_l3proto_put(l3proto); 667 nf_ct_l3proto_put(l3proto);
650 nf_ct_extend_unregister(&nat_extend); 668 nf_ct_extend_unregister(&nat_extend);
651 rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL); 669 rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
index 112dcfa12900..cf7a42bf9820 100644
--- a/net/ipv4/netfilter/nf_nat_helper.c
+++ b/net/ipv4/netfilter/nf_nat_helper.c
@@ -193,7 +193,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb,
193 nf_conntrack_tcp_update(skb, ip_hdrlen(skb), 193 nf_conntrack_tcp_update(skb, ip_hdrlen(skb),
194 ct, CTINFO2DIR(ctinfo)); 194 ct, CTINFO2DIR(ctinfo));
195 195
196 nf_conntrack_event_cache(IPCT_NATSEQADJ, skb); 196 nf_conntrack_event_cache(IPCT_NATSEQADJ, ct);
197 } 197 }
198 return 1; 198 return 1;
199} 199}
diff --git a/net/ipv4/netfilter/nf_nat_pptp.c b/net/ipv4/netfilter/nf_nat_pptp.c
index da3d91a5ef5c..9eb171056c63 100644
--- a/net/ipv4/netfilter/nf_nat_pptp.c
+++ b/net/ipv4/netfilter/nf_nat_pptp.c
@@ -40,6 +40,7 @@ MODULE_ALIAS("ip_nat_pptp");
40static void pptp_nat_expected(struct nf_conn *ct, 40static void pptp_nat_expected(struct nf_conn *ct,
41 struct nf_conntrack_expect *exp) 41 struct nf_conntrack_expect *exp)
42{ 42{
43 struct net *net = nf_ct_net(ct);
43 const struct nf_conn *master = ct->master; 44 const struct nf_conn *master = ct->master;
44 struct nf_conntrack_expect *other_exp; 45 struct nf_conntrack_expect *other_exp;
45 struct nf_conntrack_tuple t; 46 struct nf_conntrack_tuple t;
@@ -73,7 +74,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
73 74
74 pr_debug("trying to unexpect other dir: "); 75 pr_debug("trying to unexpect other dir: ");
75 nf_ct_dump_tuple_ip(&t); 76 nf_ct_dump_tuple_ip(&t);
76 other_exp = nf_ct_expect_find_get(&t); 77 other_exp = nf_ct_expect_find_get(net, &t);
77 if (other_exp) { 78 if (other_exp) {
78 nf_ct_unexpect_related(other_exp); 79 nf_ct_unexpect_related(other_exp);
79 nf_ct_expect_put(other_exp); 80 nf_ct_expect_put(other_exp);
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index e8b4d0d4439e..bea54a685109 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -33,7 +33,7 @@ static struct
33 struct ipt_replace repl; 33 struct ipt_replace repl;
34 struct ipt_standard entries[3]; 34 struct ipt_standard entries[3];
35 struct ipt_error term; 35 struct ipt_error term;
36} nat_initial_table __initdata = { 36} nat_initial_table __net_initdata = {
37 .repl = { 37 .repl = {
38 .name = "nat", 38 .name = "nat",
39 .valid_hooks = NAT_VALID_HOOKS, 39 .valid_hooks = NAT_VALID_HOOKS,
@@ -58,47 +58,42 @@ static struct
58 .term = IPT_ERROR_INIT, /* ERROR */ 58 .term = IPT_ERROR_INIT, /* ERROR */
59}; 59};
60 60
61static struct xt_table __nat_table = { 61static struct xt_table nat_table = {
62 .name = "nat", 62 .name = "nat",
63 .valid_hooks = NAT_VALID_HOOKS, 63 .valid_hooks = NAT_VALID_HOOKS,
64 .lock = __RW_LOCK_UNLOCKED(__nat_table.lock), 64 .lock = __RW_LOCK_UNLOCKED(__nat_table.lock),
65 .me = THIS_MODULE, 65 .me = THIS_MODULE,
66 .af = AF_INET, 66 .af = AF_INET,
67}; 67};
68static struct xt_table *nat_table;
69 68
70/* Source NAT */ 69/* Source NAT */
71static unsigned int ipt_snat_target(struct sk_buff *skb, 70static unsigned int
72 const struct net_device *in, 71ipt_snat_target(struct sk_buff *skb, const struct xt_target_param *par)
73 const struct net_device *out,
74 unsigned int hooknum,
75 const struct xt_target *target,
76 const void *targinfo)
77{ 72{
78 struct nf_conn *ct; 73 struct nf_conn *ct;
79 enum ip_conntrack_info ctinfo; 74 enum ip_conntrack_info ctinfo;
80 const struct nf_nat_multi_range_compat *mr = targinfo; 75 const struct nf_nat_multi_range_compat *mr = par->targinfo;
81 76
82 NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING); 77 NF_CT_ASSERT(par->hooknum == NF_INET_POST_ROUTING);
83 78
84 ct = nf_ct_get(skb, &ctinfo); 79 ct = nf_ct_get(skb, &ctinfo);
85 80
86 /* Connection must be valid and new. */ 81 /* Connection must be valid and new. */
87 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || 82 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
88 ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)); 83 ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
89 NF_CT_ASSERT(out); 84 NF_CT_ASSERT(par->out != NULL);
90 85
91 return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC); 86 return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC);
92} 87}
93 88
94/* Before 2.6.11 we did implicit source NAT if required. Warn about change. */ 89/* Before 2.6.11 we did implicit source NAT if required. Warn about change. */
95static void warn_if_extra_mangle(__be32 dstip, __be32 srcip) 90static void warn_if_extra_mangle(struct net *net, __be32 dstip, __be32 srcip)
96{ 91{
97 static int warned = 0; 92 static int warned = 0;
98 struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } }; 93 struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } };
99 struct rtable *rt; 94 struct rtable *rt;
100 95
101 if (ip_route_output_key(&init_net, &rt, &fl) != 0) 96 if (ip_route_output_key(net, &rt, &fl) != 0)
102 return; 97 return;
103 98
104 if (rt->rt_src != srcip && !warned) { 99 if (rt->rt_src != srcip && !warned) {
@@ -110,40 +105,32 @@ static void warn_if_extra_mangle(__be32 dstip, __be32 srcip)
110 ip_rt_put(rt); 105 ip_rt_put(rt);
111} 106}
112 107
113static unsigned int ipt_dnat_target(struct sk_buff *skb, 108static unsigned int
114 const struct net_device *in, 109ipt_dnat_target(struct sk_buff *skb, const struct xt_target_param *par)
115 const struct net_device *out,
116 unsigned int hooknum,
117 const struct xt_target *target,
118 const void *targinfo)
119{ 110{
120 struct nf_conn *ct; 111 struct nf_conn *ct;
121 enum ip_conntrack_info ctinfo; 112 enum ip_conntrack_info ctinfo;
122 const struct nf_nat_multi_range_compat *mr = targinfo; 113 const struct nf_nat_multi_range_compat *mr = par->targinfo;
123 114
124 NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING || 115 NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING ||
125 hooknum == NF_INET_LOCAL_OUT); 116 par->hooknum == NF_INET_LOCAL_OUT);
126 117
127 ct = nf_ct_get(skb, &ctinfo); 118 ct = nf_ct_get(skb, &ctinfo);
128 119
129 /* Connection must be valid and new. */ 120 /* Connection must be valid and new. */
130 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); 121 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
131 122
132 if (hooknum == NF_INET_LOCAL_OUT && 123 if (par->hooknum == NF_INET_LOCAL_OUT &&
133 mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) 124 mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)
134 warn_if_extra_mangle(ip_hdr(skb)->daddr, 125 warn_if_extra_mangle(dev_net(par->out), ip_hdr(skb)->daddr,
135 mr->range[0].min_ip); 126 mr->range[0].min_ip);
136 127
137 return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST); 128 return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST);
138} 129}
139 130
140static bool ipt_snat_checkentry(const char *tablename, 131static bool ipt_snat_checkentry(const struct xt_tgchk_param *par)
141 const void *entry,
142 const struct xt_target *target,
143 void *targinfo,
144 unsigned int hook_mask)
145{ 132{
146 const struct nf_nat_multi_range_compat *mr = targinfo; 133 const struct nf_nat_multi_range_compat *mr = par->targinfo;
147 134
148 /* Must be a valid range */ 135 /* Must be a valid range */
149 if (mr->rangesize != 1) { 136 if (mr->rangesize != 1) {
@@ -153,13 +140,9 @@ static bool ipt_snat_checkentry(const char *tablename,
153 return true; 140 return true;
154} 141}
155 142
156static bool ipt_dnat_checkentry(const char *tablename, 143static bool ipt_dnat_checkentry(const struct xt_tgchk_param *par)
157 const void *entry,
158 const struct xt_target *target,
159 void *targinfo,
160 unsigned int hook_mask)
161{ 144{
162 const struct nf_nat_multi_range_compat *mr = targinfo; 145 const struct nf_nat_multi_range_compat *mr = par->targinfo;
163 146
164 /* Must be a valid range */ 147 /* Must be a valid range */
165 if (mr->rangesize != 1) { 148 if (mr->rangesize != 1) {
@@ -194,9 +177,10 @@ int nf_nat_rule_find(struct sk_buff *skb,
194 const struct net_device *out, 177 const struct net_device *out,
195 struct nf_conn *ct) 178 struct nf_conn *ct)
196{ 179{
180 struct net *net = nf_ct_net(ct);
197 int ret; 181 int ret;
198 182
199 ret = ipt_do_table(skb, hooknum, in, out, nat_table); 183 ret = ipt_do_table(skb, hooknum, in, out, net->ipv4.nat_table);
200 184
201 if (ret == NF_ACCEPT) { 185 if (ret == NF_ACCEPT) {
202 if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum))) 186 if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum)))
@@ -226,14 +210,32 @@ static struct xt_target ipt_dnat_reg __read_mostly = {
226 .family = AF_INET, 210 .family = AF_INET,
227}; 211};
228 212
213static int __net_init nf_nat_rule_net_init(struct net *net)
214{
215 net->ipv4.nat_table = ipt_register_table(net, &nat_table,
216 &nat_initial_table.repl);
217 if (IS_ERR(net->ipv4.nat_table))
218 return PTR_ERR(net->ipv4.nat_table);
219 return 0;
220}
221
222static void __net_exit nf_nat_rule_net_exit(struct net *net)
223{
224 ipt_unregister_table(net->ipv4.nat_table);
225}
226
227static struct pernet_operations nf_nat_rule_net_ops = {
228 .init = nf_nat_rule_net_init,
229 .exit = nf_nat_rule_net_exit,
230};
231
229int __init nf_nat_rule_init(void) 232int __init nf_nat_rule_init(void)
230{ 233{
231 int ret; 234 int ret;
232 235
233 nat_table = ipt_register_table(&init_net, &__nat_table, 236 ret = register_pernet_subsys(&nf_nat_rule_net_ops);
234 &nat_initial_table.repl); 237 if (ret != 0)
235 if (IS_ERR(nat_table)) 238 goto out;
236 return PTR_ERR(nat_table);
237 ret = xt_register_target(&ipt_snat_reg); 239 ret = xt_register_target(&ipt_snat_reg);
238 if (ret != 0) 240 if (ret != 0)
239 goto unregister_table; 241 goto unregister_table;
@@ -247,8 +249,8 @@ int __init nf_nat_rule_init(void)
247 unregister_snat: 249 unregister_snat:
248 xt_unregister_target(&ipt_snat_reg); 250 xt_unregister_target(&ipt_snat_reg);
249 unregister_table: 251 unregister_table:
250 ipt_unregister_table(nat_table); 252 unregister_pernet_subsys(&nf_nat_rule_net_ops);
251 253 out:
252 return ret; 254 return ret;
253} 255}
254 256
@@ -256,5 +258,5 @@ void nf_nat_rule_cleanup(void)
256{ 258{
257 xt_unregister_target(&ipt_dnat_reg); 259 xt_unregister_target(&ipt_dnat_reg);
258 xt_unregister_target(&ipt_snat_reg); 260 xt_unregister_target(&ipt_snat_reg);
259 ipt_unregister_table(nat_table); 261 unregister_pernet_subsys(&nf_nat_rule_net_ops);
260} 262}
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 8c6c5e71f210..4cb4844a3220 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -23,7 +23,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
23 .saddr = iph->saddr, } }, 23 .saddr = iph->saddr, } },
24 }; 24 };
25 25
26 dst = ip6_route_output(&init_net, skb->sk, &fl); 26 dst = ip6_route_output(dev_net(skb->dst->dev), skb->sk, &fl);
27 27
28#ifdef CONFIG_XFRM 28#ifdef CONFIG_XFRM
29 if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && 29 if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 0cfcce7b18d8..53ea512c4608 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -55,30 +55,29 @@ config IP6_NF_IPTABLES
55 55
56 To compile it as a module, choose M here. If unsure, say N. 56 To compile it as a module, choose M here. If unsure, say N.
57 57
58if IP6_NF_IPTABLES
59
58# The simple matches. 60# The simple matches.
59config IP6_NF_MATCH_RT 61config IP6_NF_MATCH_AH
60 tristate '"rt" Routing header match support' 62 tristate '"ah" match support'
61 depends on IP6_NF_IPTABLES
62 depends on NETFILTER_ADVANCED 63 depends on NETFILTER_ADVANCED
63 help 64 help
64 rt matching allows you to match packets based on the routing 65 This module allows one to match AH packets.
65 header of the packet.
66 66
67 To compile it as a module, choose M here. If unsure, say N. 67 To compile it as a module, choose M here. If unsure, say N.
68 68
69config IP6_NF_MATCH_OPTS 69config IP6_NF_MATCH_EUI64
70 tristate '"hopbyhop" and "dst" opts header match support' 70 tristate '"eui64" address check'
71 depends on IP6_NF_IPTABLES
72 depends on NETFILTER_ADVANCED 71 depends on NETFILTER_ADVANCED
73 help 72 help
74 This allows one to match packets based on the hop-by-hop 73 This module performs checking on the IPv6 source address
75 and destination options headers of a packet. 74 Compares the last 64 bits with the EUI64 (delivered
75 from the MAC address) address
76 76
77 To compile it as a module, choose M here. If unsure, say N. 77 To compile it as a module, choose M here. If unsure, say N.
78 78
79config IP6_NF_MATCH_FRAG 79config IP6_NF_MATCH_FRAG
80 tristate '"frag" Fragmentation header match support' 80 tristate '"frag" Fragmentation header match support'
81 depends on IP6_NF_IPTABLES
82 depends on NETFILTER_ADVANCED 81 depends on NETFILTER_ADVANCED
83 help 82 help
84 frag matching allows you to match packets based on the fragmentation 83 frag matching allows you to match packets based on the fragmentation
@@ -86,9 +85,17 @@ config IP6_NF_MATCH_FRAG
86 85
87 To compile it as a module, choose M here. If unsure, say N. 86 To compile it as a module, choose M here. If unsure, say N.
88 87
88config IP6_NF_MATCH_OPTS
89 tristate '"hbh" hop-by-hop and "dst" opts header match support'
90 depends on NETFILTER_ADVANCED
91 help
92 This allows one to match packets based on the hop-by-hop
93 and destination options headers of a packet.
94
95 To compile it as a module, choose M here. If unsure, say N.
96
89config IP6_NF_MATCH_HL 97config IP6_NF_MATCH_HL
90 tristate '"hl" match support' 98 tristate '"hl" match support'
91 depends on IP6_NF_IPTABLES
92 depends on NETFILTER_ADVANCED 99 depends on NETFILTER_ADVANCED
93 help 100 help
94 HL matching allows you to match packets based on the hop 101 HL matching allows you to match packets based on the hop
@@ -98,7 +105,6 @@ config IP6_NF_MATCH_HL
98 105
99config IP6_NF_MATCH_IPV6HEADER 106config IP6_NF_MATCH_IPV6HEADER
100 tristate '"ipv6header" IPv6 Extension Headers Match' 107 tristate '"ipv6header" IPv6 Extension Headers Match'
101 depends on IP6_NF_IPTABLES
102 default m if NETFILTER_ADVANCED=n 108 default m if NETFILTER_ADVANCED=n
103 help 109 help
104 This module allows one to match packets based upon 110 This module allows one to match packets based upon
@@ -106,54 +112,40 @@ config IP6_NF_MATCH_IPV6HEADER
106 112
107 To compile it as a module, choose M here. If unsure, say N. 113 To compile it as a module, choose M here. If unsure, say N.
108 114
109config IP6_NF_MATCH_AH
110 tristate '"ah" match support'
111 depends on IP6_NF_IPTABLES
112 depends on NETFILTER_ADVANCED
113 help
114 This module allows one to match AH packets.
115
116 To compile it as a module, choose M here. If unsure, say N.
117
118config IP6_NF_MATCH_MH 115config IP6_NF_MATCH_MH
119 tristate '"mh" match support' 116 tristate '"mh" match support'
120 depends on IP6_NF_IPTABLES
121 depends on NETFILTER_ADVANCED 117 depends on NETFILTER_ADVANCED
122 help 118 help
123 This module allows one to match MH packets. 119 This module allows one to match MH packets.
124 120
125 To compile it as a module, choose M here. If unsure, say N. 121 To compile it as a module, choose M here. If unsure, say N.
126 122
127config IP6_NF_MATCH_EUI64 123config IP6_NF_MATCH_RT
128 tristate '"eui64" address check' 124 tristate '"rt" Routing header match support'
129 depends on IP6_NF_IPTABLES
130 depends on NETFILTER_ADVANCED 125 depends on NETFILTER_ADVANCED
131 help 126 help
132 This module performs checking on the IPv6 source address 127 rt matching allows you to match packets based on the routing
133 Compares the last 64 bits with the EUI64 (delivered 128 header of the packet.
134 from the MAC address) address
135 129
136 To compile it as a module, choose M here. If unsure, say N. 130 To compile it as a module, choose M here. If unsure, say N.
137 131
138# The targets 132# The targets
139config IP6_NF_FILTER 133config IP6_NF_TARGET_LOG
140 tristate "Packet filtering" 134 tristate "LOG target support"
141 depends on IP6_NF_IPTABLES
142 default m if NETFILTER_ADVANCED=n 135 default m if NETFILTER_ADVANCED=n
143 help 136 help
144 Packet filtering defines a table `filter', which has a series of 137 This option adds a `LOG' target, which allows you to create rules in
145 rules for simple packet filtering at local input, forwarding and 138 any iptables table which records the packet header to the syslog.
146 local output. See the man page for iptables(8).
147 139
148 To compile it as a module, choose M here. If unsure, say N. 140 To compile it as a module, choose M here. If unsure, say N.
149 141
150config IP6_NF_TARGET_LOG 142config IP6_NF_FILTER
151 tristate "LOG target support" 143 tristate "Packet filtering"
152 depends on IP6_NF_FILTER
153 default m if NETFILTER_ADVANCED=n 144 default m if NETFILTER_ADVANCED=n
154 help 145 help
155 This option adds a `LOG' target, which allows you to create rules in 146 Packet filtering defines a table `filter', which has a series of
156 any iptables table which records the packet header to the syslog. 147 rules for simple packet filtering at local input, forwarding and
148 local output. See the man page for iptables(8).
157 149
158 To compile it as a module, choose M here. If unsure, say N. 150 To compile it as a module, choose M here. If unsure, say N.
159 151
@@ -170,7 +162,6 @@ config IP6_NF_TARGET_REJECT
170 162
171config IP6_NF_MANGLE 163config IP6_NF_MANGLE
172 tristate "Packet mangling" 164 tristate "Packet mangling"
173 depends on IP6_NF_IPTABLES
174 default m if NETFILTER_ADVANCED=n 165 default m if NETFILTER_ADVANCED=n
175 help 166 help
176 This option adds a `mangle' table to iptables: see the man page for 167 This option adds a `mangle' table to iptables: see the man page for
@@ -198,7 +189,6 @@ config IP6_NF_TARGET_HL
198 189
199config IP6_NF_RAW 190config IP6_NF_RAW
200 tristate 'raw table support (required for TRACE)' 191 tristate 'raw table support (required for TRACE)'
201 depends on IP6_NF_IPTABLES
202 depends on NETFILTER_ADVANCED 192 depends on NETFILTER_ADVANCED
203 help 193 help
204 This option adds a `raw' table to ip6tables. This table is the very 194 This option adds a `raw' table to ip6tables. This table is the very
@@ -211,7 +201,6 @@ config IP6_NF_RAW
211# security table for MAC policy 201# security table for MAC policy
212config IP6_NF_SECURITY 202config IP6_NF_SECURITY
213 tristate "Security table" 203 tristate "Security table"
214 depends on IP6_NF_IPTABLES
215 depends on SECURITY 204 depends on SECURITY
216 depends on NETFILTER_ADVANCED 205 depends on NETFILTER_ADVANCED
217 help 206 help
@@ -220,5 +209,7 @@ config IP6_NF_SECURITY
220 209
221 If unsure, say N. 210 If unsure, say N.
222 211
212endif # IP6_NF_IPTABLES
213
223endmenu 214endmenu
224 215
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 0b4557e03431..a33485dc81cb 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -200,32 +200,25 @@ ip6_checkentry(const struct ip6t_ip6 *ipv6)
200} 200}
201 201
202static unsigned int 202static unsigned int
203ip6t_error(struct sk_buff *skb, 203ip6t_error(struct sk_buff *skb, const struct xt_target_param *par)
204 const struct net_device *in,
205 const struct net_device *out,
206 unsigned int hooknum,
207 const struct xt_target *target,
208 const void *targinfo)
209{ 204{
210 if (net_ratelimit()) 205 if (net_ratelimit())
211 printk("ip6_tables: error: `%s'\n", (char *)targinfo); 206 printk("ip6_tables: error: `%s'\n",
207 (const char *)par->targinfo);
212 208
213 return NF_DROP; 209 return NF_DROP;
214} 210}
215 211
216/* Performance critical - called for every packet */ 212/* Performance critical - called for every packet */
217static inline bool 213static inline bool
218do_match(struct ip6t_entry_match *m, 214do_match(struct ip6t_entry_match *m, const struct sk_buff *skb,
219 const struct sk_buff *skb, 215 struct xt_match_param *par)
220 const struct net_device *in,
221 const struct net_device *out,
222 int offset,
223 unsigned int protoff,
224 bool *hotdrop)
225{ 216{
217 par->match = m->u.kernel.match;
218 par->matchinfo = m->data;
219
226 /* Stop iteration if it doesn't match */ 220 /* Stop iteration if it doesn't match */
227 if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data, 221 if (!m->u.kernel.match->match(skb, par))
228 offset, protoff, hotdrop))
229 return true; 222 return true;
230 else 223 else
231 return false; 224 return false;
@@ -355,8 +348,6 @@ ip6t_do_table(struct sk_buff *skb,
355 struct xt_table *table) 348 struct xt_table *table)
356{ 349{
357 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); 350 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
358 int offset = 0;
359 unsigned int protoff = 0;
360 bool hotdrop = false; 351 bool hotdrop = false;
361 /* Initializing verdict to NF_DROP keeps gcc happy. */ 352 /* Initializing verdict to NF_DROP keeps gcc happy. */
362 unsigned int verdict = NF_DROP; 353 unsigned int verdict = NF_DROP;
@@ -364,6 +355,8 @@ ip6t_do_table(struct sk_buff *skb,
364 void *table_base; 355 void *table_base;
365 struct ip6t_entry *e, *back; 356 struct ip6t_entry *e, *back;
366 struct xt_table_info *private; 357 struct xt_table_info *private;
358 struct xt_match_param mtpar;
359 struct xt_target_param tgpar;
367 360
368 /* Initialization */ 361 /* Initialization */
369 indev = in ? in->name : nulldevname; 362 indev = in ? in->name : nulldevname;
@@ -374,6 +367,11 @@ ip6t_do_table(struct sk_buff *skb,
374 * things we don't know, ie. tcp syn flag or ports). If the 367 * things we don't know, ie. tcp syn flag or ports). If the
375 * rule is also a fragment-specific rule, non-fragments won't 368 * rule is also a fragment-specific rule, non-fragments won't
376 * match it. */ 369 * match it. */
370 mtpar.hotdrop = &hotdrop;
371 mtpar.in = tgpar.in = in;
372 mtpar.out = tgpar.out = out;
373 mtpar.family = tgpar.family = NFPROTO_IPV6;
374 tgpar.hooknum = hook;
377 375
378 read_lock_bh(&table->lock); 376 read_lock_bh(&table->lock);
379 IP_NF_ASSERT(table->valid_hooks & (1 << hook)); 377 IP_NF_ASSERT(table->valid_hooks & (1 << hook));
@@ -388,12 +386,10 @@ ip6t_do_table(struct sk_buff *skb,
388 IP_NF_ASSERT(e); 386 IP_NF_ASSERT(e);
389 IP_NF_ASSERT(back); 387 IP_NF_ASSERT(back);
390 if (ip6_packet_match(skb, indev, outdev, &e->ipv6, 388 if (ip6_packet_match(skb, indev, outdev, &e->ipv6,
391 &protoff, &offset, &hotdrop)) { 389 &mtpar.thoff, &mtpar.fragoff, &hotdrop)) {
392 struct ip6t_entry_target *t; 390 struct ip6t_entry_target *t;
393 391
394 if (IP6T_MATCH_ITERATE(e, do_match, 392 if (IP6T_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0)
395 skb, in, out,
396 offset, protoff, &hotdrop) != 0)
397 goto no_match; 393 goto no_match;
398 394
399 ADD_COUNTER(e->counters, 395 ADD_COUNTER(e->counters,
@@ -441,15 +437,15 @@ ip6t_do_table(struct sk_buff *skb,
441 } else { 437 } else {
442 /* Targets which reenter must return 438 /* Targets which reenter must return
443 abs. verdicts */ 439 abs. verdicts */
440 tgpar.target = t->u.kernel.target;
441 tgpar.targinfo = t->data;
442
444#ifdef CONFIG_NETFILTER_DEBUG 443#ifdef CONFIG_NETFILTER_DEBUG
445 ((struct ip6t_entry *)table_base)->comefrom 444 ((struct ip6t_entry *)table_base)->comefrom
446 = 0xeeeeeeec; 445 = 0xeeeeeeec;
447#endif 446#endif
448 verdict = t->u.kernel.target->target(skb, 447 verdict = t->u.kernel.target->target(skb,
449 in, out, 448 &tgpar);
450 hook,
451 t->u.kernel.target,
452 t->data);
453 449
454#ifdef CONFIG_NETFILTER_DEBUG 450#ifdef CONFIG_NETFILTER_DEBUG
455 if (((struct ip6t_entry *)table_base)->comefrom 451 if (((struct ip6t_entry *)table_base)->comefrom
@@ -602,12 +598,17 @@ mark_source_chains(struct xt_table_info *newinfo,
602static int 598static int
603cleanup_match(struct ip6t_entry_match *m, unsigned int *i) 599cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
604{ 600{
601 struct xt_mtdtor_param par;
602
605 if (i && (*i)-- == 0) 603 if (i && (*i)-- == 0)
606 return 1; 604 return 1;
607 605
608 if (m->u.kernel.match->destroy) 606 par.match = m->u.kernel.match;
609 m->u.kernel.match->destroy(m->u.kernel.match, m->data); 607 par.matchinfo = m->data;
610 module_put(m->u.kernel.match->me); 608 par.family = NFPROTO_IPV6;
609 if (par.match->destroy != NULL)
610 par.match->destroy(&par);
611 module_put(par.match->me);
611 return 0; 612 return 0;
612} 613}
613 614
@@ -632,34 +633,28 @@ check_entry(struct ip6t_entry *e, const char *name)
632 return 0; 633 return 0;
633} 634}
634 635
635static int check_match(struct ip6t_entry_match *m, const char *name, 636static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
636 const struct ip6t_ip6 *ipv6, 637 unsigned int *i)
637 unsigned int hookmask, unsigned int *i)
638{ 638{
639 struct xt_match *match; 639 const struct ip6t_ip6 *ipv6 = par->entryinfo;
640 int ret; 640 int ret;
641 641
642 match = m->u.kernel.match; 642 par->match = m->u.kernel.match;
643 ret = xt_check_match(match, AF_INET6, m->u.match_size - sizeof(*m), 643 par->matchinfo = m->data;
644 name, hookmask, ipv6->proto, 644
645 ipv6->invflags & IP6T_INV_PROTO); 645 ret = xt_check_match(par, m->u.match_size - sizeof(*m),
646 if (!ret && m->u.kernel.match->checkentry 646 ipv6->proto, ipv6->invflags & IP6T_INV_PROTO);
647 && !m->u.kernel.match->checkentry(name, ipv6, match, m->data, 647 if (ret < 0) {
648 hookmask)) {
649 duprintf("ip_tables: check failed for `%s'.\n", 648 duprintf("ip_tables: check failed for `%s'.\n",
650 m->u.kernel.match->name); 649 par.match->name);
651 ret = -EINVAL; 650 return ret;
652 } 651 }
653 if (!ret) 652 ++*i;
654 (*i)++; 653 return 0;
655 return ret;
656} 654}
657 655
658static int 656static int
659find_check_match(struct ip6t_entry_match *m, 657find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
660 const char *name,
661 const struct ip6t_ip6 *ipv6,
662 unsigned int hookmask,
663 unsigned int *i) 658 unsigned int *i)
664{ 659{
665 struct xt_match *match; 660 struct xt_match *match;
@@ -674,7 +669,7 @@ find_check_match(struct ip6t_entry_match *m,
674 } 669 }
675 m->u.kernel.match = match; 670 m->u.kernel.match = match;
676 671
677 ret = check_match(m, name, ipv6, hookmask, i); 672 ret = check_match(m, par, i);
678 if (ret) 673 if (ret)
679 goto err; 674 goto err;
680 675
@@ -686,23 +681,26 @@ err:
686 681
687static int check_target(struct ip6t_entry *e, const char *name) 682static int check_target(struct ip6t_entry *e, const char *name)
688{ 683{
689 struct ip6t_entry_target *t; 684 struct ip6t_entry_target *t = ip6t_get_target(e);
690 struct xt_target *target; 685 struct xt_tgchk_param par = {
686 .table = name,
687 .entryinfo = e,
688 .target = t->u.kernel.target,
689 .targinfo = t->data,
690 .hook_mask = e->comefrom,
691 .family = NFPROTO_IPV6,
692 };
691 int ret; 693 int ret;
692 694
693 t = ip6t_get_target(e); 695 t = ip6t_get_target(e);
694 target = t->u.kernel.target; 696 ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
695 ret = xt_check_target(target, AF_INET6, t->u.target_size - sizeof(*t), 697 e->ipv6.proto, e->ipv6.invflags & IP6T_INV_PROTO);
696 name, e->comefrom, e->ipv6.proto, 698 if (ret < 0) {
697 e->ipv6.invflags & IP6T_INV_PROTO);
698 if (!ret && t->u.kernel.target->checkentry
699 && !t->u.kernel.target->checkentry(name, e, target, t->data,
700 e->comefrom)) {
701 duprintf("ip_tables: check failed for `%s'.\n", 699 duprintf("ip_tables: check failed for `%s'.\n",
702 t->u.kernel.target->name); 700 t->u.kernel.target->name);
703 ret = -EINVAL; 701 return ret;
704 } 702 }
705 return ret; 703 return 0;
706} 704}
707 705
708static int 706static int
@@ -713,14 +711,18 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
713 struct xt_target *target; 711 struct xt_target *target;
714 int ret; 712 int ret;
715 unsigned int j; 713 unsigned int j;
714 struct xt_mtchk_param mtpar;
716 715
717 ret = check_entry(e, name); 716 ret = check_entry(e, name);
718 if (ret) 717 if (ret)
719 return ret; 718 return ret;
720 719
721 j = 0; 720 j = 0;
722 ret = IP6T_MATCH_ITERATE(e, find_check_match, name, &e->ipv6, 721 mtpar.table = name;
723 e->comefrom, &j); 722 mtpar.entryinfo = &e->ipv6;
723 mtpar.hook_mask = e->comefrom;
724 mtpar.family = NFPROTO_IPV6;
725 ret = IP6T_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
724 if (ret != 0) 726 if (ret != 0)
725 goto cleanup_matches; 727 goto cleanup_matches;
726 728
@@ -795,6 +797,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
795static int 797static int
796cleanup_entry(struct ip6t_entry *e, unsigned int *i) 798cleanup_entry(struct ip6t_entry *e, unsigned int *i)
797{ 799{
800 struct xt_tgdtor_param par;
798 struct ip6t_entry_target *t; 801 struct ip6t_entry_target *t;
799 802
800 if (i && (*i)-- == 0) 803 if (i && (*i)-- == 0)
@@ -803,9 +806,13 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i)
803 /* Cleanup all matches */ 806 /* Cleanup all matches */
804 IP6T_MATCH_ITERATE(e, cleanup_match, NULL); 807 IP6T_MATCH_ITERATE(e, cleanup_match, NULL);
805 t = ip6t_get_target(e); 808 t = ip6t_get_target(e);
806 if (t->u.kernel.target->destroy) 809
807 t->u.kernel.target->destroy(t->u.kernel.target, t->data); 810 par.target = t->u.kernel.target;
808 module_put(t->u.kernel.target->me); 811 par.targinfo = t->data;
812 par.family = NFPROTO_IPV6;
813 if (par.target->destroy != NULL)
814 par.target->destroy(&par);
815 module_put(par.target->me);
809 return 0; 816 return 0;
810} 817}
811 818
@@ -1677,10 +1684,14 @@ static int compat_check_entry(struct ip6t_entry *e, const char *name,
1677{ 1684{
1678 unsigned int j; 1685 unsigned int j;
1679 int ret; 1686 int ret;
1687 struct xt_mtchk_param mtpar;
1680 1688
1681 j = 0; 1689 j = 0;
1682 ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, 1690 mtpar.table = name;
1683 e->comefrom, &j); 1691 mtpar.entryinfo = &e->ipv6;
1692 mtpar.hook_mask = e->comefrom;
1693 mtpar.family = NFPROTO_IPV6;
1694 ret = IP6T_MATCH_ITERATE(e, check_match, &mtpar, &j);
1684 if (ret) 1695 if (ret)
1685 goto cleanup_matches; 1696 goto cleanup_matches;
1686 1697
@@ -2146,30 +2157,23 @@ icmp6_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
2146} 2157}
2147 2158
2148static bool 2159static bool
2149icmp6_match(const struct sk_buff *skb, 2160icmp6_match(const struct sk_buff *skb, const struct xt_match_param *par)
2150 const struct net_device *in,
2151 const struct net_device *out,
2152 const struct xt_match *match,
2153 const void *matchinfo,
2154 int offset,
2155 unsigned int protoff,
2156 bool *hotdrop)
2157{ 2161{
2158 const struct icmp6hdr *ic; 2162 const struct icmp6hdr *ic;
2159 struct icmp6hdr _icmph; 2163 struct icmp6hdr _icmph;
2160 const struct ip6t_icmp *icmpinfo = matchinfo; 2164 const struct ip6t_icmp *icmpinfo = par->matchinfo;
2161 2165
2162 /* Must not be a fragment. */ 2166 /* Must not be a fragment. */
2163 if (offset) 2167 if (par->fragoff != 0)
2164 return false; 2168 return false;
2165 2169
2166 ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph); 2170 ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph);
2167 if (ic == NULL) { 2171 if (ic == NULL) {
2168 /* We've been asked to examine this packet, and we 2172 /* We've been asked to examine this packet, and we
2169 * can't. Hence, no choice but to drop. 2173 * can't. Hence, no choice but to drop.
2170 */ 2174 */
2171 duprintf("Dropping evil ICMP tinygram.\n"); 2175 duprintf("Dropping evil ICMP tinygram.\n");
2172 *hotdrop = true; 2176 *par->hotdrop = true;
2173 return false; 2177 return false;
2174 } 2178 }
2175 2179
@@ -2181,14 +2185,9 @@ icmp6_match(const struct sk_buff *skb,
2181} 2185}
2182 2186
2183/* Called when user tries to insert an entry of this type. */ 2187/* Called when user tries to insert an entry of this type. */
2184static bool 2188static bool icmp6_checkentry(const struct xt_mtchk_param *par)
2185icmp6_checkentry(const char *tablename,
2186 const void *entry,
2187 const struct xt_match *match,
2188 void *matchinfo,
2189 unsigned int hook_mask)
2190{ 2189{
2191 const struct ip6t_icmp *icmpinfo = matchinfo; 2190 const struct ip6t_icmp *icmpinfo = par->matchinfo;
2192 2191
2193 /* Must specify no unknown invflags */ 2192 /* Must specify no unknown invflags */
2194 return !(icmpinfo->invflags & ~IP6T_ICMP_INV); 2193 return !(icmpinfo->invflags & ~IP6T_ICMP_INV);
diff --git a/net/ipv6/netfilter/ip6t_HL.c b/net/ipv6/netfilter/ip6t_HL.c
index d5f8fd5f29d3..27b5adf670a2 100644
--- a/net/ipv6/netfilter/ip6t_HL.c
+++ b/net/ipv6/netfilter/ip6t_HL.c
@@ -19,12 +19,10 @@ MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field modification target");
19MODULE_LICENSE("GPL"); 19MODULE_LICENSE("GPL");
20 20
21static unsigned int 21static unsigned int
22hl_tg6(struct sk_buff *skb, const struct net_device *in, 22hl_tg6(struct sk_buff *skb, const struct xt_target_param *par)
23 const struct net_device *out, unsigned int hooknum,
24 const struct xt_target *target, const void *targinfo)
25{ 23{
26 struct ipv6hdr *ip6h; 24 struct ipv6hdr *ip6h;
27 const struct ip6t_HL_info *info = targinfo; 25 const struct ip6t_HL_info *info = par->targinfo;
28 int new_hl; 26 int new_hl;
29 27
30 if (!skb_make_writable(skb, skb->len)) 28 if (!skb_make_writable(skb, skb->len))
@@ -56,12 +54,9 @@ hl_tg6(struct sk_buff *skb, const struct net_device *in,
56 return XT_CONTINUE; 54 return XT_CONTINUE;
57} 55}
58 56
59static bool 57static bool hl_tg6_check(const struct xt_tgchk_param *par)
60hl_tg6_check(const char *tablename, const void *entry,
61 const struct xt_target *target, void *targinfo,
62 unsigned int hook_mask)
63{ 58{
64 const struct ip6t_HL_info *info = targinfo; 59 const struct ip6t_HL_info *info = par->targinfo;
65 60
66 if (info->mode > IP6T_HL_MAXMODE) { 61 if (info->mode > IP6T_HL_MAXMODE) {
67 printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n", 62 printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n",
@@ -78,7 +73,7 @@ hl_tg6_check(const char *tablename, const void *entry,
78 73
79static struct xt_target hl_tg6_reg __read_mostly = { 74static struct xt_target hl_tg6_reg __read_mostly = {
80 .name = "HL", 75 .name = "HL",
81 .family = AF_INET6, 76 .family = NFPROTO_IPV6,
82 .target = hl_tg6, 77 .target = hl_tg6,
83 .targetsize = sizeof(struct ip6t_HL_info), 78 .targetsize = sizeof(struct ip6t_HL_info),
84 .table = "mangle", 79 .table = "mangle",
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 3a2316974f83..caa441d09567 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -385,7 +385,7 @@ static struct nf_loginfo default_loginfo = {
385}; 385};
386 386
387static void 387static void
388ip6t_log_packet(unsigned int pf, 388ip6t_log_packet(u_int8_t pf,
389 unsigned int hooknum, 389 unsigned int hooknum,
390 const struct sk_buff *skb, 390 const struct sk_buff *skb,
391 const struct net_device *in, 391 const struct net_device *in,
@@ -438,28 +438,24 @@ ip6t_log_packet(unsigned int pf,
438} 438}
439 439
440static unsigned int 440static unsigned int
441log_tg6(struct sk_buff *skb, const struct net_device *in, 441log_tg6(struct sk_buff *skb, const struct xt_target_param *par)
442 const struct net_device *out, unsigned int hooknum,
443 const struct xt_target *target, const void *targinfo)
444{ 442{
445 const struct ip6t_log_info *loginfo = targinfo; 443 const struct ip6t_log_info *loginfo = par->targinfo;
446 struct nf_loginfo li; 444 struct nf_loginfo li;
447 445
448 li.type = NF_LOG_TYPE_LOG; 446 li.type = NF_LOG_TYPE_LOG;
449 li.u.log.level = loginfo->level; 447 li.u.log.level = loginfo->level;
450 li.u.log.logflags = loginfo->logflags; 448 li.u.log.logflags = loginfo->logflags;
451 449
452 ip6t_log_packet(PF_INET6, hooknum, skb, in, out, &li, loginfo->prefix); 450 ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in, par->out,
451 &li, loginfo->prefix);
453 return XT_CONTINUE; 452 return XT_CONTINUE;
454} 453}
455 454
456 455
457static bool 456static bool log_tg6_check(const struct xt_tgchk_param *par)
458log_tg6_check(const char *tablename, const void *entry,
459 const struct xt_target *target, void *targinfo,
460 unsigned int hook_mask)
461{ 457{
462 const struct ip6t_log_info *loginfo = targinfo; 458 const struct ip6t_log_info *loginfo = par->targinfo;
463 459
464 if (loginfo->level >= 8) { 460 if (loginfo->level >= 8) {
465 pr_debug("LOG: level %u >= 8\n", loginfo->level); 461 pr_debug("LOG: level %u >= 8\n", loginfo->level);
@@ -475,7 +471,7 @@ log_tg6_check(const char *tablename, const void *entry,
475 471
476static struct xt_target log_tg6_reg __read_mostly = { 472static struct xt_target log_tg6_reg __read_mostly = {
477 .name = "LOG", 473 .name = "LOG",
478 .family = AF_INET6, 474 .family = NFPROTO_IPV6,
479 .target = log_tg6, 475 .target = log_tg6,
480 .targetsize = sizeof(struct ip6t_log_info), 476 .targetsize = sizeof(struct ip6t_log_info),
481 .checkentry = log_tg6_check, 477 .checkentry = log_tg6_check,
@@ -495,7 +491,7 @@ static int __init log_tg6_init(void)
495 ret = xt_register_target(&log_tg6_reg); 491 ret = xt_register_target(&log_tg6_reg);
496 if (ret < 0) 492 if (ret < 0)
497 return ret; 493 return ret;
498 nf_log_register(PF_INET6, &ip6t_logger); 494 nf_log_register(NFPROTO_IPV6, &ip6t_logger);
499 return 0; 495 return 0;
500} 496}
501 497
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index 44c8d65a2431..0981b4ccb8b1 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -35,7 +35,7 @@ MODULE_DESCRIPTION("Xtables: packet \"rejection\" target for IPv6");
35MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
36 36
37/* Send RST reply */ 37/* Send RST reply */
38static void send_reset(struct sk_buff *oldskb) 38static void send_reset(struct net *net, struct sk_buff *oldskb)
39{ 39{
40 struct sk_buff *nskb; 40 struct sk_buff *nskb;
41 struct tcphdr otcph, *tcph; 41 struct tcphdr otcph, *tcph;
@@ -94,7 +94,7 @@ static void send_reset(struct sk_buff *oldskb)
94 fl.fl_ip_sport = otcph.dest; 94 fl.fl_ip_sport = otcph.dest;
95 fl.fl_ip_dport = otcph.source; 95 fl.fl_ip_dport = otcph.source;
96 security_skb_classify_flow(oldskb, &fl); 96 security_skb_classify_flow(oldskb, &fl);
97 dst = ip6_route_output(&init_net, NULL, &fl); 97 dst = ip6_route_output(net, NULL, &fl);
98 if (dst == NULL) 98 if (dst == NULL)
99 return; 99 return;
100 if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0)) 100 if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0))
@@ -163,20 +163,20 @@ static void send_reset(struct sk_buff *oldskb)
163} 163}
164 164
165static inline void 165static inline void
166send_unreach(struct sk_buff *skb_in, unsigned char code, unsigned int hooknum) 166send_unreach(struct net *net, struct sk_buff *skb_in, unsigned char code,
167 unsigned int hooknum)
167{ 168{
168 if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL) 169 if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL)
169 skb_in->dev = init_net.loopback_dev; 170 skb_in->dev = net->loopback_dev;
170 171
171 icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL); 172 icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL);
172} 173}
173 174
174static unsigned int 175static unsigned int
175reject_tg6(struct sk_buff *skb, const struct net_device *in, 176reject_tg6(struct sk_buff *skb, const struct xt_target_param *par)
176 const struct net_device *out, unsigned int hooknum,
177 const struct xt_target *target, const void *targinfo)
178{ 177{
179 const struct ip6t_reject_info *reject = targinfo; 178 const struct ip6t_reject_info *reject = par->targinfo;
179 struct net *net = dev_net((par->in != NULL) ? par->in : par->out);
180 180
181 pr_debug("%s: medium point\n", __func__); 181 pr_debug("%s: medium point\n", __func__);
182 /* WARNING: This code causes reentry within ip6tables. 182 /* WARNING: This code causes reentry within ip6tables.
@@ -184,25 +184,25 @@ reject_tg6(struct sk_buff *skb, const struct net_device *in,
184 must return an absolute verdict. --RR */ 184 must return an absolute verdict. --RR */
185 switch (reject->with) { 185 switch (reject->with) {
186 case IP6T_ICMP6_NO_ROUTE: 186 case IP6T_ICMP6_NO_ROUTE:
187 send_unreach(skb, ICMPV6_NOROUTE, hooknum); 187 send_unreach(net, skb, ICMPV6_NOROUTE, par->hooknum);
188 break; 188 break;
189 case IP6T_ICMP6_ADM_PROHIBITED: 189 case IP6T_ICMP6_ADM_PROHIBITED:
190 send_unreach(skb, ICMPV6_ADM_PROHIBITED, hooknum); 190 send_unreach(net, skb, ICMPV6_ADM_PROHIBITED, par->hooknum);
191 break; 191 break;
192 case IP6T_ICMP6_NOT_NEIGHBOUR: 192 case IP6T_ICMP6_NOT_NEIGHBOUR:
193 send_unreach(skb, ICMPV6_NOT_NEIGHBOUR, hooknum); 193 send_unreach(net, skb, ICMPV6_NOT_NEIGHBOUR, par->hooknum);
194 break; 194 break;
195 case IP6T_ICMP6_ADDR_UNREACH: 195 case IP6T_ICMP6_ADDR_UNREACH:
196 send_unreach(skb, ICMPV6_ADDR_UNREACH, hooknum); 196 send_unreach(net, skb, ICMPV6_ADDR_UNREACH, par->hooknum);
197 break; 197 break;
198 case IP6T_ICMP6_PORT_UNREACH: 198 case IP6T_ICMP6_PORT_UNREACH:
199 send_unreach(skb, ICMPV6_PORT_UNREACH, hooknum); 199 send_unreach(net, skb, ICMPV6_PORT_UNREACH, par->hooknum);
200 break; 200 break;
201 case IP6T_ICMP6_ECHOREPLY: 201 case IP6T_ICMP6_ECHOREPLY:
202 /* Do nothing */ 202 /* Do nothing */
203 break; 203 break;
204 case IP6T_TCP_RESET: 204 case IP6T_TCP_RESET:
205 send_reset(skb); 205 send_reset(net, skb);
206 break; 206 break;
207 default: 207 default:
208 if (net_ratelimit()) 208 if (net_ratelimit())
@@ -213,13 +213,10 @@ reject_tg6(struct sk_buff *skb, const struct net_device *in,
213 return NF_DROP; 213 return NF_DROP;
214} 214}
215 215
216static bool 216static bool reject_tg6_check(const struct xt_tgchk_param *par)
217reject_tg6_check(const char *tablename, const void *entry,
218 const struct xt_target *target, void *targinfo,
219 unsigned int hook_mask)
220{ 217{
221 const struct ip6t_reject_info *rejinfo = targinfo; 218 const struct ip6t_reject_info *rejinfo = par->targinfo;
222 const struct ip6t_entry *e = entry; 219 const struct ip6t_entry *e = par->entryinfo;
223 220
224 if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) { 221 if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
225 printk("ip6t_REJECT: ECHOREPLY is not supported.\n"); 222 printk("ip6t_REJECT: ECHOREPLY is not supported.\n");
@@ -237,7 +234,7 @@ reject_tg6_check(const char *tablename, const void *entry,
237 234
238static struct xt_target reject_tg6_reg __read_mostly = { 235static struct xt_target reject_tg6_reg __read_mostly = {
239 .name = "REJECT", 236 .name = "REJECT",
240 .family = AF_INET6, 237 .family = NFPROTO_IPV6,
241 .target = reject_tg6, 238 .target = reject_tg6,
242 .targetsize = sizeof(struct ip6t_reject_info), 239 .targetsize = sizeof(struct ip6t_reject_info),
243 .table = "filter", 240 .table = "filter",
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
index 429629fd63b6..3a82f24746b9 100644
--- a/net/ipv6/netfilter/ip6t_ah.c
+++ b/net/ipv6/netfilter/ip6t_ah.c
@@ -36,14 +36,11 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
36 return r; 36 return r;
37} 37}
38 38
39static bool 39static bool ah_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
40ah_mt6(const struct sk_buff *skb, const struct net_device *in,
41 const struct net_device *out, const struct xt_match *match,
42 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
43{ 40{
44 struct ip_auth_hdr _ah; 41 struct ip_auth_hdr _ah;
45 const struct ip_auth_hdr *ah; 42 const struct ip_auth_hdr *ah;
46 const struct ip6t_ah *ahinfo = matchinfo; 43 const struct ip6t_ah *ahinfo = par->matchinfo;
47 unsigned int ptr; 44 unsigned int ptr;
48 unsigned int hdrlen = 0; 45 unsigned int hdrlen = 0;
49 int err; 46 int err;
@@ -51,13 +48,13 @@ ah_mt6(const struct sk_buff *skb, const struct net_device *in,
51 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL); 48 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL);
52 if (err < 0) { 49 if (err < 0) {
53 if (err != -ENOENT) 50 if (err != -ENOENT)
54 *hotdrop = true; 51 *par->hotdrop = true;
55 return false; 52 return false;
56 } 53 }
57 54
58 ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); 55 ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
59 if (ah == NULL) { 56 if (ah == NULL) {
60 *hotdrop = true; 57 *par->hotdrop = true;
61 return false; 58 return false;
62 } 59 }
63 60
@@ -93,13 +90,9 @@ ah_mt6(const struct sk_buff *skb, const struct net_device *in,
93 !(ahinfo->hdrres && ah->reserved); 90 !(ahinfo->hdrres && ah->reserved);
94} 91}
95 92
96/* Called when user tries to insert an entry of this type. */ 93static bool ah_mt6_check(const struct xt_mtchk_param *par)
97static bool
98ah_mt6_check(const char *tablename, const void *entry,
99 const struct xt_match *match, void *matchinfo,
100 unsigned int hook_mask)
101{ 94{
102 const struct ip6t_ah *ahinfo = matchinfo; 95 const struct ip6t_ah *ahinfo = par->matchinfo;
103 96
104 if (ahinfo->invflags & ~IP6T_AH_INV_MASK) { 97 if (ahinfo->invflags & ~IP6T_AH_INV_MASK) {
105 pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags); 98 pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags);
@@ -110,7 +103,7 @@ ah_mt6_check(const char *tablename, const void *entry,
110 103
111static struct xt_match ah_mt6_reg __read_mostly = { 104static struct xt_match ah_mt6_reg __read_mostly = {
112 .name = "ah", 105 .name = "ah",
113 .family = AF_INET6, 106 .family = NFPROTO_IPV6,
114 .match = ah_mt6, 107 .match = ah_mt6,
115 .matchsize = sizeof(struct ip6t_ah), 108 .matchsize = sizeof(struct ip6t_ah),
116 .checkentry = ah_mt6_check, 109 .checkentry = ah_mt6_check,
diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
index 8f331f12b2ec..db610bacbcce 100644
--- a/net/ipv6/netfilter/ip6t_eui64.c
+++ b/net/ipv6/netfilter/ip6t_eui64.c
@@ -20,18 +20,15 @@ MODULE_LICENSE("GPL");
20MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); 20MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
21 21
22static bool 22static bool
23eui64_mt6(const struct sk_buff *skb, const struct net_device *in, 23eui64_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
24 const struct net_device *out, const struct xt_match *match,
25 const void *matchinfo, int offset, unsigned int protoff,
26 bool *hotdrop)
27{ 24{
28 unsigned char eui64[8]; 25 unsigned char eui64[8];
29 int i = 0; 26 int i = 0;
30 27
31 if (!(skb_mac_header(skb) >= skb->head && 28 if (!(skb_mac_header(skb) >= skb->head &&
32 skb_mac_header(skb) + ETH_HLEN <= skb->data) && 29 skb_mac_header(skb) + ETH_HLEN <= skb->data) &&
33 offset != 0) { 30 par->fragoff != 0) {
34 *hotdrop = true; 31 *par->hotdrop = true;
35 return false; 32 return false;
36 } 33 }
37 34
@@ -60,7 +57,7 @@ eui64_mt6(const struct sk_buff *skb, const struct net_device *in,
60 57
61static struct xt_match eui64_mt6_reg __read_mostly = { 58static struct xt_match eui64_mt6_reg __read_mostly = {
62 .name = "eui64", 59 .name = "eui64",
63 .family = AF_INET6, 60 .family = NFPROTO_IPV6,
64 .match = eui64_mt6, 61 .match = eui64_mt6,
65 .matchsize = sizeof(int), 62 .matchsize = sizeof(int),
66 .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) | 63 .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) |
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
index e2bbc63dba5b..673aa0a5084e 100644
--- a/net/ipv6/netfilter/ip6t_frag.c
+++ b/net/ipv6/netfilter/ip6t_frag.c
@@ -35,27 +35,24 @@ id_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
35} 35}
36 36
37static bool 37static bool
38frag_mt6(const struct sk_buff *skb, const struct net_device *in, 38frag_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
39 const struct net_device *out, const struct xt_match *match,
40 const void *matchinfo, int offset, unsigned int protoff,
41 bool *hotdrop)
42{ 39{
43 struct frag_hdr _frag; 40 struct frag_hdr _frag;
44 const struct frag_hdr *fh; 41 const struct frag_hdr *fh;
45 const struct ip6t_frag *fraginfo = matchinfo; 42 const struct ip6t_frag *fraginfo = par->matchinfo;
46 unsigned int ptr; 43 unsigned int ptr;
47 int err; 44 int err;
48 45
49 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL); 46 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL);
50 if (err < 0) { 47 if (err < 0) {
51 if (err != -ENOENT) 48 if (err != -ENOENT)
52 *hotdrop = true; 49 *par->hotdrop = true;
53 return false; 50 return false;
54 } 51 }
55 52
56 fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); 53 fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
57 if (fh == NULL) { 54 if (fh == NULL) {
58 *hotdrop = true; 55 *par->hotdrop = true;
59 return false; 56 return false;
60 } 57 }
61 58
@@ -110,13 +107,9 @@ frag_mt6(const struct sk_buff *skb, const struct net_device *in,
110 && (ntohs(fh->frag_off) & IP6_MF)); 107 && (ntohs(fh->frag_off) & IP6_MF));
111} 108}
112 109
113/* Called when user tries to insert an entry of this type. */ 110static bool frag_mt6_check(const struct xt_mtchk_param *par)
114static bool
115frag_mt6_check(const char *tablename, const void *ip,
116 const struct xt_match *match, void *matchinfo,
117 unsigned int hook_mask)
118{ 111{
119 const struct ip6t_frag *fraginfo = matchinfo; 112 const struct ip6t_frag *fraginfo = par->matchinfo;
120 113
121 if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) { 114 if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) {
122 pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags); 115 pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags);
@@ -127,7 +120,7 @@ frag_mt6_check(const char *tablename, const void *ip,
127 120
128static struct xt_match frag_mt6_reg __read_mostly = { 121static struct xt_match frag_mt6_reg __read_mostly = {
129 .name = "frag", 122 .name = "frag",
130 .family = AF_INET6, 123 .family = NFPROTO_IPV6,
131 .match = frag_mt6, 124 .match = frag_mt6,
132 .matchsize = sizeof(struct ip6t_frag), 125 .matchsize = sizeof(struct ip6t_frag),
133 .checkentry = frag_mt6_check, 126 .checkentry = frag_mt6_check,
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c
index 26654b26d7fa..cbe8dec9744b 100644
--- a/net/ipv6/netfilter/ip6t_hbh.c
+++ b/net/ipv6/netfilter/ip6t_hbh.c
@@ -42,14 +42,11 @@ MODULE_ALIAS("ip6t_dst");
42 */ 42 */
43 43
44static bool 44static bool
45hbh_mt6(const struct sk_buff *skb, const struct net_device *in, 45hbh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
46 const struct net_device *out, const struct xt_match *match,
47 const void *matchinfo, int offset, unsigned int protoff,
48 bool *hotdrop)
49{ 46{
50 struct ipv6_opt_hdr _optsh; 47 struct ipv6_opt_hdr _optsh;
51 const struct ipv6_opt_hdr *oh; 48 const struct ipv6_opt_hdr *oh;
52 const struct ip6t_opts *optinfo = matchinfo; 49 const struct ip6t_opts *optinfo = par->matchinfo;
53 unsigned int temp; 50 unsigned int temp;
54 unsigned int ptr; 51 unsigned int ptr;
55 unsigned int hdrlen = 0; 52 unsigned int hdrlen = 0;
@@ -61,16 +58,16 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in,
61 unsigned int optlen; 58 unsigned int optlen;
62 int err; 59 int err;
63 60
64 err = ipv6_find_hdr(skb, &ptr, match->data, NULL); 61 err = ipv6_find_hdr(skb, &ptr, par->match->data, NULL);
65 if (err < 0) { 62 if (err < 0) {
66 if (err != -ENOENT) 63 if (err != -ENOENT)
67 *hotdrop = true; 64 *par->hotdrop = true;
68 return false; 65 return false;
69 } 66 }
70 67
71 oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh); 68 oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
72 if (oh == NULL) { 69 if (oh == NULL) {
73 *hotdrop = true; 70 *par->hotdrop = true;
74 return false; 71 return false;
75 } 72 }
76 73
@@ -163,13 +160,9 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in,
163 return false; 160 return false;
164} 161}
165 162
166/* Called when user tries to insert an entry of this type. */ 163static bool hbh_mt6_check(const struct xt_mtchk_param *par)
167static bool
168hbh_mt6_check(const char *tablename, const void *entry,
169 const struct xt_match *match, void *matchinfo,
170 unsigned int hook_mask)
171{ 164{
172 const struct ip6t_opts *optsinfo = matchinfo; 165 const struct ip6t_opts *optsinfo = par->matchinfo;
173 166
174 if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) { 167 if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
175 pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags); 168 pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
@@ -187,7 +180,7 @@ hbh_mt6_check(const char *tablename, const void *entry,
187static struct xt_match hbh_mt6_reg[] __read_mostly = { 180static struct xt_match hbh_mt6_reg[] __read_mostly = {
188 { 181 {
189 .name = "hbh", 182 .name = "hbh",
190 .family = AF_INET6, 183 .family = NFPROTO_IPV6,
191 .match = hbh_mt6, 184 .match = hbh_mt6,
192 .matchsize = sizeof(struct ip6t_opts), 185 .matchsize = sizeof(struct ip6t_opts),
193 .checkentry = hbh_mt6_check, 186 .checkentry = hbh_mt6_check,
@@ -196,7 +189,7 @@ static struct xt_match hbh_mt6_reg[] __read_mostly = {
196 }, 189 },
197 { 190 {
198 .name = "dst", 191 .name = "dst",
199 .family = AF_INET6, 192 .family = NFPROTO_IPV6,
200 .match = hbh_mt6, 193 .match = hbh_mt6,
201 .matchsize = sizeof(struct ip6t_opts), 194 .matchsize = sizeof(struct ip6t_opts),
202 .checkentry = hbh_mt6_check, 195 .checkentry = hbh_mt6_check,
diff --git a/net/ipv6/netfilter/ip6t_hl.c b/net/ipv6/netfilter/ip6t_hl.c
index 345671673845..c964dca1132d 100644
--- a/net/ipv6/netfilter/ip6t_hl.c
+++ b/net/ipv6/netfilter/ip6t_hl.c
@@ -19,12 +19,9 @@ MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
19MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field match"); 19MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field match");
20MODULE_LICENSE("GPL"); 20MODULE_LICENSE("GPL");
21 21
22static bool 22static bool hl_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
23hl_mt6(const struct sk_buff *skb, const struct net_device *in,
24 const struct net_device *out, const struct xt_match *match,
25 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
26{ 23{
27 const struct ip6t_hl_info *info = matchinfo; 24 const struct ip6t_hl_info *info = par->matchinfo;
28 const struct ipv6hdr *ip6h = ipv6_hdr(skb); 25 const struct ipv6hdr *ip6h = ipv6_hdr(skb);
29 26
30 switch (info->mode) { 27 switch (info->mode) {
@@ -51,7 +48,7 @@ hl_mt6(const struct sk_buff *skb, const struct net_device *in,
51 48
52static struct xt_match hl_mt6_reg __read_mostly = { 49static struct xt_match hl_mt6_reg __read_mostly = {
53 .name = "hl", 50 .name = "hl",
54 .family = AF_INET6, 51 .family = NFPROTO_IPV6,
55 .match = hl_mt6, 52 .match = hl_mt6,
56 .matchsize = sizeof(struct ip6t_hl_info), 53 .matchsize = sizeof(struct ip6t_hl_info),
57 .me = THIS_MODULE, 54 .me = THIS_MODULE,
diff --git a/net/ipv6/netfilter/ip6t_ipv6header.c b/net/ipv6/netfilter/ip6t_ipv6header.c
index 317a8960a757..14e6724d5672 100644
--- a/net/ipv6/netfilter/ip6t_ipv6header.c
+++ b/net/ipv6/netfilter/ip6t_ipv6header.c
@@ -27,12 +27,9 @@ MODULE_DESCRIPTION("Xtables: IPv6 header types match");
27MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); 27MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
28 28
29static bool 29static bool
30ipv6header_mt6(const struct sk_buff *skb, const struct net_device *in, 30ipv6header_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
31 const struct net_device *out, const struct xt_match *match,
32 const void *matchinfo, int offset, unsigned int protoff,
33 bool *hotdrop)
34{ 31{
35 const struct ip6t_ipv6header_info *info = matchinfo; 32 const struct ip6t_ipv6header_info *info = par->matchinfo;
36 unsigned int temp; 33 unsigned int temp;
37 int len; 34 int len;
38 u8 nexthdr; 35 u8 nexthdr;
@@ -121,12 +118,9 @@ ipv6header_mt6(const struct sk_buff *skb, const struct net_device *in,
121 } 118 }
122} 119}
123 120
124static bool 121static bool ipv6header_mt6_check(const struct xt_mtchk_param *par)
125ipv6header_mt6_check(const char *tablename, const void *ip,
126 const struct xt_match *match, void *matchinfo,
127 unsigned int hook_mask)
128{ 122{
129 const struct ip6t_ipv6header_info *info = matchinfo; 123 const struct ip6t_ipv6header_info *info = par->matchinfo;
130 124
131 /* invflags is 0 or 0xff in hard mode */ 125 /* invflags is 0 or 0xff in hard mode */
132 if ((!info->modeflag) && info->invflags != 0x00 && 126 if ((!info->modeflag) && info->invflags != 0x00 &&
@@ -138,7 +132,7 @@ ipv6header_mt6_check(const char *tablename, const void *ip,
138 132
139static struct xt_match ipv6header_mt6_reg __read_mostly = { 133static struct xt_match ipv6header_mt6_reg __read_mostly = {
140 .name = "ipv6header", 134 .name = "ipv6header",
141 .family = AF_INET6, 135 .family = NFPROTO_IPV6,
142 .match = ipv6header_mt6, 136 .match = ipv6header_mt6,
143 .matchsize = sizeof(struct ip6t_ipv6header_info), 137 .matchsize = sizeof(struct ip6t_ipv6header_info),
144 .checkentry = ipv6header_mt6_check, 138 .checkentry = ipv6header_mt6_check,
diff --git a/net/ipv6/netfilter/ip6t_mh.c b/net/ipv6/netfilter/ip6t_mh.c
index e06678d07ec8..aafe4e66577b 100644
--- a/net/ipv6/netfilter/ip6t_mh.c
+++ b/net/ipv6/netfilter/ip6t_mh.c
@@ -37,32 +37,29 @@ type_match(u_int8_t min, u_int8_t max, u_int8_t type, bool invert)
37 return (type >= min && type <= max) ^ invert; 37 return (type >= min && type <= max) ^ invert;
38} 38}
39 39
40static bool 40static bool mh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
41mh_mt6(const struct sk_buff *skb, const struct net_device *in,
42 const struct net_device *out, const struct xt_match *match,
43 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
44{ 41{
45 struct ip6_mh _mh; 42 struct ip6_mh _mh;
46 const struct ip6_mh *mh; 43 const struct ip6_mh *mh;
47 const struct ip6t_mh *mhinfo = matchinfo; 44 const struct ip6t_mh *mhinfo = par->matchinfo;
48 45
49 /* Must not be a fragment. */ 46 /* Must not be a fragment. */
50 if (offset) 47 if (par->fragoff != 0)
51 return false; 48 return false;
52 49
53 mh = skb_header_pointer(skb, protoff, sizeof(_mh), &_mh); 50 mh = skb_header_pointer(skb, par->thoff, sizeof(_mh), &_mh);
54 if (mh == NULL) { 51 if (mh == NULL) {
55 /* We've been asked to examine this packet, and we 52 /* We've been asked to examine this packet, and we
56 can't. Hence, no choice but to drop. */ 53 can't. Hence, no choice but to drop. */
57 duprintf("Dropping evil MH tinygram.\n"); 54 duprintf("Dropping evil MH tinygram.\n");
58 *hotdrop = true; 55 *par->hotdrop = true;
59 return false; 56 return false;
60 } 57 }
61 58
62 if (mh->ip6mh_proto != IPPROTO_NONE) { 59 if (mh->ip6mh_proto != IPPROTO_NONE) {
63 duprintf("Dropping invalid MH Payload Proto: %u\n", 60 duprintf("Dropping invalid MH Payload Proto: %u\n",
64 mh->ip6mh_proto); 61 mh->ip6mh_proto);
65 *hotdrop = true; 62 *par->hotdrop = true;
66 return false; 63 return false;
67 } 64 }
68 65
@@ -70,13 +67,9 @@ mh_mt6(const struct sk_buff *skb, const struct net_device *in,
70 !!(mhinfo->invflags & IP6T_MH_INV_TYPE)); 67 !!(mhinfo->invflags & IP6T_MH_INV_TYPE));
71} 68}
72 69
73/* Called when user tries to insert an entry of this type. */ 70static bool mh_mt6_check(const struct xt_mtchk_param *par)
74static bool
75mh_mt6_check(const char *tablename, const void *entry,
76 const struct xt_match *match, void *matchinfo,
77 unsigned int hook_mask)
78{ 71{
79 const struct ip6t_mh *mhinfo = matchinfo; 72 const struct ip6t_mh *mhinfo = par->matchinfo;
80 73
81 /* Must specify no unknown invflags */ 74 /* Must specify no unknown invflags */
82 return !(mhinfo->invflags & ~IP6T_MH_INV_MASK); 75 return !(mhinfo->invflags & ~IP6T_MH_INV_MASK);
@@ -84,7 +77,7 @@ mh_mt6_check(const char *tablename, const void *entry,
84 77
85static struct xt_match mh_mt6_reg __read_mostly = { 78static struct xt_match mh_mt6_reg __read_mostly = {
86 .name = "mh", 79 .name = "mh",
87 .family = AF_INET6, 80 .family = NFPROTO_IPV6,
88 .checkentry = mh_mt6_check, 81 .checkentry = mh_mt6_check,
89 .match = mh_mt6, 82 .match = mh_mt6,
90 .matchsize = sizeof(struct ip6t_mh), 83 .matchsize = sizeof(struct ip6t_mh),
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index 81aaf7aaaabf..356b8d6f6baa 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -36,14 +36,11 @@ segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
36 return r; 36 return r;
37} 37}
38 38
39static bool 39static bool rt_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
40rt_mt6(const struct sk_buff *skb, const struct net_device *in,
41 const struct net_device *out, const struct xt_match *match,
42 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
43{ 40{
44 struct ipv6_rt_hdr _route; 41 struct ipv6_rt_hdr _route;
45 const struct ipv6_rt_hdr *rh; 42 const struct ipv6_rt_hdr *rh;
46 const struct ip6t_rt *rtinfo = matchinfo; 43 const struct ip6t_rt *rtinfo = par->matchinfo;
47 unsigned int temp; 44 unsigned int temp;
48 unsigned int ptr; 45 unsigned int ptr;
49 unsigned int hdrlen = 0; 46 unsigned int hdrlen = 0;
@@ -55,13 +52,13 @@ rt_mt6(const struct sk_buff *skb, const struct net_device *in,
55 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL); 52 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL);
56 if (err < 0) { 53 if (err < 0) {
57 if (err != -ENOENT) 54 if (err != -ENOENT)
58 *hotdrop = true; 55 *par->hotdrop = true;
59 return false; 56 return false;
60 } 57 }
61 58
62 rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); 59 rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
63 if (rh == NULL) { 60 if (rh == NULL) {
64 *hotdrop = true; 61 *par->hotdrop = true;
65 return false; 62 return false;
66 } 63 }
67 64
@@ -189,13 +186,9 @@ rt_mt6(const struct sk_buff *skb, const struct net_device *in,
189 return false; 186 return false;
190} 187}
191 188
192/* Called when user tries to insert an entry of this type. */ 189static bool rt_mt6_check(const struct xt_mtchk_param *par)
193static bool
194rt_mt6_check(const char *tablename, const void *entry,
195 const struct xt_match *match, void *matchinfo,
196 unsigned int hook_mask)
197{ 190{
198 const struct ip6t_rt *rtinfo = matchinfo; 191 const struct ip6t_rt *rtinfo = par->matchinfo;
199 192
200 if (rtinfo->invflags & ~IP6T_RT_INV_MASK) { 193 if (rtinfo->invflags & ~IP6T_RT_INV_MASK) {
201 pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags); 194 pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags);
@@ -214,7 +207,7 @@ rt_mt6_check(const char *tablename, const void *entry,
214 207
215static struct xt_match rt_mt6_reg __read_mostly = { 208static struct xt_match rt_mt6_reg __read_mostly = {
216 .name = "rt", 209 .name = "rt",
217 .family = AF_INET6, 210 .family = NFPROTO_IPV6,
218 .match = rt_mt6, 211 .match = rt_mt6,
219 .matchsize = sizeof(struct ip6t_rt), 212 .matchsize = sizeof(struct ip6t_rt),
220 .checkentry = rt_mt6_check, 213 .checkentry = rt_mt6_check,
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 55a2c290bad4..b110a8a85a14 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -68,7 +68,7 @@ ip6t_local_in_hook(unsigned int hook,
68 int (*okfn)(struct sk_buff *)) 68 int (*okfn)(struct sk_buff *))
69{ 69{
70 return ip6t_do_table(skb, hook, in, out, 70 return ip6t_do_table(skb, hook, in, out,
71 nf_local_in_net(in, out)->ipv6.ip6table_filter); 71 dev_net(in)->ipv6.ip6table_filter);
72} 72}
73 73
74static unsigned int 74static unsigned int
@@ -79,7 +79,7 @@ ip6t_forward_hook(unsigned int hook,
79 int (*okfn)(struct sk_buff *)) 79 int (*okfn)(struct sk_buff *))
80{ 80{
81 return ip6t_do_table(skb, hook, in, out, 81 return ip6t_do_table(skb, hook, in, out,
82 nf_forward_net(in, out)->ipv6.ip6table_filter); 82 dev_net(in)->ipv6.ip6table_filter);
83} 83}
84 84
85static unsigned int 85static unsigned int
@@ -100,7 +100,7 @@ ip6t_local_out_hook(unsigned int hook,
100#endif 100#endif
101 101
102 return ip6t_do_table(skb, hook, in, out, 102 return ip6t_do_table(skb, hook, in, out,
103 nf_local_out_net(in, out)->ipv6.ip6table_filter); 103 dev_net(out)->ipv6.ip6table_filter);
104} 104}
105 105
106static struct nf_hook_ops ip6t_ops[] __read_mostly = { 106static struct nf_hook_ops ip6t_ops[] __read_mostly = {
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index f405cea21a8b..d0b31b259d4d 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -67,17 +67,29 @@ static struct xt_table packet_mangler = {
67 67
68/* The work comes in here from netfilter.c. */ 68/* The work comes in here from netfilter.c. */
69static unsigned int 69static unsigned int
70ip6t_route_hook(unsigned int hook, 70ip6t_in_hook(unsigned int hook,
71 struct sk_buff *skb, 71 struct sk_buff *skb,
72 const struct net_device *in, 72 const struct net_device *in,
73 const struct net_device *out, 73 const struct net_device *out,
74 int (*okfn)(struct sk_buff *)) 74 int (*okfn)(struct sk_buff *))
75{ 75{
76 return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle); 76 return ip6t_do_table(skb, hook, in, out,
77 dev_net(in)->ipv6.ip6table_mangle);
77} 78}
78 79
79static unsigned int 80static unsigned int
80ip6t_local_hook(unsigned int hook, 81ip6t_post_routing_hook(unsigned int hook,
82 struct sk_buff *skb,
83 const struct net_device *in,
84 const struct net_device *out,
85 int (*okfn)(struct sk_buff *))
86{
87 return ip6t_do_table(skb, hook, in, out,
88 dev_net(out)->ipv6.ip6table_mangle);
89}
90
91static unsigned int
92ip6t_local_out_hook(unsigned int hook,
81 struct sk_buff *skb, 93 struct sk_buff *skb,
82 const struct net_device *in, 94 const struct net_device *in,
83 const struct net_device *out, 95 const struct net_device *out,
@@ -108,7 +120,8 @@ ip6t_local_hook(unsigned int hook,
108 /* flowlabel and prio (includes version, which shouldn't change either */ 120 /* flowlabel and prio (includes version, which shouldn't change either */
109 flowlabel = *((u_int32_t *)ipv6_hdr(skb)); 121 flowlabel = *((u_int32_t *)ipv6_hdr(skb));
110 122
111 ret = ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle); 123 ret = ip6t_do_table(skb, hook, in, out,
124 dev_net(out)->ipv6.ip6table_mangle);
112 125
113 if (ret != NF_DROP && ret != NF_STOLEN 126 if (ret != NF_DROP && ret != NF_STOLEN
114 && (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) 127 && (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr))
@@ -122,35 +135,35 @@ ip6t_local_hook(unsigned int hook,
122 135
123static struct nf_hook_ops ip6t_ops[] __read_mostly = { 136static struct nf_hook_ops ip6t_ops[] __read_mostly = {
124 { 137 {
125 .hook = ip6t_route_hook, 138 .hook = ip6t_in_hook,
126 .owner = THIS_MODULE, 139 .owner = THIS_MODULE,
127 .pf = PF_INET6, 140 .pf = PF_INET6,
128 .hooknum = NF_INET_PRE_ROUTING, 141 .hooknum = NF_INET_PRE_ROUTING,
129 .priority = NF_IP6_PRI_MANGLE, 142 .priority = NF_IP6_PRI_MANGLE,
130 }, 143 },
131 { 144 {
132 .hook = ip6t_route_hook, 145 .hook = ip6t_in_hook,
133 .owner = THIS_MODULE, 146 .owner = THIS_MODULE,
134 .pf = PF_INET6, 147 .pf = PF_INET6,
135 .hooknum = NF_INET_LOCAL_IN, 148 .hooknum = NF_INET_LOCAL_IN,
136 .priority = NF_IP6_PRI_MANGLE, 149 .priority = NF_IP6_PRI_MANGLE,
137 }, 150 },
138 { 151 {
139 .hook = ip6t_route_hook, 152 .hook = ip6t_in_hook,
140 .owner = THIS_MODULE, 153 .owner = THIS_MODULE,
141 .pf = PF_INET6, 154 .pf = PF_INET6,
142 .hooknum = NF_INET_FORWARD, 155 .hooknum = NF_INET_FORWARD,
143 .priority = NF_IP6_PRI_MANGLE, 156 .priority = NF_IP6_PRI_MANGLE,
144 }, 157 },
145 { 158 {
146 .hook = ip6t_local_hook, 159 .hook = ip6t_local_out_hook,
147 .owner = THIS_MODULE, 160 .owner = THIS_MODULE,
148 .pf = PF_INET6, 161 .pf = PF_INET6,
149 .hooknum = NF_INET_LOCAL_OUT, 162 .hooknum = NF_INET_LOCAL_OUT,
150 .priority = NF_IP6_PRI_MANGLE, 163 .priority = NF_IP6_PRI_MANGLE,
151 }, 164 },
152 { 165 {
153 .hook = ip6t_route_hook, 166 .hook = ip6t_post_routing_hook,
154 .owner = THIS_MODULE, 167 .owner = THIS_MODULE,
155 .pf = PF_INET6, 168 .pf = PF_INET6,
156 .hooknum = NF_INET_POST_ROUTING, 169 .hooknum = NF_INET_POST_ROUTING,
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index 92b91077ac29..109fab6f831a 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -45,25 +45,37 @@ static struct xt_table packet_raw = {
45 45
46/* The work comes in here from netfilter.c. */ 46/* The work comes in here from netfilter.c. */
47static unsigned int 47static unsigned int
48ip6t_hook(unsigned int hook, 48ip6t_pre_routing_hook(unsigned int hook,
49 struct sk_buff *skb, 49 struct sk_buff *skb,
50 const struct net_device *in, 50 const struct net_device *in,
51 const struct net_device *out, 51 const struct net_device *out,
52 int (*okfn)(struct sk_buff *)) 52 int (*okfn)(struct sk_buff *))
53{ 53{
54 return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_raw); 54 return ip6t_do_table(skb, hook, in, out,
55 dev_net(in)->ipv6.ip6table_raw);
56}
57
58static unsigned int
59ip6t_local_out_hook(unsigned int hook,
60 struct sk_buff *skb,
61 const struct net_device *in,
62 const struct net_device *out,
63 int (*okfn)(struct sk_buff *))
64{
65 return ip6t_do_table(skb, hook, in, out,
66 dev_net(out)->ipv6.ip6table_raw);
55} 67}
56 68
57static struct nf_hook_ops ip6t_ops[] __read_mostly = { 69static struct nf_hook_ops ip6t_ops[] __read_mostly = {
58 { 70 {
59 .hook = ip6t_hook, 71 .hook = ip6t_pre_routing_hook,
60 .pf = PF_INET6, 72 .pf = PF_INET6,
61 .hooknum = NF_INET_PRE_ROUTING, 73 .hooknum = NF_INET_PRE_ROUTING,
62 .priority = NF_IP6_PRI_FIRST, 74 .priority = NF_IP6_PRI_FIRST,
63 .owner = THIS_MODULE, 75 .owner = THIS_MODULE,
64 }, 76 },
65 { 77 {
66 .hook = ip6t_hook, 78 .hook = ip6t_local_out_hook,
67 .pf = PF_INET6, 79 .pf = PF_INET6,
68 .hooknum = NF_INET_LOCAL_OUT, 80 .hooknum = NF_INET_LOCAL_OUT,
69 .priority = NF_IP6_PRI_FIRST, 81 .priority = NF_IP6_PRI_FIRST,
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
index 6e7131036bc6..20bc52f13e43 100644
--- a/net/ipv6/netfilter/ip6table_security.c
+++ b/net/ipv6/netfilter/ip6table_security.c
@@ -72,7 +72,7 @@ ip6t_local_in_hook(unsigned int hook,
72 int (*okfn)(struct sk_buff *)) 72 int (*okfn)(struct sk_buff *))
73{ 73{
74 return ip6t_do_table(skb, hook, in, out, 74 return ip6t_do_table(skb, hook, in, out,
75 nf_local_in_net(in, out)->ipv6.ip6table_security); 75 dev_net(in)->ipv6.ip6table_security);
76} 76}
77 77
78static unsigned int 78static unsigned int
@@ -83,7 +83,7 @@ ip6t_forward_hook(unsigned int hook,
83 int (*okfn)(struct sk_buff *)) 83 int (*okfn)(struct sk_buff *))
84{ 84{
85 return ip6t_do_table(skb, hook, in, out, 85 return ip6t_do_table(skb, hook, in, out,
86 nf_forward_net(in, out)->ipv6.ip6table_security); 86 dev_net(in)->ipv6.ip6table_security);
87} 87}
88 88
89static unsigned int 89static unsigned int
@@ -95,7 +95,7 @@ ip6t_local_out_hook(unsigned int hook,
95{ 95{
96 /* TBD: handle short packets via raw socket */ 96 /* TBD: handle short packets via raw socket */
97 return ip6t_do_table(skb, hook, in, out, 97 return ip6t_do_table(skb, hook, in, out,
98 nf_local_out_net(in, out)->ipv6.ip6table_security); 98 dev_net(out)->ipv6.ip6table_security);
99} 99}
100 100
101static struct nf_hook_ops ip6t_ops[] __read_mostly = { 101static struct nf_hook_ops ip6t_ops[] __read_mostly = {
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 85050c072abd..e91db16611d9 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -211,11 +211,10 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
211 return NF_STOLEN; 211 return NF_STOLEN;
212} 212}
213 213
214static unsigned int ipv6_conntrack_in(unsigned int hooknum, 214static unsigned int __ipv6_conntrack_in(struct net *net,
215 struct sk_buff *skb, 215 unsigned int hooknum,
216 const struct net_device *in, 216 struct sk_buff *skb,
217 const struct net_device *out, 217 int (*okfn)(struct sk_buff *))
218 int (*okfn)(struct sk_buff *))
219{ 218{
220 struct sk_buff *reasm = skb->nfct_reasm; 219 struct sk_buff *reasm = skb->nfct_reasm;
221 220
@@ -225,7 +224,7 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
225 if (!reasm->nfct) { 224 if (!reasm->nfct) {
226 unsigned int ret; 225 unsigned int ret;
227 226
228 ret = nf_conntrack_in(PF_INET6, hooknum, reasm); 227 ret = nf_conntrack_in(net, PF_INET6, hooknum, reasm);
229 if (ret != NF_ACCEPT) 228 if (ret != NF_ACCEPT)
230 return ret; 229 return ret;
231 } 230 }
@@ -235,7 +234,16 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
235 return NF_ACCEPT; 234 return NF_ACCEPT;
236 } 235 }
237 236
238 return nf_conntrack_in(PF_INET6, hooknum, skb); 237 return nf_conntrack_in(net, PF_INET6, hooknum, skb);
238}
239
240static unsigned int ipv6_conntrack_in(unsigned int hooknum,
241 struct sk_buff *skb,
242 const struct net_device *in,
243 const struct net_device *out,
244 int (*okfn)(struct sk_buff *))
245{
246 return __ipv6_conntrack_in(dev_net(in), hooknum, skb, okfn);
239} 247}
240 248
241static unsigned int ipv6_conntrack_local(unsigned int hooknum, 249static unsigned int ipv6_conntrack_local(unsigned int hooknum,
@@ -250,7 +258,7 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum,
250 printk("ipv6_conntrack_local: packet too short\n"); 258 printk("ipv6_conntrack_local: packet too short\n");
251 return NF_ACCEPT; 259 return NF_ACCEPT;
252 } 260 }
253 return ipv6_conntrack_in(hooknum, skb, in, out, okfn); 261 return __ipv6_conntrack_in(dev_net(out), hooknum, skb, okfn);
254} 262}
255 263
256static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { 264static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 14d47d833545..05726177903f 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -81,7 +81,7 @@ static int icmpv6_packet(struct nf_conn *ct,
81 const struct sk_buff *skb, 81 const struct sk_buff *skb,
82 unsigned int dataoff, 82 unsigned int dataoff,
83 enum ip_conntrack_info ctinfo, 83 enum ip_conntrack_info ctinfo,
84 int pf, 84 u_int8_t pf,
85 unsigned int hooknum) 85 unsigned int hooknum)
86{ 86{
87 /* Try to delete connection immediately after all replies: 87 /* Try to delete connection immediately after all replies:
@@ -93,7 +93,7 @@ static int icmpv6_packet(struct nf_conn *ct,
93 nf_ct_kill_acct(ct, ctinfo, skb); 93 nf_ct_kill_acct(ct, ctinfo, skb);
94 } else { 94 } else {
95 atomic_inc(&ct->proto.icmp.count); 95 atomic_inc(&ct->proto.icmp.count);
96 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb); 96 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct);
97 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout); 97 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout);
98 } 98 }
99 99
@@ -122,7 +122,8 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb,
122} 122}
123 123
124static int 124static int
125icmpv6_error_message(struct sk_buff *skb, 125icmpv6_error_message(struct net *net,
126 struct sk_buff *skb,
126 unsigned int icmp6off, 127 unsigned int icmp6off,
127 enum ip_conntrack_info *ctinfo, 128 enum ip_conntrack_info *ctinfo,
128 unsigned int hooknum) 129 unsigned int hooknum)
@@ -156,7 +157,7 @@ icmpv6_error_message(struct sk_buff *skb,
156 157
157 *ctinfo = IP_CT_RELATED; 158 *ctinfo = IP_CT_RELATED;
158 159
159 h = nf_conntrack_find_get(&intuple); 160 h = nf_conntrack_find_get(net, &intuple);
160 if (!h) { 161 if (!h) {
161 pr_debug("icmpv6_error: no match\n"); 162 pr_debug("icmpv6_error: no match\n");
162 return -NF_ACCEPT; 163 return -NF_ACCEPT;
@@ -172,21 +173,21 @@ icmpv6_error_message(struct sk_buff *skb,
172} 173}
173 174
174static int 175static int
175icmpv6_error(struct sk_buff *skb, unsigned int dataoff, 176icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
176 enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum) 177 enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum)
177{ 178{
178 const struct icmp6hdr *icmp6h; 179 const struct icmp6hdr *icmp6h;
179 struct icmp6hdr _ih; 180 struct icmp6hdr _ih;
180 181
181 icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih); 182 icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih);
182 if (icmp6h == NULL) { 183 if (icmp6h == NULL) {
183 if (LOG_INVALID(IPPROTO_ICMPV6)) 184 if (LOG_INVALID(net, IPPROTO_ICMPV6))
184 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, 185 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
185 "nf_ct_icmpv6: short packet "); 186 "nf_ct_icmpv6: short packet ");
186 return -NF_ACCEPT; 187 return -NF_ACCEPT;
187 } 188 }
188 189
189 if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && 190 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
190 nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) { 191 nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) {
191 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, 192 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
192 "nf_ct_icmpv6: ICMPv6 checksum failed\n"); 193 "nf_ct_icmpv6: ICMPv6 checksum failed\n");
@@ -197,7 +198,7 @@ icmpv6_error(struct sk_buff *skb, unsigned int dataoff,
197 if (icmp6h->icmp6_type >= 128) 198 if (icmp6h->icmp6_type >= 128)
198 return NF_ACCEPT; 199 return NF_ACCEPT;
199 200
200 return icmpv6_error_message(skb, dataoff, ctinfo, hooknum); 201 return icmpv6_error_message(net, skb, dataoff, ctinfo, hooknum);
201} 202}
202 203
203#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 204#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index ee898e74808d..f70b4145ffc7 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -38,10 +38,11 @@ config NF_CONNTRACK
38 38
39 To compile it as a module, choose M here. If unsure, say N. 39 To compile it as a module, choose M here. If unsure, say N.
40 40
41if NF_CONNTRACK
42
41config NF_CT_ACCT 43config NF_CT_ACCT
42 bool "Connection tracking flow accounting" 44 bool "Connection tracking flow accounting"
43 depends on NETFILTER_ADVANCED 45 depends on NETFILTER_ADVANCED
44 depends on NF_CONNTRACK
45 help 46 help
46 If this option is enabled, the connection tracking code will 47 If this option is enabled, the connection tracking code will
47 keep per-flow packet and byte counters. 48 keep per-flow packet and byte counters.
@@ -63,7 +64,6 @@ config NF_CT_ACCT
63config NF_CONNTRACK_MARK 64config NF_CONNTRACK_MARK
64 bool 'Connection mark tracking support' 65 bool 'Connection mark tracking support'
65 depends on NETFILTER_ADVANCED 66 depends on NETFILTER_ADVANCED
66 depends on NF_CONNTRACK
67 help 67 help
68 This option enables support for connection marks, used by the 68 This option enables support for connection marks, used by the
69 `CONNMARK' target and `connmark' match. Similar to the mark value 69 `CONNMARK' target and `connmark' match. Similar to the mark value
@@ -72,7 +72,7 @@ config NF_CONNTRACK_MARK
72 72
73config NF_CONNTRACK_SECMARK 73config NF_CONNTRACK_SECMARK
74 bool 'Connection tracking security mark support' 74 bool 'Connection tracking security mark support'
75 depends on NF_CONNTRACK && NETWORK_SECMARK 75 depends on NETWORK_SECMARK
76 default m if NETFILTER_ADVANCED=n 76 default m if NETFILTER_ADVANCED=n
77 help 77 help
78 This option enables security markings to be applied to 78 This option enables security markings to be applied to
@@ -85,7 +85,6 @@ config NF_CONNTRACK_SECMARK
85 85
86config NF_CONNTRACK_EVENTS 86config NF_CONNTRACK_EVENTS
87 bool "Connection tracking events" 87 bool "Connection tracking events"
88 depends on NF_CONNTRACK
89 depends on NETFILTER_ADVANCED 88 depends on NETFILTER_ADVANCED
90 help 89 help
91 If this option is enabled, the connection tracking code will 90 If this option is enabled, the connection tracking code will
@@ -96,7 +95,7 @@ config NF_CONNTRACK_EVENTS
96 95
97config NF_CT_PROTO_DCCP 96config NF_CT_PROTO_DCCP
98 tristate 'DCCP protocol connection tracking support (EXPERIMENTAL)' 97 tristate 'DCCP protocol connection tracking support (EXPERIMENTAL)'
99 depends on EXPERIMENTAL && NF_CONNTRACK 98 depends on EXPERIMENTAL
100 depends on NETFILTER_ADVANCED 99 depends on NETFILTER_ADVANCED
101 default IP_DCCP 100 default IP_DCCP
102 help 101 help
@@ -107,11 +106,10 @@ config NF_CT_PROTO_DCCP
107 106
108config NF_CT_PROTO_GRE 107config NF_CT_PROTO_GRE
109 tristate 108 tristate
110 depends on NF_CONNTRACK
111 109
112config NF_CT_PROTO_SCTP 110config NF_CT_PROTO_SCTP
113 tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)' 111 tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)'
114 depends on EXPERIMENTAL && NF_CONNTRACK 112 depends on EXPERIMENTAL
115 depends on NETFILTER_ADVANCED 113 depends on NETFILTER_ADVANCED
116 default IP_SCTP 114 default IP_SCTP
117 help 115 help
@@ -123,7 +121,6 @@ config NF_CT_PROTO_SCTP
123 121
124config NF_CT_PROTO_UDPLITE 122config NF_CT_PROTO_UDPLITE
125 tristate 'UDP-Lite protocol connection tracking support' 123 tristate 'UDP-Lite protocol connection tracking support'
126 depends on NF_CONNTRACK
127 depends on NETFILTER_ADVANCED 124 depends on NETFILTER_ADVANCED
128 help 125 help
129 With this option enabled, the layer 3 independent connection 126 With this option enabled, the layer 3 independent connection
@@ -134,7 +131,6 @@ config NF_CT_PROTO_UDPLITE
134 131
135config NF_CONNTRACK_AMANDA 132config NF_CONNTRACK_AMANDA
136 tristate "Amanda backup protocol support" 133 tristate "Amanda backup protocol support"
137 depends on NF_CONNTRACK
138 depends on NETFILTER_ADVANCED 134 depends on NETFILTER_ADVANCED
139 select TEXTSEARCH 135 select TEXTSEARCH
140 select TEXTSEARCH_KMP 136 select TEXTSEARCH_KMP
@@ -150,7 +146,6 @@ config NF_CONNTRACK_AMANDA
150 146
151config NF_CONNTRACK_FTP 147config NF_CONNTRACK_FTP
152 tristate "FTP protocol support" 148 tristate "FTP protocol support"
153 depends on NF_CONNTRACK
154 default m if NETFILTER_ADVANCED=n 149 default m if NETFILTER_ADVANCED=n
155 help 150 help
156 Tracking FTP connections is problematic: special helpers are 151 Tracking FTP connections is problematic: special helpers are
@@ -165,7 +160,7 @@ config NF_CONNTRACK_FTP
165 160
166config NF_CONNTRACK_H323 161config NF_CONNTRACK_H323
167 tristate "H.323 protocol support" 162 tristate "H.323 protocol support"
168 depends on NF_CONNTRACK && (IPV6 || IPV6=n) 163 depends on (IPV6 || IPV6=n)
169 depends on NETFILTER_ADVANCED 164 depends on NETFILTER_ADVANCED
170 help 165 help
171 H.323 is a VoIP signalling protocol from ITU-T. As one of the most 166 H.323 is a VoIP signalling protocol from ITU-T. As one of the most
@@ -185,7 +180,6 @@ config NF_CONNTRACK_H323
185 180
186config NF_CONNTRACK_IRC 181config NF_CONNTRACK_IRC
187 tristate "IRC protocol support" 182 tristate "IRC protocol support"
188 depends on NF_CONNTRACK
189 default m if NETFILTER_ADVANCED=n 183 default m if NETFILTER_ADVANCED=n
190 help 184 help
191 There is a commonly-used extension to IRC called 185 There is a commonly-used extension to IRC called
@@ -201,7 +195,6 @@ config NF_CONNTRACK_IRC
201 195
202config NF_CONNTRACK_NETBIOS_NS 196config NF_CONNTRACK_NETBIOS_NS
203 tristate "NetBIOS name service protocol support" 197 tristate "NetBIOS name service protocol support"
204 depends on NF_CONNTRACK
205 depends on NETFILTER_ADVANCED 198 depends on NETFILTER_ADVANCED
206 help 199 help
207 NetBIOS name service requests are sent as broadcast messages from an 200 NetBIOS name service requests are sent as broadcast messages from an
@@ -221,7 +214,6 @@ config NF_CONNTRACK_NETBIOS_NS
221 214
222config NF_CONNTRACK_PPTP 215config NF_CONNTRACK_PPTP
223 tristate "PPtP protocol support" 216 tristate "PPtP protocol support"
224 depends on NF_CONNTRACK
225 depends on NETFILTER_ADVANCED 217 depends on NETFILTER_ADVANCED
226 select NF_CT_PROTO_GRE 218 select NF_CT_PROTO_GRE
227 help 219 help
@@ -241,7 +233,7 @@ config NF_CONNTRACK_PPTP
241 233
242config NF_CONNTRACK_SANE 234config NF_CONNTRACK_SANE
243 tristate "SANE protocol support (EXPERIMENTAL)" 235 tristate "SANE protocol support (EXPERIMENTAL)"
244 depends on EXPERIMENTAL && NF_CONNTRACK 236 depends on EXPERIMENTAL
245 depends on NETFILTER_ADVANCED 237 depends on NETFILTER_ADVANCED
246 help 238 help
247 SANE is a protocol for remote access to scanners as implemented 239 SANE is a protocol for remote access to scanners as implemented
@@ -255,7 +247,6 @@ config NF_CONNTRACK_SANE
255 247
256config NF_CONNTRACK_SIP 248config NF_CONNTRACK_SIP
257 tristate "SIP protocol support" 249 tristate "SIP protocol support"
258 depends on NF_CONNTRACK
259 default m if NETFILTER_ADVANCED=n 250 default m if NETFILTER_ADVANCED=n
260 help 251 help
261 SIP is an application-layer control protocol that can establish, 252 SIP is an application-layer control protocol that can establish,
@@ -268,7 +259,6 @@ config NF_CONNTRACK_SIP
268 259
269config NF_CONNTRACK_TFTP 260config NF_CONNTRACK_TFTP
270 tristate "TFTP protocol support" 261 tristate "TFTP protocol support"
271 depends on NF_CONNTRACK
272 depends on NETFILTER_ADVANCED 262 depends on NETFILTER_ADVANCED
273 help 263 help
274 TFTP connection tracking helper, this is required depending 264 TFTP connection tracking helper, this is required depending
@@ -280,13 +270,29 @@ config NF_CONNTRACK_TFTP
280 270
281config NF_CT_NETLINK 271config NF_CT_NETLINK
282 tristate 'Connection tracking netlink interface' 272 tristate 'Connection tracking netlink interface'
283 depends on NF_CONNTRACK
284 select NETFILTER_NETLINK 273 select NETFILTER_NETLINK
285 depends on NF_NAT=n || NF_NAT 274 depends on NF_NAT=n || NF_NAT
286 default m if NETFILTER_ADVANCED=n 275 default m if NETFILTER_ADVANCED=n
287 help 276 help
288 This option enables support for a netlink-based userspace interface 277 This option enables support for a netlink-based userspace interface
289 278
279# transparent proxy support
280config NETFILTER_TPROXY
281 tristate "Transparent proxying support (EXPERIMENTAL)"
282 depends on EXPERIMENTAL
283 depends on IP_NF_MANGLE
284 depends on NETFILTER_ADVANCED
285 help
286 This option enables transparent proxying support, that is,
287 support for handling non-locally bound IPv4 TCP and UDP sockets.
288 For it to work you will have to configure certain iptables rules
289 and use policy routing. For more information on how to set it up
290 see Documentation/networking/tproxy.txt.
291
292 To compile it as a module, choose M here. If unsure, say N.
293
294endif # NF_CONNTRACK
295
290config NETFILTER_XTABLES 296config NETFILTER_XTABLES
291 tristate "Netfilter Xtables support (required for ip_tables)" 297 tristate "Netfilter Xtables support (required for ip_tables)"
292 default m if NETFILTER_ADVANCED=n 298 default m if NETFILTER_ADVANCED=n
@@ -294,11 +300,12 @@ config NETFILTER_XTABLES
294 This is required if you intend to use any of ip_tables, 300 This is required if you intend to use any of ip_tables,
295 ip6_tables or arp_tables. 301 ip6_tables or arp_tables.
296 302
303if NETFILTER_XTABLES
304
297# alphabetically ordered list of targets 305# alphabetically ordered list of targets
298 306
299config NETFILTER_XT_TARGET_CLASSIFY 307config NETFILTER_XT_TARGET_CLASSIFY
300 tristate '"CLASSIFY" target support' 308 tristate '"CLASSIFY" target support'
301 depends on NETFILTER_XTABLES
302 depends on NETFILTER_ADVANCED 309 depends on NETFILTER_ADVANCED
303 help 310 help
304 This option adds a `CLASSIFY' target, which enables the user to set 311 This option adds a `CLASSIFY' target, which enables the user to set
@@ -311,8 +318,6 @@ config NETFILTER_XT_TARGET_CLASSIFY
311 318
312config NETFILTER_XT_TARGET_CONNMARK 319config NETFILTER_XT_TARGET_CONNMARK
313 tristate '"CONNMARK" target support' 320 tristate '"CONNMARK" target support'
314 depends on NETFILTER_XTABLES
315 depends on IP_NF_MANGLE || IP6_NF_MANGLE
316 depends on NF_CONNTRACK 321 depends on NF_CONNTRACK
317 depends on NETFILTER_ADVANCED 322 depends on NETFILTER_ADVANCED
318 select NF_CONNTRACK_MARK 323 select NF_CONNTRACK_MARK
@@ -325,9 +330,20 @@ config NETFILTER_XT_TARGET_CONNMARK
325 <file:Documentation/kbuild/modules.txt>. The module will be called 330 <file:Documentation/kbuild/modules.txt>. The module will be called
326 ipt_CONNMARK.ko. If unsure, say `N'. 331 ipt_CONNMARK.ko. If unsure, say `N'.
327 332
333config NETFILTER_XT_TARGET_CONNSECMARK
334 tristate '"CONNSECMARK" target support'
335 depends on NF_CONNTRACK && NF_CONNTRACK_SECMARK
336 default m if NETFILTER_ADVANCED=n
337 help
338 The CONNSECMARK target copies security markings from packets
339 to connections, and restores security markings from connections
340 to packets (if the packets are not already marked). This would
341 normally be used in conjunction with the SECMARK target.
342
343 To compile it as a module, choose M here. If unsure, say N.
344
328config NETFILTER_XT_TARGET_DSCP 345config NETFILTER_XT_TARGET_DSCP
329 tristate '"DSCP" and "TOS" target support' 346 tristate '"DSCP" and "TOS" target support'
330 depends on NETFILTER_XTABLES
331 depends on IP_NF_MANGLE || IP6_NF_MANGLE 347 depends on IP_NF_MANGLE || IP6_NF_MANGLE
332 depends on NETFILTER_ADVANCED 348 depends on NETFILTER_ADVANCED
333 help 349 help
@@ -344,7 +360,6 @@ config NETFILTER_XT_TARGET_DSCP
344 360
345config NETFILTER_XT_TARGET_MARK 361config NETFILTER_XT_TARGET_MARK
346 tristate '"MARK" target support' 362 tristate '"MARK" target support'
347 depends on NETFILTER_XTABLES
348 default m if NETFILTER_ADVANCED=n 363 default m if NETFILTER_ADVANCED=n
349 help 364 help
350 This option adds a `MARK' target, which allows you to create rules 365 This option adds a `MARK' target, which allows you to create rules
@@ -356,21 +371,8 @@ config NETFILTER_XT_TARGET_MARK
356 371
357 To compile it as a module, choose M here. If unsure, say N. 372 To compile it as a module, choose M here. If unsure, say N.
358 373
359config NETFILTER_XT_TARGET_NFQUEUE
360 tristate '"NFQUEUE" target Support'
361 depends on NETFILTER_XTABLES
362 depends on NETFILTER_ADVANCED
363 help
364 This target replaced the old obsolete QUEUE target.
365
366 As opposed to QUEUE, it supports 65535 different queues,
367 not just one.
368
369 To compile it as a module, choose M here. If unsure, say N.
370
371config NETFILTER_XT_TARGET_NFLOG 374config NETFILTER_XT_TARGET_NFLOG
372 tristate '"NFLOG" target support' 375 tristate '"NFLOG" target support'
373 depends on NETFILTER_XTABLES
374 default m if NETFILTER_ADVANCED=n 376 default m if NETFILTER_ADVANCED=n
375 help 377 help
376 This option enables the NFLOG target, which allows to LOG 378 This option enables the NFLOG target, which allows to LOG
@@ -380,9 +382,19 @@ config NETFILTER_XT_TARGET_NFLOG
380 382
381 To compile it as a module, choose M here. If unsure, say N. 383 To compile it as a module, choose M here. If unsure, say N.
382 384
385config NETFILTER_XT_TARGET_NFQUEUE
386 tristate '"NFQUEUE" target Support'
387 depends on NETFILTER_ADVANCED
388 help
389 This target replaced the old obsolete QUEUE target.
390
391 As opposed to QUEUE, it supports 65535 different queues,
392 not just one.
393
394 To compile it as a module, choose M here. If unsure, say N.
395
383config NETFILTER_XT_TARGET_NOTRACK 396config NETFILTER_XT_TARGET_NOTRACK
384 tristate '"NOTRACK" target support' 397 tristate '"NOTRACK" target support'
385 depends on NETFILTER_XTABLES
386 depends on IP_NF_RAW || IP6_NF_RAW 398 depends on IP_NF_RAW || IP6_NF_RAW
387 depends on NF_CONNTRACK 399 depends on NF_CONNTRACK
388 depends on NETFILTER_ADVANCED 400 depends on NETFILTER_ADVANCED
@@ -397,7 +409,6 @@ config NETFILTER_XT_TARGET_NOTRACK
397 409
398config NETFILTER_XT_TARGET_RATEEST 410config NETFILTER_XT_TARGET_RATEEST
399 tristate '"RATEEST" target support' 411 tristate '"RATEEST" target support'
400 depends on NETFILTER_XTABLES
401 depends on NETFILTER_ADVANCED 412 depends on NETFILTER_ADVANCED
402 help 413 help
403 This option adds a `RATEEST' target, which allows to measure 414 This option adds a `RATEEST' target, which allows to measure
@@ -406,9 +417,23 @@ config NETFILTER_XT_TARGET_RATEEST
406 417
407 To compile it as a module, choose M here. If unsure, say N. 418 To compile it as a module, choose M here. If unsure, say N.
408 419
420config NETFILTER_XT_TARGET_TPROXY
421 tristate '"TPROXY" target support (EXPERIMENTAL)'
422 depends on EXPERIMENTAL
423 depends on NETFILTER_TPROXY
424 depends on NETFILTER_XTABLES
425 depends on NETFILTER_ADVANCED
426 select NF_DEFRAG_IPV4
427 help
428 This option adds a `TPROXY' target, which is somewhat similar to
429 REDIRECT. It can only be used in the mangle table and is useful
430 to redirect traffic to a transparent proxy. It does _not_ depend
431 on Netfilter connection tracking and NAT, unlike REDIRECT.
432
433 To compile it as a module, choose M here. If unsure, say N.
434
409config NETFILTER_XT_TARGET_TRACE 435config NETFILTER_XT_TARGET_TRACE
410 tristate '"TRACE" target support' 436 tristate '"TRACE" target support'
411 depends on NETFILTER_XTABLES
412 depends on IP_NF_RAW || IP6_NF_RAW 437 depends on IP_NF_RAW || IP6_NF_RAW
413 depends on NETFILTER_ADVANCED 438 depends on NETFILTER_ADVANCED
414 help 439 help
@@ -421,7 +446,7 @@ config NETFILTER_XT_TARGET_TRACE
421 446
422config NETFILTER_XT_TARGET_SECMARK 447config NETFILTER_XT_TARGET_SECMARK
423 tristate '"SECMARK" target support' 448 tristate '"SECMARK" target support'
424 depends on NETFILTER_XTABLES && NETWORK_SECMARK 449 depends on NETWORK_SECMARK
425 default m if NETFILTER_ADVANCED=n 450 default m if NETFILTER_ADVANCED=n
426 help 451 help
427 The SECMARK target allows security marking of network 452 The SECMARK target allows security marking of network
@@ -429,21 +454,9 @@ config NETFILTER_XT_TARGET_SECMARK
429 454
430 To compile it as a module, choose M here. If unsure, say N. 455 To compile it as a module, choose M here. If unsure, say N.
431 456
432config NETFILTER_XT_TARGET_CONNSECMARK
433 tristate '"CONNSECMARK" target support'
434 depends on NETFILTER_XTABLES && NF_CONNTRACK && NF_CONNTRACK_SECMARK
435 default m if NETFILTER_ADVANCED=n
436 help
437 The CONNSECMARK target copies security markings from packets
438 to connections, and restores security markings from connections
439 to packets (if the packets are not already marked). This would
440 normally be used in conjunction with the SECMARK target.
441
442 To compile it as a module, choose M here. If unsure, say N.
443
444config NETFILTER_XT_TARGET_TCPMSS 457config NETFILTER_XT_TARGET_TCPMSS
445 tristate '"TCPMSS" target support' 458 tristate '"TCPMSS" target support'
446 depends on NETFILTER_XTABLES && (IPV6 || IPV6=n) 459 depends on (IPV6 || IPV6=n)
447 default m if NETFILTER_ADVANCED=n 460 default m if NETFILTER_ADVANCED=n
448 ---help--- 461 ---help---
449 This option adds a `TCPMSS' target, which allows you to alter the 462 This option adds a `TCPMSS' target, which allows you to alter the
@@ -470,7 +483,7 @@ config NETFILTER_XT_TARGET_TCPMSS
470 483
471config NETFILTER_XT_TARGET_TCPOPTSTRIP 484config NETFILTER_XT_TARGET_TCPOPTSTRIP
472 tristate '"TCPOPTSTRIP" target support (EXPERIMENTAL)' 485 tristate '"TCPOPTSTRIP" target support (EXPERIMENTAL)'
473 depends on EXPERIMENTAL && NETFILTER_XTABLES 486 depends on EXPERIMENTAL
474 depends on IP_NF_MANGLE || IP6_NF_MANGLE 487 depends on IP_NF_MANGLE || IP6_NF_MANGLE
475 depends on NETFILTER_ADVANCED 488 depends on NETFILTER_ADVANCED
476 help 489 help
@@ -479,7 +492,6 @@ config NETFILTER_XT_TARGET_TCPOPTSTRIP
479 492
480config NETFILTER_XT_MATCH_COMMENT 493config NETFILTER_XT_MATCH_COMMENT
481 tristate '"comment" match support' 494 tristate '"comment" match support'
482 depends on NETFILTER_XTABLES
483 depends on NETFILTER_ADVANCED 495 depends on NETFILTER_ADVANCED
484 help 496 help
485 This option adds a `comment' dummy-match, which allows you to put 497 This option adds a `comment' dummy-match, which allows you to put
@@ -490,7 +502,6 @@ config NETFILTER_XT_MATCH_COMMENT
490 502
491config NETFILTER_XT_MATCH_CONNBYTES 503config NETFILTER_XT_MATCH_CONNBYTES
492 tristate '"connbytes" per-connection counter match support' 504 tristate '"connbytes" per-connection counter match support'
493 depends on NETFILTER_XTABLES
494 depends on NF_CONNTRACK 505 depends on NF_CONNTRACK
495 depends on NETFILTER_ADVANCED 506 depends on NETFILTER_ADVANCED
496 select NF_CT_ACCT 507 select NF_CT_ACCT
@@ -503,7 +514,6 @@ config NETFILTER_XT_MATCH_CONNBYTES
503 514
504config NETFILTER_XT_MATCH_CONNLIMIT 515config NETFILTER_XT_MATCH_CONNLIMIT
505 tristate '"connlimit" match support"' 516 tristate '"connlimit" match support"'
506 depends on NETFILTER_XTABLES
507 depends on NF_CONNTRACK 517 depends on NF_CONNTRACK
508 depends on NETFILTER_ADVANCED 518 depends on NETFILTER_ADVANCED
509 ---help--- 519 ---help---
@@ -512,7 +522,6 @@ config NETFILTER_XT_MATCH_CONNLIMIT
512 522
513config NETFILTER_XT_MATCH_CONNMARK 523config NETFILTER_XT_MATCH_CONNMARK
514 tristate '"connmark" connection mark match support' 524 tristate '"connmark" connection mark match support'
515 depends on NETFILTER_XTABLES
516 depends on NF_CONNTRACK 525 depends on NF_CONNTRACK
517 depends on NETFILTER_ADVANCED 526 depends on NETFILTER_ADVANCED
518 select NF_CONNTRACK_MARK 527 select NF_CONNTRACK_MARK
@@ -526,7 +535,6 @@ config NETFILTER_XT_MATCH_CONNMARK
526 535
527config NETFILTER_XT_MATCH_CONNTRACK 536config NETFILTER_XT_MATCH_CONNTRACK
528 tristate '"conntrack" connection tracking match support' 537 tristate '"conntrack" connection tracking match support'
529 depends on NETFILTER_XTABLES
530 depends on NF_CONNTRACK 538 depends on NF_CONNTRACK
531 default m if NETFILTER_ADVANCED=n 539 default m if NETFILTER_ADVANCED=n
532 help 540 help
@@ -540,7 +548,6 @@ config NETFILTER_XT_MATCH_CONNTRACK
540 548
541config NETFILTER_XT_MATCH_DCCP 549config NETFILTER_XT_MATCH_DCCP
542 tristate '"dccp" protocol match support' 550 tristate '"dccp" protocol match support'
543 depends on NETFILTER_XTABLES
544 depends on NETFILTER_ADVANCED 551 depends on NETFILTER_ADVANCED
545 default IP_DCCP 552 default IP_DCCP
546 help 553 help
@@ -553,7 +560,6 @@ config NETFILTER_XT_MATCH_DCCP
553 560
554config NETFILTER_XT_MATCH_DSCP 561config NETFILTER_XT_MATCH_DSCP
555 tristate '"dscp" and "tos" match support' 562 tristate '"dscp" and "tos" match support'
556 depends on NETFILTER_XTABLES
557 depends on NETFILTER_ADVANCED 563 depends on NETFILTER_ADVANCED
558 help 564 help
559 This option adds a `DSCP' match, which allows you to match against 565 This option adds a `DSCP' match, which allows you to match against
@@ -569,7 +575,6 @@ config NETFILTER_XT_MATCH_DSCP
569 575
570config NETFILTER_XT_MATCH_ESP 576config NETFILTER_XT_MATCH_ESP
571 tristate '"esp" match support' 577 tristate '"esp" match support'
572 depends on NETFILTER_XTABLES
573 depends on NETFILTER_ADVANCED 578 depends on NETFILTER_ADVANCED
574 help 579 help
575 This match extension allows you to match a range of SPIs 580 This match extension allows you to match a range of SPIs
@@ -577,9 +582,23 @@ config NETFILTER_XT_MATCH_ESP
577 582
578 To compile it as a module, choose M here. If unsure, say N. 583 To compile it as a module, choose M here. If unsure, say N.
579 584
585config NETFILTER_XT_MATCH_HASHLIMIT
586 tristate '"hashlimit" match support'
587 depends on (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
588 depends on NETFILTER_ADVANCED
589 help
590 This option adds a `hashlimit' match.
591
592 As opposed to `limit', this match dynamically creates a hash table
593 of limit buckets, based on your selection of source/destination
594 addresses and/or ports.
595
596 It enables you to express policies like `10kpps for any given
597 destination address' or `500pps from any given source address'
598 with a single rule.
599
580config NETFILTER_XT_MATCH_HELPER 600config NETFILTER_XT_MATCH_HELPER
581 tristate '"helper" match support' 601 tristate '"helper" match support'
582 depends on NETFILTER_XTABLES
583 depends on NF_CONNTRACK 602 depends on NF_CONNTRACK
584 depends on NETFILTER_ADVANCED 603 depends on NETFILTER_ADVANCED
585 help 604 help
@@ -590,7 +609,6 @@ config NETFILTER_XT_MATCH_HELPER
590 609
591config NETFILTER_XT_MATCH_IPRANGE 610config NETFILTER_XT_MATCH_IPRANGE
592 tristate '"iprange" address range match support' 611 tristate '"iprange" address range match support'
593 depends on NETFILTER_XTABLES
594 depends on NETFILTER_ADVANCED 612 depends on NETFILTER_ADVANCED
595 ---help--- 613 ---help---
596 This option adds a "iprange" match, which allows you to match based on 614 This option adds a "iprange" match, which allows you to match based on
@@ -601,7 +619,6 @@ config NETFILTER_XT_MATCH_IPRANGE
601 619
602config NETFILTER_XT_MATCH_LENGTH 620config NETFILTER_XT_MATCH_LENGTH
603 tristate '"length" match support' 621 tristate '"length" match support'
604 depends on NETFILTER_XTABLES
605 depends on NETFILTER_ADVANCED 622 depends on NETFILTER_ADVANCED
606 help 623 help
607 This option allows you to match the length of a packet against a 624 This option allows you to match the length of a packet against a
@@ -611,7 +628,6 @@ config NETFILTER_XT_MATCH_LENGTH
611 628
612config NETFILTER_XT_MATCH_LIMIT 629config NETFILTER_XT_MATCH_LIMIT
613 tristate '"limit" match support' 630 tristate '"limit" match support'
614 depends on NETFILTER_XTABLES
615 depends on NETFILTER_ADVANCED 631 depends on NETFILTER_ADVANCED
616 help 632 help
617 limit matching allows you to control the rate at which a rule can be 633 limit matching allows you to control the rate at which a rule can be
@@ -622,7 +638,6 @@ config NETFILTER_XT_MATCH_LIMIT
622 638
623config NETFILTER_XT_MATCH_MAC 639config NETFILTER_XT_MATCH_MAC
624 tristate '"mac" address match support' 640 tristate '"mac" address match support'
625 depends on NETFILTER_XTABLES
626 depends on NETFILTER_ADVANCED 641 depends on NETFILTER_ADVANCED
627 help 642 help
628 MAC matching allows you to match packets based on the source 643 MAC matching allows you to match packets based on the source
@@ -632,7 +647,6 @@ config NETFILTER_XT_MATCH_MAC
632 647
633config NETFILTER_XT_MATCH_MARK 648config NETFILTER_XT_MATCH_MARK
634 tristate '"mark" match support' 649 tristate '"mark" match support'
635 depends on NETFILTER_XTABLES
636 default m if NETFILTER_ADVANCED=n 650 default m if NETFILTER_ADVANCED=n
637 help 651 help
638 Netfilter mark matching allows you to match packets based on the 652 Netfilter mark matching allows you to match packets based on the
@@ -641,9 +655,18 @@ config NETFILTER_XT_MATCH_MARK
641 655
642 To compile it as a module, choose M here. If unsure, say N. 656 To compile it as a module, choose M here. If unsure, say N.
643 657
658config NETFILTER_XT_MATCH_MULTIPORT
659 tristate '"multiport" Multiple port match support'
660 depends on NETFILTER_ADVANCED
661 help
662 Multiport matching allows you to match TCP or UDP packets based on
663 a series of source or destination ports: normally a rule can only
664 match a single range of ports.
665
666 To compile it as a module, choose M here. If unsure, say N.
667
644config NETFILTER_XT_MATCH_OWNER 668config NETFILTER_XT_MATCH_OWNER
645 tristate '"owner" match support' 669 tristate '"owner" match support'
646 depends on NETFILTER_XTABLES
647 depends on NETFILTER_ADVANCED 670 depends on NETFILTER_ADVANCED
648 ---help--- 671 ---help---
649 Socket owner matching allows you to match locally-generated packets 672 Socket owner matching allows you to match locally-generated packets
@@ -652,7 +675,7 @@ config NETFILTER_XT_MATCH_OWNER
652 675
653config NETFILTER_XT_MATCH_POLICY 676config NETFILTER_XT_MATCH_POLICY
654 tristate 'IPsec "policy" match support' 677 tristate 'IPsec "policy" match support'
655 depends on NETFILTER_XTABLES && XFRM 678 depends on XFRM
656 default m if NETFILTER_ADVANCED=n 679 default m if NETFILTER_ADVANCED=n
657 help 680 help
658 Policy matching allows you to match packets based on the 681 Policy matching allows you to match packets based on the
@@ -661,20 +684,9 @@ config NETFILTER_XT_MATCH_POLICY
661 684
662 To compile it as a module, choose M here. If unsure, say N. 685 To compile it as a module, choose M here. If unsure, say N.
663 686
664config NETFILTER_XT_MATCH_MULTIPORT
665 tristate '"multiport" Multiple port match support'
666 depends on NETFILTER_XTABLES
667 depends on NETFILTER_ADVANCED
668 help
669 Multiport matching allows you to match TCP or UDP packets based on
670 a series of source or destination ports: normally a rule can only
671 match a single range of ports.
672
673 To compile it as a module, choose M here. If unsure, say N.
674
675config NETFILTER_XT_MATCH_PHYSDEV 687config NETFILTER_XT_MATCH_PHYSDEV
676 tristate '"physdev" match support' 688 tristate '"physdev" match support'
677 depends on NETFILTER_XTABLES && BRIDGE && BRIDGE_NETFILTER 689 depends on BRIDGE && BRIDGE_NETFILTER
678 depends on NETFILTER_ADVANCED 690 depends on NETFILTER_ADVANCED
679 help 691 help
680 Physdev packet matching matches against the physical bridge ports 692 Physdev packet matching matches against the physical bridge ports
@@ -684,7 +696,6 @@ config NETFILTER_XT_MATCH_PHYSDEV
684 696
685config NETFILTER_XT_MATCH_PKTTYPE 697config NETFILTER_XT_MATCH_PKTTYPE
686 tristate '"pkttype" packet type match support' 698 tristate '"pkttype" packet type match support'
687 depends on NETFILTER_XTABLES
688 depends on NETFILTER_ADVANCED 699 depends on NETFILTER_ADVANCED
689 help 700 help
690 Packet type matching allows you to match a packet by 701 Packet type matching allows you to match a packet by
@@ -697,7 +708,6 @@ config NETFILTER_XT_MATCH_PKTTYPE
697 708
698config NETFILTER_XT_MATCH_QUOTA 709config NETFILTER_XT_MATCH_QUOTA
699 tristate '"quota" match support' 710 tristate '"quota" match support'
700 depends on NETFILTER_XTABLES
701 depends on NETFILTER_ADVANCED 711 depends on NETFILTER_ADVANCED
702 help 712 help
703 This option adds a `quota' match, which allows to match on a 713 This option adds a `quota' match, which allows to match on a
@@ -708,7 +718,6 @@ config NETFILTER_XT_MATCH_QUOTA
708 718
709config NETFILTER_XT_MATCH_RATEEST 719config NETFILTER_XT_MATCH_RATEEST
710 tristate '"rateest" match support' 720 tristate '"rateest" match support'
711 depends on NETFILTER_XTABLES
712 depends on NETFILTER_ADVANCED 721 depends on NETFILTER_ADVANCED
713 select NETFILTER_XT_TARGET_RATEEST 722 select NETFILTER_XT_TARGET_RATEEST
714 help 723 help
@@ -719,7 +728,6 @@ config NETFILTER_XT_MATCH_RATEEST
719 728
720config NETFILTER_XT_MATCH_REALM 729config NETFILTER_XT_MATCH_REALM
721 tristate '"realm" match support' 730 tristate '"realm" match support'
722 depends on NETFILTER_XTABLES
723 depends on NETFILTER_ADVANCED 731 depends on NETFILTER_ADVANCED
724 select NET_CLS_ROUTE 732 select NET_CLS_ROUTE
725 help 733 help
@@ -732,9 +740,26 @@ config NETFILTER_XT_MATCH_REALM
732 If you want to compile it as a module, say M here and read 740 If you want to compile it as a module, say M here and read
733 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. 741 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
734 742
743config NETFILTER_XT_MATCH_RECENT
744 tristate '"recent" match support'
745 depends on NETFILTER_ADVANCED
746 ---help---
747 This match is used for creating one or many lists of recently
748 used addresses and then matching against that/those list(s).
749
750 Short options are available by using 'iptables -m recent -h'
751 Official Website: <http://snowman.net/projects/ipt_recent/>
752
753config NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
754 bool 'Enable obsolete /proc/net/ipt_recent'
755 depends on NETFILTER_XT_MATCH_RECENT && PROC_FS
756 ---help---
757 This option enables the old /proc/net/ipt_recent interface,
758 which has been obsoleted by /proc/net/xt_recent.
759
735config NETFILTER_XT_MATCH_SCTP 760config NETFILTER_XT_MATCH_SCTP
736 tristate '"sctp" protocol match support (EXPERIMENTAL)' 761 tristate '"sctp" protocol match support (EXPERIMENTAL)'
737 depends on NETFILTER_XTABLES && EXPERIMENTAL 762 depends on EXPERIMENTAL
738 depends on NETFILTER_ADVANCED 763 depends on NETFILTER_ADVANCED
739 default IP_SCTP 764 default IP_SCTP
740 help 765 help
@@ -745,9 +770,23 @@ config NETFILTER_XT_MATCH_SCTP
745 If you want to compile it as a module, say M here and read 770 If you want to compile it as a module, say M here and read
746 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. 771 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
747 772
773config NETFILTER_XT_MATCH_SOCKET
774 tristate '"socket" match support (EXPERIMENTAL)'
775 depends on EXPERIMENTAL
776 depends on NETFILTER_TPROXY
777 depends on NETFILTER_XTABLES
778 depends on NETFILTER_ADVANCED
779 select NF_DEFRAG_IPV4
780 help
781 This option adds a `socket' match, which can be used to match
782 packets for which a TCP or UDP socket lookup finds a valid socket.
783 It can be used in combination with the MARK target and policy
784 routing to implement full featured non-locally bound sockets.
785
786 To compile it as a module, choose M here. If unsure, say N.
787
748config NETFILTER_XT_MATCH_STATE 788config NETFILTER_XT_MATCH_STATE
749 tristate '"state" match support' 789 tristate '"state" match support'
750 depends on NETFILTER_XTABLES
751 depends on NF_CONNTRACK 790 depends on NF_CONNTRACK
752 default m if NETFILTER_ADVANCED=n 791 default m if NETFILTER_ADVANCED=n
753 help 792 help
@@ -759,7 +798,6 @@ config NETFILTER_XT_MATCH_STATE
759 798
760config NETFILTER_XT_MATCH_STATISTIC 799config NETFILTER_XT_MATCH_STATISTIC
761 tristate '"statistic" match support' 800 tristate '"statistic" match support'
762 depends on NETFILTER_XTABLES
763 depends on NETFILTER_ADVANCED 801 depends on NETFILTER_ADVANCED
764 help 802 help
765 This option adds a `statistic' match, which allows you to match 803 This option adds a `statistic' match, which allows you to match
@@ -769,7 +807,6 @@ config NETFILTER_XT_MATCH_STATISTIC
769 807
770config NETFILTER_XT_MATCH_STRING 808config NETFILTER_XT_MATCH_STRING
771 tristate '"string" match support' 809 tristate '"string" match support'
772 depends on NETFILTER_XTABLES
773 depends on NETFILTER_ADVANCED 810 depends on NETFILTER_ADVANCED
774 select TEXTSEARCH 811 select TEXTSEARCH
775 select TEXTSEARCH_KMP 812 select TEXTSEARCH_KMP
@@ -783,7 +820,6 @@ config NETFILTER_XT_MATCH_STRING
783 820
784config NETFILTER_XT_MATCH_TCPMSS 821config NETFILTER_XT_MATCH_TCPMSS
785 tristate '"tcpmss" match support' 822 tristate '"tcpmss" match support'
786 depends on NETFILTER_XTABLES
787 depends on NETFILTER_ADVANCED 823 depends on NETFILTER_ADVANCED
788 help 824 help
789 This option adds a `tcpmss' match, which allows you to examine the 825 This option adds a `tcpmss' match, which allows you to examine the
@@ -794,7 +830,6 @@ config NETFILTER_XT_MATCH_TCPMSS
794 830
795config NETFILTER_XT_MATCH_TIME 831config NETFILTER_XT_MATCH_TIME
796 tristate '"time" match support' 832 tristate '"time" match support'
797 depends on NETFILTER_XTABLES
798 depends on NETFILTER_ADVANCED 833 depends on NETFILTER_ADVANCED
799 ---help--- 834 ---help---
800 This option adds a "time" match, which allows you to match based on 835 This option adds a "time" match, which allows you to match based on
@@ -809,7 +844,6 @@ config NETFILTER_XT_MATCH_TIME
809 844
810config NETFILTER_XT_MATCH_U32 845config NETFILTER_XT_MATCH_U32
811 tristate '"u32" match support' 846 tristate '"u32" match support'
812 depends on NETFILTER_XTABLES
813 depends on NETFILTER_ADVANCED 847 depends on NETFILTER_ADVANCED
814 ---help--- 848 ---help---
815 u32 allows you to extract quantities of up to 4 bytes from a packet, 849 u32 allows you to extract quantities of up to 4 bytes from a packet,
@@ -821,20 +855,6 @@ config NETFILTER_XT_MATCH_U32
821 855
822 Details and examples are in the kernel module source. 856 Details and examples are in the kernel module source.
823 857
824config NETFILTER_XT_MATCH_HASHLIMIT 858endif # NETFILTER_XTABLES
825 tristate '"hashlimit" match support'
826 depends on NETFILTER_XTABLES && (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
827 depends on NETFILTER_ADVANCED
828 help
829 This option adds a `hashlimit' match.
830
831 As opposed to `limit', this match dynamically creates a hash table
832 of limit buckets, based on your selection of source/destination
833 addresses and/or ports.
834
835 It enables you to express policies like `10kpps for any given
836 destination address' or `500pps from any given source address'
837 with a single rule.
838 859
839endmenu 860endmenu
840
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 3bd2cc556aea..8ce67665882d 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -34,6 +34,9 @@ obj-$(CONFIG_NF_CONNTRACK_SANE) += nf_conntrack_sane.o
34obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o 34obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o
35obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o 35obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o
36 36
37# transparent proxy support
38obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o
39
37# generic X tables 40# generic X tables
38obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o 41obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
39 42
@@ -48,6 +51,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
48obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o 51obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
49obj-$(CONFIG_NETFILTER_XT_TARGET_RATEEST) += xt_RATEEST.o 52obj-$(CONFIG_NETFILTER_XT_TARGET_RATEEST) += xt_RATEEST.o
50obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o 53obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
54obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o
51obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o 55obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
52obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o 56obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o
53obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o 57obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
@@ -76,7 +80,9 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o
76obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o 80obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o
77obj-$(CONFIG_NETFILTER_XT_MATCH_RATEEST) += xt_rateest.o 81obj-$(CONFIG_NETFILTER_XT_MATCH_RATEEST) += xt_rateest.o
78obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o 82obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
83obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT) += xt_recent.o
79obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o 84obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
85obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
80obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o 86obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
81obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o 87obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
82obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o 88obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 292fa28146fb..a90ac83c5918 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -26,7 +26,7 @@
26 26
27static DEFINE_MUTEX(afinfo_mutex); 27static DEFINE_MUTEX(afinfo_mutex);
28 28
29const struct nf_afinfo *nf_afinfo[NPROTO] __read_mostly; 29const struct nf_afinfo *nf_afinfo[NFPROTO_NUMPROTO] __read_mostly;
30EXPORT_SYMBOL(nf_afinfo); 30EXPORT_SYMBOL(nf_afinfo);
31 31
32int nf_register_afinfo(const struct nf_afinfo *afinfo) 32int nf_register_afinfo(const struct nf_afinfo *afinfo)
@@ -51,7 +51,7 @@ void nf_unregister_afinfo(const struct nf_afinfo *afinfo)
51} 51}
52EXPORT_SYMBOL_GPL(nf_unregister_afinfo); 52EXPORT_SYMBOL_GPL(nf_unregister_afinfo);
53 53
54struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS] __read_mostly; 54struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] __read_mostly;
55EXPORT_SYMBOL(nf_hooks); 55EXPORT_SYMBOL(nf_hooks);
56static DEFINE_MUTEX(nf_hook_mutex); 56static DEFINE_MUTEX(nf_hook_mutex);
57 57
@@ -113,7 +113,7 @@ EXPORT_SYMBOL(nf_unregister_hooks);
113 113
114unsigned int nf_iterate(struct list_head *head, 114unsigned int nf_iterate(struct list_head *head,
115 struct sk_buff *skb, 115 struct sk_buff *skb,
116 int hook, 116 unsigned int hook,
117 const struct net_device *indev, 117 const struct net_device *indev,
118 const struct net_device *outdev, 118 const struct net_device *outdev,
119 struct list_head **i, 119 struct list_head **i,
@@ -155,7 +155,7 @@ unsigned int nf_iterate(struct list_head *head,
155 155
156/* Returns 1 if okfn() needs to be executed by the caller, 156/* Returns 1 if okfn() needs to be executed by the caller,
157 * -EPERM for NF_DROP, 0 otherwise. */ 157 * -EPERM for NF_DROP, 0 otherwise. */
158int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb, 158int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb,
159 struct net_device *indev, 159 struct net_device *indev,
160 struct net_device *outdev, 160 struct net_device *outdev,
161 int (*okfn)(struct sk_buff *), 161 int (*okfn)(struct sk_buff *),
@@ -165,14 +165,6 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
165 unsigned int verdict; 165 unsigned int verdict;
166 int ret = 0; 166 int ret = 0;
167 167
168#ifdef CONFIG_NET_NS
169 struct net *net;
170
171 net = indev == NULL ? dev_net(outdev) : dev_net(indev);
172 if (net != &init_net)
173 return 1;
174#endif
175
176 /* We may already have this, but read-locks nest anyway */ 168 /* We may already have this, but read-locks nest anyway */
177 rcu_read_lock(); 169 rcu_read_lock();
178 170
@@ -264,7 +256,7 @@ EXPORT_SYMBOL(proc_net_netfilter);
264void __init netfilter_init(void) 256void __init netfilter_init(void)
265{ 257{
266 int i, h; 258 int i, h;
267 for (i = 0; i < NPROTO; i++) { 259 for (i = 0; i < ARRAY_SIZE(nf_hooks); i++) {
268 for (h = 0; h < NF_MAX_HOOKS; h++) 260 for (h = 0; h < NF_MAX_HOOKS; h++)
269 INIT_LIST_HEAD(&nf_hooks[i][h]); 261 INIT_LIST_HEAD(&nf_hooks[i][h]);
270 } 262 }
diff --git a/net/netfilter/nf_conntrack_acct.c b/net/netfilter/nf_conntrack_acct.c
index 59bd8b903a19..03591d37b9cc 100644
--- a/net/netfilter/nf_conntrack_acct.c
+++ b/net/netfilter/nf_conntrack_acct.c
@@ -22,19 +22,17 @@
22#define NF_CT_ACCT_DEFAULT 0 22#define NF_CT_ACCT_DEFAULT 0
23#endif 23#endif
24 24
25int nf_ct_acct __read_mostly = NF_CT_ACCT_DEFAULT; 25static int nf_ct_acct __read_mostly = NF_CT_ACCT_DEFAULT;
26EXPORT_SYMBOL_GPL(nf_ct_acct);
27 26
28module_param_named(acct, nf_ct_acct, bool, 0644); 27module_param_named(acct, nf_ct_acct, bool, 0644);
29MODULE_PARM_DESC(acct, "Enable connection tracking flow accounting."); 28MODULE_PARM_DESC(acct, "Enable connection tracking flow accounting.");
30 29
31#ifdef CONFIG_SYSCTL 30#ifdef CONFIG_SYSCTL
32static struct ctl_table_header *acct_sysctl_header;
33static struct ctl_table acct_sysctl_table[] = { 31static struct ctl_table acct_sysctl_table[] = {
34 { 32 {
35 .ctl_name = CTL_UNNUMBERED, 33 .ctl_name = CTL_UNNUMBERED,
36 .procname = "nf_conntrack_acct", 34 .procname = "nf_conntrack_acct",
37 .data = &nf_ct_acct, 35 .data = &init_net.ct.sysctl_acct,
38 .maxlen = sizeof(unsigned int), 36 .maxlen = sizeof(unsigned int),
39 .mode = 0644, 37 .mode = 0644,
40 .proc_handler = &proc_dointvec, 38 .proc_handler = &proc_dointvec,
@@ -64,41 +62,87 @@ static struct nf_ct_ext_type acct_extend __read_mostly = {
64 .id = NF_CT_EXT_ACCT, 62 .id = NF_CT_EXT_ACCT,
65}; 63};
66 64
67int nf_conntrack_acct_init(void) 65#ifdef CONFIG_SYSCTL
66static int nf_conntrack_acct_init_sysctl(struct net *net)
68{ 67{
69 int ret; 68 struct ctl_table *table;
70 69
71#ifdef CONFIG_NF_CT_ACCT 70 table = kmemdup(acct_sysctl_table, sizeof(acct_sysctl_table),
72 printk(KERN_WARNING "CONFIG_NF_CT_ACCT is deprecated and will be removed soon. Plase use\n"); 71 GFP_KERNEL);
73 printk(KERN_WARNING "nf_conntrack.acct=1 kernel paramater, acct=1 nf_conntrack module option or\n"); 72 if (!table)
74 printk(KERN_WARNING "sysctl net.netfilter.nf_conntrack_acct=1 to enable it.\n"); 73 goto out;
75#endif 74
75 table[0].data = &net->ct.sysctl_acct;
76 76
77 ret = nf_ct_extend_register(&acct_extend); 77 net->ct.acct_sysctl_header = register_net_sysctl_table(net,
78 if (ret < 0) { 78 nf_net_netfilter_sysctl_path, table);
79 printk(KERN_ERR "nf_conntrack_acct: Unable to register extension\n"); 79 if (!net->ct.acct_sysctl_header) {
80 return ret; 80 printk(KERN_ERR "nf_conntrack_acct: can't register to sysctl.\n");
81 goto out_register;
81 } 82 }
83 return 0;
82 84
83#ifdef CONFIG_SYSCTL 85out_register:
84 acct_sysctl_header = register_sysctl_paths(nf_net_netfilter_sysctl_path, 86 kfree(table);
85 acct_sysctl_table); 87out:
88 return -ENOMEM;
89}
86 90
87 if (!acct_sysctl_header) { 91static void nf_conntrack_acct_fini_sysctl(struct net *net)
88 nf_ct_extend_unregister(&acct_extend); 92{
93 struct ctl_table *table;
89 94
90 printk(KERN_ERR "nf_conntrack_acct: can't register to sysctl.\n"); 95 table = net->ct.acct_sysctl_header->ctl_table_arg;
91 return -ENOMEM; 96 unregister_net_sysctl_table(net->ct.acct_sysctl_header);
92 } 97 kfree(table);
98}
99#else
100static int nf_conntrack_acct_init_sysctl(struct net *net)
101{
102 return 0;
103}
104
105static void nf_conntrack_acct_fini_sysctl(struct net *net)
106{
107}
108#endif
109
110int nf_conntrack_acct_init(struct net *net)
111{
112 int ret;
113
114 net->ct.sysctl_acct = nf_ct_acct;
115
116 if (net_eq(net, &init_net)) {
117#ifdef CONFIG_NF_CT_ACCT
118 printk(KERN_WARNING "CONFIG_NF_CT_ACCT is deprecated and will be removed soon. Plase use\n");
119 printk(KERN_WARNING "nf_conntrack.acct=1 kernel paramater, acct=1 nf_conntrack module option or\n");
120 printk(KERN_WARNING "sysctl net.netfilter.nf_conntrack_acct=1 to enable it.\n");
93#endif 121#endif
94 122
123 ret = nf_ct_extend_register(&acct_extend);
124 if (ret < 0) {
125 printk(KERN_ERR "nf_conntrack_acct: Unable to register extension\n");
126 goto out_extend_register;
127 }
128 }
129
130 ret = nf_conntrack_acct_init_sysctl(net);
131 if (ret < 0)
132 goto out_sysctl;
133
95 return 0; 134 return 0;
135
136out_sysctl:
137 if (net_eq(net, &init_net))
138 nf_ct_extend_unregister(&acct_extend);
139out_extend_register:
140 return ret;
96} 141}
97 142
98void nf_conntrack_acct_fini(void) 143void nf_conntrack_acct_fini(struct net *net)
99{ 144{
100#ifdef CONFIG_SYSCTL 145 nf_conntrack_acct_fini_sysctl(net);
101 unregister_sysctl_table(acct_sysctl_header); 146 if (net_eq(net, &init_net))
102#endif 147 nf_ct_extend_unregister(&acct_extend);
103 nf_ct_extend_unregister(&acct_extend);
104} 148}
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 9d1830da8e84..27de3c7b006e 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -44,30 +44,17 @@
44DEFINE_SPINLOCK(nf_conntrack_lock); 44DEFINE_SPINLOCK(nf_conntrack_lock);
45EXPORT_SYMBOL_GPL(nf_conntrack_lock); 45EXPORT_SYMBOL_GPL(nf_conntrack_lock);
46 46
47/* nf_conntrack_standalone needs this */
48atomic_t nf_conntrack_count = ATOMIC_INIT(0);
49EXPORT_SYMBOL_GPL(nf_conntrack_count);
50
51unsigned int nf_conntrack_htable_size __read_mostly; 47unsigned int nf_conntrack_htable_size __read_mostly;
52EXPORT_SYMBOL_GPL(nf_conntrack_htable_size); 48EXPORT_SYMBOL_GPL(nf_conntrack_htable_size);
53 49
54int nf_conntrack_max __read_mostly; 50int nf_conntrack_max __read_mostly;
55EXPORT_SYMBOL_GPL(nf_conntrack_max); 51EXPORT_SYMBOL_GPL(nf_conntrack_max);
56 52
57struct hlist_head *nf_conntrack_hash __read_mostly;
58EXPORT_SYMBOL_GPL(nf_conntrack_hash);
59
60struct nf_conn nf_conntrack_untracked __read_mostly; 53struct nf_conn nf_conntrack_untracked __read_mostly;
61EXPORT_SYMBOL_GPL(nf_conntrack_untracked); 54EXPORT_SYMBOL_GPL(nf_conntrack_untracked);
62 55
63unsigned int nf_ct_log_invalid __read_mostly;
64HLIST_HEAD(unconfirmed);
65static int nf_conntrack_vmalloc __read_mostly;
66static struct kmem_cache *nf_conntrack_cachep __read_mostly; 56static struct kmem_cache *nf_conntrack_cachep __read_mostly;
67 57
68DEFINE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
69EXPORT_PER_CPU_SYMBOL(nf_conntrack_stat);
70
71static int nf_conntrack_hash_rnd_initted; 58static int nf_conntrack_hash_rnd_initted;
72static unsigned int nf_conntrack_hash_rnd; 59static unsigned int nf_conntrack_hash_rnd;
73 60
@@ -180,6 +167,7 @@ static void
180destroy_conntrack(struct nf_conntrack *nfct) 167destroy_conntrack(struct nf_conntrack *nfct)
181{ 168{
182 struct nf_conn *ct = (struct nf_conn *)nfct; 169 struct nf_conn *ct = (struct nf_conn *)nfct;
170 struct net *net = nf_ct_net(ct);
183 struct nf_conntrack_l4proto *l4proto; 171 struct nf_conntrack_l4proto *l4proto;
184 172
185 pr_debug("destroy_conntrack(%p)\n", ct); 173 pr_debug("destroy_conntrack(%p)\n", ct);
@@ -212,7 +200,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
212 hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode); 200 hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
213 } 201 }
214 202
215 NF_CT_STAT_INC(delete); 203 NF_CT_STAT_INC(net, delete);
216 spin_unlock_bh(&nf_conntrack_lock); 204 spin_unlock_bh(&nf_conntrack_lock);
217 205
218 if (ct->master) 206 if (ct->master)
@@ -225,6 +213,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
225static void death_by_timeout(unsigned long ul_conntrack) 213static void death_by_timeout(unsigned long ul_conntrack)
226{ 214{
227 struct nf_conn *ct = (void *)ul_conntrack; 215 struct nf_conn *ct = (void *)ul_conntrack;
216 struct net *net = nf_ct_net(ct);
228 struct nf_conn_help *help = nfct_help(ct); 217 struct nf_conn_help *help = nfct_help(ct);
229 struct nf_conntrack_helper *helper; 218 struct nf_conntrack_helper *helper;
230 219
@@ -239,14 +228,14 @@ static void death_by_timeout(unsigned long ul_conntrack)
239 spin_lock_bh(&nf_conntrack_lock); 228 spin_lock_bh(&nf_conntrack_lock);
240 /* Inside lock so preempt is disabled on module removal path. 229 /* Inside lock so preempt is disabled on module removal path.
241 * Otherwise we can get spurious warnings. */ 230 * Otherwise we can get spurious warnings. */
242 NF_CT_STAT_INC(delete_list); 231 NF_CT_STAT_INC(net, delete_list);
243 clean_from_lists(ct); 232 clean_from_lists(ct);
244 spin_unlock_bh(&nf_conntrack_lock); 233 spin_unlock_bh(&nf_conntrack_lock);
245 nf_ct_put(ct); 234 nf_ct_put(ct);
246} 235}
247 236
248struct nf_conntrack_tuple_hash * 237struct nf_conntrack_tuple_hash *
249__nf_conntrack_find(const struct nf_conntrack_tuple *tuple) 238__nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple)
250{ 239{
251 struct nf_conntrack_tuple_hash *h; 240 struct nf_conntrack_tuple_hash *h;
252 struct hlist_node *n; 241 struct hlist_node *n;
@@ -256,13 +245,13 @@ __nf_conntrack_find(const struct nf_conntrack_tuple *tuple)
256 * at least once for the stats anyway. 245 * at least once for the stats anyway.
257 */ 246 */
258 local_bh_disable(); 247 local_bh_disable();
259 hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) { 248 hlist_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnode) {
260 if (nf_ct_tuple_equal(tuple, &h->tuple)) { 249 if (nf_ct_tuple_equal(tuple, &h->tuple)) {
261 NF_CT_STAT_INC(found); 250 NF_CT_STAT_INC(net, found);
262 local_bh_enable(); 251 local_bh_enable();
263 return h; 252 return h;
264 } 253 }
265 NF_CT_STAT_INC(searched); 254 NF_CT_STAT_INC(net, searched);
266 } 255 }
267 local_bh_enable(); 256 local_bh_enable();
268 257
@@ -272,13 +261,13 @@ EXPORT_SYMBOL_GPL(__nf_conntrack_find);
272 261
273/* Find a connection corresponding to a tuple. */ 262/* Find a connection corresponding to a tuple. */
274struct nf_conntrack_tuple_hash * 263struct nf_conntrack_tuple_hash *
275nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple) 264nf_conntrack_find_get(struct net *net, const struct nf_conntrack_tuple *tuple)
276{ 265{
277 struct nf_conntrack_tuple_hash *h; 266 struct nf_conntrack_tuple_hash *h;
278 struct nf_conn *ct; 267 struct nf_conn *ct;
279 268
280 rcu_read_lock(); 269 rcu_read_lock();
281 h = __nf_conntrack_find(tuple); 270 h = __nf_conntrack_find(net, tuple);
282 if (h) { 271 if (h) {
283 ct = nf_ct_tuplehash_to_ctrack(h); 272 ct = nf_ct_tuplehash_to_ctrack(h);
284 if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use))) 273 if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
@@ -294,10 +283,12 @@ static void __nf_conntrack_hash_insert(struct nf_conn *ct,
294 unsigned int hash, 283 unsigned int hash,
295 unsigned int repl_hash) 284 unsigned int repl_hash)
296{ 285{
286 struct net *net = nf_ct_net(ct);
287
297 hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode, 288 hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
298 &nf_conntrack_hash[hash]); 289 &net->ct.hash[hash]);
299 hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnode, 290 hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnode,
300 &nf_conntrack_hash[repl_hash]); 291 &net->ct.hash[repl_hash]);
301} 292}
302 293
303void nf_conntrack_hash_insert(struct nf_conn *ct) 294void nf_conntrack_hash_insert(struct nf_conn *ct)
@@ -323,8 +314,10 @@ __nf_conntrack_confirm(struct sk_buff *skb)
323 struct nf_conn_help *help; 314 struct nf_conn_help *help;
324 struct hlist_node *n; 315 struct hlist_node *n;
325 enum ip_conntrack_info ctinfo; 316 enum ip_conntrack_info ctinfo;
317 struct net *net;
326 318
327 ct = nf_ct_get(skb, &ctinfo); 319 ct = nf_ct_get(skb, &ctinfo);
320 net = nf_ct_net(ct);
328 321
329 /* ipt_REJECT uses nf_conntrack_attach to attach related 322 /* ipt_REJECT uses nf_conntrack_attach to attach related
330 ICMP/TCP RST packets in other direction. Actual packet 323 ICMP/TCP RST packets in other direction. Actual packet
@@ -351,11 +344,11 @@ __nf_conntrack_confirm(struct sk_buff *skb)
351 /* See if there's one in the list already, including reverse: 344 /* See if there's one in the list already, including reverse:
352 NAT could have grabbed it without realizing, since we're 345 NAT could have grabbed it without realizing, since we're
353 not in the hash. If there is, we lost race. */ 346 not in the hash. If there is, we lost race. */
354 hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode) 347 hlist_for_each_entry(h, n, &net->ct.hash[hash], hnode)
355 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, 348 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
356 &h->tuple)) 349 &h->tuple))
357 goto out; 350 goto out;
358 hlist_for_each_entry(h, n, &nf_conntrack_hash[repl_hash], hnode) 351 hlist_for_each_entry(h, n, &net->ct.hash[repl_hash], hnode)
359 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple, 352 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple,
360 &h->tuple)) 353 &h->tuple))
361 goto out; 354 goto out;
@@ -371,22 +364,22 @@ __nf_conntrack_confirm(struct sk_buff *skb)
371 add_timer(&ct->timeout); 364 add_timer(&ct->timeout);
372 atomic_inc(&ct->ct_general.use); 365 atomic_inc(&ct->ct_general.use);
373 set_bit(IPS_CONFIRMED_BIT, &ct->status); 366 set_bit(IPS_CONFIRMED_BIT, &ct->status);
374 NF_CT_STAT_INC(insert); 367 NF_CT_STAT_INC(net, insert);
375 spin_unlock_bh(&nf_conntrack_lock); 368 spin_unlock_bh(&nf_conntrack_lock);
376 help = nfct_help(ct); 369 help = nfct_help(ct);
377 if (help && help->helper) 370 if (help && help->helper)
378 nf_conntrack_event_cache(IPCT_HELPER, skb); 371 nf_conntrack_event_cache(IPCT_HELPER, ct);
379#ifdef CONFIG_NF_NAT_NEEDED 372#ifdef CONFIG_NF_NAT_NEEDED
380 if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status) || 373 if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status) ||
381 test_bit(IPS_DST_NAT_DONE_BIT, &ct->status)) 374 test_bit(IPS_DST_NAT_DONE_BIT, &ct->status))
382 nf_conntrack_event_cache(IPCT_NATINFO, skb); 375 nf_conntrack_event_cache(IPCT_NATINFO, ct);
383#endif 376#endif
384 nf_conntrack_event_cache(master_ct(ct) ? 377 nf_conntrack_event_cache(master_ct(ct) ?
385 IPCT_RELATED : IPCT_NEW, skb); 378 IPCT_RELATED : IPCT_NEW, ct);
386 return NF_ACCEPT; 379 return NF_ACCEPT;
387 380
388out: 381out:
389 NF_CT_STAT_INC(insert_failed); 382 NF_CT_STAT_INC(net, insert_failed);
390 spin_unlock_bh(&nf_conntrack_lock); 383 spin_unlock_bh(&nf_conntrack_lock);
391 return NF_DROP; 384 return NF_DROP;
392} 385}
@@ -398,6 +391,7 @@ int
398nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, 391nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
399 const struct nf_conn *ignored_conntrack) 392 const struct nf_conn *ignored_conntrack)
400{ 393{
394 struct net *net = nf_ct_net(ignored_conntrack);
401 struct nf_conntrack_tuple_hash *h; 395 struct nf_conntrack_tuple_hash *h;
402 struct hlist_node *n; 396 struct hlist_node *n;
403 unsigned int hash = hash_conntrack(tuple); 397 unsigned int hash = hash_conntrack(tuple);
@@ -406,14 +400,14 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
406 * least once for the stats anyway. 400 * least once for the stats anyway.
407 */ 401 */
408 rcu_read_lock_bh(); 402 rcu_read_lock_bh();
409 hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) { 403 hlist_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnode) {
410 if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack && 404 if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
411 nf_ct_tuple_equal(tuple, &h->tuple)) { 405 nf_ct_tuple_equal(tuple, &h->tuple)) {
412 NF_CT_STAT_INC(found); 406 NF_CT_STAT_INC(net, found);
413 rcu_read_unlock_bh(); 407 rcu_read_unlock_bh();
414 return 1; 408 return 1;
415 } 409 }
416 NF_CT_STAT_INC(searched); 410 NF_CT_STAT_INC(net, searched);
417 } 411 }
418 rcu_read_unlock_bh(); 412 rcu_read_unlock_bh();
419 413
@@ -425,7 +419,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken);
425 419
426/* There's a small race here where we may free a just-assured 420/* There's a small race here where we may free a just-assured
427 connection. Too bad: we're in trouble anyway. */ 421 connection. Too bad: we're in trouble anyway. */
428static noinline int early_drop(unsigned int hash) 422static noinline int early_drop(struct net *net, unsigned int hash)
429{ 423{
430 /* Use oldest entry, which is roughly LRU */ 424 /* Use oldest entry, which is roughly LRU */
431 struct nf_conntrack_tuple_hash *h; 425 struct nf_conntrack_tuple_hash *h;
@@ -436,7 +430,7 @@ static noinline int early_drop(unsigned int hash)
436 430
437 rcu_read_lock(); 431 rcu_read_lock();
438 for (i = 0; i < nf_conntrack_htable_size; i++) { 432 for (i = 0; i < nf_conntrack_htable_size; i++) {
439 hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], 433 hlist_for_each_entry_rcu(h, n, &net->ct.hash[hash],
440 hnode) { 434 hnode) {
441 tmp = nf_ct_tuplehash_to_ctrack(h); 435 tmp = nf_ct_tuplehash_to_ctrack(h);
442 if (!test_bit(IPS_ASSURED_BIT, &tmp->status)) 436 if (!test_bit(IPS_ASSURED_BIT, &tmp->status))
@@ -458,13 +452,14 @@ static noinline int early_drop(unsigned int hash)
458 if (del_timer(&ct->timeout)) { 452 if (del_timer(&ct->timeout)) {
459 death_by_timeout((unsigned long)ct); 453 death_by_timeout((unsigned long)ct);
460 dropped = 1; 454 dropped = 1;
461 NF_CT_STAT_INC_ATOMIC(early_drop); 455 NF_CT_STAT_INC_ATOMIC(net, early_drop);
462 } 456 }
463 nf_ct_put(ct); 457 nf_ct_put(ct);
464 return dropped; 458 return dropped;
465} 459}
466 460
467struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, 461struct nf_conn *nf_conntrack_alloc(struct net *net,
462 const struct nf_conntrack_tuple *orig,
468 const struct nf_conntrack_tuple *repl, 463 const struct nf_conntrack_tuple *repl,
469 gfp_t gfp) 464 gfp_t gfp)
470{ 465{
@@ -476,13 +471,13 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
476 } 471 }
477 472
478 /* We don't want any race condition at early drop stage */ 473 /* We don't want any race condition at early drop stage */
479 atomic_inc(&nf_conntrack_count); 474 atomic_inc(&net->ct.count);
480 475
481 if (nf_conntrack_max && 476 if (nf_conntrack_max &&
482 unlikely(atomic_read(&nf_conntrack_count) > nf_conntrack_max)) { 477 unlikely(atomic_read(&net->ct.count) > nf_conntrack_max)) {
483 unsigned int hash = hash_conntrack(orig); 478 unsigned int hash = hash_conntrack(orig);
484 if (!early_drop(hash)) { 479 if (!early_drop(net, hash)) {
485 atomic_dec(&nf_conntrack_count); 480 atomic_dec(&net->ct.count);
486 if (net_ratelimit()) 481 if (net_ratelimit())
487 printk(KERN_WARNING 482 printk(KERN_WARNING
488 "nf_conntrack: table full, dropping" 483 "nf_conntrack: table full, dropping"
@@ -494,7 +489,7 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
494 ct = kmem_cache_zalloc(nf_conntrack_cachep, gfp); 489 ct = kmem_cache_zalloc(nf_conntrack_cachep, gfp);
495 if (ct == NULL) { 490 if (ct == NULL) {
496 pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n"); 491 pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n");
497 atomic_dec(&nf_conntrack_count); 492 atomic_dec(&net->ct.count);
498 return ERR_PTR(-ENOMEM); 493 return ERR_PTR(-ENOMEM);
499 } 494 }
500 495
@@ -503,6 +498,9 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
503 ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl; 498 ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
504 /* Don't set timer yet: wait for confirmation */ 499 /* Don't set timer yet: wait for confirmation */
505 setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct); 500 setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct);
501#ifdef CONFIG_NET_NS
502 ct->ct_net = net;
503#endif
506 INIT_RCU_HEAD(&ct->rcu); 504 INIT_RCU_HEAD(&ct->rcu);
507 505
508 return ct; 506 return ct;
@@ -512,10 +510,11 @@ EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
512static void nf_conntrack_free_rcu(struct rcu_head *head) 510static void nf_conntrack_free_rcu(struct rcu_head *head)
513{ 511{
514 struct nf_conn *ct = container_of(head, struct nf_conn, rcu); 512 struct nf_conn *ct = container_of(head, struct nf_conn, rcu);
513 struct net *net = nf_ct_net(ct);
515 514
516 nf_ct_ext_free(ct); 515 nf_ct_ext_free(ct);
517 kmem_cache_free(nf_conntrack_cachep, ct); 516 kmem_cache_free(nf_conntrack_cachep, ct);
518 atomic_dec(&nf_conntrack_count); 517 atomic_dec(&net->ct.count);
519} 518}
520 519
521void nf_conntrack_free(struct nf_conn *ct) 520void nf_conntrack_free(struct nf_conn *ct)
@@ -528,7 +527,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_free);
528/* Allocate a new conntrack: we return -ENOMEM if classification 527/* Allocate a new conntrack: we return -ENOMEM if classification
529 failed due to stress. Otherwise it really is unclassifiable. */ 528 failed due to stress. Otherwise it really is unclassifiable. */
530static struct nf_conntrack_tuple_hash * 529static struct nf_conntrack_tuple_hash *
531init_conntrack(const struct nf_conntrack_tuple *tuple, 530init_conntrack(struct net *net,
531 const struct nf_conntrack_tuple *tuple,
532 struct nf_conntrack_l3proto *l3proto, 532 struct nf_conntrack_l3proto *l3proto,
533 struct nf_conntrack_l4proto *l4proto, 533 struct nf_conntrack_l4proto *l4proto,
534 struct sk_buff *skb, 534 struct sk_buff *skb,
@@ -544,7 +544,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
544 return NULL; 544 return NULL;
545 } 545 }
546 546
547 ct = nf_conntrack_alloc(tuple, &repl_tuple, GFP_ATOMIC); 547 ct = nf_conntrack_alloc(net, tuple, &repl_tuple, GFP_ATOMIC);
548 if (ct == NULL || IS_ERR(ct)) { 548 if (ct == NULL || IS_ERR(ct)) {
549 pr_debug("Can't allocate conntrack.\n"); 549 pr_debug("Can't allocate conntrack.\n");
550 return (struct nf_conntrack_tuple_hash *)ct; 550 return (struct nf_conntrack_tuple_hash *)ct;
@@ -559,7 +559,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
559 nf_ct_acct_ext_add(ct, GFP_ATOMIC); 559 nf_ct_acct_ext_add(ct, GFP_ATOMIC);
560 560
561 spin_lock_bh(&nf_conntrack_lock); 561 spin_lock_bh(&nf_conntrack_lock);
562 exp = nf_ct_find_expectation(tuple); 562 exp = nf_ct_find_expectation(net, tuple);
563 if (exp) { 563 if (exp) {
564 pr_debug("conntrack: expectation arrives ct=%p exp=%p\n", 564 pr_debug("conntrack: expectation arrives ct=%p exp=%p\n",
565 ct, exp); 565 ct, exp);
@@ -579,7 +579,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
579 ct->secmark = exp->master->secmark; 579 ct->secmark = exp->master->secmark;
580#endif 580#endif
581 nf_conntrack_get(&ct->master->ct_general); 581 nf_conntrack_get(&ct->master->ct_general);
582 NF_CT_STAT_INC(expect_new); 582 NF_CT_STAT_INC(net, expect_new);
583 } else { 583 } else {
584 struct nf_conntrack_helper *helper; 584 struct nf_conntrack_helper *helper;
585 585
@@ -589,11 +589,12 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
589 if (help) 589 if (help)
590 rcu_assign_pointer(help->helper, helper); 590 rcu_assign_pointer(help->helper, helper);
591 } 591 }
592 NF_CT_STAT_INC(new); 592 NF_CT_STAT_INC(net, new);
593 } 593 }
594 594
595 /* Overload tuple linked list to put us in unconfirmed list. */ 595 /* Overload tuple linked list to put us in unconfirmed list. */
596 hlist_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode, &unconfirmed); 596 hlist_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
597 &net->ct.unconfirmed);
597 598
598 spin_unlock_bh(&nf_conntrack_lock); 599 spin_unlock_bh(&nf_conntrack_lock);
599 600
@@ -608,7 +609,8 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
608 609
609/* On success, returns conntrack ptr, sets skb->nfct and ctinfo */ 610/* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
610static inline struct nf_conn * 611static inline struct nf_conn *
611resolve_normal_ct(struct sk_buff *skb, 612resolve_normal_ct(struct net *net,
613 struct sk_buff *skb,
612 unsigned int dataoff, 614 unsigned int dataoff,
613 u_int16_t l3num, 615 u_int16_t l3num,
614 u_int8_t protonum, 616 u_int8_t protonum,
@@ -629,9 +631,9 @@ resolve_normal_ct(struct sk_buff *skb,
629 } 631 }
630 632
631 /* look for tuple match */ 633 /* look for tuple match */
632 h = nf_conntrack_find_get(&tuple); 634 h = nf_conntrack_find_get(net, &tuple);
633 if (!h) { 635 if (!h) {
634 h = init_conntrack(&tuple, l3proto, l4proto, skb, dataoff); 636 h = init_conntrack(net, &tuple, l3proto, l4proto, skb, dataoff);
635 if (!h) 637 if (!h)
636 return NULL; 638 return NULL;
637 if (IS_ERR(h)) 639 if (IS_ERR(h))
@@ -665,7 +667,8 @@ resolve_normal_ct(struct sk_buff *skb,
665} 667}
666 668
667unsigned int 669unsigned int
668nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff *skb) 670nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
671 struct sk_buff *skb)
669{ 672{
670 struct nf_conn *ct; 673 struct nf_conn *ct;
671 enum ip_conntrack_info ctinfo; 674 enum ip_conntrack_info ctinfo;
@@ -678,44 +681,46 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff *skb)
678 681
679 /* Previously seen (loopback or untracked)? Ignore. */ 682 /* Previously seen (loopback or untracked)? Ignore. */
680 if (skb->nfct) { 683 if (skb->nfct) {
681 NF_CT_STAT_INC_ATOMIC(ignore); 684 NF_CT_STAT_INC_ATOMIC(net, ignore);
682 return NF_ACCEPT; 685 return NF_ACCEPT;
683 } 686 }
684 687
685 /* rcu_read_lock()ed by nf_hook_slow */ 688 /* rcu_read_lock()ed by nf_hook_slow */
686 l3proto = __nf_ct_l3proto_find((u_int16_t)pf); 689 l3proto = __nf_ct_l3proto_find(pf);
687 ret = l3proto->get_l4proto(skb, skb_network_offset(skb), 690 ret = l3proto->get_l4proto(skb, skb_network_offset(skb),
688 &dataoff, &protonum); 691 &dataoff, &protonum);
689 if (ret <= 0) { 692 if (ret <= 0) {
690 pr_debug("not prepared to track yet or error occured\n"); 693 pr_debug("not prepared to track yet or error occured\n");
691 NF_CT_STAT_INC_ATOMIC(error); 694 NF_CT_STAT_INC_ATOMIC(net, error);
692 NF_CT_STAT_INC_ATOMIC(invalid); 695 NF_CT_STAT_INC_ATOMIC(net, invalid);
693 return -ret; 696 return -ret;
694 } 697 }
695 698
696 l4proto = __nf_ct_l4proto_find((u_int16_t)pf, protonum); 699 l4proto = __nf_ct_l4proto_find(pf, protonum);
697 700
698 /* It may be an special packet, error, unclean... 701 /* It may be an special packet, error, unclean...
699 * inverse of the return code tells to the netfilter 702 * inverse of the return code tells to the netfilter
700 * core what to do with the packet. */ 703 * core what to do with the packet. */
701 if (l4proto->error != NULL && 704 if (l4proto->error != NULL) {
702 (ret = l4proto->error(skb, dataoff, &ctinfo, pf, hooknum)) <= 0) { 705 ret = l4proto->error(net, skb, dataoff, &ctinfo, pf, hooknum);
703 NF_CT_STAT_INC_ATOMIC(error); 706 if (ret <= 0) {
704 NF_CT_STAT_INC_ATOMIC(invalid); 707 NF_CT_STAT_INC_ATOMIC(net, error);
705 return -ret; 708 NF_CT_STAT_INC_ATOMIC(net, invalid);
709 return -ret;
710 }
706 } 711 }
707 712
708 ct = resolve_normal_ct(skb, dataoff, pf, protonum, l3proto, l4proto, 713 ct = resolve_normal_ct(net, skb, dataoff, pf, protonum,
709 &set_reply, &ctinfo); 714 l3proto, l4proto, &set_reply, &ctinfo);
710 if (!ct) { 715 if (!ct) {
711 /* Not valid part of a connection */ 716 /* Not valid part of a connection */
712 NF_CT_STAT_INC_ATOMIC(invalid); 717 NF_CT_STAT_INC_ATOMIC(net, invalid);
713 return NF_ACCEPT; 718 return NF_ACCEPT;
714 } 719 }
715 720
716 if (IS_ERR(ct)) { 721 if (IS_ERR(ct)) {
717 /* Too stressed to deal. */ 722 /* Too stressed to deal. */
718 NF_CT_STAT_INC_ATOMIC(drop); 723 NF_CT_STAT_INC_ATOMIC(net, drop);
719 return NF_DROP; 724 return NF_DROP;
720 } 725 }
721 726
@@ -728,12 +733,12 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff *skb)
728 pr_debug("nf_conntrack_in: Can't track with proto module\n"); 733 pr_debug("nf_conntrack_in: Can't track with proto module\n");
729 nf_conntrack_put(skb->nfct); 734 nf_conntrack_put(skb->nfct);
730 skb->nfct = NULL; 735 skb->nfct = NULL;
731 NF_CT_STAT_INC_ATOMIC(invalid); 736 NF_CT_STAT_INC_ATOMIC(net, invalid);
732 return -ret; 737 return -ret;
733 } 738 }
734 739
735 if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status)) 740 if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status))
736 nf_conntrack_event_cache(IPCT_STATUS, skb); 741 nf_conntrack_event_cache(IPCT_STATUS, ct);
737 742
738 return ret; 743 return ret;
739} 744}
@@ -846,7 +851,7 @@ acct:
846 851
847 /* must be unlocked when calling event cache */ 852 /* must be unlocked when calling event cache */
848 if (event) 853 if (event)
849 nf_conntrack_event_cache(event, skb); 854 nf_conntrack_event_cache(event, ct);
850} 855}
851EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct); 856EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct);
852 857
@@ -938,7 +943,7 @@ static void nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
938 943
939/* Bring out ya dead! */ 944/* Bring out ya dead! */
940static struct nf_conn * 945static struct nf_conn *
941get_next_corpse(int (*iter)(struct nf_conn *i, void *data), 946get_next_corpse(struct net *net, int (*iter)(struct nf_conn *i, void *data),
942 void *data, unsigned int *bucket) 947 void *data, unsigned int *bucket)
943{ 948{
944 struct nf_conntrack_tuple_hash *h; 949 struct nf_conntrack_tuple_hash *h;
@@ -947,13 +952,13 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
947 952
948 spin_lock_bh(&nf_conntrack_lock); 953 spin_lock_bh(&nf_conntrack_lock);
949 for (; *bucket < nf_conntrack_htable_size; (*bucket)++) { 954 for (; *bucket < nf_conntrack_htable_size; (*bucket)++) {
950 hlist_for_each_entry(h, n, &nf_conntrack_hash[*bucket], hnode) { 955 hlist_for_each_entry(h, n, &net->ct.hash[*bucket], hnode) {
951 ct = nf_ct_tuplehash_to_ctrack(h); 956 ct = nf_ct_tuplehash_to_ctrack(h);
952 if (iter(ct, data)) 957 if (iter(ct, data))
953 goto found; 958 goto found;
954 } 959 }
955 } 960 }
956 hlist_for_each_entry(h, n, &unconfirmed, hnode) { 961 hlist_for_each_entry(h, n, &net->ct.unconfirmed, hnode) {
957 ct = nf_ct_tuplehash_to_ctrack(h); 962 ct = nf_ct_tuplehash_to_ctrack(h);
958 if (iter(ct, data)) 963 if (iter(ct, data))
959 set_bit(IPS_DYING_BIT, &ct->status); 964 set_bit(IPS_DYING_BIT, &ct->status);
@@ -966,13 +971,14 @@ found:
966 return ct; 971 return ct;
967} 972}
968 973
969void 974void nf_ct_iterate_cleanup(struct net *net,
970nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data) 975 int (*iter)(struct nf_conn *i, void *data),
976 void *data)
971{ 977{
972 struct nf_conn *ct; 978 struct nf_conn *ct;
973 unsigned int bucket = 0; 979 unsigned int bucket = 0;
974 980
975 while ((ct = get_next_corpse(iter, data, &bucket)) != NULL) { 981 while ((ct = get_next_corpse(net, iter, data, &bucket)) != NULL) {
976 /* Time to push up daises... */ 982 /* Time to push up daises... */
977 if (del_timer(&ct->timeout)) 983 if (del_timer(&ct->timeout))
978 death_by_timeout((unsigned long)ct); 984 death_by_timeout((unsigned long)ct);
@@ -998,27 +1004,26 @@ void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, unsigned int s
998} 1004}
999EXPORT_SYMBOL_GPL(nf_ct_free_hashtable); 1005EXPORT_SYMBOL_GPL(nf_ct_free_hashtable);
1000 1006
1001void nf_conntrack_flush(void) 1007void nf_conntrack_flush(struct net *net)
1002{ 1008{
1003 nf_ct_iterate_cleanup(kill_all, NULL); 1009 nf_ct_iterate_cleanup(net, kill_all, NULL);
1004} 1010}
1005EXPORT_SYMBOL_GPL(nf_conntrack_flush); 1011EXPORT_SYMBOL_GPL(nf_conntrack_flush);
1006 1012
1007/* Mishearing the voices in his head, our hero wonders how he's 1013static void nf_conntrack_cleanup_init_net(void)
1008 supposed to kill the mall. */
1009void nf_conntrack_cleanup(void)
1010{ 1014{
1011 rcu_assign_pointer(ip_ct_attach, NULL); 1015 nf_conntrack_helper_fini();
1012 1016 nf_conntrack_proto_fini();
1013 /* This makes sure all current packets have passed through 1017 kmem_cache_destroy(nf_conntrack_cachep);
1014 netfilter framework. Roll on, two-stage module 1018}
1015 delete... */
1016 synchronize_net();
1017 1019
1018 nf_ct_event_cache_flush(); 1020static void nf_conntrack_cleanup_net(struct net *net)
1021{
1022 nf_ct_event_cache_flush(net);
1023 nf_conntrack_ecache_fini(net);
1019 i_see_dead_people: 1024 i_see_dead_people:
1020 nf_conntrack_flush(); 1025 nf_conntrack_flush(net);
1021 if (atomic_read(&nf_conntrack_count) != 0) { 1026 if (atomic_read(&net->ct.count) != 0) {
1022 schedule(); 1027 schedule();
1023 goto i_see_dead_people; 1028 goto i_see_dead_people;
1024 } 1029 }
@@ -1026,16 +1031,31 @@ void nf_conntrack_cleanup(void)
1026 while (atomic_read(&nf_conntrack_untracked.ct_general.use) > 1) 1031 while (atomic_read(&nf_conntrack_untracked.ct_general.use) > 1)
1027 schedule(); 1032 schedule();
1028 1033
1029 rcu_assign_pointer(nf_ct_destroy, NULL); 1034 nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
1030
1031 kmem_cache_destroy(nf_conntrack_cachep);
1032 nf_ct_free_hashtable(nf_conntrack_hash, nf_conntrack_vmalloc,
1033 nf_conntrack_htable_size); 1035 nf_conntrack_htable_size);
1036 nf_conntrack_acct_fini(net);
1037 nf_conntrack_expect_fini(net);
1038 free_percpu(net->ct.stat);
1039}
1034 1040
1035 nf_conntrack_acct_fini(); 1041/* Mishearing the voices in his head, our hero wonders how he's
1036 nf_conntrack_expect_fini(); 1042 supposed to kill the mall. */
1037 nf_conntrack_helper_fini(); 1043void nf_conntrack_cleanup(struct net *net)
1038 nf_conntrack_proto_fini(); 1044{
1045 if (net_eq(net, &init_net))
1046 rcu_assign_pointer(ip_ct_attach, NULL);
1047
1048 /* This makes sure all current packets have passed through
1049 netfilter framework. Roll on, two-stage module
1050 delete... */
1051 synchronize_net();
1052
1053 nf_conntrack_cleanup_net(net);
1054
1055 if (net_eq(net, &init_net)) {
1056 rcu_assign_pointer(nf_ct_destroy, NULL);
1057 nf_conntrack_cleanup_init_net();
1058 }
1039} 1059}
1040 1060
1041struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced) 1061struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced)
@@ -1094,8 +1114,8 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
1094 */ 1114 */
1095 spin_lock_bh(&nf_conntrack_lock); 1115 spin_lock_bh(&nf_conntrack_lock);
1096 for (i = 0; i < nf_conntrack_htable_size; i++) { 1116 for (i = 0; i < nf_conntrack_htable_size; i++) {
1097 while (!hlist_empty(&nf_conntrack_hash[i])) { 1117 while (!hlist_empty(&init_net.ct.hash[i])) {
1098 h = hlist_entry(nf_conntrack_hash[i].first, 1118 h = hlist_entry(init_net.ct.hash[i].first,
1099 struct nf_conntrack_tuple_hash, hnode); 1119 struct nf_conntrack_tuple_hash, hnode);
1100 hlist_del_rcu(&h->hnode); 1120 hlist_del_rcu(&h->hnode);
1101 bucket = __hash_conntrack(&h->tuple, hashsize, rnd); 1121 bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
@@ -1103,12 +1123,12 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
1103 } 1123 }
1104 } 1124 }
1105 old_size = nf_conntrack_htable_size; 1125 old_size = nf_conntrack_htable_size;
1106 old_vmalloced = nf_conntrack_vmalloc; 1126 old_vmalloced = init_net.ct.hash_vmalloc;
1107 old_hash = nf_conntrack_hash; 1127 old_hash = init_net.ct.hash;
1108 1128
1109 nf_conntrack_htable_size = hashsize; 1129 nf_conntrack_htable_size = hashsize;
1110 nf_conntrack_vmalloc = vmalloced; 1130 init_net.ct.hash_vmalloc = vmalloced;
1111 nf_conntrack_hash = hash; 1131 init_net.ct.hash = hash;
1112 nf_conntrack_hash_rnd = rnd; 1132 nf_conntrack_hash_rnd = rnd;
1113 spin_unlock_bh(&nf_conntrack_lock); 1133 spin_unlock_bh(&nf_conntrack_lock);
1114 1134
@@ -1120,7 +1140,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_set_hashsize);
1120module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint, 1140module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint,
1121 &nf_conntrack_htable_size, 0600); 1141 &nf_conntrack_htable_size, 0600);
1122 1142
1123int __init nf_conntrack_init(void) 1143static int nf_conntrack_init_init_net(void)
1124{ 1144{
1125 int max_factor = 8; 1145 int max_factor = 8;
1126 int ret; 1146 int ret;
@@ -1142,13 +1162,6 @@ int __init nf_conntrack_init(void)
1142 * entries. */ 1162 * entries. */
1143 max_factor = 4; 1163 max_factor = 4;
1144 } 1164 }
1145 nf_conntrack_hash = nf_ct_alloc_hashtable(&nf_conntrack_htable_size,
1146 &nf_conntrack_vmalloc);
1147 if (!nf_conntrack_hash) {
1148 printk(KERN_ERR "Unable to create nf_conntrack_hash\n");
1149 goto err_out;
1150 }
1151
1152 nf_conntrack_max = max_factor * nf_conntrack_htable_size; 1165 nf_conntrack_max = max_factor * nf_conntrack_htable_size;
1153 1166
1154 printk("nf_conntrack version %s (%u buckets, %d max)\n", 1167 printk("nf_conntrack version %s (%u buckets, %d max)\n",
@@ -1160,48 +1173,103 @@ int __init nf_conntrack_init(void)
1160 0, 0, NULL); 1173 0, 0, NULL);
1161 if (!nf_conntrack_cachep) { 1174 if (!nf_conntrack_cachep) {
1162 printk(KERN_ERR "Unable to create nf_conn slab cache\n"); 1175 printk(KERN_ERR "Unable to create nf_conn slab cache\n");
1163 goto err_free_hash; 1176 ret = -ENOMEM;
1177 goto err_cache;
1164 } 1178 }
1165 1179
1166 ret = nf_conntrack_proto_init(); 1180 ret = nf_conntrack_proto_init();
1167 if (ret < 0) 1181 if (ret < 0)
1168 goto err_free_conntrack_slab; 1182 goto err_proto;
1169
1170 ret = nf_conntrack_expect_init();
1171 if (ret < 0)
1172 goto out_fini_proto;
1173 1183
1174 ret = nf_conntrack_helper_init(); 1184 ret = nf_conntrack_helper_init();
1175 if (ret < 0) 1185 if (ret < 0)
1176 goto out_fini_expect; 1186 goto err_helper;
1177 1187
1178 ret = nf_conntrack_acct_init(); 1188 return 0;
1179 if (ret < 0)
1180 goto out_fini_helper;
1181 1189
1182 /* For use by REJECT target */ 1190err_helper:
1183 rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach); 1191 nf_conntrack_proto_fini();
1184 rcu_assign_pointer(nf_ct_destroy, destroy_conntrack); 1192err_proto:
1193 kmem_cache_destroy(nf_conntrack_cachep);
1194err_cache:
1195 return ret;
1196}
1197
1198static int nf_conntrack_init_net(struct net *net)
1199{
1200 int ret;
1201
1202 atomic_set(&net->ct.count, 0);
1203 INIT_HLIST_HEAD(&net->ct.unconfirmed);
1204 net->ct.stat = alloc_percpu(struct ip_conntrack_stat);
1205 if (!net->ct.stat) {
1206 ret = -ENOMEM;
1207 goto err_stat;
1208 }
1209 ret = nf_conntrack_ecache_init(net);
1210 if (ret < 0)
1211 goto err_ecache;
1212 net->ct.hash = nf_ct_alloc_hashtable(&nf_conntrack_htable_size,
1213 &net->ct.hash_vmalloc);
1214 if (!net->ct.hash) {
1215 ret = -ENOMEM;
1216 printk(KERN_ERR "Unable to create nf_conntrack_hash\n");
1217 goto err_hash;
1218 }
1219 ret = nf_conntrack_expect_init(net);
1220 if (ret < 0)
1221 goto err_expect;
1222 ret = nf_conntrack_acct_init(net);
1223 if (ret < 0)
1224 goto err_acct;
1185 1225
1186 /* Set up fake conntrack: 1226 /* Set up fake conntrack:
1187 - to never be deleted, not in any hashes */ 1227 - to never be deleted, not in any hashes */
1228#ifdef CONFIG_NET_NS
1229 nf_conntrack_untracked.ct_net = &init_net;
1230#endif
1188 atomic_set(&nf_conntrack_untracked.ct_general.use, 1); 1231 atomic_set(&nf_conntrack_untracked.ct_general.use, 1);
1189 /* - and look it like as a confirmed connection */ 1232 /* - and look it like as a confirmed connection */
1190 set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status); 1233 set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status);
1191 1234
1192 return ret; 1235 return 0;
1193 1236
1194out_fini_helper: 1237err_acct:
1195 nf_conntrack_helper_fini(); 1238 nf_conntrack_expect_fini(net);
1196out_fini_expect: 1239err_expect:
1197 nf_conntrack_expect_fini(); 1240 nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
1198out_fini_proto:
1199 nf_conntrack_proto_fini();
1200err_free_conntrack_slab:
1201 kmem_cache_destroy(nf_conntrack_cachep);
1202err_free_hash:
1203 nf_ct_free_hashtable(nf_conntrack_hash, nf_conntrack_vmalloc,
1204 nf_conntrack_htable_size); 1241 nf_conntrack_htable_size);
1205err_out: 1242err_hash:
1206 return -ENOMEM; 1243 nf_conntrack_ecache_fini(net);
1244err_ecache:
1245 free_percpu(net->ct.stat);
1246err_stat:
1247 return ret;
1248}
1249
1250int nf_conntrack_init(struct net *net)
1251{
1252 int ret;
1253
1254 if (net_eq(net, &init_net)) {
1255 ret = nf_conntrack_init_init_net();
1256 if (ret < 0)
1257 goto out_init_net;
1258 }
1259 ret = nf_conntrack_init_net(net);
1260 if (ret < 0)
1261 goto out_net;
1262
1263 if (net_eq(net, &init_net)) {
1264 /* For use by REJECT target */
1265 rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach);
1266 rcu_assign_pointer(nf_ct_destroy, destroy_conntrack);
1267 }
1268 return 0;
1269
1270out_net:
1271 if (net_eq(net, &init_net))
1272 nf_conntrack_cleanup_init_net();
1273out_init_net:
1274 return ret;
1207} 1275}
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
index 83c41ac3505b..a5f5e2e65d13 100644
--- a/net/netfilter/nf_conntrack_ecache.c
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -29,9 +29,6 @@ EXPORT_SYMBOL_GPL(nf_conntrack_chain);
29ATOMIC_NOTIFIER_HEAD(nf_ct_expect_chain); 29ATOMIC_NOTIFIER_HEAD(nf_ct_expect_chain);
30EXPORT_SYMBOL_GPL(nf_ct_expect_chain); 30EXPORT_SYMBOL_GPL(nf_ct_expect_chain);
31 31
32DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
33EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache);
34
35/* deliver cached events and clear cache entry - must be called with locally 32/* deliver cached events and clear cache entry - must be called with locally
36 * disabled softirqs */ 33 * disabled softirqs */
37static inline void 34static inline void
@@ -51,10 +48,11 @@ __nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache)
51 * by code prior to async packet handling for freeing the skb */ 48 * by code prior to async packet handling for freeing the skb */
52void nf_ct_deliver_cached_events(const struct nf_conn *ct) 49void nf_ct_deliver_cached_events(const struct nf_conn *ct)
53{ 50{
51 struct net *net = nf_ct_net(ct);
54 struct nf_conntrack_ecache *ecache; 52 struct nf_conntrack_ecache *ecache;
55 53
56 local_bh_disable(); 54 local_bh_disable();
57 ecache = &__get_cpu_var(nf_conntrack_ecache); 55 ecache = per_cpu_ptr(net->ct.ecache, raw_smp_processor_id());
58 if (ecache->ct == ct) 56 if (ecache->ct == ct)
59 __nf_ct_deliver_cached_events(ecache); 57 __nf_ct_deliver_cached_events(ecache);
60 local_bh_enable(); 58 local_bh_enable();
@@ -64,10 +62,11 @@ EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
64/* Deliver cached events for old pending events, if current conntrack != old */ 62/* Deliver cached events for old pending events, if current conntrack != old */
65void __nf_ct_event_cache_init(struct nf_conn *ct) 63void __nf_ct_event_cache_init(struct nf_conn *ct)
66{ 64{
65 struct net *net = nf_ct_net(ct);
67 struct nf_conntrack_ecache *ecache; 66 struct nf_conntrack_ecache *ecache;
68 67
69 /* take care of delivering potentially old events */ 68 /* take care of delivering potentially old events */
70 ecache = &__get_cpu_var(nf_conntrack_ecache); 69 ecache = per_cpu_ptr(net->ct.ecache, raw_smp_processor_id());
71 BUG_ON(ecache->ct == ct); 70 BUG_ON(ecache->ct == ct);
72 if (ecache->ct) 71 if (ecache->ct)
73 __nf_ct_deliver_cached_events(ecache); 72 __nf_ct_deliver_cached_events(ecache);
@@ -79,18 +78,31 @@ EXPORT_SYMBOL_GPL(__nf_ct_event_cache_init);
79 78
80/* flush the event cache - touches other CPU's data and must not be called 79/* flush the event cache - touches other CPU's data and must not be called
81 * while packets are still passing through the code */ 80 * while packets are still passing through the code */
82void nf_ct_event_cache_flush(void) 81void nf_ct_event_cache_flush(struct net *net)
83{ 82{
84 struct nf_conntrack_ecache *ecache; 83 struct nf_conntrack_ecache *ecache;
85 int cpu; 84 int cpu;
86 85
87 for_each_possible_cpu(cpu) { 86 for_each_possible_cpu(cpu) {
88 ecache = &per_cpu(nf_conntrack_ecache, cpu); 87 ecache = per_cpu_ptr(net->ct.ecache, cpu);
89 if (ecache->ct) 88 if (ecache->ct)
90 nf_ct_put(ecache->ct); 89 nf_ct_put(ecache->ct);
91 } 90 }
92} 91}
93 92
93int nf_conntrack_ecache_init(struct net *net)
94{
95 net->ct.ecache = alloc_percpu(struct nf_conntrack_ecache);
96 if (!net->ct.ecache)
97 return -ENOMEM;
98 return 0;
99}
100
101void nf_conntrack_ecache_fini(struct net *net)
102{
103 free_percpu(net->ct.ecache);
104}
105
94int nf_conntrack_register_notifier(struct notifier_block *nb) 106int nf_conntrack_register_notifier(struct notifier_block *nb)
95{ 107{
96 return atomic_notifier_chain_register(&nf_conntrack_chain, nb); 108 return atomic_notifier_chain_register(&nf_conntrack_chain, nb);
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index e8f0dead267f..37a703bc3b8e 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -28,17 +28,12 @@
28#include <net/netfilter/nf_conntrack_helper.h> 28#include <net/netfilter/nf_conntrack_helper.h>
29#include <net/netfilter/nf_conntrack_tuple.h> 29#include <net/netfilter/nf_conntrack_tuple.h>
30 30
31struct hlist_head *nf_ct_expect_hash __read_mostly;
32EXPORT_SYMBOL_GPL(nf_ct_expect_hash);
33
34unsigned int nf_ct_expect_hsize __read_mostly; 31unsigned int nf_ct_expect_hsize __read_mostly;
35EXPORT_SYMBOL_GPL(nf_ct_expect_hsize); 32EXPORT_SYMBOL_GPL(nf_ct_expect_hsize);
36 33
37static unsigned int nf_ct_expect_hash_rnd __read_mostly; 34static unsigned int nf_ct_expect_hash_rnd __read_mostly;
38static unsigned int nf_ct_expect_count;
39unsigned int nf_ct_expect_max __read_mostly; 35unsigned int nf_ct_expect_max __read_mostly;
40static int nf_ct_expect_hash_rnd_initted __read_mostly; 36static int nf_ct_expect_hash_rnd_initted __read_mostly;
41static int nf_ct_expect_vmalloc;
42 37
43static struct kmem_cache *nf_ct_expect_cachep __read_mostly; 38static struct kmem_cache *nf_ct_expect_cachep __read_mostly;
44 39
@@ -46,18 +41,19 @@ static struct kmem_cache *nf_ct_expect_cachep __read_mostly;
46void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) 41void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
47{ 42{
48 struct nf_conn_help *master_help = nfct_help(exp->master); 43 struct nf_conn_help *master_help = nfct_help(exp->master);
44 struct net *net = nf_ct_exp_net(exp);
49 45
50 NF_CT_ASSERT(master_help); 46 NF_CT_ASSERT(master_help);
51 NF_CT_ASSERT(!timer_pending(&exp->timeout)); 47 NF_CT_ASSERT(!timer_pending(&exp->timeout));
52 48
53 hlist_del_rcu(&exp->hnode); 49 hlist_del_rcu(&exp->hnode);
54 nf_ct_expect_count--; 50 net->ct.expect_count--;
55 51
56 hlist_del(&exp->lnode); 52 hlist_del(&exp->lnode);
57 master_help->expecting[exp->class]--; 53 master_help->expecting[exp->class]--;
58 nf_ct_expect_put(exp); 54 nf_ct_expect_put(exp);
59 55
60 NF_CT_STAT_INC(expect_delete); 56 NF_CT_STAT_INC(net, expect_delete);
61} 57}
62EXPORT_SYMBOL_GPL(nf_ct_unlink_expect); 58EXPORT_SYMBOL_GPL(nf_ct_unlink_expect);
63 59
@@ -87,17 +83,17 @@ static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple
87} 83}
88 84
89struct nf_conntrack_expect * 85struct nf_conntrack_expect *
90__nf_ct_expect_find(const struct nf_conntrack_tuple *tuple) 86__nf_ct_expect_find(struct net *net, const struct nf_conntrack_tuple *tuple)
91{ 87{
92 struct nf_conntrack_expect *i; 88 struct nf_conntrack_expect *i;
93 struct hlist_node *n; 89 struct hlist_node *n;
94 unsigned int h; 90 unsigned int h;
95 91
96 if (!nf_ct_expect_count) 92 if (!net->ct.expect_count)
97 return NULL; 93 return NULL;
98 94
99 h = nf_ct_expect_dst_hash(tuple); 95 h = nf_ct_expect_dst_hash(tuple);
100 hlist_for_each_entry_rcu(i, n, &nf_ct_expect_hash[h], hnode) { 96 hlist_for_each_entry_rcu(i, n, &net->ct.expect_hash[h], hnode) {
101 if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) 97 if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask))
102 return i; 98 return i;
103 } 99 }
@@ -107,12 +103,12 @@ EXPORT_SYMBOL_GPL(__nf_ct_expect_find);
107 103
108/* Just find a expectation corresponding to a tuple. */ 104/* Just find a expectation corresponding to a tuple. */
109struct nf_conntrack_expect * 105struct nf_conntrack_expect *
110nf_ct_expect_find_get(const struct nf_conntrack_tuple *tuple) 106nf_ct_expect_find_get(struct net *net, const struct nf_conntrack_tuple *tuple)
111{ 107{
112 struct nf_conntrack_expect *i; 108 struct nf_conntrack_expect *i;
113 109
114 rcu_read_lock(); 110 rcu_read_lock();
115 i = __nf_ct_expect_find(tuple); 111 i = __nf_ct_expect_find(net, tuple);
116 if (i && !atomic_inc_not_zero(&i->use)) 112 if (i && !atomic_inc_not_zero(&i->use))
117 i = NULL; 113 i = NULL;
118 rcu_read_unlock(); 114 rcu_read_unlock();
@@ -124,17 +120,17 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_find_get);
124/* If an expectation for this connection is found, it gets delete from 120/* If an expectation for this connection is found, it gets delete from
125 * global list then returned. */ 121 * global list then returned. */
126struct nf_conntrack_expect * 122struct nf_conntrack_expect *
127nf_ct_find_expectation(const struct nf_conntrack_tuple *tuple) 123nf_ct_find_expectation(struct net *net, const struct nf_conntrack_tuple *tuple)
128{ 124{
129 struct nf_conntrack_expect *i, *exp = NULL; 125 struct nf_conntrack_expect *i, *exp = NULL;
130 struct hlist_node *n; 126 struct hlist_node *n;
131 unsigned int h; 127 unsigned int h;
132 128
133 if (!nf_ct_expect_count) 129 if (!net->ct.expect_count)
134 return NULL; 130 return NULL;
135 131
136 h = nf_ct_expect_dst_hash(tuple); 132 h = nf_ct_expect_dst_hash(tuple);
137 hlist_for_each_entry(i, n, &nf_ct_expect_hash[h], hnode) { 133 hlist_for_each_entry(i, n, &net->ct.expect_hash[h], hnode) {
138 if (!(i->flags & NF_CT_EXPECT_INACTIVE) && 134 if (!(i->flags & NF_CT_EXPECT_INACTIVE) &&
139 nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) { 135 nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) {
140 exp = i; 136 exp = i;
@@ -241,7 +237,7 @@ struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me)
241EXPORT_SYMBOL_GPL(nf_ct_expect_alloc); 237EXPORT_SYMBOL_GPL(nf_ct_expect_alloc);
242 238
243void nf_ct_expect_init(struct nf_conntrack_expect *exp, unsigned int class, 239void nf_ct_expect_init(struct nf_conntrack_expect *exp, unsigned int class,
244 int family, 240 u_int8_t family,
245 const union nf_inet_addr *saddr, 241 const union nf_inet_addr *saddr,
246 const union nf_inet_addr *daddr, 242 const union nf_inet_addr *daddr,
247 u_int8_t proto, const __be16 *src, const __be16 *dst) 243 u_int8_t proto, const __be16 *src, const __be16 *dst)
@@ -311,6 +307,7 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_put);
311static void nf_ct_expect_insert(struct nf_conntrack_expect *exp) 307static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
312{ 308{
313 struct nf_conn_help *master_help = nfct_help(exp->master); 309 struct nf_conn_help *master_help = nfct_help(exp->master);
310 struct net *net = nf_ct_exp_net(exp);
314 const struct nf_conntrack_expect_policy *p; 311 const struct nf_conntrack_expect_policy *p;
315 unsigned int h = nf_ct_expect_dst_hash(&exp->tuple); 312 unsigned int h = nf_ct_expect_dst_hash(&exp->tuple);
316 313
@@ -319,8 +316,8 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
319 hlist_add_head(&exp->lnode, &master_help->expectations); 316 hlist_add_head(&exp->lnode, &master_help->expectations);
320 master_help->expecting[exp->class]++; 317 master_help->expecting[exp->class]++;
321 318
322 hlist_add_head_rcu(&exp->hnode, &nf_ct_expect_hash[h]); 319 hlist_add_head_rcu(&exp->hnode, &net->ct.expect_hash[h]);
323 nf_ct_expect_count++; 320 net->ct.expect_count++;
324 321
325 setup_timer(&exp->timeout, nf_ct_expectation_timed_out, 322 setup_timer(&exp->timeout, nf_ct_expectation_timed_out,
326 (unsigned long)exp); 323 (unsigned long)exp);
@@ -329,7 +326,7 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
329 add_timer(&exp->timeout); 326 add_timer(&exp->timeout);
330 327
331 atomic_inc(&exp->use); 328 atomic_inc(&exp->use);
332 NF_CT_STAT_INC(expect_create); 329 NF_CT_STAT_INC(net, expect_create);
333} 330}
334 331
335/* Race with expectations being used means we could have none to find; OK. */ 332/* Race with expectations being used means we could have none to find; OK. */
@@ -371,6 +368,7 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
371 struct nf_conntrack_expect *i; 368 struct nf_conntrack_expect *i;
372 struct nf_conn *master = expect->master; 369 struct nf_conn *master = expect->master;
373 struct nf_conn_help *master_help = nfct_help(master); 370 struct nf_conn_help *master_help = nfct_help(master);
371 struct net *net = nf_ct_exp_net(expect);
374 struct hlist_node *n; 372 struct hlist_node *n;
375 unsigned int h; 373 unsigned int h;
376 int ret; 374 int ret;
@@ -383,7 +381,7 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
383 goto out; 381 goto out;
384 } 382 }
385 h = nf_ct_expect_dst_hash(&expect->tuple); 383 h = nf_ct_expect_dst_hash(&expect->tuple);
386 hlist_for_each_entry(i, n, &nf_ct_expect_hash[h], hnode) { 384 hlist_for_each_entry(i, n, &net->ct.expect_hash[h], hnode) {
387 if (expect_matches(i, expect)) { 385 if (expect_matches(i, expect)) {
388 /* Refresh timer: if it's dying, ignore.. */ 386 /* Refresh timer: if it's dying, ignore.. */
389 if (refresh_timer(i)) { 387 if (refresh_timer(i)) {
@@ -406,7 +404,7 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
406 } 404 }
407 } 405 }
408 406
409 if (nf_ct_expect_count >= nf_ct_expect_max) { 407 if (net->ct.expect_count >= nf_ct_expect_max) {
410 if (net_ratelimit()) 408 if (net_ratelimit())
411 printk(KERN_WARNING 409 printk(KERN_WARNING
412 "nf_conntrack: expectation table full\n"); 410 "nf_conntrack: expectation table full\n");
@@ -425,16 +423,18 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_related);
425 423
426#ifdef CONFIG_PROC_FS 424#ifdef CONFIG_PROC_FS
427struct ct_expect_iter_state { 425struct ct_expect_iter_state {
426 struct seq_net_private p;
428 unsigned int bucket; 427 unsigned int bucket;
429}; 428};
430 429
431static struct hlist_node *ct_expect_get_first(struct seq_file *seq) 430static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
432{ 431{
432 struct net *net = seq_file_net(seq);
433 struct ct_expect_iter_state *st = seq->private; 433 struct ct_expect_iter_state *st = seq->private;
434 struct hlist_node *n; 434 struct hlist_node *n;
435 435
436 for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) { 436 for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
437 n = rcu_dereference(nf_ct_expect_hash[st->bucket].first); 437 n = rcu_dereference(net->ct.expect_hash[st->bucket].first);
438 if (n) 438 if (n)
439 return n; 439 return n;
440 } 440 }
@@ -444,13 +444,14 @@ static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
444static struct hlist_node *ct_expect_get_next(struct seq_file *seq, 444static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
445 struct hlist_node *head) 445 struct hlist_node *head)
446{ 446{
447 struct net *net = seq_file_net(seq);
447 struct ct_expect_iter_state *st = seq->private; 448 struct ct_expect_iter_state *st = seq->private;
448 449
449 head = rcu_dereference(head->next); 450 head = rcu_dereference(head->next);
450 while (head == NULL) { 451 while (head == NULL) {
451 if (++st->bucket >= nf_ct_expect_hsize) 452 if (++st->bucket >= nf_ct_expect_hsize)
452 return NULL; 453 return NULL;
453 head = rcu_dereference(nf_ct_expect_hash[st->bucket].first); 454 head = rcu_dereference(net->ct.expect_hash[st->bucket].first);
454 } 455 }
455 return head; 456 return head;
456} 457}
@@ -524,7 +525,7 @@ static const struct seq_operations exp_seq_ops = {
524 525
525static int exp_open(struct inode *inode, struct file *file) 526static int exp_open(struct inode *inode, struct file *file)
526{ 527{
527 return seq_open_private(file, &exp_seq_ops, 528 return seq_open_net(inode, file, &exp_seq_ops,
528 sizeof(struct ct_expect_iter_state)); 529 sizeof(struct ct_expect_iter_state));
529} 530}
530 531
@@ -533,72 +534,79 @@ static const struct file_operations exp_file_ops = {
533 .open = exp_open, 534 .open = exp_open,
534 .read = seq_read, 535 .read = seq_read,
535 .llseek = seq_lseek, 536 .llseek = seq_lseek,
536 .release = seq_release_private, 537 .release = seq_release_net,
537}; 538};
538#endif /* CONFIG_PROC_FS */ 539#endif /* CONFIG_PROC_FS */
539 540
540static int __init exp_proc_init(void) 541static int exp_proc_init(struct net *net)
541{ 542{
542#ifdef CONFIG_PROC_FS 543#ifdef CONFIG_PROC_FS
543 struct proc_dir_entry *proc; 544 struct proc_dir_entry *proc;
544 545
545 proc = proc_net_fops_create(&init_net, "nf_conntrack_expect", 0440, &exp_file_ops); 546 proc = proc_net_fops_create(net, "nf_conntrack_expect", 0440, &exp_file_ops);
546 if (!proc) 547 if (!proc)
547 return -ENOMEM; 548 return -ENOMEM;
548#endif /* CONFIG_PROC_FS */ 549#endif /* CONFIG_PROC_FS */
549 return 0; 550 return 0;
550} 551}
551 552
552static void exp_proc_remove(void) 553static void exp_proc_remove(struct net *net)
553{ 554{
554#ifdef CONFIG_PROC_FS 555#ifdef CONFIG_PROC_FS
555 proc_net_remove(&init_net, "nf_conntrack_expect"); 556 proc_net_remove(net, "nf_conntrack_expect");
556#endif /* CONFIG_PROC_FS */ 557#endif /* CONFIG_PROC_FS */
557} 558}
558 559
559module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0600); 560module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0600);
560 561
561int __init nf_conntrack_expect_init(void) 562int nf_conntrack_expect_init(struct net *net)
562{ 563{
563 int err = -ENOMEM; 564 int err = -ENOMEM;
564 565
565 if (!nf_ct_expect_hsize) { 566 if (net_eq(net, &init_net)) {
566 nf_ct_expect_hsize = nf_conntrack_htable_size / 256; 567 if (!nf_ct_expect_hsize) {
567 if (!nf_ct_expect_hsize) 568 nf_ct_expect_hsize = nf_conntrack_htable_size / 256;
568 nf_ct_expect_hsize = 1; 569 if (!nf_ct_expect_hsize)
570 nf_ct_expect_hsize = 1;
571 }
572 nf_ct_expect_max = nf_ct_expect_hsize * 4;
569 } 573 }
570 nf_ct_expect_max = nf_ct_expect_hsize * 4;
571 574
572 nf_ct_expect_hash = nf_ct_alloc_hashtable(&nf_ct_expect_hsize, 575 net->ct.expect_count = 0;
573 &nf_ct_expect_vmalloc); 576 net->ct.expect_hash = nf_ct_alloc_hashtable(&nf_ct_expect_hsize,
574 if (nf_ct_expect_hash == NULL) 577 &net->ct.expect_vmalloc);
578 if (net->ct.expect_hash == NULL)
575 goto err1; 579 goto err1;
576 580
577 nf_ct_expect_cachep = kmem_cache_create("nf_conntrack_expect", 581 if (net_eq(net, &init_net)) {
582 nf_ct_expect_cachep = kmem_cache_create("nf_conntrack_expect",
578 sizeof(struct nf_conntrack_expect), 583 sizeof(struct nf_conntrack_expect),
579 0, 0, NULL); 584 0, 0, NULL);
580 if (!nf_ct_expect_cachep) 585 if (!nf_ct_expect_cachep)
581 goto err2; 586 goto err2;
587 }
582 588
583 err = exp_proc_init(); 589 err = exp_proc_init(net);
584 if (err < 0) 590 if (err < 0)
585 goto err3; 591 goto err3;
586 592
587 return 0; 593 return 0;
588 594
589err3: 595err3:
590 kmem_cache_destroy(nf_ct_expect_cachep); 596 if (net_eq(net, &init_net))
597 kmem_cache_destroy(nf_ct_expect_cachep);
591err2: 598err2:
592 nf_ct_free_hashtable(nf_ct_expect_hash, nf_ct_expect_vmalloc, 599 nf_ct_free_hashtable(net->ct.expect_hash, net->ct.expect_vmalloc,
593 nf_ct_expect_hsize); 600 nf_ct_expect_hsize);
594err1: 601err1:
595 return err; 602 return err;
596} 603}
597 604
598void nf_conntrack_expect_fini(void) 605void nf_conntrack_expect_fini(struct net *net)
599{ 606{
600 exp_proc_remove(); 607 exp_proc_remove(net);
601 kmem_cache_destroy(nf_ct_expect_cachep); 608 if (net_eq(net, &init_net))
602 nf_ct_free_hashtable(nf_ct_expect_hash, nf_ct_expect_vmalloc, 609 kmem_cache_destroy(nf_ct_expect_cachep);
610 nf_ct_free_hashtable(net->ct.expect_hash, net->ct.expect_vmalloc,
603 nf_ct_expect_hsize); 611 nf_ct_expect_hsize);
604} 612}
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index bb20672fe036..4f7107107e99 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -318,7 +318,8 @@ static int find_nl_seq(u32 seq, const struct nf_ct_ftp_master *info, int dir)
318} 318}
319 319
320/* We don't update if it's older than what we have. */ 320/* We don't update if it's older than what we have. */
321static void update_nl_seq(u32 nl_seq, struct nf_ct_ftp_master *info, int dir, 321static void update_nl_seq(struct nf_conn *ct, u32 nl_seq,
322 struct nf_ct_ftp_master *info, int dir,
322 struct sk_buff *skb) 323 struct sk_buff *skb)
323{ 324{
324 unsigned int i, oldest = NUM_SEQ_TO_REMEMBER; 325 unsigned int i, oldest = NUM_SEQ_TO_REMEMBER;
@@ -336,11 +337,11 @@ static void update_nl_seq(u32 nl_seq, struct nf_ct_ftp_master *info, int dir,
336 337
337 if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) { 338 if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) {
338 info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq; 339 info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq;
339 nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb); 340 nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, ct);
340 } else if (oldest != NUM_SEQ_TO_REMEMBER && 341 } else if (oldest != NUM_SEQ_TO_REMEMBER &&
341 after(nl_seq, info->seq_aft_nl[dir][oldest])) { 342 after(nl_seq, info->seq_aft_nl[dir][oldest])) {
342 info->seq_aft_nl[dir][oldest] = nl_seq; 343 info->seq_aft_nl[dir][oldest] = nl_seq;
343 nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb); 344 nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, ct);
344 } 345 }
345} 346}
346 347
@@ -509,7 +510,7 @@ out_update_nl:
509 /* Now if this ends in \n, update ftp info. Seq may have been 510 /* Now if this ends in \n, update ftp info. Seq may have been
510 * adjusted by NAT code. */ 511 * adjusted by NAT code. */
511 if (ends_in_nl) 512 if (ends_in_nl)
512 update_nl_seq(seq, ct_ftp_info, dir, skb); 513 update_nl_seq(ct, seq, ct_ftp_info, dir, skb);
513 out: 514 out:
514 spin_unlock_bh(&nf_ftp_lock); 515 spin_unlock_bh(&nf_ftp_lock);
515 return ret; 516 return ret;
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index 2f83c158934d..c1504f71cdff 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -709,7 +709,8 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct,
709/* If the calling party is on the same side of the forward-to party, 709/* If the calling party is on the same side of the forward-to party,
710 * we don't need to track the second call */ 710 * we don't need to track the second call */
711static int callforward_do_filter(const union nf_inet_addr *src, 711static int callforward_do_filter(const union nf_inet_addr *src,
712 const union nf_inet_addr *dst, int family) 712 const union nf_inet_addr *dst,
713 u_int8_t family)
713{ 714{
714 const struct nf_afinfo *afinfo; 715 const struct nf_afinfo *afinfo;
715 struct flowi fl1, fl2; 716 struct flowi fl1, fl2;
@@ -1209,6 +1210,7 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct,
1209 union nf_inet_addr *addr, 1210 union nf_inet_addr *addr,
1210 __be16 port) 1211 __be16 port)
1211{ 1212{
1213 struct net *net = nf_ct_net(ct);
1212 struct nf_conntrack_expect *exp; 1214 struct nf_conntrack_expect *exp;
1213 struct nf_conntrack_tuple tuple; 1215 struct nf_conntrack_tuple tuple;
1214 1216
@@ -1218,7 +1220,7 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct,
1218 tuple.dst.u.tcp.port = port; 1220 tuple.dst.u.tcp.port = port;
1219 tuple.dst.protonum = IPPROTO_TCP; 1221 tuple.dst.protonum = IPPROTO_TCP;
1220 1222
1221 exp = __nf_ct_expect_find(&tuple); 1223 exp = __nf_ct_expect_find(net, &tuple);
1222 if (exp && exp->master == ct) 1224 if (exp && exp->master == ct)
1223 return exp; 1225 return exp;
1224 return NULL; 1226 return NULL;
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 8e0b4c8f62a8..9c06b9f86ad4 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -123,29 +123,18 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
123} 123}
124EXPORT_SYMBOL_GPL(nf_conntrack_helper_register); 124EXPORT_SYMBOL_GPL(nf_conntrack_helper_register);
125 125
126void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) 126static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
127 struct net *net)
127{ 128{
128 struct nf_conntrack_tuple_hash *h; 129 struct nf_conntrack_tuple_hash *h;
129 struct nf_conntrack_expect *exp; 130 struct nf_conntrack_expect *exp;
130 const struct hlist_node *n, *next; 131 const struct hlist_node *n, *next;
131 unsigned int i; 132 unsigned int i;
132 133
133 mutex_lock(&nf_ct_helper_mutex);
134 hlist_del_rcu(&me->hnode);
135 nf_ct_helper_count--;
136 mutex_unlock(&nf_ct_helper_mutex);
137
138 /* Make sure every nothing is still using the helper unless its a
139 * connection in the hash.
140 */
141 synchronize_rcu();
142
143 spin_lock_bh(&nf_conntrack_lock);
144
145 /* Get rid of expectations */ 134 /* Get rid of expectations */
146 for (i = 0; i < nf_ct_expect_hsize; i++) { 135 for (i = 0; i < nf_ct_expect_hsize; i++) {
147 hlist_for_each_entry_safe(exp, n, next, 136 hlist_for_each_entry_safe(exp, n, next,
148 &nf_ct_expect_hash[i], hnode) { 137 &net->ct.expect_hash[i], hnode) {
149 struct nf_conn_help *help = nfct_help(exp->master); 138 struct nf_conn_help *help = nfct_help(exp->master);
150 if ((help->helper == me || exp->helper == me) && 139 if ((help->helper == me || exp->helper == me) &&
151 del_timer(&exp->timeout)) { 140 del_timer(&exp->timeout)) {
@@ -156,12 +145,31 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
156 } 145 }
157 146
158 /* Get rid of expecteds, set helpers to NULL. */ 147 /* Get rid of expecteds, set helpers to NULL. */
159 hlist_for_each_entry(h, n, &unconfirmed, hnode) 148 hlist_for_each_entry(h, n, &net->ct.unconfirmed, hnode)
160 unhelp(h, me); 149 unhelp(h, me);
161 for (i = 0; i < nf_conntrack_htable_size; i++) { 150 for (i = 0; i < nf_conntrack_htable_size; i++) {
162 hlist_for_each_entry(h, n, &nf_conntrack_hash[i], hnode) 151 hlist_for_each_entry(h, n, &net->ct.hash[i], hnode)
163 unhelp(h, me); 152 unhelp(h, me);
164 } 153 }
154}
155
156void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
157{
158 struct net *net;
159
160 mutex_lock(&nf_ct_helper_mutex);
161 hlist_del_rcu(&me->hnode);
162 nf_ct_helper_count--;
163 mutex_unlock(&nf_ct_helper_mutex);
164
165 /* Make sure every nothing is still using the helper unless its a
166 * connection in the hash.
167 */
168 synchronize_rcu();
169
170 spin_lock_bh(&nf_conntrack_lock);
171 for_each_net(net)
172 __nf_conntrack_helper_unregister(me, net);
165 spin_unlock_bh(&nf_conntrack_lock); 173 spin_unlock_bh(&nf_conntrack_lock);
166} 174}
167EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister); 175EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index a8752031adcb..cadfd15b44f6 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -549,7 +549,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
549 last = (struct nf_conn *)cb->args[1]; 549 last = (struct nf_conn *)cb->args[1];
550 for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) { 550 for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
551restart: 551restart:
552 hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[cb->args[0]], 552 hlist_for_each_entry_rcu(h, n, &init_net.ct.hash[cb->args[0]],
553 hnode) { 553 hnode) {
554 if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL) 554 if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
555 continue; 555 continue;
@@ -794,14 +794,14 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
794 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3); 794 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3);
795 else { 795 else {
796 /* Flush the whole table */ 796 /* Flush the whole table */
797 nf_conntrack_flush(); 797 nf_conntrack_flush(&init_net);
798 return 0; 798 return 0;
799 } 799 }
800 800
801 if (err < 0) 801 if (err < 0)
802 return err; 802 return err;
803 803
804 h = nf_conntrack_find_get(&tuple); 804 h = nf_conntrack_find_get(&init_net, &tuple);
805 if (!h) 805 if (!h)
806 return -ENOENT; 806 return -ENOENT;
807 807
@@ -847,7 +847,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
847 if (err < 0) 847 if (err < 0)
848 return err; 848 return err;
849 849
850 h = nf_conntrack_find_get(&tuple); 850 h = nf_conntrack_find_get(&init_net, &tuple);
851 if (!h) 851 if (!h)
852 return -ENOENT; 852 return -ENOENT;
853 853
@@ -1125,7 +1125,7 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
1125 struct nf_conn_help *help; 1125 struct nf_conn_help *help;
1126 struct nf_conntrack_helper *helper; 1126 struct nf_conntrack_helper *helper;
1127 1127
1128 ct = nf_conntrack_alloc(otuple, rtuple, GFP_KERNEL); 1128 ct = nf_conntrack_alloc(&init_net, otuple, rtuple, GFP_KERNEL);
1129 if (ct == NULL || IS_ERR(ct)) 1129 if (ct == NULL || IS_ERR(ct))
1130 return -ENOMEM; 1130 return -ENOMEM;
1131 1131
@@ -1213,9 +1213,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1213 1213
1214 spin_lock_bh(&nf_conntrack_lock); 1214 spin_lock_bh(&nf_conntrack_lock);
1215 if (cda[CTA_TUPLE_ORIG]) 1215 if (cda[CTA_TUPLE_ORIG])
1216 h = __nf_conntrack_find(&otuple); 1216 h = __nf_conntrack_find(&init_net, &otuple);
1217 else if (cda[CTA_TUPLE_REPLY]) 1217 else if (cda[CTA_TUPLE_REPLY])
1218 h = __nf_conntrack_find(&rtuple); 1218 h = __nf_conntrack_find(&init_net, &rtuple);
1219 1219
1220 if (h == NULL) { 1220 if (h == NULL) {
1221 struct nf_conntrack_tuple master; 1221 struct nf_conntrack_tuple master;
@@ -1230,7 +1230,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1230 if (err < 0) 1230 if (err < 0)
1231 goto out_unlock; 1231 goto out_unlock;
1232 1232
1233 master_h = __nf_conntrack_find(&master); 1233 master_h = __nf_conntrack_find(&init_net, &master);
1234 if (master_h == NULL) { 1234 if (master_h == NULL) {
1235 err = -ENOENT; 1235 err = -ENOENT;
1236 goto out_unlock; 1236 goto out_unlock;
@@ -1458,6 +1458,7 @@ static int ctnetlink_exp_done(struct netlink_callback *cb)
1458static int 1458static int
1459ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) 1459ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
1460{ 1460{
1461 struct net *net = &init_net;
1461 struct nf_conntrack_expect *exp, *last; 1462 struct nf_conntrack_expect *exp, *last;
1462 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); 1463 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
1463 struct hlist_node *n; 1464 struct hlist_node *n;
@@ -1467,7 +1468,7 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
1467 last = (struct nf_conntrack_expect *)cb->args[1]; 1468 last = (struct nf_conntrack_expect *)cb->args[1];
1468 for (; cb->args[0] < nf_ct_expect_hsize; cb->args[0]++) { 1469 for (; cb->args[0] < nf_ct_expect_hsize; cb->args[0]++) {
1469restart: 1470restart:
1470 hlist_for_each_entry(exp, n, &nf_ct_expect_hash[cb->args[0]], 1471 hlist_for_each_entry(exp, n, &net->ct.expect_hash[cb->args[0]],
1471 hnode) { 1472 hnode) {
1472 if (l3proto && exp->tuple.src.l3num != l3proto) 1473 if (l3proto && exp->tuple.src.l3num != l3proto)
1473 continue; 1474 continue;
@@ -1529,7 +1530,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1529 if (err < 0) 1530 if (err < 0)
1530 return err; 1531 return err;
1531 1532
1532 exp = nf_ct_expect_find_get(&tuple); 1533 exp = nf_ct_expect_find_get(&init_net, &tuple);
1533 if (!exp) 1534 if (!exp)
1534 return -ENOENT; 1535 return -ENOENT;
1535 1536
@@ -1583,7 +1584,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1583 return err; 1584 return err;
1584 1585
1585 /* bump usage count to 2 */ 1586 /* bump usage count to 2 */
1586 exp = nf_ct_expect_find_get(&tuple); 1587 exp = nf_ct_expect_find_get(&init_net, &tuple);
1587 if (!exp) 1588 if (!exp)
1588 return -ENOENT; 1589 return -ENOENT;
1589 1590
@@ -1613,7 +1614,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1613 } 1614 }
1614 for (i = 0; i < nf_ct_expect_hsize; i++) { 1615 for (i = 0; i < nf_ct_expect_hsize; i++) {
1615 hlist_for_each_entry_safe(exp, n, next, 1616 hlist_for_each_entry_safe(exp, n, next,
1616 &nf_ct_expect_hash[i], 1617 &init_net.ct.expect_hash[i],
1617 hnode) { 1618 hnode) {
1618 m_help = nfct_help(exp->master); 1619 m_help = nfct_help(exp->master);
1619 if (m_help->helper == h 1620 if (m_help->helper == h
@@ -1629,7 +1630,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1629 spin_lock_bh(&nf_conntrack_lock); 1630 spin_lock_bh(&nf_conntrack_lock);
1630 for (i = 0; i < nf_ct_expect_hsize; i++) { 1631 for (i = 0; i < nf_ct_expect_hsize; i++) {
1631 hlist_for_each_entry_safe(exp, n, next, 1632 hlist_for_each_entry_safe(exp, n, next,
1632 &nf_ct_expect_hash[i], 1633 &init_net.ct.expect_hash[i],
1633 hnode) { 1634 hnode) {
1634 if (del_timer(&exp->timeout)) { 1635 if (del_timer(&exp->timeout)) {
1635 nf_ct_unlink_expect(exp); 1636 nf_ct_unlink_expect(exp);
@@ -1670,7 +1671,7 @@ ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3)
1670 return err; 1671 return err;
1671 1672
1672 /* Look for master conntrack of this expectation */ 1673 /* Look for master conntrack of this expectation */
1673 h = nf_conntrack_find_get(&master_tuple); 1674 h = nf_conntrack_find_get(&init_net, &master_tuple);
1674 if (!h) 1675 if (!h)
1675 return -ENOENT; 1676 return -ENOENT;
1676 ct = nf_ct_tuplehash_to_ctrack(h); 1677 ct = nf_ct_tuplehash_to_ctrack(h);
@@ -1724,7 +1725,7 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
1724 return err; 1725 return err;
1725 1726
1726 spin_lock_bh(&nf_conntrack_lock); 1727 spin_lock_bh(&nf_conntrack_lock);
1727 exp = __nf_ct_expect_find(&tuple); 1728 exp = __nf_ct_expect_find(&init_net, &tuple);
1728 1729
1729 if (!exp) { 1730 if (!exp) {
1730 spin_unlock_bh(&nf_conntrack_lock); 1731 spin_unlock_bh(&nf_conntrack_lock);
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 97e54b0e43a3..373e51e91ce5 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -98,6 +98,7 @@ EXPORT_SYMBOL(pptp_msg_name);
98static void pptp_expectfn(struct nf_conn *ct, 98static void pptp_expectfn(struct nf_conn *ct,
99 struct nf_conntrack_expect *exp) 99 struct nf_conntrack_expect *exp)
100{ 100{
101 struct net *net = nf_ct_net(ct);
101 typeof(nf_nat_pptp_hook_expectfn) nf_nat_pptp_expectfn; 102 typeof(nf_nat_pptp_hook_expectfn) nf_nat_pptp_expectfn;
102 pr_debug("increasing timeouts\n"); 103 pr_debug("increasing timeouts\n");
103 104
@@ -121,7 +122,7 @@ static void pptp_expectfn(struct nf_conn *ct,
121 pr_debug("trying to unexpect other dir: "); 122 pr_debug("trying to unexpect other dir: ");
122 nf_ct_dump_tuple(&inv_t); 123 nf_ct_dump_tuple(&inv_t);
123 124
124 exp_other = nf_ct_expect_find_get(&inv_t); 125 exp_other = nf_ct_expect_find_get(net, &inv_t);
125 if (exp_other) { 126 if (exp_other) {
126 /* delete other expectation. */ 127 /* delete other expectation. */
127 pr_debug("found\n"); 128 pr_debug("found\n");
@@ -134,7 +135,8 @@ static void pptp_expectfn(struct nf_conn *ct,
134 rcu_read_unlock(); 135 rcu_read_unlock();
135} 136}
136 137
137static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t) 138static int destroy_sibling_or_exp(struct net *net,
139 const struct nf_conntrack_tuple *t)
138{ 140{
139 const struct nf_conntrack_tuple_hash *h; 141 const struct nf_conntrack_tuple_hash *h;
140 struct nf_conntrack_expect *exp; 142 struct nf_conntrack_expect *exp;
@@ -143,7 +145,7 @@ static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
143 pr_debug("trying to timeout ct or exp for tuple "); 145 pr_debug("trying to timeout ct or exp for tuple ");
144 nf_ct_dump_tuple(t); 146 nf_ct_dump_tuple(t);
145 147
146 h = nf_conntrack_find_get(t); 148 h = nf_conntrack_find_get(net, t);
147 if (h) { 149 if (h) {
148 sibling = nf_ct_tuplehash_to_ctrack(h); 150 sibling = nf_ct_tuplehash_to_ctrack(h);
149 pr_debug("setting timeout of conntrack %p to 0\n", sibling); 151 pr_debug("setting timeout of conntrack %p to 0\n", sibling);
@@ -154,7 +156,7 @@ static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
154 nf_ct_put(sibling); 156 nf_ct_put(sibling);
155 return 1; 157 return 1;
156 } else { 158 } else {
157 exp = nf_ct_expect_find_get(t); 159 exp = nf_ct_expect_find_get(net, t);
158 if (exp) { 160 if (exp) {
159 pr_debug("unexpect_related of expect %p\n", exp); 161 pr_debug("unexpect_related of expect %p\n", exp);
160 nf_ct_unexpect_related(exp); 162 nf_ct_unexpect_related(exp);
@@ -168,6 +170,7 @@ static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
168/* timeout GRE data connections */ 170/* timeout GRE data connections */
169static void pptp_destroy_siblings(struct nf_conn *ct) 171static void pptp_destroy_siblings(struct nf_conn *ct)
170{ 172{
173 struct net *net = nf_ct_net(ct);
171 const struct nf_conn_help *help = nfct_help(ct); 174 const struct nf_conn_help *help = nfct_help(ct);
172 struct nf_conntrack_tuple t; 175 struct nf_conntrack_tuple t;
173 176
@@ -178,7 +181,7 @@ static void pptp_destroy_siblings(struct nf_conn *ct)
178 t.dst.protonum = IPPROTO_GRE; 181 t.dst.protonum = IPPROTO_GRE;
179 t.src.u.gre.key = help->help.ct_pptp_info.pns_call_id; 182 t.src.u.gre.key = help->help.ct_pptp_info.pns_call_id;
180 t.dst.u.gre.key = help->help.ct_pptp_info.pac_call_id; 183 t.dst.u.gre.key = help->help.ct_pptp_info.pac_call_id;
181 if (!destroy_sibling_or_exp(&t)) 184 if (!destroy_sibling_or_exp(net, &t))
182 pr_debug("failed to timeout original pns->pac ct/exp\n"); 185 pr_debug("failed to timeout original pns->pac ct/exp\n");
183 186
184 /* try reply (pac->pns) tuple */ 187 /* try reply (pac->pns) tuple */
@@ -186,7 +189,7 @@ static void pptp_destroy_siblings(struct nf_conn *ct)
186 t.dst.protonum = IPPROTO_GRE; 189 t.dst.protonum = IPPROTO_GRE;
187 t.src.u.gre.key = help->help.ct_pptp_info.pac_call_id; 190 t.src.u.gre.key = help->help.ct_pptp_info.pac_call_id;
188 t.dst.u.gre.key = help->help.ct_pptp_info.pns_call_id; 191 t.dst.u.gre.key = help->help.ct_pptp_info.pns_call_id;
189 if (!destroy_sibling_or_exp(&t)) 192 if (!destroy_sibling_or_exp(net, &t))
190 pr_debug("failed to timeout reply pac->pns ct/exp\n"); 193 pr_debug("failed to timeout reply pac->pns ct/exp\n");
191} 194}
192 195
@@ -594,15 +597,32 @@ static struct nf_conntrack_helper pptp __read_mostly = {
594 .expect_policy = &pptp_exp_policy, 597 .expect_policy = &pptp_exp_policy,
595}; 598};
596 599
600static void nf_conntrack_pptp_net_exit(struct net *net)
601{
602 nf_ct_gre_keymap_flush(net);
603}
604
605static struct pernet_operations nf_conntrack_pptp_net_ops = {
606 .exit = nf_conntrack_pptp_net_exit,
607};
608
597static int __init nf_conntrack_pptp_init(void) 609static int __init nf_conntrack_pptp_init(void)
598{ 610{
599 return nf_conntrack_helper_register(&pptp); 611 int rv;
612
613 rv = nf_conntrack_helper_register(&pptp);
614 if (rv < 0)
615 return rv;
616 rv = register_pernet_subsys(&nf_conntrack_pptp_net_ops);
617 if (rv < 0)
618 nf_conntrack_helper_unregister(&pptp);
619 return rv;
600} 620}
601 621
602static void __exit nf_conntrack_pptp_fini(void) 622static void __exit nf_conntrack_pptp_fini(void)
603{ 623{
604 nf_conntrack_helper_unregister(&pptp); 624 nf_conntrack_helper_unregister(&pptp);
605 nf_ct_gre_keymap_flush(); 625 unregister_pernet_subsys(&nf_conntrack_pptp_net_ops);
606} 626}
607 627
608module_init(nf_conntrack_pptp_init); 628module_init(nf_conntrack_pptp_init);
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index a49fc932629b..a59a307e685d 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -207,6 +207,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register);
207 207
208void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto) 208void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
209{ 209{
210 struct net *net;
211
210 BUG_ON(proto->l3proto >= AF_MAX); 212 BUG_ON(proto->l3proto >= AF_MAX);
211 213
212 mutex_lock(&nf_ct_proto_mutex); 214 mutex_lock(&nf_ct_proto_mutex);
@@ -219,7 +221,8 @@ void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
219 synchronize_rcu(); 221 synchronize_rcu();
220 222
221 /* Remove all contrack entries for this protocol */ 223 /* Remove all contrack entries for this protocol */
222 nf_ct_iterate_cleanup(kill_l3proto, proto); 224 for_each_net(net)
225 nf_ct_iterate_cleanup(net, kill_l3proto, proto);
223} 226}
224EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister); 227EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister);
225 228
@@ -316,6 +319,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register);
316 319
317void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto) 320void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
318{ 321{
322 struct net *net;
323
319 BUG_ON(l4proto->l3proto >= PF_MAX); 324 BUG_ON(l4proto->l3proto >= PF_MAX);
320 325
321 mutex_lock(&nf_ct_proto_mutex); 326 mutex_lock(&nf_ct_proto_mutex);
@@ -328,7 +333,8 @@ void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
328 synchronize_rcu(); 333 synchronize_rcu();
329 334
330 /* Remove all contrack entries for this protocol */ 335 /* Remove all contrack entries for this protocol */
331 nf_ct_iterate_cleanup(kill_l4proto, l4proto); 336 for_each_net(net)
337 nf_ct_iterate_cleanup(net, kill_l4proto, l4proto);
332} 338}
333EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister); 339EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister);
334 340
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index e7866dd3cde6..8fcf1762fabf 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -418,6 +418,7 @@ static bool dccp_invert_tuple(struct nf_conntrack_tuple *inv,
418static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb, 418static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
419 unsigned int dataoff) 419 unsigned int dataoff)
420{ 420{
421 struct net *net = nf_ct_net(ct);
421 struct dccp_hdr _dh, *dh; 422 struct dccp_hdr _dh, *dh;
422 const char *msg; 423 const char *msg;
423 u_int8_t state; 424 u_int8_t state;
@@ -445,7 +446,7 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
445 return true; 446 return true;
446 447
447out_invalid: 448out_invalid:
448 if (LOG_INVALID(IPPROTO_DCCP)) 449 if (LOG_INVALID(net, IPPROTO_DCCP))
449 nf_log_packet(nf_ct_l3num(ct), 0, skb, NULL, NULL, NULL, msg); 450 nf_log_packet(nf_ct_l3num(ct), 0, skb, NULL, NULL, NULL, msg);
450 return false; 451 return false;
451} 452}
@@ -461,8 +462,9 @@ static u64 dccp_ack_seq(const struct dccp_hdr *dh)
461 462
462static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb, 463static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
463 unsigned int dataoff, enum ip_conntrack_info ctinfo, 464 unsigned int dataoff, enum ip_conntrack_info ctinfo,
464 int pf, unsigned int hooknum) 465 u_int8_t pf, unsigned int hooknum)
465{ 466{
467 struct net *net = nf_ct_net(ct);
466 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 468 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
467 struct dccp_hdr _dh, *dh; 469 struct dccp_hdr _dh, *dh;
468 u_int8_t type, old_state, new_state; 470 u_int8_t type, old_state, new_state;
@@ -524,13 +526,13 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
524 ct->proto.dccp.last_pkt = type; 526 ct->proto.dccp.last_pkt = type;
525 527
526 write_unlock_bh(&dccp_lock); 528 write_unlock_bh(&dccp_lock);
527 if (LOG_INVALID(IPPROTO_DCCP)) 529 if (LOG_INVALID(net, IPPROTO_DCCP))
528 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 530 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
529 "nf_ct_dccp: invalid packet ignored "); 531 "nf_ct_dccp: invalid packet ignored ");
530 return NF_ACCEPT; 532 return NF_ACCEPT;
531 case CT_DCCP_INVALID: 533 case CT_DCCP_INVALID:
532 write_unlock_bh(&dccp_lock); 534 write_unlock_bh(&dccp_lock);
533 if (LOG_INVALID(IPPROTO_DCCP)) 535 if (LOG_INVALID(net, IPPROTO_DCCP))
534 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 536 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
535 "nf_ct_dccp: invalid state transition "); 537 "nf_ct_dccp: invalid state transition ");
536 return -NF_ACCEPT; 538 return -NF_ACCEPT;
@@ -545,9 +547,9 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
545 return NF_ACCEPT; 547 return NF_ACCEPT;
546} 548}
547 549
548static int dccp_error(struct sk_buff *skb, unsigned int dataoff, 550static int dccp_error(struct net *net, struct sk_buff *skb,
549 enum ip_conntrack_info *ctinfo, int pf, 551 unsigned int dataoff, enum ip_conntrack_info *ctinfo,
550 unsigned int hooknum) 552 u_int8_t pf, unsigned int hooknum)
551{ 553{
552 struct dccp_hdr _dh, *dh; 554 struct dccp_hdr _dh, *dh;
553 unsigned int dccp_len = skb->len - dataoff; 555 unsigned int dccp_len = skb->len - dataoff;
@@ -575,7 +577,7 @@ static int dccp_error(struct sk_buff *skb, unsigned int dataoff,
575 } 577 }
576 } 578 }
577 579
578 if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && 580 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
579 nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_DCCP, 581 nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_DCCP,
580 pf)) { 582 pf)) {
581 msg = "nf_ct_dccp: bad checksum "; 583 msg = "nf_ct_dccp: bad checksum ";
@@ -590,7 +592,7 @@ static int dccp_error(struct sk_buff *skb, unsigned int dataoff,
590 return NF_ACCEPT; 592 return NF_ACCEPT;
591 593
592out_invalid: 594out_invalid:
593 if (LOG_INVALID(IPPROTO_DCCP)) 595 if (LOG_INVALID(net, IPPROTO_DCCP))
594 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, msg); 596 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, msg);
595 return -NF_ACCEPT; 597 return -NF_ACCEPT;
596} 598}
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index e31b0e7bd0b1..dbe680af85d2 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -45,7 +45,7 @@ static int packet(struct nf_conn *ct,
45 const struct sk_buff *skb, 45 const struct sk_buff *skb,
46 unsigned int dataoff, 46 unsigned int dataoff,
47 enum ip_conntrack_info ctinfo, 47 enum ip_conntrack_info ctinfo,
48 int pf, 48 u_int8_t pf,
49 unsigned int hooknum) 49 unsigned int hooknum)
50{ 50{
51 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_generic_timeout); 51 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_generic_timeout);
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index 9bd03967fea4..a2cdbcbf64c4 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -29,8 +29,11 @@
29#include <linux/list.h> 29#include <linux/list.h>
30#include <linux/seq_file.h> 30#include <linux/seq_file.h>
31#include <linux/in.h> 31#include <linux/in.h>
32#include <linux/netdevice.h>
32#include <linux/skbuff.h> 33#include <linux/skbuff.h>
33 34#include <net/dst.h>
35#include <net/net_namespace.h>
36#include <net/netns/generic.h>
34#include <net/netfilter/nf_conntrack_l4proto.h> 37#include <net/netfilter/nf_conntrack_l4proto.h>
35#include <net/netfilter/nf_conntrack_helper.h> 38#include <net/netfilter/nf_conntrack_helper.h>
36#include <net/netfilter/nf_conntrack_core.h> 39#include <net/netfilter/nf_conntrack_core.h>
@@ -40,19 +43,23 @@
40#define GRE_TIMEOUT (30 * HZ) 43#define GRE_TIMEOUT (30 * HZ)
41#define GRE_STREAM_TIMEOUT (180 * HZ) 44#define GRE_STREAM_TIMEOUT (180 * HZ)
42 45
43static DEFINE_RWLOCK(nf_ct_gre_lock); 46static int proto_gre_net_id;
44static LIST_HEAD(gre_keymap_list); 47struct netns_proto_gre {
48 rwlock_t keymap_lock;
49 struct list_head keymap_list;
50};
45 51
46void nf_ct_gre_keymap_flush(void) 52void nf_ct_gre_keymap_flush(struct net *net)
47{ 53{
54 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
48 struct nf_ct_gre_keymap *km, *tmp; 55 struct nf_ct_gre_keymap *km, *tmp;
49 56
50 write_lock_bh(&nf_ct_gre_lock); 57 write_lock_bh(&net_gre->keymap_lock);
51 list_for_each_entry_safe(km, tmp, &gre_keymap_list, list) { 58 list_for_each_entry_safe(km, tmp, &net_gre->keymap_list, list) {
52 list_del(&km->list); 59 list_del(&km->list);
53 kfree(km); 60 kfree(km);
54 } 61 }
55 write_unlock_bh(&nf_ct_gre_lock); 62 write_unlock_bh(&net_gre->keymap_lock);
56} 63}
57EXPORT_SYMBOL(nf_ct_gre_keymap_flush); 64EXPORT_SYMBOL(nf_ct_gre_keymap_flush);
58 65
@@ -67,19 +74,20 @@ static inline int gre_key_cmpfn(const struct nf_ct_gre_keymap *km,
67} 74}
68 75
69/* look up the source key for a given tuple */ 76/* look up the source key for a given tuple */
70static __be16 gre_keymap_lookup(struct nf_conntrack_tuple *t) 77static __be16 gre_keymap_lookup(struct net *net, struct nf_conntrack_tuple *t)
71{ 78{
79 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
72 struct nf_ct_gre_keymap *km; 80 struct nf_ct_gre_keymap *km;
73 __be16 key = 0; 81 __be16 key = 0;
74 82
75 read_lock_bh(&nf_ct_gre_lock); 83 read_lock_bh(&net_gre->keymap_lock);
76 list_for_each_entry(km, &gre_keymap_list, list) { 84 list_for_each_entry(km, &net_gre->keymap_list, list) {
77 if (gre_key_cmpfn(km, t)) { 85 if (gre_key_cmpfn(km, t)) {
78 key = km->tuple.src.u.gre.key; 86 key = km->tuple.src.u.gre.key;
79 break; 87 break;
80 } 88 }
81 } 89 }
82 read_unlock_bh(&nf_ct_gre_lock); 90 read_unlock_bh(&net_gre->keymap_lock);
83 91
84 pr_debug("lookup src key 0x%x for ", key); 92 pr_debug("lookup src key 0x%x for ", key);
85 nf_ct_dump_tuple(t); 93 nf_ct_dump_tuple(t);
@@ -91,20 +99,22 @@ static __be16 gre_keymap_lookup(struct nf_conntrack_tuple *t)
91int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, 99int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
92 struct nf_conntrack_tuple *t) 100 struct nf_conntrack_tuple *t)
93{ 101{
102 struct net *net = nf_ct_net(ct);
103 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
94 struct nf_conn_help *help = nfct_help(ct); 104 struct nf_conn_help *help = nfct_help(ct);
95 struct nf_ct_gre_keymap **kmp, *km; 105 struct nf_ct_gre_keymap **kmp, *km;
96 106
97 kmp = &help->help.ct_pptp_info.keymap[dir]; 107 kmp = &help->help.ct_pptp_info.keymap[dir];
98 if (*kmp) { 108 if (*kmp) {
99 /* check whether it's a retransmission */ 109 /* check whether it's a retransmission */
100 read_lock_bh(&nf_ct_gre_lock); 110 read_lock_bh(&net_gre->keymap_lock);
101 list_for_each_entry(km, &gre_keymap_list, list) { 111 list_for_each_entry(km, &net_gre->keymap_list, list) {
102 if (gre_key_cmpfn(km, t) && km == *kmp) { 112 if (gre_key_cmpfn(km, t) && km == *kmp) {
103 read_unlock_bh(&nf_ct_gre_lock); 113 read_unlock_bh(&net_gre->keymap_lock);
104 return 0; 114 return 0;
105 } 115 }
106 } 116 }
107 read_unlock_bh(&nf_ct_gre_lock); 117 read_unlock_bh(&net_gre->keymap_lock);
108 pr_debug("trying to override keymap_%s for ct %p\n", 118 pr_debug("trying to override keymap_%s for ct %p\n",
109 dir == IP_CT_DIR_REPLY ? "reply" : "orig", ct); 119 dir == IP_CT_DIR_REPLY ? "reply" : "orig", ct);
110 return -EEXIST; 120 return -EEXIST;
@@ -119,9 +129,9 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
119 pr_debug("adding new entry %p: ", km); 129 pr_debug("adding new entry %p: ", km);
120 nf_ct_dump_tuple(&km->tuple); 130 nf_ct_dump_tuple(&km->tuple);
121 131
122 write_lock_bh(&nf_ct_gre_lock); 132 write_lock_bh(&net_gre->keymap_lock);
123 list_add_tail(&km->list, &gre_keymap_list); 133 list_add_tail(&km->list, &net_gre->keymap_list);
124 write_unlock_bh(&nf_ct_gre_lock); 134 write_unlock_bh(&net_gre->keymap_lock);
125 135
126 return 0; 136 return 0;
127} 137}
@@ -130,12 +140,14 @@ EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_add);
130/* destroy the keymap entries associated with specified master ct */ 140/* destroy the keymap entries associated with specified master ct */
131void nf_ct_gre_keymap_destroy(struct nf_conn *ct) 141void nf_ct_gre_keymap_destroy(struct nf_conn *ct)
132{ 142{
143 struct net *net = nf_ct_net(ct);
144 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
133 struct nf_conn_help *help = nfct_help(ct); 145 struct nf_conn_help *help = nfct_help(ct);
134 enum ip_conntrack_dir dir; 146 enum ip_conntrack_dir dir;
135 147
136 pr_debug("entering for ct %p\n", ct); 148 pr_debug("entering for ct %p\n", ct);
137 149
138 write_lock_bh(&nf_ct_gre_lock); 150 write_lock_bh(&net_gre->keymap_lock);
139 for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) { 151 for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) {
140 if (help->help.ct_pptp_info.keymap[dir]) { 152 if (help->help.ct_pptp_info.keymap[dir]) {
141 pr_debug("removing %p from list\n", 153 pr_debug("removing %p from list\n",
@@ -145,7 +157,7 @@ void nf_ct_gre_keymap_destroy(struct nf_conn *ct)
145 help->help.ct_pptp_info.keymap[dir] = NULL; 157 help->help.ct_pptp_info.keymap[dir] = NULL;
146 } 158 }
147 } 159 }
148 write_unlock_bh(&nf_ct_gre_lock); 160 write_unlock_bh(&net_gre->keymap_lock);
149} 161}
150EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_destroy); 162EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_destroy);
151 163
@@ -164,6 +176,7 @@ static bool gre_invert_tuple(struct nf_conntrack_tuple *tuple,
164static bool gre_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, 176static bool gre_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
165 struct nf_conntrack_tuple *tuple) 177 struct nf_conntrack_tuple *tuple)
166{ 178{
179 struct net *net = dev_net(skb->dev ? skb->dev : skb->dst->dev);
167 const struct gre_hdr_pptp *pgrehdr; 180 const struct gre_hdr_pptp *pgrehdr;
168 struct gre_hdr_pptp _pgrehdr; 181 struct gre_hdr_pptp _pgrehdr;
169 __be16 srckey; 182 __be16 srckey;
@@ -190,7 +203,7 @@ static bool gre_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
190 } 203 }
191 204
192 tuple->dst.u.gre.key = pgrehdr->call_id; 205 tuple->dst.u.gre.key = pgrehdr->call_id;
193 srckey = gre_keymap_lookup(tuple); 206 srckey = gre_keymap_lookup(net, tuple);
194 tuple->src.u.gre.key = srckey; 207 tuple->src.u.gre.key = srckey;
195 208
196 return true; 209 return true;
@@ -219,7 +232,7 @@ static int gre_packet(struct nf_conn *ct,
219 const struct sk_buff *skb, 232 const struct sk_buff *skb,
220 unsigned int dataoff, 233 unsigned int dataoff,
221 enum ip_conntrack_info ctinfo, 234 enum ip_conntrack_info ctinfo,
222 int pf, 235 u_int8_t pf,
223 unsigned int hooknum) 236 unsigned int hooknum)
224{ 237{
225 /* If we've seen traffic both ways, this is a GRE connection. 238 /* If we've seen traffic both ways, this is a GRE connection.
@@ -229,7 +242,7 @@ static int gre_packet(struct nf_conn *ct,
229 ct->proto.gre.stream_timeout); 242 ct->proto.gre.stream_timeout);
230 /* Also, more likely to be important, and not a probe. */ 243 /* Also, more likely to be important, and not a probe. */
231 set_bit(IPS_ASSURED_BIT, &ct->status); 244 set_bit(IPS_ASSURED_BIT, &ct->status);
232 nf_conntrack_event_cache(IPCT_STATUS, skb); 245 nf_conntrack_event_cache(IPCT_STATUS, ct);
233 } else 246 } else
234 nf_ct_refresh_acct(ct, ctinfo, skb, 247 nf_ct_refresh_acct(ct, ctinfo, skb,
235 ct->proto.gre.timeout); 248 ct->proto.gre.timeout);
@@ -285,15 +298,53 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = {
285#endif 298#endif
286}; 299};
287 300
301static int proto_gre_net_init(struct net *net)
302{
303 struct netns_proto_gre *net_gre;
304 int rv;
305
306 net_gre = kmalloc(sizeof(struct netns_proto_gre), GFP_KERNEL);
307 if (!net_gre)
308 return -ENOMEM;
309 rwlock_init(&net_gre->keymap_lock);
310 INIT_LIST_HEAD(&net_gre->keymap_list);
311
312 rv = net_assign_generic(net, proto_gre_net_id, net_gre);
313 if (rv < 0)
314 kfree(net_gre);
315 return rv;
316}
317
318static void proto_gre_net_exit(struct net *net)
319{
320 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
321
322 nf_ct_gre_keymap_flush(net);
323 kfree(net_gre);
324}
325
326static struct pernet_operations proto_gre_net_ops = {
327 .init = proto_gre_net_init,
328 .exit = proto_gre_net_exit,
329};
330
288static int __init nf_ct_proto_gre_init(void) 331static int __init nf_ct_proto_gre_init(void)
289{ 332{
290 return nf_conntrack_l4proto_register(&nf_conntrack_l4proto_gre4); 333 int rv;
334
335 rv = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_gre4);
336 if (rv < 0)
337 return rv;
338 rv = register_pernet_gen_device(&proto_gre_net_id, &proto_gre_net_ops);
339 if (rv < 0)
340 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4);
341 return rv;
291} 342}
292 343
293static void nf_ct_proto_gre_fini(void) 344static void nf_ct_proto_gre_fini(void)
294{ 345{
295 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4); 346 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4);
296 nf_ct_gre_keymap_flush(); 347 unregister_pernet_gen_device(proto_gre_net_id, &proto_gre_net_ops);
297} 348}
298 349
299module_init(nf_ct_proto_gre_init); 350module_init(nf_ct_proto_gre_init);
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 30aa5b94a771..ae8c2609e230 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -287,7 +287,7 @@ static int sctp_packet(struct nf_conn *ct,
287 const struct sk_buff *skb, 287 const struct sk_buff *skb,
288 unsigned int dataoff, 288 unsigned int dataoff,
289 enum ip_conntrack_info ctinfo, 289 enum ip_conntrack_info ctinfo,
290 int pf, 290 u_int8_t pf,
291 unsigned int hooknum) 291 unsigned int hooknum)
292{ 292{
293 enum sctp_conntrack new_state, old_state; 293 enum sctp_conntrack new_state, old_state;
@@ -369,7 +369,7 @@ static int sctp_packet(struct nf_conn *ct,
369 369
370 ct->proto.sctp.state = new_state; 370 ct->proto.sctp.state = new_state;
371 if (old_state != new_state) 371 if (old_state != new_state)
372 nf_conntrack_event_cache(IPCT_PROTOINFO, skb); 372 nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
373 } 373 }
374 write_unlock_bh(&sctp_lock); 374 write_unlock_bh(&sctp_lock);
375 375
@@ -380,7 +380,7 @@ static int sctp_packet(struct nf_conn *ct,
380 new_state == SCTP_CONNTRACK_ESTABLISHED) { 380 new_state == SCTP_CONNTRACK_ESTABLISHED) {
381 pr_debug("Setting assured bit\n"); 381 pr_debug("Setting assured bit\n");
382 set_bit(IPS_ASSURED_BIT, &ct->status); 382 set_bit(IPS_ASSURED_BIT, &ct->status);
383 nf_conntrack_event_cache(IPCT_STATUS, skb); 383 nf_conntrack_event_cache(IPCT_STATUS, ct);
384 } 384 }
385 385
386 return NF_ACCEPT; 386 return NF_ACCEPT;
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 6f61261888ef..f947ec41e391 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -486,8 +486,9 @@ static bool tcp_in_window(const struct nf_conn *ct,
486 const struct sk_buff *skb, 486 const struct sk_buff *skb,
487 unsigned int dataoff, 487 unsigned int dataoff,
488 const struct tcphdr *tcph, 488 const struct tcphdr *tcph,
489 int pf) 489 u_int8_t pf)
490{ 490{
491 struct net *net = nf_ct_net(ct);
491 struct ip_ct_tcp_state *sender = &state->seen[dir]; 492 struct ip_ct_tcp_state *sender = &state->seen[dir];
492 struct ip_ct_tcp_state *receiver = &state->seen[!dir]; 493 struct ip_ct_tcp_state *receiver = &state->seen[!dir];
493 const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; 494 const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
@@ -668,7 +669,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
668 if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL || 669 if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL ||
669 nf_ct_tcp_be_liberal) 670 nf_ct_tcp_be_liberal)
670 res = true; 671 res = true;
671 if (!res && LOG_INVALID(IPPROTO_TCP)) 672 if (!res && LOG_INVALID(net, IPPROTO_TCP))
672 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 673 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
673 "nf_ct_tcp: %s ", 674 "nf_ct_tcp: %s ",
674 before(seq, sender->td_maxend + 1) ? 675 before(seq, sender->td_maxend + 1) ?
@@ -746,10 +747,11 @@ static const u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG) + 1] =
746}; 747};
747 748
748/* Protect conntrack agaist broken packets. Code taken from ipt_unclean.c. */ 749/* Protect conntrack agaist broken packets. Code taken from ipt_unclean.c. */
749static int tcp_error(struct sk_buff *skb, 750static int tcp_error(struct net *net,
751 struct sk_buff *skb,
750 unsigned int dataoff, 752 unsigned int dataoff,
751 enum ip_conntrack_info *ctinfo, 753 enum ip_conntrack_info *ctinfo,
752 int pf, 754 u_int8_t pf,
753 unsigned int hooknum) 755 unsigned int hooknum)
754{ 756{
755 const struct tcphdr *th; 757 const struct tcphdr *th;
@@ -760,7 +762,7 @@ static int tcp_error(struct sk_buff *skb,
760 /* Smaller that minimal TCP header? */ 762 /* Smaller that minimal TCP header? */
761 th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph); 763 th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
762 if (th == NULL) { 764 if (th == NULL) {
763 if (LOG_INVALID(IPPROTO_TCP)) 765 if (LOG_INVALID(net, IPPROTO_TCP))
764 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 766 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
765 "nf_ct_tcp: short packet "); 767 "nf_ct_tcp: short packet ");
766 return -NF_ACCEPT; 768 return -NF_ACCEPT;
@@ -768,7 +770,7 @@ static int tcp_error(struct sk_buff *skb,
768 770
769 /* Not whole TCP header or malformed packet */ 771 /* Not whole TCP header or malformed packet */
770 if (th->doff*4 < sizeof(struct tcphdr) || tcplen < th->doff*4) { 772 if (th->doff*4 < sizeof(struct tcphdr) || tcplen < th->doff*4) {
771 if (LOG_INVALID(IPPROTO_TCP)) 773 if (LOG_INVALID(net, IPPROTO_TCP))
772 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 774 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
773 "nf_ct_tcp: truncated/malformed packet "); 775 "nf_ct_tcp: truncated/malformed packet ");
774 return -NF_ACCEPT; 776 return -NF_ACCEPT;
@@ -779,9 +781,9 @@ static int tcp_error(struct sk_buff *skb,
779 * because the checksum is assumed to be correct. 781 * because the checksum is assumed to be correct.
780 */ 782 */
781 /* FIXME: Source route IP option packets --RR */ 783 /* FIXME: Source route IP option packets --RR */
782 if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && 784 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
783 nf_checksum(skb, hooknum, dataoff, IPPROTO_TCP, pf)) { 785 nf_checksum(skb, hooknum, dataoff, IPPROTO_TCP, pf)) {
784 if (LOG_INVALID(IPPROTO_TCP)) 786 if (LOG_INVALID(net, IPPROTO_TCP))
785 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 787 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
786 "nf_ct_tcp: bad TCP checksum "); 788 "nf_ct_tcp: bad TCP checksum ");
787 return -NF_ACCEPT; 789 return -NF_ACCEPT;
@@ -790,7 +792,7 @@ static int tcp_error(struct sk_buff *skb,
790 /* Check TCP flags. */ 792 /* Check TCP flags. */
791 tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|TH_CWR|TH_PUSH)); 793 tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|TH_CWR|TH_PUSH));
792 if (!tcp_valid_flags[tcpflags]) { 794 if (!tcp_valid_flags[tcpflags]) {
793 if (LOG_INVALID(IPPROTO_TCP)) 795 if (LOG_INVALID(net, IPPROTO_TCP))
794 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 796 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
795 "nf_ct_tcp: invalid TCP flag combination "); 797 "nf_ct_tcp: invalid TCP flag combination ");
796 return -NF_ACCEPT; 798 return -NF_ACCEPT;
@@ -804,9 +806,10 @@ static int tcp_packet(struct nf_conn *ct,
804 const struct sk_buff *skb, 806 const struct sk_buff *skb,
805 unsigned int dataoff, 807 unsigned int dataoff,
806 enum ip_conntrack_info ctinfo, 808 enum ip_conntrack_info ctinfo,
807 int pf, 809 u_int8_t pf,
808 unsigned int hooknum) 810 unsigned int hooknum)
809{ 811{
812 struct net *net = nf_ct_net(ct);
810 struct nf_conntrack_tuple *tuple; 813 struct nf_conntrack_tuple *tuple;
811 enum tcp_conntrack new_state, old_state; 814 enum tcp_conntrack new_state, old_state;
812 enum ip_conntrack_dir dir; 815 enum ip_conntrack_dir dir;
@@ -885,7 +888,7 @@ static int tcp_packet(struct nf_conn *ct,
885 * thus initiate a clean new session. 888 * thus initiate a clean new session.
886 */ 889 */
887 write_unlock_bh(&tcp_lock); 890 write_unlock_bh(&tcp_lock);
888 if (LOG_INVALID(IPPROTO_TCP)) 891 if (LOG_INVALID(net, IPPROTO_TCP))
889 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 892 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
890 "nf_ct_tcp: killing out of sync session "); 893 "nf_ct_tcp: killing out of sync session ");
891 nf_ct_kill(ct); 894 nf_ct_kill(ct);
@@ -898,7 +901,7 @@ static int tcp_packet(struct nf_conn *ct,
898 segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th); 901 segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th);
899 902
900 write_unlock_bh(&tcp_lock); 903 write_unlock_bh(&tcp_lock);
901 if (LOG_INVALID(IPPROTO_TCP)) 904 if (LOG_INVALID(net, IPPROTO_TCP))
902 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 905 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
903 "nf_ct_tcp: invalid packet ignored "); 906 "nf_ct_tcp: invalid packet ignored ");
904 return NF_ACCEPT; 907 return NF_ACCEPT;
@@ -907,7 +910,7 @@ static int tcp_packet(struct nf_conn *ct,
907 pr_debug("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n", 910 pr_debug("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
908 dir, get_conntrack_index(th), old_state); 911 dir, get_conntrack_index(th), old_state);
909 write_unlock_bh(&tcp_lock); 912 write_unlock_bh(&tcp_lock);
910 if (LOG_INVALID(IPPROTO_TCP)) 913 if (LOG_INVALID(net, IPPROTO_TCP))
911 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 914 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
912 "nf_ct_tcp: invalid state "); 915 "nf_ct_tcp: invalid state ");
913 return -NF_ACCEPT; 916 return -NF_ACCEPT;
@@ -968,9 +971,9 @@ static int tcp_packet(struct nf_conn *ct,
968 timeout = tcp_timeouts[new_state]; 971 timeout = tcp_timeouts[new_state];
969 write_unlock_bh(&tcp_lock); 972 write_unlock_bh(&tcp_lock);
970 973
971 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb); 974 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct);
972 if (new_state != old_state) 975 if (new_state != old_state)
973 nf_conntrack_event_cache(IPCT_PROTOINFO, skb); 976 nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
974 977
975 if (!test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { 978 if (!test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
976 /* If only reply is a RST, we can consider ourselves not to 979 /* If only reply is a RST, we can consider ourselves not to
@@ -989,7 +992,7 @@ static int tcp_packet(struct nf_conn *ct,
989 after SYN_RECV or a valid answer for a picked up 992 after SYN_RECV or a valid answer for a picked up
990 connection. */ 993 connection. */
991 set_bit(IPS_ASSURED_BIT, &ct->status); 994 set_bit(IPS_ASSURED_BIT, &ct->status);
992 nf_conntrack_event_cache(IPCT_STATUS, skb); 995 nf_conntrack_event_cache(IPCT_STATUS, ct);
993 } 996 }
994 nf_ct_refresh_acct(ct, ctinfo, skb, timeout); 997 nf_ct_refresh_acct(ct, ctinfo, skb, timeout);
995 998
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index 8b21762e65de..7c2ca48698be 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -66,7 +66,7 @@ static int udp_packet(struct nf_conn *ct,
66 const struct sk_buff *skb, 66 const struct sk_buff *skb,
67 unsigned int dataoff, 67 unsigned int dataoff,
68 enum ip_conntrack_info ctinfo, 68 enum ip_conntrack_info ctinfo,
69 int pf, 69 u_int8_t pf,
70 unsigned int hooknum) 70 unsigned int hooknum)
71{ 71{
72 /* If we've seen traffic both ways, this is some kind of UDP 72 /* If we've seen traffic both ways, this is some kind of UDP
@@ -75,7 +75,7 @@ static int udp_packet(struct nf_conn *ct,
75 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout_stream); 75 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout_stream);
76 /* Also, more likely to be important, and not a probe */ 76 /* Also, more likely to be important, and not a probe */
77 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status)) 77 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
78 nf_conntrack_event_cache(IPCT_STATUS, skb); 78 nf_conntrack_event_cache(IPCT_STATUS, ct);
79 } else 79 } else
80 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout); 80 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout);
81 81
@@ -89,9 +89,9 @@ static bool udp_new(struct nf_conn *ct, const struct sk_buff *skb,
89 return true; 89 return true;
90} 90}
91 91
92static int udp_error(struct sk_buff *skb, unsigned int dataoff, 92static int udp_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
93 enum ip_conntrack_info *ctinfo, 93 enum ip_conntrack_info *ctinfo,
94 int pf, 94 u_int8_t pf,
95 unsigned int hooknum) 95 unsigned int hooknum)
96{ 96{
97 unsigned int udplen = skb->len - dataoff; 97 unsigned int udplen = skb->len - dataoff;
@@ -101,7 +101,7 @@ static int udp_error(struct sk_buff *skb, unsigned int dataoff,
101 /* Header is too small? */ 101 /* Header is too small? */
102 hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr); 102 hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
103 if (hdr == NULL) { 103 if (hdr == NULL) {
104 if (LOG_INVALID(IPPROTO_UDP)) 104 if (LOG_INVALID(net, IPPROTO_UDP))
105 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 105 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
106 "nf_ct_udp: short packet "); 106 "nf_ct_udp: short packet ");
107 return -NF_ACCEPT; 107 return -NF_ACCEPT;
@@ -109,7 +109,7 @@ static int udp_error(struct sk_buff *skb, unsigned int dataoff,
109 109
110 /* Truncated/malformed packets */ 110 /* Truncated/malformed packets */
111 if (ntohs(hdr->len) > udplen || ntohs(hdr->len) < sizeof(*hdr)) { 111 if (ntohs(hdr->len) > udplen || ntohs(hdr->len) < sizeof(*hdr)) {
112 if (LOG_INVALID(IPPROTO_UDP)) 112 if (LOG_INVALID(net, IPPROTO_UDP))
113 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 113 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
114 "nf_ct_udp: truncated/malformed packet "); 114 "nf_ct_udp: truncated/malformed packet ");
115 return -NF_ACCEPT; 115 return -NF_ACCEPT;
@@ -123,9 +123,9 @@ static int udp_error(struct sk_buff *skb, unsigned int dataoff,
123 * We skip checking packets on the outgoing path 123 * We skip checking packets on the outgoing path
124 * because the checksum is assumed to be correct. 124 * because the checksum is assumed to be correct.
125 * FIXME: Source route IP option packets --RR */ 125 * FIXME: Source route IP option packets --RR */
126 if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && 126 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
127 nf_checksum(skb, hooknum, dataoff, IPPROTO_UDP, pf)) { 127 nf_checksum(skb, hooknum, dataoff, IPPROTO_UDP, pf)) {
128 if (LOG_INVALID(IPPROTO_UDP)) 128 if (LOG_INVALID(net, IPPROTO_UDP))
129 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 129 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
130 "nf_ct_udp: bad UDP checksum "); 130 "nf_ct_udp: bad UDP checksum ");
131 return -NF_ACCEPT; 131 return -NF_ACCEPT;
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index 1fa62f3c24f1..d22d839e4f94 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -65,7 +65,7 @@ static int udplite_packet(struct nf_conn *ct,
65 const struct sk_buff *skb, 65 const struct sk_buff *skb,
66 unsigned int dataoff, 66 unsigned int dataoff,
67 enum ip_conntrack_info ctinfo, 67 enum ip_conntrack_info ctinfo,
68 int pf, 68 u_int8_t pf,
69 unsigned int hooknum) 69 unsigned int hooknum)
70{ 70{
71 /* If we've seen traffic both ways, this is some kind of UDP 71 /* If we've seen traffic both ways, this is some kind of UDP
@@ -75,7 +75,7 @@ static int udplite_packet(struct nf_conn *ct,
75 nf_ct_udplite_timeout_stream); 75 nf_ct_udplite_timeout_stream);
76 /* Also, more likely to be important, and not a probe */ 76 /* Also, more likely to be important, and not a probe */
77 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status)) 77 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
78 nf_conntrack_event_cache(IPCT_STATUS, skb); 78 nf_conntrack_event_cache(IPCT_STATUS, ct);
79 } else 79 } else
80 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udplite_timeout); 80 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udplite_timeout);
81 81
@@ -89,9 +89,11 @@ static bool udplite_new(struct nf_conn *ct, const struct sk_buff *skb,
89 return true; 89 return true;
90} 90}
91 91
92static int udplite_error(struct sk_buff *skb, unsigned int dataoff, 92static int udplite_error(struct net *net,
93 struct sk_buff *skb,
94 unsigned int dataoff,
93 enum ip_conntrack_info *ctinfo, 95 enum ip_conntrack_info *ctinfo,
94 int pf, 96 u_int8_t pf,
95 unsigned int hooknum) 97 unsigned int hooknum)
96{ 98{
97 unsigned int udplen = skb->len - dataoff; 99 unsigned int udplen = skb->len - dataoff;
@@ -102,7 +104,7 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
102 /* Header is too small? */ 104 /* Header is too small? */
103 hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr); 105 hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
104 if (hdr == NULL) { 106 if (hdr == NULL) {
105 if (LOG_INVALID(IPPROTO_UDPLITE)) 107 if (LOG_INVALID(net, IPPROTO_UDPLITE))
106 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 108 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
107 "nf_ct_udplite: short packet "); 109 "nf_ct_udplite: short packet ");
108 return -NF_ACCEPT; 110 return -NF_ACCEPT;
@@ -112,7 +114,7 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
112 if (cscov == 0) 114 if (cscov == 0)
113 cscov = udplen; 115 cscov = udplen;
114 else if (cscov < sizeof(*hdr) || cscov > udplen) { 116 else if (cscov < sizeof(*hdr) || cscov > udplen) {
115 if (LOG_INVALID(IPPROTO_UDPLITE)) 117 if (LOG_INVALID(net, IPPROTO_UDPLITE))
116 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 118 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
117 "nf_ct_udplite: invalid checksum coverage "); 119 "nf_ct_udplite: invalid checksum coverage ");
118 return -NF_ACCEPT; 120 return -NF_ACCEPT;
@@ -120,17 +122,17 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
120 122
121 /* UDPLITE mandates checksums */ 123 /* UDPLITE mandates checksums */
122 if (!hdr->check) { 124 if (!hdr->check) {
123 if (LOG_INVALID(IPPROTO_UDPLITE)) 125 if (LOG_INVALID(net, IPPROTO_UDPLITE))
124 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 126 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
125 "nf_ct_udplite: checksum missing "); 127 "nf_ct_udplite: checksum missing ");
126 return -NF_ACCEPT; 128 return -NF_ACCEPT;
127 } 129 }
128 130
129 /* Checksum invalid? Ignore. */ 131 /* Checksum invalid? Ignore. */
130 if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && 132 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
131 nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_UDP, 133 nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_UDP,
132 pf)) { 134 pf)) {
133 if (LOG_INVALID(IPPROTO_UDPLITE)) 135 if (LOG_INVALID(net, IPPROTO_UDPLITE))
134 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 136 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
135 "nf_ct_udplite: bad UDPLite checksum "); 137 "nf_ct_udplite: bad UDPLite checksum ");
136 return -NF_ACCEPT; 138 return -NF_ACCEPT;
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 1fa306be60fb..6813f1c8863f 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -736,6 +736,7 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb,
736 struct nf_conntrack_expect *exp, *rtp_exp, *rtcp_exp; 736 struct nf_conntrack_expect *exp, *rtp_exp, *rtcp_exp;
737 enum ip_conntrack_info ctinfo; 737 enum ip_conntrack_info ctinfo;
738 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 738 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
739 struct net *net = nf_ct_net(ct);
739 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 740 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
740 union nf_inet_addr *saddr; 741 union nf_inet_addr *saddr;
741 struct nf_conntrack_tuple tuple; 742 struct nf_conntrack_tuple tuple;
@@ -775,7 +776,7 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb,
775 776
776 rcu_read_lock(); 777 rcu_read_lock();
777 do { 778 do {
778 exp = __nf_ct_expect_find(&tuple); 779 exp = __nf_ct_expect_find(net, &tuple);
779 780
780 if (!exp || exp->master == ct || 781 if (!exp || exp->master == ct ||
781 nfct_help(exp->master)->helper != nfct_help(ct)->helper || 782 nfct_help(exp->master)->helper != nfct_help(ct)->helper ||
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 8509db14670b..98106d4e89f0 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -40,18 +40,20 @@ print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
40EXPORT_SYMBOL_GPL(print_tuple); 40EXPORT_SYMBOL_GPL(print_tuple);
41 41
42struct ct_iter_state { 42struct ct_iter_state {
43 struct seq_net_private p;
43 unsigned int bucket; 44 unsigned int bucket;
44}; 45};
45 46
46static struct hlist_node *ct_get_first(struct seq_file *seq) 47static struct hlist_node *ct_get_first(struct seq_file *seq)
47{ 48{
49 struct net *net = seq_file_net(seq);
48 struct ct_iter_state *st = seq->private; 50 struct ct_iter_state *st = seq->private;
49 struct hlist_node *n; 51 struct hlist_node *n;
50 52
51 for (st->bucket = 0; 53 for (st->bucket = 0;
52 st->bucket < nf_conntrack_htable_size; 54 st->bucket < nf_conntrack_htable_size;
53 st->bucket++) { 55 st->bucket++) {
54 n = rcu_dereference(nf_conntrack_hash[st->bucket].first); 56 n = rcu_dereference(net->ct.hash[st->bucket].first);
55 if (n) 57 if (n)
56 return n; 58 return n;
57 } 59 }
@@ -61,13 +63,14 @@ static struct hlist_node *ct_get_first(struct seq_file *seq)
61static struct hlist_node *ct_get_next(struct seq_file *seq, 63static struct hlist_node *ct_get_next(struct seq_file *seq,
62 struct hlist_node *head) 64 struct hlist_node *head)
63{ 65{
66 struct net *net = seq_file_net(seq);
64 struct ct_iter_state *st = seq->private; 67 struct ct_iter_state *st = seq->private;
65 68
66 head = rcu_dereference(head->next); 69 head = rcu_dereference(head->next);
67 while (head == NULL) { 70 while (head == NULL) {
68 if (++st->bucket >= nf_conntrack_htable_size) 71 if (++st->bucket >= nf_conntrack_htable_size)
69 return NULL; 72 return NULL;
70 head = rcu_dereference(nf_conntrack_hash[st->bucket].first); 73 head = rcu_dereference(net->ct.hash[st->bucket].first);
71 } 74 }
72 return head; 75 return head;
73} 76}
@@ -177,7 +180,7 @@ static const struct seq_operations ct_seq_ops = {
177 180
178static int ct_open(struct inode *inode, struct file *file) 181static int ct_open(struct inode *inode, struct file *file)
179{ 182{
180 return seq_open_private(file, &ct_seq_ops, 183 return seq_open_net(inode, file, &ct_seq_ops,
181 sizeof(struct ct_iter_state)); 184 sizeof(struct ct_iter_state));
182} 185}
183 186
@@ -186,11 +189,12 @@ static const struct file_operations ct_file_ops = {
186 .open = ct_open, 189 .open = ct_open,
187 .read = seq_read, 190 .read = seq_read,
188 .llseek = seq_lseek, 191 .llseek = seq_lseek,
189 .release = seq_release_private, 192 .release = seq_release_net,
190}; 193};
191 194
192static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) 195static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
193{ 196{
197 struct net *net = seq_file_net(seq);
194 int cpu; 198 int cpu;
195 199
196 if (*pos == 0) 200 if (*pos == 0)
@@ -200,7 +204,7 @@ static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
200 if (!cpu_possible(cpu)) 204 if (!cpu_possible(cpu))
201 continue; 205 continue;
202 *pos = cpu + 1; 206 *pos = cpu + 1;
203 return &per_cpu(nf_conntrack_stat, cpu); 207 return per_cpu_ptr(net->ct.stat, cpu);
204 } 208 }
205 209
206 return NULL; 210 return NULL;
@@ -208,13 +212,14 @@ static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
208 212
209static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) 213static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
210{ 214{
215 struct net *net = seq_file_net(seq);
211 int cpu; 216 int cpu;
212 217
213 for (cpu = *pos; cpu < NR_CPUS; ++cpu) { 218 for (cpu = *pos; cpu < NR_CPUS; ++cpu) {
214 if (!cpu_possible(cpu)) 219 if (!cpu_possible(cpu))
215 continue; 220 continue;
216 *pos = cpu + 1; 221 *pos = cpu + 1;
217 return &per_cpu(nf_conntrack_stat, cpu); 222 return per_cpu_ptr(net->ct.stat, cpu);
218 } 223 }
219 224
220 return NULL; 225 return NULL;
@@ -226,7 +231,8 @@ static void ct_cpu_seq_stop(struct seq_file *seq, void *v)
226 231
227static int ct_cpu_seq_show(struct seq_file *seq, void *v) 232static int ct_cpu_seq_show(struct seq_file *seq, void *v)
228{ 233{
229 unsigned int nr_conntracks = atomic_read(&nf_conntrack_count); 234 struct net *net = seq_file_net(seq);
235 unsigned int nr_conntracks = atomic_read(&net->ct.count);
230 const struct ip_conntrack_stat *st = v; 236 const struct ip_conntrack_stat *st = v;
231 237
232 if (v == SEQ_START_TOKEN) { 238 if (v == SEQ_START_TOKEN) {
@@ -266,7 +272,8 @@ static const struct seq_operations ct_cpu_seq_ops = {
266 272
267static int ct_cpu_seq_open(struct inode *inode, struct file *file) 273static int ct_cpu_seq_open(struct inode *inode, struct file *file)
268{ 274{
269 return seq_open(file, &ct_cpu_seq_ops); 275 return seq_open_net(inode, file, &ct_cpu_seq_ops,
276 sizeof(struct seq_net_private));
270} 277}
271 278
272static const struct file_operations ct_cpu_seq_fops = { 279static const struct file_operations ct_cpu_seq_fops = {
@@ -274,56 +281,52 @@ static const struct file_operations ct_cpu_seq_fops = {
274 .open = ct_cpu_seq_open, 281 .open = ct_cpu_seq_open,
275 .read = seq_read, 282 .read = seq_read,
276 .llseek = seq_lseek, 283 .llseek = seq_lseek,
277 .release = seq_release, 284 .release = seq_release_net,
278}; 285};
279 286
280static int nf_conntrack_standalone_init_proc(void) 287static int nf_conntrack_standalone_init_proc(struct net *net)
281{ 288{
282 struct proc_dir_entry *pde; 289 struct proc_dir_entry *pde;
283 290
284 pde = proc_net_fops_create(&init_net, "nf_conntrack", 0440, &ct_file_ops); 291 pde = proc_net_fops_create(net, "nf_conntrack", 0440, &ct_file_ops);
285 if (!pde) 292 if (!pde)
286 goto out_nf_conntrack; 293 goto out_nf_conntrack;
287 294
288 pde = proc_create("nf_conntrack", S_IRUGO, init_net.proc_net_stat, 295 pde = proc_create("nf_conntrack", S_IRUGO, net->proc_net_stat,
289 &ct_cpu_seq_fops); 296 &ct_cpu_seq_fops);
290 if (!pde) 297 if (!pde)
291 goto out_stat_nf_conntrack; 298 goto out_stat_nf_conntrack;
292 return 0; 299 return 0;
293 300
294out_stat_nf_conntrack: 301out_stat_nf_conntrack:
295 proc_net_remove(&init_net, "nf_conntrack"); 302 proc_net_remove(net, "nf_conntrack");
296out_nf_conntrack: 303out_nf_conntrack:
297 return -ENOMEM; 304 return -ENOMEM;
298} 305}
299 306
300static void nf_conntrack_standalone_fini_proc(void) 307static void nf_conntrack_standalone_fini_proc(struct net *net)
301{ 308{
302 remove_proc_entry("nf_conntrack", init_net.proc_net_stat); 309 remove_proc_entry("nf_conntrack", net->proc_net_stat);
303 proc_net_remove(&init_net, "nf_conntrack"); 310 proc_net_remove(net, "nf_conntrack");
304} 311}
305#else 312#else
306static int nf_conntrack_standalone_init_proc(void) 313static int nf_conntrack_standalone_init_proc(struct net *net)
307{ 314{
308 return 0; 315 return 0;
309} 316}
310 317
311static void nf_conntrack_standalone_fini_proc(void) 318static void nf_conntrack_standalone_fini_proc(struct net *net)
312{ 319{
313} 320}
314#endif /* CONFIG_PROC_FS */ 321#endif /* CONFIG_PROC_FS */
315 322
316/* Sysctl support */ 323/* Sysctl support */
317 324
318int nf_conntrack_checksum __read_mostly = 1;
319EXPORT_SYMBOL_GPL(nf_conntrack_checksum);
320
321#ifdef CONFIG_SYSCTL 325#ifdef CONFIG_SYSCTL
322/* Log invalid packets of a given protocol */ 326/* Log invalid packets of a given protocol */
323static int log_invalid_proto_min = 0; 327static int log_invalid_proto_min = 0;
324static int log_invalid_proto_max = 255; 328static int log_invalid_proto_max = 255;
325 329
326static struct ctl_table_header *nf_ct_sysctl_header;
327static struct ctl_table_header *nf_ct_netfilter_header; 330static struct ctl_table_header *nf_ct_netfilter_header;
328 331
329static ctl_table nf_ct_sysctl_table[] = { 332static ctl_table nf_ct_sysctl_table[] = {
@@ -338,7 +341,7 @@ static ctl_table nf_ct_sysctl_table[] = {
338 { 341 {
339 .ctl_name = NET_NF_CONNTRACK_COUNT, 342 .ctl_name = NET_NF_CONNTRACK_COUNT,
340 .procname = "nf_conntrack_count", 343 .procname = "nf_conntrack_count",
341 .data = &nf_conntrack_count, 344 .data = &init_net.ct.count,
342 .maxlen = sizeof(int), 345 .maxlen = sizeof(int),
343 .mode = 0444, 346 .mode = 0444,
344 .proc_handler = &proc_dointvec, 347 .proc_handler = &proc_dointvec,
@@ -354,7 +357,7 @@ static ctl_table nf_ct_sysctl_table[] = {
354 { 357 {
355 .ctl_name = NET_NF_CONNTRACK_CHECKSUM, 358 .ctl_name = NET_NF_CONNTRACK_CHECKSUM,
356 .procname = "nf_conntrack_checksum", 359 .procname = "nf_conntrack_checksum",
357 .data = &nf_conntrack_checksum, 360 .data = &init_net.ct.sysctl_checksum,
358 .maxlen = sizeof(unsigned int), 361 .maxlen = sizeof(unsigned int),
359 .mode = 0644, 362 .mode = 0644,
360 .proc_handler = &proc_dointvec, 363 .proc_handler = &proc_dointvec,
@@ -362,7 +365,7 @@ static ctl_table nf_ct_sysctl_table[] = {
362 { 365 {
363 .ctl_name = NET_NF_CONNTRACK_LOG_INVALID, 366 .ctl_name = NET_NF_CONNTRACK_LOG_INVALID,
364 .procname = "nf_conntrack_log_invalid", 367 .procname = "nf_conntrack_log_invalid",
365 .data = &nf_ct_log_invalid, 368 .data = &init_net.ct.sysctl_log_invalid,
366 .maxlen = sizeof(unsigned int), 369 .maxlen = sizeof(unsigned int),
367 .mode = 0644, 370 .mode = 0644,
368 .proc_handler = &proc_dointvec_minmax, 371 .proc_handler = &proc_dointvec_minmax,
@@ -400,74 +403,109 @@ static struct ctl_path nf_ct_path[] = {
400 { } 403 { }
401}; 404};
402 405
403EXPORT_SYMBOL_GPL(nf_ct_log_invalid); 406static int nf_conntrack_standalone_init_sysctl(struct net *net)
404
405static int nf_conntrack_standalone_init_sysctl(void)
406{ 407{
407 nf_ct_netfilter_header = 408 struct ctl_table *table;
408 register_sysctl_paths(nf_ct_path, nf_ct_netfilter_table); 409
409 if (!nf_ct_netfilter_header) 410 if (net_eq(net, &init_net)) {
410 goto out; 411 nf_ct_netfilter_header =
411 412 register_sysctl_paths(nf_ct_path, nf_ct_netfilter_table);
412 nf_ct_sysctl_header = 413 if (!nf_ct_netfilter_header)
413 register_sysctl_paths(nf_net_netfilter_sysctl_path, 414 goto out;
414 nf_ct_sysctl_table); 415 }
415 if (!nf_ct_sysctl_header) 416
417 table = kmemdup(nf_ct_sysctl_table, sizeof(nf_ct_sysctl_table),
418 GFP_KERNEL);
419 if (!table)
420 goto out_kmemdup;
421
422 table[1].data = &net->ct.count;
423 table[3].data = &net->ct.sysctl_checksum;
424 table[4].data = &net->ct.sysctl_log_invalid;
425
426 net->ct.sysctl_header = register_net_sysctl_table(net,
427 nf_net_netfilter_sysctl_path, table);
428 if (!net->ct.sysctl_header)
416 goto out_unregister_netfilter; 429 goto out_unregister_netfilter;
417 430
418 return 0; 431 return 0;
419 432
420out_unregister_netfilter: 433out_unregister_netfilter:
421 unregister_sysctl_table(nf_ct_netfilter_header); 434 kfree(table);
435out_kmemdup:
436 if (net_eq(net, &init_net))
437 unregister_sysctl_table(nf_ct_netfilter_header);
422out: 438out:
423 printk("nf_conntrack: can't register to sysctl.\n"); 439 printk("nf_conntrack: can't register to sysctl.\n");
424 return -ENOMEM; 440 return -ENOMEM;
425} 441}
426 442
427static void nf_conntrack_standalone_fini_sysctl(void) 443static void nf_conntrack_standalone_fini_sysctl(struct net *net)
428{ 444{
429 unregister_sysctl_table(nf_ct_netfilter_header); 445 struct ctl_table *table;
430 unregister_sysctl_table(nf_ct_sysctl_header); 446
447 if (net_eq(net, &init_net))
448 unregister_sysctl_table(nf_ct_netfilter_header);
449 table = net->ct.sysctl_header->ctl_table_arg;
450 unregister_net_sysctl_table(net->ct.sysctl_header);
451 kfree(table);
431} 452}
432#else 453#else
433static int nf_conntrack_standalone_init_sysctl(void) 454static int nf_conntrack_standalone_init_sysctl(struct net *net)
434{ 455{
435 return 0; 456 return 0;
436} 457}
437 458
438static void nf_conntrack_standalone_fini_sysctl(void) 459static void nf_conntrack_standalone_fini_sysctl(struct net *net)
439{ 460{
440} 461}
441#endif /* CONFIG_SYSCTL */ 462#endif /* CONFIG_SYSCTL */
442 463
443static int __init nf_conntrack_standalone_init(void) 464static int nf_conntrack_net_init(struct net *net)
444{ 465{
445 int ret; 466 int ret;
446 467
447 ret = nf_conntrack_init(); 468 ret = nf_conntrack_init(net);
448 if (ret < 0) 469 if (ret < 0)
449 goto out; 470 goto out_init;
450 ret = nf_conntrack_standalone_init_proc(); 471 ret = nf_conntrack_standalone_init_proc(net);
451 if (ret < 0) 472 if (ret < 0)
452 goto out_proc; 473 goto out_proc;
453 ret = nf_conntrack_standalone_init_sysctl(); 474 net->ct.sysctl_checksum = 1;
475 net->ct.sysctl_log_invalid = 0;
476 ret = nf_conntrack_standalone_init_sysctl(net);
454 if (ret < 0) 477 if (ret < 0)
455 goto out_sysctl; 478 goto out_sysctl;
456 return 0; 479 return 0;
457 480
458out_sysctl: 481out_sysctl:
459 nf_conntrack_standalone_fini_proc(); 482 nf_conntrack_standalone_fini_proc(net);
460out_proc: 483out_proc:
461 nf_conntrack_cleanup(); 484 nf_conntrack_cleanup(net);
462out: 485out_init:
463 return ret; 486 return ret;
464} 487}
465 488
489static void nf_conntrack_net_exit(struct net *net)
490{
491 nf_conntrack_standalone_fini_sysctl(net);
492 nf_conntrack_standalone_fini_proc(net);
493 nf_conntrack_cleanup(net);
494}
495
496static struct pernet_operations nf_conntrack_net_ops = {
497 .init = nf_conntrack_net_init,
498 .exit = nf_conntrack_net_exit,
499};
500
501static int __init nf_conntrack_standalone_init(void)
502{
503 return register_pernet_subsys(&nf_conntrack_net_ops);
504}
505
466static void __exit nf_conntrack_standalone_fini(void) 506static void __exit nf_conntrack_standalone_fini(void)
467{ 507{
468 nf_conntrack_standalone_fini_sysctl(); 508 unregister_pernet_subsys(&nf_conntrack_net_ops);
469 nf_conntrack_standalone_fini_proc();
470 nf_conntrack_cleanup();
471} 509}
472 510
473module_init(nf_conntrack_standalone_init); 511module_init(nf_conntrack_standalone_init);
diff --git a/net/netfilter/nf_internals.h b/net/netfilter/nf_internals.h
index 196269c1e586..bf6609978af7 100644
--- a/net/netfilter/nf_internals.h
+++ b/net/netfilter/nf_internals.h
@@ -15,7 +15,7 @@
15/* core.c */ 15/* core.c */
16extern unsigned int nf_iterate(struct list_head *head, 16extern unsigned int nf_iterate(struct list_head *head,
17 struct sk_buff *skb, 17 struct sk_buff *skb,
18 int hook, 18 unsigned int hook,
19 const struct net_device *indev, 19 const struct net_device *indev,
20 const struct net_device *outdev, 20 const struct net_device *outdev,
21 struct list_head **i, 21 struct list_head **i,
@@ -25,7 +25,7 @@ extern unsigned int nf_iterate(struct list_head *head,
25/* nf_queue.c */ 25/* nf_queue.c */
26extern int nf_queue(struct sk_buff *skb, 26extern int nf_queue(struct sk_buff *skb,
27 struct list_head *elem, 27 struct list_head *elem,
28 int pf, unsigned int hook, 28 u_int8_t pf, unsigned int hook,
29 struct net_device *indev, 29 struct net_device *indev,
30 struct net_device *outdev, 30 struct net_device *outdev,
31 int (*okfn)(struct sk_buff *), 31 int (*okfn)(struct sk_buff *),
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 9fda6ee95a31..fa8ae5d2659c 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -15,16 +15,16 @@
15 15
16#define NF_LOG_PREFIXLEN 128 16#define NF_LOG_PREFIXLEN 128
17 17
18static const struct nf_logger *nf_loggers[NPROTO] __read_mostly; 18static const struct nf_logger *nf_loggers[NFPROTO_NUMPROTO] __read_mostly;
19static DEFINE_MUTEX(nf_log_mutex); 19static DEFINE_MUTEX(nf_log_mutex);
20 20
21/* return EBUSY if somebody else is registered, EEXIST if the same logger 21/* return EBUSY if somebody else is registered, EEXIST if the same logger
22 * is registred, 0 on success. */ 22 * is registred, 0 on success. */
23int nf_log_register(int pf, const struct nf_logger *logger) 23int nf_log_register(u_int8_t pf, const struct nf_logger *logger)
24{ 24{
25 int ret; 25 int ret;
26 26
27 if (pf >= NPROTO) 27 if (pf >= ARRAY_SIZE(nf_loggers))
28 return -EINVAL; 28 return -EINVAL;
29 29
30 /* Any setup of logging members must be done before 30 /* Any setup of logging members must be done before
@@ -45,9 +45,9 @@ int nf_log_register(int pf, const struct nf_logger *logger)
45} 45}
46EXPORT_SYMBOL(nf_log_register); 46EXPORT_SYMBOL(nf_log_register);
47 47
48void nf_log_unregister_pf(int pf) 48void nf_log_unregister_pf(u_int8_t pf)
49{ 49{
50 if (pf >= NPROTO) 50 if (pf >= ARRAY_SIZE(nf_loggers))
51 return; 51 return;
52 mutex_lock(&nf_log_mutex); 52 mutex_lock(&nf_log_mutex);
53 rcu_assign_pointer(nf_loggers[pf], NULL); 53 rcu_assign_pointer(nf_loggers[pf], NULL);
@@ -63,7 +63,7 @@ void nf_log_unregister(const struct nf_logger *logger)
63 int i; 63 int i;
64 64
65 mutex_lock(&nf_log_mutex); 65 mutex_lock(&nf_log_mutex);
66 for (i = 0; i < NPROTO; i++) { 66 for (i = 0; i < ARRAY_SIZE(nf_loggers); i++) {
67 if (nf_loggers[i] == logger) 67 if (nf_loggers[i] == logger)
68 rcu_assign_pointer(nf_loggers[i], NULL); 68 rcu_assign_pointer(nf_loggers[i], NULL);
69 } 69 }
@@ -73,7 +73,7 @@ void nf_log_unregister(const struct nf_logger *logger)
73} 73}
74EXPORT_SYMBOL(nf_log_unregister); 74EXPORT_SYMBOL(nf_log_unregister);
75 75
76void nf_log_packet(int pf, 76void nf_log_packet(u_int8_t pf,
77 unsigned int hooknum, 77 unsigned int hooknum,
78 const struct sk_buff *skb, 78 const struct sk_buff *skb,
79 const struct net_device *in, 79 const struct net_device *in,
@@ -103,7 +103,7 @@ static void *seq_start(struct seq_file *seq, loff_t *pos)
103{ 103{
104 rcu_read_lock(); 104 rcu_read_lock();
105 105
106 if (*pos >= NPROTO) 106 if (*pos >= ARRAY_SIZE(nf_loggers))
107 return NULL; 107 return NULL;
108 108
109 return pos; 109 return pos;
@@ -113,7 +113,7 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
113{ 113{
114 (*pos)++; 114 (*pos)++;
115 115
116 if (*pos >= NPROTO) 116 if (*pos >= ARRAY_SIZE(nf_loggers))
117 return NULL; 117 return NULL;
118 118
119 return pos; 119 return pos;
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index 582ec3efc8a5..4f2310c93e01 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -16,17 +16,17 @@
16 * long term mutex. The handler must provide an an outfn() to accept packets 16 * long term mutex. The handler must provide an an outfn() to accept packets
17 * for queueing and must reinject all packets it receives, no matter what. 17 * for queueing and must reinject all packets it receives, no matter what.
18 */ 18 */
19static const struct nf_queue_handler *queue_handler[NPROTO]; 19static const struct nf_queue_handler *queue_handler[NFPROTO_NUMPROTO] __read_mostly;
20 20
21static DEFINE_MUTEX(queue_handler_mutex); 21static DEFINE_MUTEX(queue_handler_mutex);
22 22
23/* return EBUSY when somebody else is registered, return EEXIST if the 23/* return EBUSY when somebody else is registered, return EEXIST if the
24 * same handler is registered, return 0 in case of success. */ 24 * same handler is registered, return 0 in case of success. */
25int nf_register_queue_handler(int pf, const struct nf_queue_handler *qh) 25int nf_register_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
26{ 26{
27 int ret; 27 int ret;
28 28
29 if (pf >= NPROTO) 29 if (pf >= ARRAY_SIZE(queue_handler))
30 return -EINVAL; 30 return -EINVAL;
31 31
32 mutex_lock(&queue_handler_mutex); 32 mutex_lock(&queue_handler_mutex);
@@ -45,9 +45,9 @@ int nf_register_queue_handler(int pf, const struct nf_queue_handler *qh)
45EXPORT_SYMBOL(nf_register_queue_handler); 45EXPORT_SYMBOL(nf_register_queue_handler);
46 46
47/* The caller must flush their queue before this */ 47/* The caller must flush their queue before this */
48int nf_unregister_queue_handler(int pf, const struct nf_queue_handler *qh) 48int nf_unregister_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
49{ 49{
50 if (pf >= NPROTO) 50 if (pf >= ARRAY_SIZE(queue_handler))
51 return -EINVAL; 51 return -EINVAL;
52 52
53 mutex_lock(&queue_handler_mutex); 53 mutex_lock(&queue_handler_mutex);
@@ -67,10 +67,10 @@ EXPORT_SYMBOL(nf_unregister_queue_handler);
67 67
68void nf_unregister_queue_handlers(const struct nf_queue_handler *qh) 68void nf_unregister_queue_handlers(const struct nf_queue_handler *qh)
69{ 69{
70 int pf; 70 u_int8_t pf;
71 71
72 mutex_lock(&queue_handler_mutex); 72 mutex_lock(&queue_handler_mutex);
73 for (pf = 0; pf < NPROTO; pf++) { 73 for (pf = 0; pf < ARRAY_SIZE(queue_handler); pf++) {
74 if (queue_handler[pf] == qh) 74 if (queue_handler[pf] == qh)
75 rcu_assign_pointer(queue_handler[pf], NULL); 75 rcu_assign_pointer(queue_handler[pf], NULL);
76 } 76 }
@@ -107,7 +107,7 @@ static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
107 */ 107 */
108static int __nf_queue(struct sk_buff *skb, 108static int __nf_queue(struct sk_buff *skb,
109 struct list_head *elem, 109 struct list_head *elem,
110 int pf, unsigned int hook, 110 u_int8_t pf, unsigned int hook,
111 struct net_device *indev, 111 struct net_device *indev,
112 struct net_device *outdev, 112 struct net_device *outdev,
113 int (*okfn)(struct sk_buff *), 113 int (*okfn)(struct sk_buff *),
@@ -191,7 +191,7 @@ err:
191 191
192int nf_queue(struct sk_buff *skb, 192int nf_queue(struct sk_buff *skb,
193 struct list_head *elem, 193 struct list_head *elem,
194 int pf, unsigned int hook, 194 u_int8_t pf, unsigned int hook,
195 struct net_device *indev, 195 struct net_device *indev,
196 struct net_device *outdev, 196 struct net_device *outdev,
197 int (*okfn)(struct sk_buff *), 197 int (*okfn)(struct sk_buff *),
@@ -285,7 +285,7 @@ EXPORT_SYMBOL(nf_reinject);
285#ifdef CONFIG_PROC_FS 285#ifdef CONFIG_PROC_FS
286static void *seq_start(struct seq_file *seq, loff_t *pos) 286static void *seq_start(struct seq_file *seq, loff_t *pos)
287{ 287{
288 if (*pos >= NPROTO) 288 if (*pos >= ARRAY_SIZE(queue_handler))
289 return NULL; 289 return NULL;
290 290
291 return pos; 291 return pos;
@@ -295,7 +295,7 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
295{ 295{
296 (*pos)++; 296 (*pos)++;
297 297
298 if (*pos >= NPROTO) 298 if (*pos >= ARRAY_SIZE(queue_handler))
299 return NULL; 299 return NULL;
300 300
301 return pos; 301 return pos;
diff --git a/net/netfilter/nf_sockopt.c b/net/netfilter/nf_sockopt.c
index 01489681fa96..8ab829f86574 100644
--- a/net/netfilter/nf_sockopt.c
+++ b/net/netfilter/nf_sockopt.c
@@ -60,14 +60,11 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg)
60} 60}
61EXPORT_SYMBOL(nf_unregister_sockopt); 61EXPORT_SYMBOL(nf_unregister_sockopt);
62 62
63static struct nf_sockopt_ops *nf_sockopt_find(struct sock *sk, int pf, 63static struct nf_sockopt_ops *nf_sockopt_find(struct sock *sk, u_int8_t pf,
64 int val, int get) 64 int val, int get)
65{ 65{
66 struct nf_sockopt_ops *ops; 66 struct nf_sockopt_ops *ops;
67 67
68 if (!net_eq(sock_net(sk), &init_net))
69 return ERR_PTR(-ENOPROTOOPT);
70
71 if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0) 68 if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0)
72 return ERR_PTR(-EINTR); 69 return ERR_PTR(-EINTR);
73 70
@@ -96,7 +93,7 @@ out:
96} 93}
97 94
98/* Call get/setsockopt() */ 95/* Call get/setsockopt() */
99static int nf_sockopt(struct sock *sk, int pf, int val, 96static int nf_sockopt(struct sock *sk, u_int8_t pf, int val,
100 char __user *opt, int *len, int get) 97 char __user *opt, int *len, int get)
101{ 98{
102 struct nf_sockopt_ops *ops; 99 struct nf_sockopt_ops *ops;
@@ -115,21 +112,22 @@ static int nf_sockopt(struct sock *sk, int pf, int val,
115 return ret; 112 return ret;
116} 113}
117 114
118int nf_setsockopt(struct sock *sk, int pf, int val, char __user *opt, 115int nf_setsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt,
119 int len) 116 int len)
120{ 117{
121 return nf_sockopt(sk, pf, val, opt, &len, 0); 118 return nf_sockopt(sk, pf, val, opt, &len, 0);
122} 119}
123EXPORT_SYMBOL(nf_setsockopt); 120EXPORT_SYMBOL(nf_setsockopt);
124 121
125int nf_getsockopt(struct sock *sk, int pf, int val, char __user *opt, int *len) 122int nf_getsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt,
123 int *len)
126{ 124{
127 return nf_sockopt(sk, pf, val, opt, len, 1); 125 return nf_sockopt(sk, pf, val, opt, len, 1);
128} 126}
129EXPORT_SYMBOL(nf_getsockopt); 127EXPORT_SYMBOL(nf_getsockopt);
130 128
131#ifdef CONFIG_COMPAT 129#ifdef CONFIG_COMPAT
132static int compat_nf_sockopt(struct sock *sk, int pf, int val, 130static int compat_nf_sockopt(struct sock *sk, u_int8_t pf, int val,
133 char __user *opt, int *len, int get) 131 char __user *opt, int *len, int get)
134{ 132{
135 struct nf_sockopt_ops *ops; 133 struct nf_sockopt_ops *ops;
@@ -155,14 +153,14 @@ static int compat_nf_sockopt(struct sock *sk, int pf, int val,
155 return ret; 153 return ret;
156} 154}
157 155
158int compat_nf_setsockopt(struct sock *sk, int pf, 156int compat_nf_setsockopt(struct sock *sk, u_int8_t pf,
159 int val, char __user *opt, int len) 157 int val, char __user *opt, int len)
160{ 158{
161 return compat_nf_sockopt(sk, pf, val, opt, &len, 0); 159 return compat_nf_sockopt(sk, pf, val, opt, &len, 0);
162} 160}
163EXPORT_SYMBOL(compat_nf_setsockopt); 161EXPORT_SYMBOL(compat_nf_setsockopt);
164 162
165int compat_nf_getsockopt(struct sock *sk, int pf, 163int compat_nf_getsockopt(struct sock *sk, u_int8_t pf,
166 int val, char __user *opt, int *len) 164 int val, char __user *opt, int *len)
167{ 165{
168 return compat_nf_sockopt(sk, pf, val, opt, len, 1); 166 return compat_nf_sockopt(sk, pf, val, opt, len, 1);
diff --git a/net/netfilter/nf_tproxy_core.c b/net/netfilter/nf_tproxy_core.c
new file mode 100644
index 000000000000..fe34f4bf74cc
--- /dev/null
+++ b/net/netfilter/nf_tproxy_core.c
@@ -0,0 +1,96 @@
1/*
2 * Transparent proxy support for Linux/iptables
3 *
4 * Copyright (c) 2006-2007 BalaBit IT Ltd.
5 * Author: Balazs Scheidler, Krisztian Kovacs
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12
13#include <linux/version.h>
14#include <linux/module.h>
15
16#include <linux/net.h>
17#include <linux/if.h>
18#include <linux/netdevice.h>
19#include <net/udp.h>
20#include <net/netfilter/nf_tproxy_core.h>
21
22struct sock *
23nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
24 const __be32 saddr, const __be32 daddr,
25 const __be16 sport, const __be16 dport,
26 const struct net_device *in, bool listening_only)
27{
28 struct sock *sk;
29
30 /* look up socket */
31 switch (protocol) {
32 case IPPROTO_TCP:
33 if (listening_only)
34 sk = __inet_lookup_listener(net, &tcp_hashinfo,
35 daddr, ntohs(dport),
36 in->ifindex);
37 else
38 sk = __inet_lookup(net, &tcp_hashinfo,
39 saddr, sport, daddr, dport,
40 in->ifindex);
41 break;
42 case IPPROTO_UDP:
43 sk = udp4_lib_lookup(net, saddr, sport, daddr, dport,
44 in->ifindex);
45 break;
46 default:
47 WARN_ON(1);
48 sk = NULL;
49 }
50
51 pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, listener only: %d, sock %p\n",
52 protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), listening_only, sk);
53
54 return sk;
55}
56EXPORT_SYMBOL_GPL(nf_tproxy_get_sock_v4);
57
58static void
59nf_tproxy_destructor(struct sk_buff *skb)
60{
61 struct sock *sk = skb->sk;
62
63 skb->sk = NULL;
64 skb->destructor = NULL;
65
66 if (sk)
67 nf_tproxy_put_sock(sk);
68}
69
70/* consumes sk */
71int
72nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk)
73{
74 if (inet_sk(sk)->transparent) {
75 skb->sk = sk;
76 skb->destructor = nf_tproxy_destructor;
77 return 1;
78 } else
79 nf_tproxy_put_sock(sk);
80
81 return 0;
82}
83EXPORT_SYMBOL_GPL(nf_tproxy_assign_sock);
84
85static int __init nf_tproxy_init(void)
86{
87 pr_info("NF_TPROXY: Transparent proxy support initialized, version 4.1.0\n");
88 pr_info("NF_TPROXY: Copyright (c) 2006-2007 BalaBit IT Ltd.\n");
89 return 0;
90}
91
92module_init(nf_tproxy_init);
93
94MODULE_LICENSE("GPL");
95MODULE_AUTHOR("Krisztian Kovacs");
96MODULE_DESCRIPTION("Transparent proxy support core routines");
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 9a35b57ab76d..41e0105d3828 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -359,7 +359,7 @@ static inline int
359__build_packet_message(struct nfulnl_instance *inst, 359__build_packet_message(struct nfulnl_instance *inst,
360 const struct sk_buff *skb, 360 const struct sk_buff *skb,
361 unsigned int data_len, 361 unsigned int data_len,
362 unsigned int pf, 362 u_int8_t pf,
363 unsigned int hooknum, 363 unsigned int hooknum,
364 const struct net_device *indev, 364 const struct net_device *indev,
365 const struct net_device *outdev, 365 const struct net_device *outdev,
@@ -534,7 +534,7 @@ static struct nf_loginfo default_loginfo = {
534 534
535/* log handler for internal netfilter logging api */ 535/* log handler for internal netfilter logging api */
536static void 536static void
537nfulnl_log_packet(unsigned int pf, 537nfulnl_log_packet(u_int8_t pf,
538 unsigned int hooknum, 538 unsigned int hooknum,
539 const struct sk_buff *skb, 539 const struct sk_buff *skb,
540 const struct net_device *in, 540 const struct net_device *in,
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 5d75cd86ebb3..89837a4eef76 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -30,7 +30,7 @@
30 30
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 32MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
33MODULE_DESCRIPTION("[ip,ip6,arp]_tables backend module"); 33MODULE_DESCRIPTION("{ip,ip6,arp,eb}_tables backend module");
34 34
35#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) 35#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
36 36
@@ -58,17 +58,20 @@ static struct xt_af *xt;
58#define duprintf(format, args...) 58#define duprintf(format, args...)
59#endif 59#endif
60 60
61static const char *const xt_prefix[NPROTO] = { 61static const char *const xt_prefix[NFPROTO_NUMPROTO] = {
62 [AF_INET] = "ip", 62 [NFPROTO_UNSPEC] = "x",
63 [AF_INET6] = "ip6", 63 [NFPROTO_IPV4] = "ip",
64 [NF_ARP] = "arp", 64 [NFPROTO_ARP] = "arp",
65 [NFPROTO_BRIDGE] = "eb",
66 [NFPROTO_IPV6] = "ip6",
65}; 67};
66 68
67/* Registration hooks for targets. */ 69/* Registration hooks for targets. */
68int 70int
69xt_register_target(struct xt_target *target) 71xt_register_target(struct xt_target *target)
70{ 72{
71 int ret, af = target->family; 73 u_int8_t af = target->family;
74 int ret;
72 75
73 ret = mutex_lock_interruptible(&xt[af].mutex); 76 ret = mutex_lock_interruptible(&xt[af].mutex);
74 if (ret != 0) 77 if (ret != 0)
@@ -82,7 +85,7 @@ EXPORT_SYMBOL(xt_register_target);
82void 85void
83xt_unregister_target(struct xt_target *target) 86xt_unregister_target(struct xt_target *target)
84{ 87{
85 int af = target->family; 88 u_int8_t af = target->family;
86 89
87 mutex_lock(&xt[af].mutex); 90 mutex_lock(&xt[af].mutex);
88 list_del(&target->list); 91 list_del(&target->list);
@@ -123,7 +126,8 @@ EXPORT_SYMBOL(xt_unregister_targets);
123int 126int
124xt_register_match(struct xt_match *match) 127xt_register_match(struct xt_match *match)
125{ 128{
126 int ret, af = match->family; 129 u_int8_t af = match->family;
130 int ret;
127 131
128 ret = mutex_lock_interruptible(&xt[af].mutex); 132 ret = mutex_lock_interruptible(&xt[af].mutex);
129 if (ret != 0) 133 if (ret != 0)
@@ -139,7 +143,7 @@ EXPORT_SYMBOL(xt_register_match);
139void 143void
140xt_unregister_match(struct xt_match *match) 144xt_unregister_match(struct xt_match *match)
141{ 145{
142 int af = match->family; 146 u_int8_t af = match->family;
143 147
144 mutex_lock(&xt[af].mutex); 148 mutex_lock(&xt[af].mutex);
145 list_del(&match->list); 149 list_del(&match->list);
@@ -185,7 +189,7 @@ EXPORT_SYMBOL(xt_unregister_matches);
185 */ 189 */
186 190
187/* Find match, grabs ref. Returns ERR_PTR() on error. */ 191/* Find match, grabs ref. Returns ERR_PTR() on error. */
188struct xt_match *xt_find_match(int af, const char *name, u8 revision) 192struct xt_match *xt_find_match(u8 af, const char *name, u8 revision)
189{ 193{
190 struct xt_match *m; 194 struct xt_match *m;
191 int err = 0; 195 int err = 0;
@@ -205,12 +209,17 @@ struct xt_match *xt_find_match(int af, const char *name, u8 revision)
205 } 209 }
206 } 210 }
207 mutex_unlock(&xt[af].mutex); 211 mutex_unlock(&xt[af].mutex);
212
213 if (af != NFPROTO_UNSPEC)
214 /* Try searching again in the family-independent list */
215 return xt_find_match(NFPROTO_UNSPEC, name, revision);
216
208 return ERR_PTR(err); 217 return ERR_PTR(err);
209} 218}
210EXPORT_SYMBOL(xt_find_match); 219EXPORT_SYMBOL(xt_find_match);
211 220
212/* Find target, grabs ref. Returns ERR_PTR() on error. */ 221/* Find target, grabs ref. Returns ERR_PTR() on error. */
213struct xt_target *xt_find_target(int af, const char *name, u8 revision) 222struct xt_target *xt_find_target(u8 af, const char *name, u8 revision)
214{ 223{
215 struct xt_target *t; 224 struct xt_target *t;
216 int err = 0; 225 int err = 0;
@@ -230,11 +239,16 @@ struct xt_target *xt_find_target(int af, const char *name, u8 revision)
230 } 239 }
231 } 240 }
232 mutex_unlock(&xt[af].mutex); 241 mutex_unlock(&xt[af].mutex);
242
243 if (af != NFPROTO_UNSPEC)
244 /* Try searching again in the family-independent list */
245 return xt_find_target(NFPROTO_UNSPEC, name, revision);
246
233 return ERR_PTR(err); 247 return ERR_PTR(err);
234} 248}
235EXPORT_SYMBOL(xt_find_target); 249EXPORT_SYMBOL(xt_find_target);
236 250
237struct xt_target *xt_request_find_target(int af, const char *name, u8 revision) 251struct xt_target *xt_request_find_target(u8 af, const char *name, u8 revision)
238{ 252{
239 struct xt_target *target; 253 struct xt_target *target;
240 254
@@ -246,7 +260,7 @@ struct xt_target *xt_request_find_target(int af, const char *name, u8 revision)
246} 260}
247EXPORT_SYMBOL_GPL(xt_request_find_target); 261EXPORT_SYMBOL_GPL(xt_request_find_target);
248 262
249static int match_revfn(int af, const char *name, u8 revision, int *bestp) 263static int match_revfn(u8 af, const char *name, u8 revision, int *bestp)
250{ 264{
251 const struct xt_match *m; 265 const struct xt_match *m;
252 int have_rev = 0; 266 int have_rev = 0;
@@ -262,7 +276,7 @@ static int match_revfn(int af, const char *name, u8 revision, int *bestp)
262 return have_rev; 276 return have_rev;
263} 277}
264 278
265static int target_revfn(int af, const char *name, u8 revision, int *bestp) 279static int target_revfn(u8 af, const char *name, u8 revision, int *bestp)
266{ 280{
267 const struct xt_target *t; 281 const struct xt_target *t;
268 int have_rev = 0; 282 int have_rev = 0;
@@ -279,7 +293,7 @@ static int target_revfn(int af, const char *name, u8 revision, int *bestp)
279} 293}
280 294
281/* Returns true or false (if no such extension at all) */ 295/* Returns true or false (if no such extension at all) */
282int xt_find_revision(int af, const char *name, u8 revision, int target, 296int xt_find_revision(u8 af, const char *name, u8 revision, int target,
283 int *err) 297 int *err)
284{ 298{
285 int have_rev, best = -1; 299 int have_rev, best = -1;
@@ -307,37 +321,47 @@ int xt_find_revision(int af, const char *name, u8 revision, int target,
307} 321}
308EXPORT_SYMBOL_GPL(xt_find_revision); 322EXPORT_SYMBOL_GPL(xt_find_revision);
309 323
310int xt_check_match(const struct xt_match *match, unsigned short family, 324int xt_check_match(struct xt_mtchk_param *par,
311 unsigned int size, const char *table, unsigned int hook_mask, 325 unsigned int size, u_int8_t proto, bool inv_proto)
312 unsigned short proto, int inv_proto)
313{ 326{
314 if (XT_ALIGN(match->matchsize) != size) { 327 if (XT_ALIGN(par->match->matchsize) != size &&
328 par->match->matchsize != -1) {
329 /*
330 * ebt_among is exempt from centralized matchsize checking
331 * because it uses a dynamic-size data set.
332 */
315 printk("%s_tables: %s match: invalid size %Zu != %u\n", 333 printk("%s_tables: %s match: invalid size %Zu != %u\n",
316 xt_prefix[family], match->name, 334 xt_prefix[par->family], par->match->name,
317 XT_ALIGN(match->matchsize), size); 335 XT_ALIGN(par->match->matchsize), size);
318 return -EINVAL; 336 return -EINVAL;
319 } 337 }
320 if (match->table && strcmp(match->table, table)) { 338 if (par->match->table != NULL &&
339 strcmp(par->match->table, par->table) != 0) {
321 printk("%s_tables: %s match: only valid in %s table, not %s\n", 340 printk("%s_tables: %s match: only valid in %s table, not %s\n",
322 xt_prefix[family], match->name, match->table, table); 341 xt_prefix[par->family], par->match->name,
342 par->match->table, par->table);
323 return -EINVAL; 343 return -EINVAL;
324 } 344 }
325 if (match->hooks && (hook_mask & ~match->hooks) != 0) { 345 if (par->match->hooks && (par->hook_mask & ~par->match->hooks) != 0) {
326 printk("%s_tables: %s match: bad hook_mask %u/%u\n", 346 printk("%s_tables: %s match: bad hook_mask %#x/%#x\n",
327 xt_prefix[family], match->name, hook_mask, match->hooks); 347 xt_prefix[par->family], par->match->name,
348 par->hook_mask, par->match->hooks);
328 return -EINVAL; 349 return -EINVAL;
329 } 350 }
330 if (match->proto && (match->proto != proto || inv_proto)) { 351 if (par->match->proto && (par->match->proto != proto || inv_proto)) {
331 printk("%s_tables: %s match: only valid for protocol %u\n", 352 printk("%s_tables: %s match: only valid for protocol %u\n",
332 xt_prefix[family], match->name, match->proto); 353 xt_prefix[par->family], par->match->name,
354 par->match->proto);
333 return -EINVAL; 355 return -EINVAL;
334 } 356 }
357 if (par->match->checkentry != NULL && !par->match->checkentry(par))
358 return -EINVAL;
335 return 0; 359 return 0;
336} 360}
337EXPORT_SYMBOL_GPL(xt_check_match); 361EXPORT_SYMBOL_GPL(xt_check_match);
338 362
339#ifdef CONFIG_COMPAT 363#ifdef CONFIG_COMPAT
340int xt_compat_add_offset(int af, unsigned int offset, short delta) 364int xt_compat_add_offset(u_int8_t af, unsigned int offset, short delta)
341{ 365{
342 struct compat_delta *tmp; 366 struct compat_delta *tmp;
343 367
@@ -359,7 +383,7 @@ int xt_compat_add_offset(int af, unsigned int offset, short delta)
359} 383}
360EXPORT_SYMBOL_GPL(xt_compat_add_offset); 384EXPORT_SYMBOL_GPL(xt_compat_add_offset);
361 385
362void xt_compat_flush_offsets(int af) 386void xt_compat_flush_offsets(u_int8_t af)
363{ 387{
364 struct compat_delta *tmp, *next; 388 struct compat_delta *tmp, *next;
365 389
@@ -373,7 +397,7 @@ void xt_compat_flush_offsets(int af)
373} 397}
374EXPORT_SYMBOL_GPL(xt_compat_flush_offsets); 398EXPORT_SYMBOL_GPL(xt_compat_flush_offsets);
375 399
376short xt_compat_calc_jump(int af, unsigned int offset) 400short xt_compat_calc_jump(u_int8_t af, unsigned int offset)
377{ 401{
378 struct compat_delta *tmp; 402 struct compat_delta *tmp;
379 short delta; 403 short delta;
@@ -448,32 +472,36 @@ int xt_compat_match_to_user(struct xt_entry_match *m, void __user **dstptr,
448EXPORT_SYMBOL_GPL(xt_compat_match_to_user); 472EXPORT_SYMBOL_GPL(xt_compat_match_to_user);
449#endif /* CONFIG_COMPAT */ 473#endif /* CONFIG_COMPAT */
450 474
451int xt_check_target(const struct xt_target *target, unsigned short family, 475int xt_check_target(struct xt_tgchk_param *par,
452 unsigned int size, const char *table, unsigned int hook_mask, 476 unsigned int size, u_int8_t proto, bool inv_proto)
453 unsigned short proto, int inv_proto)
454{ 477{
455 if (XT_ALIGN(target->targetsize) != size) { 478 if (XT_ALIGN(par->target->targetsize) != size) {
456 printk("%s_tables: %s target: invalid size %Zu != %u\n", 479 printk("%s_tables: %s target: invalid size %Zu != %u\n",
457 xt_prefix[family], target->name, 480 xt_prefix[par->family], par->target->name,
458 XT_ALIGN(target->targetsize), size); 481 XT_ALIGN(par->target->targetsize), size);
459 return -EINVAL; 482 return -EINVAL;
460 } 483 }
461 if (target->table && strcmp(target->table, table)) { 484 if (par->target->table != NULL &&
485 strcmp(par->target->table, par->table) != 0) {
462 printk("%s_tables: %s target: only valid in %s table, not %s\n", 486 printk("%s_tables: %s target: only valid in %s table, not %s\n",
463 xt_prefix[family], target->name, target->table, table); 487 xt_prefix[par->family], par->target->name,
488 par->target->table, par->table);
464 return -EINVAL; 489 return -EINVAL;
465 } 490 }
466 if (target->hooks && (hook_mask & ~target->hooks) != 0) { 491 if (par->target->hooks && (par->hook_mask & ~par->target->hooks) != 0) {
467 printk("%s_tables: %s target: bad hook_mask %u/%u\n", 492 printk("%s_tables: %s target: bad hook_mask %#x/%#x\n",
468 xt_prefix[family], target->name, hook_mask, 493 xt_prefix[par->family], par->target->name,
469 target->hooks); 494 par->hook_mask, par->target->hooks);
470 return -EINVAL; 495 return -EINVAL;
471 } 496 }
472 if (target->proto && (target->proto != proto || inv_proto)) { 497 if (par->target->proto && (par->target->proto != proto || inv_proto)) {
473 printk("%s_tables: %s target: only valid for protocol %u\n", 498 printk("%s_tables: %s target: only valid for protocol %u\n",
474 xt_prefix[family], target->name, target->proto); 499 xt_prefix[par->family], par->target->name,
500 par->target->proto);
475 return -EINVAL; 501 return -EINVAL;
476 } 502 }
503 if (par->target->checkentry != NULL && !par->target->checkentry(par))
504 return -EINVAL;
477 return 0; 505 return 0;
478} 506}
479EXPORT_SYMBOL_GPL(xt_check_target); 507EXPORT_SYMBOL_GPL(xt_check_target);
@@ -590,7 +618,8 @@ void xt_free_table_info(struct xt_table_info *info)
590EXPORT_SYMBOL(xt_free_table_info); 618EXPORT_SYMBOL(xt_free_table_info);
591 619
592/* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ 620/* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */
593struct xt_table *xt_find_table_lock(struct net *net, int af, const char *name) 621struct xt_table *xt_find_table_lock(struct net *net, u_int8_t af,
622 const char *name)
594{ 623{
595 struct xt_table *t; 624 struct xt_table *t;
596 625
@@ -612,13 +641,13 @@ void xt_table_unlock(struct xt_table *table)
612EXPORT_SYMBOL_GPL(xt_table_unlock); 641EXPORT_SYMBOL_GPL(xt_table_unlock);
613 642
614#ifdef CONFIG_COMPAT 643#ifdef CONFIG_COMPAT
615void xt_compat_lock(int af) 644void xt_compat_lock(u_int8_t af)
616{ 645{
617 mutex_lock(&xt[af].compat_mutex); 646 mutex_lock(&xt[af].compat_mutex);
618} 647}
619EXPORT_SYMBOL_GPL(xt_compat_lock); 648EXPORT_SYMBOL_GPL(xt_compat_lock);
620 649
621void xt_compat_unlock(int af) 650void xt_compat_unlock(u_int8_t af)
622{ 651{
623 mutex_unlock(&xt[af].compat_mutex); 652 mutex_unlock(&xt[af].compat_mutex);
624} 653}
@@ -722,13 +751,13 @@ EXPORT_SYMBOL_GPL(xt_unregister_table);
722#ifdef CONFIG_PROC_FS 751#ifdef CONFIG_PROC_FS
723struct xt_names_priv { 752struct xt_names_priv {
724 struct seq_net_private p; 753 struct seq_net_private p;
725 int af; 754 u_int8_t af;
726}; 755};
727static void *xt_table_seq_start(struct seq_file *seq, loff_t *pos) 756static void *xt_table_seq_start(struct seq_file *seq, loff_t *pos)
728{ 757{
729 struct xt_names_priv *priv = seq->private; 758 struct xt_names_priv *priv = seq->private;
730 struct net *net = seq_file_net(seq); 759 struct net *net = seq_file_net(seq);
731 int af = priv->af; 760 u_int8_t af = priv->af;
732 761
733 mutex_lock(&xt[af].mutex); 762 mutex_lock(&xt[af].mutex);
734 return seq_list_start(&net->xt.tables[af], *pos); 763 return seq_list_start(&net->xt.tables[af], *pos);
@@ -738,7 +767,7 @@ static void *xt_table_seq_next(struct seq_file *seq, void *v, loff_t *pos)
738{ 767{
739 struct xt_names_priv *priv = seq->private; 768 struct xt_names_priv *priv = seq->private;
740 struct net *net = seq_file_net(seq); 769 struct net *net = seq_file_net(seq);
741 int af = priv->af; 770 u_int8_t af = priv->af;
742 771
743 return seq_list_next(v, &net->xt.tables[af], pos); 772 return seq_list_next(v, &net->xt.tables[af], pos);
744} 773}
@@ -746,7 +775,7 @@ static void *xt_table_seq_next(struct seq_file *seq, void *v, loff_t *pos)
746static void xt_table_seq_stop(struct seq_file *seq, void *v) 775static void xt_table_seq_stop(struct seq_file *seq, void *v)
747{ 776{
748 struct xt_names_priv *priv = seq->private; 777 struct xt_names_priv *priv = seq->private;
749 int af = priv->af; 778 u_int8_t af = priv->af;
750 779
751 mutex_unlock(&xt[af].mutex); 780 mutex_unlock(&xt[af].mutex);
752} 781}
@@ -922,14 +951,14 @@ static const struct file_operations xt_target_ops = {
922 951
923#endif /* CONFIG_PROC_FS */ 952#endif /* CONFIG_PROC_FS */
924 953
925int xt_proto_init(struct net *net, int af) 954int xt_proto_init(struct net *net, u_int8_t af)
926{ 955{
927#ifdef CONFIG_PROC_FS 956#ifdef CONFIG_PROC_FS
928 char buf[XT_FUNCTION_MAXNAMELEN]; 957 char buf[XT_FUNCTION_MAXNAMELEN];
929 struct proc_dir_entry *proc; 958 struct proc_dir_entry *proc;
930#endif 959#endif
931 960
932 if (af >= NPROTO) 961 if (af >= ARRAY_SIZE(xt_prefix))
933 return -EINVAL; 962 return -EINVAL;
934 963
935 964
@@ -974,7 +1003,7 @@ out:
974} 1003}
975EXPORT_SYMBOL_GPL(xt_proto_init); 1004EXPORT_SYMBOL_GPL(xt_proto_init);
976 1005
977void xt_proto_fini(struct net *net, int af) 1006void xt_proto_fini(struct net *net, u_int8_t af)
978{ 1007{
979#ifdef CONFIG_PROC_FS 1008#ifdef CONFIG_PROC_FS
980 char buf[XT_FUNCTION_MAXNAMELEN]; 1009 char buf[XT_FUNCTION_MAXNAMELEN];
@@ -998,7 +1027,7 @@ static int __net_init xt_net_init(struct net *net)
998{ 1027{
999 int i; 1028 int i;
1000 1029
1001 for (i = 0; i < NPROTO; i++) 1030 for (i = 0; i < NFPROTO_NUMPROTO; i++)
1002 INIT_LIST_HEAD(&net->xt.tables[i]); 1031 INIT_LIST_HEAD(&net->xt.tables[i]);
1003 return 0; 1032 return 0;
1004} 1033}
@@ -1011,11 +1040,11 @@ static int __init xt_init(void)
1011{ 1040{
1012 int i, rv; 1041 int i, rv;
1013 1042
1014 xt = kmalloc(sizeof(struct xt_af) * NPROTO, GFP_KERNEL); 1043 xt = kmalloc(sizeof(struct xt_af) * NFPROTO_NUMPROTO, GFP_KERNEL);
1015 if (!xt) 1044 if (!xt)
1016 return -ENOMEM; 1045 return -ENOMEM;
1017 1046
1018 for (i = 0; i < NPROTO; i++) { 1047 for (i = 0; i < NFPROTO_NUMPROTO; i++) {
1019 mutex_init(&xt[i].mutex); 1048 mutex_init(&xt[i].mutex);
1020#ifdef CONFIG_COMPAT 1049#ifdef CONFIG_COMPAT
1021 mutex_init(&xt[i].compat_mutex); 1050 mutex_init(&xt[i].compat_mutex);
diff --git a/net/netfilter/xt_CLASSIFY.c b/net/netfilter/xt_CLASSIFY.c
index 77a52bf83225..011bc80dd2a1 100644
--- a/net/netfilter/xt_CLASSIFY.c
+++ b/net/netfilter/xt_CLASSIFY.c
@@ -27,50 +27,34 @@ MODULE_ALIAS("ipt_CLASSIFY");
27MODULE_ALIAS("ip6t_CLASSIFY"); 27MODULE_ALIAS("ip6t_CLASSIFY");
28 28
29static unsigned int 29static unsigned int
30classify_tg(struct sk_buff *skb, const struct net_device *in, 30classify_tg(struct sk_buff *skb, const struct xt_target_param *par)
31 const struct net_device *out, unsigned int hooknum,
32 const struct xt_target *target, const void *targinfo)
33{ 31{
34 const struct xt_classify_target_info *clinfo = targinfo; 32 const struct xt_classify_target_info *clinfo = par->targinfo;
35 33
36 skb->priority = clinfo->priority; 34 skb->priority = clinfo->priority;
37 return XT_CONTINUE; 35 return XT_CONTINUE;
38} 36}
39 37
40static struct xt_target classify_tg_reg[] __read_mostly = { 38static struct xt_target classify_tg_reg __read_mostly = {
41 { 39 .name = "CLASSIFY",
42 .family = AF_INET, 40 .revision = 0,
43 .name = "CLASSIFY", 41 .family = NFPROTO_UNSPEC,
44 .target = classify_tg, 42 .table = "mangle",
45 .targetsize = sizeof(struct xt_classify_target_info), 43 .hooks = (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD) |
46 .table = "mangle", 44 (1 << NF_INET_POST_ROUTING),
47 .hooks = (1 << NF_INET_LOCAL_OUT) | 45 .target = classify_tg,
48 (1 << NF_INET_FORWARD) | 46 .targetsize = sizeof(struct xt_classify_target_info),
49 (1 << NF_INET_POST_ROUTING), 47 .me = THIS_MODULE,
50 .me = THIS_MODULE,
51 },
52 {
53 .name = "CLASSIFY",
54 .family = AF_INET6,
55 .target = classify_tg,
56 .targetsize = sizeof(struct xt_classify_target_info),
57 .table = "mangle",
58 .hooks = (1 << NF_INET_LOCAL_OUT) |
59 (1 << NF_INET_FORWARD) |
60 (1 << NF_INET_POST_ROUTING),
61 .me = THIS_MODULE,
62 },
63}; 48};
64 49
65static int __init classify_tg_init(void) 50static int __init classify_tg_init(void)
66{ 51{
67 return xt_register_targets(classify_tg_reg, 52 return xt_register_target(&classify_tg_reg);
68 ARRAY_SIZE(classify_tg_reg));
69} 53}
70 54
71static void __exit classify_tg_exit(void) 55static void __exit classify_tg_exit(void)
72{ 56{
73 xt_unregister_targets(classify_tg_reg, ARRAY_SIZE(classify_tg_reg)); 57 xt_unregister_target(&classify_tg_reg);
74} 58}
75 59
76module_init(classify_tg_init); 60module_init(classify_tg_init);
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
index 5fecfb4794b1..d6e5ab463277 100644
--- a/net/netfilter/xt_CONNMARK.c
+++ b/net/netfilter/xt_CONNMARK.c
@@ -36,11 +36,9 @@ MODULE_ALIAS("ip6t_CONNMARK");
36#include <net/netfilter/nf_conntrack_ecache.h> 36#include <net/netfilter/nf_conntrack_ecache.h>
37 37
38static unsigned int 38static unsigned int
39connmark_tg_v0(struct sk_buff *skb, const struct net_device *in, 39connmark_tg_v0(struct sk_buff *skb, const struct xt_target_param *par)
40 const struct net_device *out, unsigned int hooknum,
41 const struct xt_target *target, const void *targinfo)
42{ 40{
43 const struct xt_connmark_target_info *markinfo = targinfo; 41 const struct xt_connmark_target_info *markinfo = par->targinfo;
44 struct nf_conn *ct; 42 struct nf_conn *ct;
45 enum ip_conntrack_info ctinfo; 43 enum ip_conntrack_info ctinfo;
46 u_int32_t diff; 44 u_int32_t diff;
@@ -54,7 +52,7 @@ connmark_tg_v0(struct sk_buff *skb, const struct net_device *in,
54 newmark = (ct->mark & ~markinfo->mask) | markinfo->mark; 52 newmark = (ct->mark & ~markinfo->mask) | markinfo->mark;
55 if (newmark != ct->mark) { 53 if (newmark != ct->mark) {
56 ct->mark = newmark; 54 ct->mark = newmark;
57 nf_conntrack_event_cache(IPCT_MARK, skb); 55 nf_conntrack_event_cache(IPCT_MARK, ct);
58 } 56 }
59 break; 57 break;
60 case XT_CONNMARK_SAVE: 58 case XT_CONNMARK_SAVE:
@@ -62,7 +60,7 @@ connmark_tg_v0(struct sk_buff *skb, const struct net_device *in,
62 (skb->mark & markinfo->mask); 60 (skb->mark & markinfo->mask);
63 if (ct->mark != newmark) { 61 if (ct->mark != newmark) {
64 ct->mark = newmark; 62 ct->mark = newmark;
65 nf_conntrack_event_cache(IPCT_MARK, skb); 63 nf_conntrack_event_cache(IPCT_MARK, ct);
66 } 64 }
67 break; 65 break;
68 case XT_CONNMARK_RESTORE: 66 case XT_CONNMARK_RESTORE:
@@ -77,11 +75,9 @@ connmark_tg_v0(struct sk_buff *skb, const struct net_device *in,
77} 75}
78 76
79static unsigned int 77static unsigned int
80connmark_tg(struct sk_buff *skb, const struct net_device *in, 78connmark_tg(struct sk_buff *skb, const struct xt_target_param *par)
81 const struct net_device *out, unsigned int hooknum,
82 const struct xt_target *target, const void *targinfo)
83{ 79{
84 const struct xt_connmark_tginfo1 *info = targinfo; 80 const struct xt_connmark_tginfo1 *info = par->targinfo;
85 enum ip_conntrack_info ctinfo; 81 enum ip_conntrack_info ctinfo;
86 struct nf_conn *ct; 82 struct nf_conn *ct;
87 u_int32_t newmark; 83 u_int32_t newmark;
@@ -95,7 +91,7 @@ connmark_tg(struct sk_buff *skb, const struct net_device *in,
95 newmark = (ct->mark & ~info->ctmask) ^ info->ctmark; 91 newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
96 if (ct->mark != newmark) { 92 if (ct->mark != newmark) {
97 ct->mark = newmark; 93 ct->mark = newmark;
98 nf_conntrack_event_cache(IPCT_MARK, skb); 94 nf_conntrack_event_cache(IPCT_MARK, ct);
99 } 95 }
100 break; 96 break;
101 case XT_CONNMARK_SAVE: 97 case XT_CONNMARK_SAVE:
@@ -103,7 +99,7 @@ connmark_tg(struct sk_buff *skb, const struct net_device *in,
103 (skb->mark & info->nfmask); 99 (skb->mark & info->nfmask);
104 if (ct->mark != newmark) { 100 if (ct->mark != newmark) {
105 ct->mark = newmark; 101 ct->mark = newmark;
106 nf_conntrack_event_cache(IPCT_MARK, skb); 102 nf_conntrack_event_cache(IPCT_MARK, ct);
107 } 103 }
108 break; 104 break;
109 case XT_CONNMARK_RESTORE: 105 case XT_CONNMARK_RESTORE:
@@ -116,18 +112,15 @@ connmark_tg(struct sk_buff *skb, const struct net_device *in,
116 return XT_CONTINUE; 112 return XT_CONTINUE;
117} 113}
118 114
119static bool 115static bool connmark_tg_check_v0(const struct xt_tgchk_param *par)
120connmark_tg_check_v0(const char *tablename, const void *entry,
121 const struct xt_target *target, void *targinfo,
122 unsigned int hook_mask)
123{ 116{
124 const struct xt_connmark_target_info *matchinfo = targinfo; 117 const struct xt_connmark_target_info *matchinfo = par->targinfo;
125 118
126 if (matchinfo->mode == XT_CONNMARK_RESTORE) { 119 if (matchinfo->mode == XT_CONNMARK_RESTORE) {
127 if (strcmp(tablename, "mangle") != 0) { 120 if (strcmp(par->table, "mangle") != 0) {
128 printk(KERN_WARNING "CONNMARK: restore can only be " 121 printk(KERN_WARNING "CONNMARK: restore can only be "
129 "called from \"mangle\" table, not \"%s\"\n", 122 "called from \"mangle\" table, not \"%s\"\n",
130 tablename); 123 par->table);
131 return false; 124 return false;
132 } 125 }
133 } 126 }
@@ -135,31 +128,27 @@ connmark_tg_check_v0(const char *tablename, const void *entry,
135 printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n"); 128 printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n");
136 return false; 129 return false;
137 } 130 }
138 if (nf_ct_l3proto_try_module_get(target->family) < 0) { 131 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
139 printk(KERN_WARNING "can't load conntrack support for " 132 printk(KERN_WARNING "can't load conntrack support for "
140 "proto=%u\n", target->family); 133 "proto=%u\n", par->family);
141 return false; 134 return false;
142 } 135 }
143 return true; 136 return true;
144} 137}
145 138
146static bool 139static bool connmark_tg_check(const struct xt_tgchk_param *par)
147connmark_tg_check(const char *tablename, const void *entry,
148 const struct xt_target *target, void *targinfo,
149 unsigned int hook_mask)
150{ 140{
151 if (nf_ct_l3proto_try_module_get(target->family) < 0) { 141 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
152 printk(KERN_WARNING "cannot load conntrack support for " 142 printk(KERN_WARNING "cannot load conntrack support for "
153 "proto=%u\n", target->family); 143 "proto=%u\n", par->family);
154 return false; 144 return false;
155 } 145 }
156 return true; 146 return true;
157} 147}
158 148
159static void 149static void connmark_tg_destroy(const struct xt_tgdtor_param *par)
160connmark_tg_destroy(const struct xt_target *target, void *targinfo)
161{ 150{
162 nf_ct_l3proto_module_put(target->family); 151 nf_ct_l3proto_module_put(par->family);
163} 152}
164 153
165#ifdef CONFIG_COMPAT 154#ifdef CONFIG_COMPAT
@@ -197,7 +186,7 @@ static struct xt_target connmark_tg_reg[] __read_mostly = {
197 { 186 {
198 .name = "CONNMARK", 187 .name = "CONNMARK",
199 .revision = 0, 188 .revision = 0,
200 .family = AF_INET, 189 .family = NFPROTO_UNSPEC,
201 .checkentry = connmark_tg_check_v0, 190 .checkentry = connmark_tg_check_v0,
202 .destroy = connmark_tg_destroy, 191 .destroy = connmark_tg_destroy,
203 .target = connmark_tg_v0, 192 .target = connmark_tg_v0,
@@ -210,34 +199,9 @@ static struct xt_target connmark_tg_reg[] __read_mostly = {
210 .me = THIS_MODULE 199 .me = THIS_MODULE
211 }, 200 },
212 { 201 {
213 .name = "CONNMARK",
214 .revision = 0,
215 .family = AF_INET6,
216 .checkentry = connmark_tg_check_v0,
217 .destroy = connmark_tg_destroy,
218 .target = connmark_tg_v0,
219 .targetsize = sizeof(struct xt_connmark_target_info),
220#ifdef CONFIG_COMPAT
221 .compatsize = sizeof(struct compat_xt_connmark_target_info),
222 .compat_from_user = connmark_tg_compat_from_user_v0,
223 .compat_to_user = connmark_tg_compat_to_user_v0,
224#endif
225 .me = THIS_MODULE
226 },
227 {
228 .name = "CONNMARK",
229 .revision = 1,
230 .family = AF_INET,
231 .checkentry = connmark_tg_check,
232 .target = connmark_tg,
233 .targetsize = sizeof(struct xt_connmark_tginfo1),
234 .destroy = connmark_tg_destroy,
235 .me = THIS_MODULE,
236 },
237 {
238 .name = "CONNMARK", 202 .name = "CONNMARK",
239 .revision = 1, 203 .revision = 1,
240 .family = AF_INET6, 204 .family = NFPROTO_UNSPEC,
241 .checkentry = connmark_tg_check, 205 .checkentry = connmark_tg_check,
242 .target = connmark_tg, 206 .target = connmark_tg,
243 .targetsize = sizeof(struct xt_connmark_tginfo1), 207 .targetsize = sizeof(struct xt_connmark_tginfo1),
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c
index 76ca1f2421eb..b54c3756fdc3 100644
--- a/net/netfilter/xt_CONNSECMARK.c
+++ b/net/netfilter/xt_CONNSECMARK.c
@@ -43,7 +43,7 @@ static void secmark_save(const struct sk_buff *skb)
43 ct = nf_ct_get(skb, &ctinfo); 43 ct = nf_ct_get(skb, &ctinfo);
44 if (ct && !ct->secmark) { 44 if (ct && !ct->secmark) {
45 ct->secmark = skb->secmark; 45 ct->secmark = skb->secmark;
46 nf_conntrack_event_cache(IPCT_SECMARK, skb); 46 nf_conntrack_event_cache(IPCT_SECMARK, ct);
47 } 47 }
48 } 48 }
49} 49}
@@ -65,11 +65,9 @@ static void secmark_restore(struct sk_buff *skb)
65} 65}
66 66
67static unsigned int 67static unsigned int
68connsecmark_tg(struct sk_buff *skb, const struct net_device *in, 68connsecmark_tg(struct sk_buff *skb, const struct xt_target_param *par)
69 const struct net_device *out, unsigned int hooknum,
70 const struct xt_target *target, const void *targinfo)
71{ 69{
72 const struct xt_connsecmark_target_info *info = targinfo; 70 const struct xt_connsecmark_target_info *info = par->targinfo;
73 71
74 switch (info->mode) { 72 switch (info->mode) {
75 case CONNSECMARK_SAVE: 73 case CONNSECMARK_SAVE:
@@ -87,16 +85,14 @@ connsecmark_tg(struct sk_buff *skb, const struct net_device *in,
87 return XT_CONTINUE; 85 return XT_CONTINUE;
88} 86}
89 87
90static bool 88static bool connsecmark_tg_check(const struct xt_tgchk_param *par)
91connsecmark_tg_check(const char *tablename, const void *entry,
92 const struct xt_target *target, void *targinfo,
93 unsigned int hook_mask)
94{ 89{
95 const struct xt_connsecmark_target_info *info = targinfo; 90 const struct xt_connsecmark_target_info *info = par->targinfo;
96 91
97 if (strcmp(tablename, "mangle") && strcmp(tablename, "security")) { 92 if (strcmp(par->table, "mangle") != 0 &&
93 strcmp(par->table, "security") != 0) {
98 printk(KERN_INFO PFX "target only valid in the \'mangle\' " 94 printk(KERN_INFO PFX "target only valid in the \'mangle\' "
99 "or \'security\' tables, not \'%s\'.\n", tablename); 95 "or \'security\' tables, not \'%s\'.\n", par->table);
100 return false; 96 return false;
101 } 97 }
102 98
@@ -110,51 +106,38 @@ connsecmark_tg_check(const char *tablename, const void *entry,
110 return false; 106 return false;
111 } 107 }
112 108
113 if (nf_ct_l3proto_try_module_get(target->family) < 0) { 109 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
114 printk(KERN_WARNING "can't load conntrack support for " 110 printk(KERN_WARNING "can't load conntrack support for "
115 "proto=%u\n", target->family); 111 "proto=%u\n", par->family);
116 return false; 112 return false;
117 } 113 }
118 return true; 114 return true;
119} 115}
120 116
121static void 117static void connsecmark_tg_destroy(const struct xt_tgdtor_param *par)
122connsecmark_tg_destroy(const struct xt_target *target, void *targinfo)
123{ 118{
124 nf_ct_l3proto_module_put(target->family); 119 nf_ct_l3proto_module_put(par->family);
125} 120}
126 121
127static struct xt_target connsecmark_tg_reg[] __read_mostly = { 122static struct xt_target connsecmark_tg_reg __read_mostly = {
128 { 123 .name = "CONNSECMARK",
129 .name = "CONNSECMARK", 124 .revision = 0,
130 .family = AF_INET, 125 .family = NFPROTO_UNSPEC,
131 .checkentry = connsecmark_tg_check, 126 .checkentry = connsecmark_tg_check,
132 .destroy = connsecmark_tg_destroy, 127 .destroy = connsecmark_tg_destroy,
133 .target = connsecmark_tg, 128 .target = connsecmark_tg,
134 .targetsize = sizeof(struct xt_connsecmark_target_info), 129 .targetsize = sizeof(struct xt_connsecmark_target_info),
135 .me = THIS_MODULE, 130 .me = THIS_MODULE,
136 },
137 {
138 .name = "CONNSECMARK",
139 .family = AF_INET6,
140 .checkentry = connsecmark_tg_check,
141 .destroy = connsecmark_tg_destroy,
142 .target = connsecmark_tg,
143 .targetsize = sizeof(struct xt_connsecmark_target_info),
144 .me = THIS_MODULE,
145 },
146}; 131};
147 132
148static int __init connsecmark_tg_init(void) 133static int __init connsecmark_tg_init(void)
149{ 134{
150 return xt_register_targets(connsecmark_tg_reg, 135 return xt_register_target(&connsecmark_tg_reg);
151 ARRAY_SIZE(connsecmark_tg_reg));
152} 136}
153 137
154static void __exit connsecmark_tg_exit(void) 138static void __exit connsecmark_tg_exit(void)
155{ 139{
156 xt_unregister_targets(connsecmark_tg_reg, 140 xt_unregister_target(&connsecmark_tg_reg);
157 ARRAY_SIZE(connsecmark_tg_reg));
158} 141}
159 142
160module_init(connsecmark_tg_init); 143module_init(connsecmark_tg_init);
diff --git a/net/netfilter/xt_DSCP.c b/net/netfilter/xt_DSCP.c
index 97efd74c04fe..6a347e768f86 100644
--- a/net/netfilter/xt_DSCP.c
+++ b/net/netfilter/xt_DSCP.c
@@ -29,11 +29,9 @@ MODULE_ALIAS("ipt_TOS");
29MODULE_ALIAS("ip6t_TOS"); 29MODULE_ALIAS("ip6t_TOS");
30 30
31static unsigned int 31static unsigned int
32dscp_tg(struct sk_buff *skb, const struct net_device *in, 32dscp_tg(struct sk_buff *skb, const struct xt_target_param *par)
33 const struct net_device *out, unsigned int hooknum,
34 const struct xt_target *target, const void *targinfo)
35{ 33{
36 const struct xt_DSCP_info *dinfo = targinfo; 34 const struct xt_DSCP_info *dinfo = par->targinfo;
37 u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT; 35 u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT;
38 36
39 if (dscp != dinfo->dscp) { 37 if (dscp != dinfo->dscp) {
@@ -48,11 +46,9 @@ dscp_tg(struct sk_buff *skb, const struct net_device *in,
48} 46}
49 47
50static unsigned int 48static unsigned int
51dscp_tg6(struct sk_buff *skb, const struct net_device *in, 49dscp_tg6(struct sk_buff *skb, const struct xt_target_param *par)
52 const struct net_device *out, unsigned int hooknum,
53 const struct xt_target *target, const void *targinfo)
54{ 50{
55 const struct xt_DSCP_info *dinfo = targinfo; 51 const struct xt_DSCP_info *dinfo = par->targinfo;
56 u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT; 52 u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT;
57 53
58 if (dscp != dinfo->dscp) { 54 if (dscp != dinfo->dscp) {
@@ -65,26 +61,21 @@ dscp_tg6(struct sk_buff *skb, const struct net_device *in,
65 return XT_CONTINUE; 61 return XT_CONTINUE;
66} 62}
67 63
68static bool 64static bool dscp_tg_check(const struct xt_tgchk_param *par)
69dscp_tg_check(const char *tablename, const void *e_void,
70 const struct xt_target *target, void *targinfo,
71 unsigned int hook_mask)
72{ 65{
73 const u_int8_t dscp = ((struct xt_DSCP_info *)targinfo)->dscp; 66 const struct xt_DSCP_info *info = par->targinfo;
74 67
75 if (dscp > XT_DSCP_MAX) { 68 if (info->dscp > XT_DSCP_MAX) {
76 printk(KERN_WARNING "DSCP: dscp %x out of range\n", dscp); 69 printk(KERN_WARNING "DSCP: dscp %x out of range\n", info->dscp);
77 return false; 70 return false;
78 } 71 }
79 return true; 72 return true;
80} 73}
81 74
82static unsigned int 75static unsigned int
83tos_tg_v0(struct sk_buff *skb, const struct net_device *in, 76tos_tg_v0(struct sk_buff *skb, const struct xt_target_param *par)
84 const struct net_device *out, unsigned int hooknum,
85 const struct xt_target *target, const void *targinfo)
86{ 77{
87 const struct ipt_tos_target_info *info = targinfo; 78 const struct ipt_tos_target_info *info = par->targinfo;
88 struct iphdr *iph = ip_hdr(skb); 79 struct iphdr *iph = ip_hdr(skb);
89 u_int8_t oldtos; 80 u_int8_t oldtos;
90 81
@@ -101,12 +92,10 @@ tos_tg_v0(struct sk_buff *skb, const struct net_device *in,
101 return XT_CONTINUE; 92 return XT_CONTINUE;
102} 93}
103 94
104static bool 95static bool tos_tg_check_v0(const struct xt_tgchk_param *par)
105tos_tg_check_v0(const char *tablename, const void *e_void,
106 const struct xt_target *target, void *targinfo,
107 unsigned int hook_mask)
108{ 96{
109 const u_int8_t tos = ((struct ipt_tos_target_info *)targinfo)->tos; 97 const struct ipt_tos_target_info *info = par->targinfo;
98 const uint8_t tos = info->tos;
110 99
111 if (tos != IPTOS_LOWDELAY && tos != IPTOS_THROUGHPUT && 100 if (tos != IPTOS_LOWDELAY && tos != IPTOS_THROUGHPUT &&
112 tos != IPTOS_RELIABILITY && tos != IPTOS_MINCOST && 101 tos != IPTOS_RELIABILITY && tos != IPTOS_MINCOST &&
@@ -119,11 +108,9 @@ tos_tg_check_v0(const char *tablename, const void *e_void,
119} 108}
120 109
121static unsigned int 110static unsigned int
122tos_tg(struct sk_buff *skb, const struct net_device *in, 111tos_tg(struct sk_buff *skb, const struct xt_target_param *par)
123 const struct net_device *out, unsigned int hooknum,
124 const struct xt_target *target, const void *targinfo)
125{ 112{
126 const struct xt_tos_target_info *info = targinfo; 113 const struct xt_tos_target_info *info = par->targinfo;
127 struct iphdr *iph = ip_hdr(skb); 114 struct iphdr *iph = ip_hdr(skb);
128 u_int8_t orig, nv; 115 u_int8_t orig, nv;
129 116
@@ -141,11 +128,9 @@ tos_tg(struct sk_buff *skb, const struct net_device *in,
141} 128}
142 129
143static unsigned int 130static unsigned int
144tos_tg6(struct sk_buff *skb, const struct net_device *in, 131tos_tg6(struct sk_buff *skb, const struct xt_target_param *par)
145 const struct net_device *out, unsigned int hooknum,
146 const struct xt_target *target, const void *targinfo)
147{ 132{
148 const struct xt_tos_target_info *info = targinfo; 133 const struct xt_tos_target_info *info = par->targinfo;
149 struct ipv6hdr *iph = ipv6_hdr(skb); 134 struct ipv6hdr *iph = ipv6_hdr(skb);
150 u_int8_t orig, nv; 135 u_int8_t orig, nv;
151 136
@@ -165,7 +150,7 @@ tos_tg6(struct sk_buff *skb, const struct net_device *in,
165static struct xt_target dscp_tg_reg[] __read_mostly = { 150static struct xt_target dscp_tg_reg[] __read_mostly = {
166 { 151 {
167 .name = "DSCP", 152 .name = "DSCP",
168 .family = AF_INET, 153 .family = NFPROTO_IPV4,
169 .checkentry = dscp_tg_check, 154 .checkentry = dscp_tg_check,
170 .target = dscp_tg, 155 .target = dscp_tg,
171 .targetsize = sizeof(struct xt_DSCP_info), 156 .targetsize = sizeof(struct xt_DSCP_info),
@@ -174,7 +159,7 @@ static struct xt_target dscp_tg_reg[] __read_mostly = {
174 }, 159 },
175 { 160 {
176 .name = "DSCP", 161 .name = "DSCP",
177 .family = AF_INET6, 162 .family = NFPROTO_IPV6,
178 .checkentry = dscp_tg_check, 163 .checkentry = dscp_tg_check,
179 .target = dscp_tg6, 164 .target = dscp_tg6,
180 .targetsize = sizeof(struct xt_DSCP_info), 165 .targetsize = sizeof(struct xt_DSCP_info),
@@ -184,7 +169,7 @@ static struct xt_target dscp_tg_reg[] __read_mostly = {
184 { 169 {
185 .name = "TOS", 170 .name = "TOS",
186 .revision = 0, 171 .revision = 0,
187 .family = AF_INET, 172 .family = NFPROTO_IPV4,
188 .table = "mangle", 173 .table = "mangle",
189 .target = tos_tg_v0, 174 .target = tos_tg_v0,
190 .targetsize = sizeof(struct ipt_tos_target_info), 175 .targetsize = sizeof(struct ipt_tos_target_info),
@@ -194,7 +179,7 @@ static struct xt_target dscp_tg_reg[] __read_mostly = {
194 { 179 {
195 .name = "TOS", 180 .name = "TOS",
196 .revision = 1, 181 .revision = 1,
197 .family = AF_INET, 182 .family = NFPROTO_IPV4,
198 .table = "mangle", 183 .table = "mangle",
199 .target = tos_tg, 184 .target = tos_tg,
200 .targetsize = sizeof(struct xt_tos_target_info), 185 .targetsize = sizeof(struct xt_tos_target_info),
@@ -203,7 +188,7 @@ static struct xt_target dscp_tg_reg[] __read_mostly = {
203 { 188 {
204 .name = "TOS", 189 .name = "TOS",
205 .revision = 1, 190 .revision = 1,
206 .family = AF_INET6, 191 .family = NFPROTO_IPV6,
207 .table = "mangle", 192 .table = "mangle",
208 .target = tos_tg6, 193 .target = tos_tg6,
209 .targetsize = sizeof(struct xt_tos_target_info), 194 .targetsize = sizeof(struct xt_tos_target_info),
diff --git a/net/netfilter/xt_MARK.c b/net/netfilter/xt_MARK.c
index f9ce20b58981..67574bcfb8ac 100644
--- a/net/netfilter/xt_MARK.c
+++ b/net/netfilter/xt_MARK.c
@@ -25,22 +25,18 @@ MODULE_ALIAS("ipt_MARK");
25MODULE_ALIAS("ip6t_MARK"); 25MODULE_ALIAS("ip6t_MARK");
26 26
27static unsigned int 27static unsigned int
28mark_tg_v0(struct sk_buff *skb, const struct net_device *in, 28mark_tg_v0(struct sk_buff *skb, const struct xt_target_param *par)
29 const struct net_device *out, unsigned int hooknum,
30 const struct xt_target *target, const void *targinfo)
31{ 29{
32 const struct xt_mark_target_info *markinfo = targinfo; 30 const struct xt_mark_target_info *markinfo = par->targinfo;
33 31
34 skb->mark = markinfo->mark; 32 skb->mark = markinfo->mark;
35 return XT_CONTINUE; 33 return XT_CONTINUE;
36} 34}
37 35
38static unsigned int 36static unsigned int
39mark_tg_v1(struct sk_buff *skb, const struct net_device *in, 37mark_tg_v1(struct sk_buff *skb, const struct xt_target_param *par)
40 const struct net_device *out, unsigned int hooknum,
41 const struct xt_target *target, const void *targinfo)
42{ 38{
43 const struct xt_mark_target_info_v1 *markinfo = targinfo; 39 const struct xt_mark_target_info_v1 *markinfo = par->targinfo;
44 int mark = 0; 40 int mark = 0;
45 41
46 switch (markinfo->mode) { 42 switch (markinfo->mode) {
@@ -62,22 +58,17 @@ mark_tg_v1(struct sk_buff *skb, const struct net_device *in,
62} 58}
63 59
64static unsigned int 60static unsigned int
65mark_tg(struct sk_buff *skb, const struct net_device *in, 61mark_tg(struct sk_buff *skb, const struct xt_target_param *par)
66 const struct net_device *out, unsigned int hooknum,
67 const struct xt_target *target, const void *targinfo)
68{ 62{
69 const struct xt_mark_tginfo2 *info = targinfo; 63 const struct xt_mark_tginfo2 *info = par->targinfo;
70 64
71 skb->mark = (skb->mark & ~info->mask) ^ info->mark; 65 skb->mark = (skb->mark & ~info->mask) ^ info->mark;
72 return XT_CONTINUE; 66 return XT_CONTINUE;
73} 67}
74 68
75static bool 69static bool mark_tg_check_v0(const struct xt_tgchk_param *par)
76mark_tg_check_v0(const char *tablename, const void *entry,
77 const struct xt_target *target, void *targinfo,
78 unsigned int hook_mask)
79{ 70{
80 const struct xt_mark_target_info *markinfo = targinfo; 71 const struct xt_mark_target_info *markinfo = par->targinfo;
81 72
82 if (markinfo->mark > 0xffffffff) { 73 if (markinfo->mark > 0xffffffff) {
83 printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); 74 printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
@@ -86,12 +77,9 @@ mark_tg_check_v0(const char *tablename, const void *entry,
86 return true; 77 return true;
87} 78}
88 79
89static bool 80static bool mark_tg_check_v1(const struct xt_tgchk_param *par)
90mark_tg_check_v1(const char *tablename, const void *entry,
91 const struct xt_target *target, void *targinfo,
92 unsigned int hook_mask)
93{ 81{
94 const struct xt_mark_target_info_v1 *markinfo = targinfo; 82 const struct xt_mark_target_info_v1 *markinfo = par->targinfo;
95 83
96 if (markinfo->mode != XT_MARK_SET 84 if (markinfo->mode != XT_MARK_SET
97 && markinfo->mode != XT_MARK_AND 85 && markinfo->mode != XT_MARK_AND
@@ -161,7 +149,7 @@ static int mark_tg_compat_to_user_v1(void __user *dst, void *src)
161static struct xt_target mark_tg_reg[] __read_mostly = { 149static struct xt_target mark_tg_reg[] __read_mostly = {
162 { 150 {
163 .name = "MARK", 151 .name = "MARK",
164 .family = AF_INET, 152 .family = NFPROTO_UNSPEC,
165 .revision = 0, 153 .revision = 0,
166 .checkentry = mark_tg_check_v0, 154 .checkentry = mark_tg_check_v0,
167 .target = mark_tg_v0, 155 .target = mark_tg_v0,
@@ -176,7 +164,7 @@ static struct xt_target mark_tg_reg[] __read_mostly = {
176 }, 164 },
177 { 165 {
178 .name = "MARK", 166 .name = "MARK",
179 .family = AF_INET, 167 .family = NFPROTO_UNSPEC,
180 .revision = 1, 168 .revision = 1,
181 .checkentry = mark_tg_check_v1, 169 .checkentry = mark_tg_check_v1,
182 .target = mark_tg_v1, 170 .target = mark_tg_v1,
@@ -190,47 +178,9 @@ static struct xt_target mark_tg_reg[] __read_mostly = {
190 .me = THIS_MODULE, 178 .me = THIS_MODULE,
191 }, 179 },
192 { 180 {
193 .name = "MARK",
194 .family = AF_INET6,
195 .revision = 0,
196 .checkentry = mark_tg_check_v0,
197 .target = mark_tg_v0,
198 .targetsize = sizeof(struct xt_mark_target_info),
199#ifdef CONFIG_COMPAT
200 .compatsize = sizeof(struct compat_xt_mark_target_info),
201 .compat_from_user = mark_tg_compat_from_user_v0,
202 .compat_to_user = mark_tg_compat_to_user_v0,
203#endif
204 .table = "mangle",
205 .me = THIS_MODULE,
206 },
207 {
208 .name = "MARK",
209 .family = AF_INET6,
210 .revision = 1,
211 .checkentry = mark_tg_check_v1,
212 .target = mark_tg_v1,
213 .targetsize = sizeof(struct xt_mark_target_info_v1),
214#ifdef CONFIG_COMPAT
215 .compatsize = sizeof(struct compat_xt_mark_target_info_v1),
216 .compat_from_user = mark_tg_compat_from_user_v1,
217 .compat_to_user = mark_tg_compat_to_user_v1,
218#endif
219 .table = "mangle",
220 .me = THIS_MODULE,
221 },
222 {
223 .name = "MARK",
224 .revision = 2,
225 .family = AF_INET,
226 .target = mark_tg,
227 .targetsize = sizeof(struct xt_mark_tginfo2),
228 .me = THIS_MODULE,
229 },
230 {
231 .name = "MARK", 181 .name = "MARK",
232 .revision = 2, 182 .revision = 2,
233 .family = AF_INET6, 183 .family = NFPROTO_UNSPEC,
234 .target = mark_tg, 184 .target = mark_tg,
235 .targetsize = sizeof(struct xt_mark_tginfo2), 185 .targetsize = sizeof(struct xt_mark_tginfo2),
236 .me = THIS_MODULE, 186 .me = THIS_MODULE,
diff --git a/net/netfilter/xt_NFLOG.c b/net/netfilter/xt_NFLOG.c
index 19ae8efae655..50e3a52d3b31 100644
--- a/net/netfilter/xt_NFLOG.c
+++ b/net/netfilter/xt_NFLOG.c
@@ -21,11 +21,9 @@ MODULE_ALIAS("ipt_NFLOG");
21MODULE_ALIAS("ip6t_NFLOG"); 21MODULE_ALIAS("ip6t_NFLOG");
22 22
23static unsigned int 23static unsigned int
24nflog_tg(struct sk_buff *skb, const struct net_device *in, 24nflog_tg(struct sk_buff *skb, const struct xt_target_param *par)
25 const struct net_device *out, unsigned int hooknum,
26 const struct xt_target *target, const void *targinfo)
27{ 25{
28 const struct xt_nflog_info *info = targinfo; 26 const struct xt_nflog_info *info = par->targinfo;
29 struct nf_loginfo li; 27 struct nf_loginfo li;
30 28
31 li.type = NF_LOG_TYPE_ULOG; 29 li.type = NF_LOG_TYPE_ULOG;
@@ -33,17 +31,14 @@ nflog_tg(struct sk_buff *skb, const struct net_device *in,
33 li.u.ulog.group = info->group; 31 li.u.ulog.group = info->group;
34 li.u.ulog.qthreshold = info->threshold; 32 li.u.ulog.qthreshold = info->threshold;
35 33
36 nf_log_packet(target->family, hooknum, skb, in, out, &li, 34 nf_log_packet(par->family, par->hooknum, skb, par->in,
37 "%s", info->prefix); 35 par->out, &li, "%s", info->prefix);
38 return XT_CONTINUE; 36 return XT_CONTINUE;
39} 37}
40 38
41static bool 39static bool nflog_tg_check(const struct xt_tgchk_param *par)
42nflog_tg_check(const char *tablename, const void *entry,
43 const struct xt_target *target, void *targetinfo,
44 unsigned int hookmask)
45{ 40{
46 const struct xt_nflog_info *info = targetinfo; 41 const struct xt_nflog_info *info = par->targinfo;
47 42
48 if (info->flags & ~XT_NFLOG_MASK) 43 if (info->flags & ~XT_NFLOG_MASK)
49 return false; 44 return false;
@@ -52,33 +47,24 @@ nflog_tg_check(const char *tablename, const void *entry,
52 return true; 47 return true;
53} 48}
54 49
55static struct xt_target nflog_tg_reg[] __read_mostly = { 50static struct xt_target nflog_tg_reg __read_mostly = {
56 { 51 .name = "NFLOG",
57 .name = "NFLOG", 52 .revision = 0,
58 .family = AF_INET, 53 .family = NFPROTO_UNSPEC,
59 .checkentry = nflog_tg_check, 54 .checkentry = nflog_tg_check,
60 .target = nflog_tg, 55 .target = nflog_tg,
61 .targetsize = sizeof(struct xt_nflog_info), 56 .targetsize = sizeof(struct xt_nflog_info),
62 .me = THIS_MODULE, 57 .me = THIS_MODULE,
63 },
64 {
65 .name = "NFLOG",
66 .family = AF_INET6,
67 .checkentry = nflog_tg_check,
68 .target = nflog_tg,
69 .targetsize = sizeof(struct xt_nflog_info),
70 .me = THIS_MODULE,
71 },
72}; 58};
73 59
74static int __init nflog_tg_init(void) 60static int __init nflog_tg_init(void)
75{ 61{
76 return xt_register_targets(nflog_tg_reg, ARRAY_SIZE(nflog_tg_reg)); 62 return xt_register_target(&nflog_tg_reg);
77} 63}
78 64
79static void __exit nflog_tg_exit(void) 65static void __exit nflog_tg_exit(void)
80{ 66{
81 xt_unregister_targets(nflog_tg_reg, ARRAY_SIZE(nflog_tg_reg)); 67 xt_unregister_target(&nflog_tg_reg);
82} 68}
83 69
84module_init(nflog_tg_init); 70module_init(nflog_tg_init);
diff --git a/net/netfilter/xt_NFQUEUE.c b/net/netfilter/xt_NFQUEUE.c
index beb24d19a56f..2cc1fff49307 100644
--- a/net/netfilter/xt_NFQUEUE.c
+++ b/net/netfilter/xt_NFQUEUE.c
@@ -24,11 +24,9 @@ MODULE_ALIAS("ip6t_NFQUEUE");
24MODULE_ALIAS("arpt_NFQUEUE"); 24MODULE_ALIAS("arpt_NFQUEUE");
25 25
26static unsigned int 26static unsigned int
27nfqueue_tg(struct sk_buff *skb, const struct net_device *in, 27nfqueue_tg(struct sk_buff *skb, const struct xt_target_param *par)
28 const struct net_device *out, unsigned int hooknum,
29 const struct xt_target *target, const void *targinfo)
30{ 28{
31 const struct xt_NFQ_info *tinfo = targinfo; 29 const struct xt_NFQ_info *tinfo = par->targinfo;
32 30
33 return NF_QUEUE_NR(tinfo->queuenum); 31 return NF_QUEUE_NR(tinfo->queuenum);
34} 32}
@@ -36,14 +34,14 @@ nfqueue_tg(struct sk_buff *skb, const struct net_device *in,
36static struct xt_target nfqueue_tg_reg[] __read_mostly = { 34static struct xt_target nfqueue_tg_reg[] __read_mostly = {
37 { 35 {
38 .name = "NFQUEUE", 36 .name = "NFQUEUE",
39 .family = AF_INET, 37 .family = NFPROTO_IPV4,
40 .target = nfqueue_tg, 38 .target = nfqueue_tg,
41 .targetsize = sizeof(struct xt_NFQ_info), 39 .targetsize = sizeof(struct xt_NFQ_info),
42 .me = THIS_MODULE, 40 .me = THIS_MODULE,
43 }, 41 },
44 { 42 {
45 .name = "NFQUEUE", 43 .name = "NFQUEUE",
46 .family = AF_INET6, 44 .family = NFPROTO_IPV6,
47 .target = nfqueue_tg, 45 .target = nfqueue_tg,
48 .targetsize = sizeof(struct xt_NFQ_info), 46 .targetsize = sizeof(struct xt_NFQ_info),
49 .me = THIS_MODULE, 47 .me = THIS_MODULE,
diff --git a/net/netfilter/xt_NOTRACK.c b/net/netfilter/xt_NOTRACK.c
index 6c9de611eb8d..e7a0a54fd4ea 100644
--- a/net/netfilter/xt_NOTRACK.c
+++ b/net/netfilter/xt_NOTRACK.c
@@ -13,9 +13,7 @@ MODULE_ALIAS("ipt_NOTRACK");
13MODULE_ALIAS("ip6t_NOTRACK"); 13MODULE_ALIAS("ip6t_NOTRACK");
14 14
15static unsigned int 15static unsigned int
16notrack_tg(struct sk_buff *skb, const struct net_device *in, 16notrack_tg(struct sk_buff *skb, const struct xt_target_param *par)
17 const struct net_device *out, unsigned int hooknum,
18 const struct xt_target *target, const void *targinfo)
19{ 17{
20 /* Previously seen (loopback)? Ignore. */ 18 /* Previously seen (loopback)? Ignore. */
21 if (skb->nfct != NULL) 19 if (skb->nfct != NULL)
@@ -32,31 +30,23 @@ notrack_tg(struct sk_buff *skb, const struct net_device *in,
32 return XT_CONTINUE; 30 return XT_CONTINUE;
33} 31}
34 32
35static struct xt_target notrack_tg_reg[] __read_mostly = { 33static struct xt_target notrack_tg_reg __read_mostly = {
36 { 34 .name = "NOTRACK",
37 .name = "NOTRACK", 35 .revision = 0,
38 .family = AF_INET, 36 .family = NFPROTO_UNSPEC,
39 .target = notrack_tg, 37 .target = notrack_tg,
40 .table = "raw", 38 .table = "raw",
41 .me = THIS_MODULE, 39 .me = THIS_MODULE,
42 },
43 {
44 .name = "NOTRACK",
45 .family = AF_INET6,
46 .target = notrack_tg,
47 .table = "raw",
48 .me = THIS_MODULE,
49 },
50}; 40};
51 41
52static int __init notrack_tg_init(void) 42static int __init notrack_tg_init(void)
53{ 43{
54 return xt_register_targets(notrack_tg_reg, ARRAY_SIZE(notrack_tg_reg)); 44 return xt_register_target(&notrack_tg_reg);
55} 45}
56 46
57static void __exit notrack_tg_exit(void) 47static void __exit notrack_tg_exit(void)
58{ 48{
59 xt_unregister_targets(notrack_tg_reg, ARRAY_SIZE(notrack_tg_reg)); 49 xt_unregister_target(&notrack_tg_reg);
60} 50}
61 51
62module_init(notrack_tg_init); 52module_init(notrack_tg_init);
diff --git a/net/netfilter/xt_RATEEST.c b/net/netfilter/xt_RATEEST.c
index 64d6ad380293..43f5676b1af4 100644
--- a/net/netfilter/xt_RATEEST.c
+++ b/net/netfilter/xt_RATEEST.c
@@ -71,14 +71,9 @@ void xt_rateest_put(struct xt_rateest *est)
71EXPORT_SYMBOL_GPL(xt_rateest_put); 71EXPORT_SYMBOL_GPL(xt_rateest_put);
72 72
73static unsigned int 73static unsigned int
74xt_rateest_tg(struct sk_buff *skb, 74xt_rateest_tg(struct sk_buff *skb, const struct xt_target_param *par)
75 const struct net_device *in,
76 const struct net_device *out,
77 unsigned int hooknum,
78 const struct xt_target *target,
79 const void *targinfo)
80{ 75{
81 const struct xt_rateest_target_info *info = targinfo; 76 const struct xt_rateest_target_info *info = par->targinfo;
82 struct gnet_stats_basic *stats = &info->est->bstats; 77 struct gnet_stats_basic *stats = &info->est->bstats;
83 78
84 spin_lock_bh(&info->est->lock); 79 spin_lock_bh(&info->est->lock);
@@ -89,14 +84,9 @@ xt_rateest_tg(struct sk_buff *skb,
89 return XT_CONTINUE; 84 return XT_CONTINUE;
90} 85}
91 86
92static bool 87static bool xt_rateest_tg_checkentry(const struct xt_tgchk_param *par)
93xt_rateest_tg_checkentry(const char *tablename,
94 const void *entry,
95 const struct xt_target *target,
96 void *targinfo,
97 unsigned int hook_mask)
98{ 88{
99 struct xt_rateest_target_info *info = targinfo; 89 struct xt_rateest_target_info *info = par->targinfo;
100 struct xt_rateest *est; 90 struct xt_rateest *est;
101 struct { 91 struct {
102 struct nlattr opt; 92 struct nlattr opt;
@@ -149,33 +139,22 @@ err1:
149 return false; 139 return false;
150} 140}
151 141
152static void xt_rateest_tg_destroy(const struct xt_target *target, 142static void xt_rateest_tg_destroy(const struct xt_tgdtor_param *par)
153 void *targinfo)
154{ 143{
155 struct xt_rateest_target_info *info = targinfo; 144 struct xt_rateest_target_info *info = par->targinfo;
156 145
157 xt_rateest_put(info->est); 146 xt_rateest_put(info->est);
158} 147}
159 148
160static struct xt_target xt_rateest_target[] __read_mostly = { 149static struct xt_target xt_rateest_tg_reg __read_mostly = {
161 { 150 .name = "RATEEST",
162 .family = AF_INET, 151 .revision = 0,
163 .name = "RATEEST", 152 .family = NFPROTO_UNSPEC,
164 .target = xt_rateest_tg, 153 .target = xt_rateest_tg,
165 .checkentry = xt_rateest_tg_checkentry, 154 .checkentry = xt_rateest_tg_checkentry,
166 .destroy = xt_rateest_tg_destroy, 155 .destroy = xt_rateest_tg_destroy,
167 .targetsize = sizeof(struct xt_rateest_target_info), 156 .targetsize = sizeof(struct xt_rateest_target_info),
168 .me = THIS_MODULE, 157 .me = THIS_MODULE,
169 },
170 {
171 .family = AF_INET6,
172 .name = "RATEEST",
173 .target = xt_rateest_tg,
174 .checkentry = xt_rateest_tg_checkentry,
175 .destroy = xt_rateest_tg_destroy,
176 .targetsize = sizeof(struct xt_rateest_target_info),
177 .me = THIS_MODULE,
178 },
179}; 158};
180 159
181static int __init xt_rateest_tg_init(void) 160static int __init xt_rateest_tg_init(void)
@@ -186,13 +165,12 @@ static int __init xt_rateest_tg_init(void)
186 INIT_HLIST_HEAD(&rateest_hash[i]); 165 INIT_HLIST_HEAD(&rateest_hash[i]);
187 166
188 get_random_bytes(&jhash_rnd, sizeof(jhash_rnd)); 167 get_random_bytes(&jhash_rnd, sizeof(jhash_rnd));
189 return xt_register_targets(xt_rateest_target, 168 return xt_register_target(&xt_rateest_tg_reg);
190 ARRAY_SIZE(xt_rateest_target));
191} 169}
192 170
193static void __exit xt_rateest_tg_fini(void) 171static void __exit xt_rateest_tg_fini(void)
194{ 172{
195 xt_unregister_targets(xt_rateest_target, ARRAY_SIZE(xt_rateest_target)); 173 xt_unregister_target(&xt_rateest_tg_reg);
196} 174}
197 175
198 176
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index 94f87ee7552b..7a6f9e6f5dfa 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -29,12 +29,10 @@ MODULE_ALIAS("ip6t_SECMARK");
29static u8 mode; 29static u8 mode;
30 30
31static unsigned int 31static unsigned int
32secmark_tg(struct sk_buff *skb, const struct net_device *in, 32secmark_tg(struct sk_buff *skb, const struct xt_target_param *par)
33 const struct net_device *out, unsigned int hooknum,
34 const struct xt_target *target, const void *targinfo)
35{ 33{
36 u32 secmark = 0; 34 u32 secmark = 0;
37 const struct xt_secmark_target_info *info = targinfo; 35 const struct xt_secmark_target_info *info = par->targinfo;
38 36
39 BUG_ON(info->mode != mode); 37 BUG_ON(info->mode != mode);
40 38
@@ -82,16 +80,14 @@ static bool checkentry_selinux(struct xt_secmark_target_info *info)
82 return true; 80 return true;
83} 81}
84 82
85static bool 83static bool secmark_tg_check(const struct xt_tgchk_param *par)
86secmark_tg_check(const char *tablename, const void *entry,
87 const struct xt_target *target, void *targinfo,
88 unsigned int hook_mask)
89{ 84{
90 struct xt_secmark_target_info *info = targinfo; 85 struct xt_secmark_target_info *info = par->targinfo;
91 86
92 if (strcmp(tablename, "mangle") && strcmp(tablename, "security")) { 87 if (strcmp(par->table, "mangle") != 0 &&
88 strcmp(par->table, "security") != 0) {
93 printk(KERN_INFO PFX "target only valid in the \'mangle\' " 89 printk(KERN_INFO PFX "target only valid in the \'mangle\' "
94 "or \'security\' tables, not \'%s\'.\n", tablename); 90 "or \'security\' tables, not \'%s\'.\n", par->table);
95 return false; 91 return false;
96 } 92 }
97 93
@@ -117,7 +113,7 @@ secmark_tg_check(const char *tablename, const void *entry,
117 return true; 113 return true;
118} 114}
119 115
120static void secmark_tg_destroy(const struct xt_target *target, void *targinfo) 116static void secmark_tg_destroy(const struct xt_tgdtor_param *par)
121{ 117{
122 switch (mode) { 118 switch (mode) {
123 case SECMARK_MODE_SEL: 119 case SECMARK_MODE_SEL:
@@ -125,35 +121,25 @@ static void secmark_tg_destroy(const struct xt_target *target, void *targinfo)
125 } 121 }
126} 122}
127 123
128static struct xt_target secmark_tg_reg[] __read_mostly = { 124static struct xt_target secmark_tg_reg __read_mostly = {
129 { 125 .name = "SECMARK",
130 .name = "SECMARK", 126 .revision = 0,
131 .family = AF_INET, 127 .family = NFPROTO_UNSPEC,
132 .checkentry = secmark_tg_check, 128 .checkentry = secmark_tg_check,
133 .destroy = secmark_tg_destroy, 129 .destroy = secmark_tg_destroy,
134 .target = secmark_tg, 130 .target = secmark_tg,
135 .targetsize = sizeof(struct xt_secmark_target_info), 131 .targetsize = sizeof(struct xt_secmark_target_info),
136 .me = THIS_MODULE, 132 .me = THIS_MODULE,
137 },
138 {
139 .name = "SECMARK",
140 .family = AF_INET6,
141 .checkentry = secmark_tg_check,
142 .destroy = secmark_tg_destroy,
143 .target = secmark_tg,
144 .targetsize = sizeof(struct xt_secmark_target_info),
145 .me = THIS_MODULE,
146 },
147}; 133};
148 134
149static int __init secmark_tg_init(void) 135static int __init secmark_tg_init(void)
150{ 136{
151 return xt_register_targets(secmark_tg_reg, ARRAY_SIZE(secmark_tg_reg)); 137 return xt_register_target(&secmark_tg_reg);
152} 138}
153 139
154static void __exit secmark_tg_exit(void) 140static void __exit secmark_tg_exit(void)
155{ 141{
156 xt_unregister_targets(secmark_tg_reg, ARRAY_SIZE(secmark_tg_reg)); 142 xt_unregister_target(&secmark_tg_reg);
157} 143}
158 144
159module_init(secmark_tg_init); 145module_init(secmark_tg_init);
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
index beb5094703cb..4f3b1f808795 100644
--- a/net/netfilter/xt_TCPMSS.c
+++ b/net/netfilter/xt_TCPMSS.c
@@ -174,15 +174,13 @@ static u_int32_t tcpmss_reverse_mtu(const struct sk_buff *skb,
174} 174}
175 175
176static unsigned int 176static unsigned int
177tcpmss_tg4(struct sk_buff *skb, const struct net_device *in, 177tcpmss_tg4(struct sk_buff *skb, const struct xt_target_param *par)
178 const struct net_device *out, unsigned int hooknum,
179 const struct xt_target *target, const void *targinfo)
180{ 178{
181 struct iphdr *iph = ip_hdr(skb); 179 struct iphdr *iph = ip_hdr(skb);
182 __be16 newlen; 180 __be16 newlen;
183 int ret; 181 int ret;
184 182
185 ret = tcpmss_mangle_packet(skb, targinfo, 183 ret = tcpmss_mangle_packet(skb, par->targinfo,
186 tcpmss_reverse_mtu(skb, PF_INET), 184 tcpmss_reverse_mtu(skb, PF_INET),
187 iph->ihl * 4, 185 iph->ihl * 4,
188 sizeof(*iph) + sizeof(struct tcphdr)); 186 sizeof(*iph) + sizeof(struct tcphdr));
@@ -199,9 +197,7 @@ tcpmss_tg4(struct sk_buff *skb, const struct net_device *in,
199 197
200#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 198#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
201static unsigned int 199static unsigned int
202tcpmss_tg6(struct sk_buff *skb, const struct net_device *in, 200tcpmss_tg6(struct sk_buff *skb, const struct xt_target_param *par)
203 const struct net_device *out, unsigned int hooknum,
204 const struct xt_target *target, const void *targinfo)
205{ 201{
206 struct ipv6hdr *ipv6h = ipv6_hdr(skb); 202 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
207 u8 nexthdr; 203 u8 nexthdr;
@@ -212,7 +208,7 @@ tcpmss_tg6(struct sk_buff *skb, const struct net_device *in,
212 tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr); 208 tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr);
213 if (tcphoff < 0) 209 if (tcphoff < 0)
214 return NF_DROP; 210 return NF_DROP;
215 ret = tcpmss_mangle_packet(skb, targinfo, 211 ret = tcpmss_mangle_packet(skb, par->targinfo,
216 tcpmss_reverse_mtu(skb, PF_INET6), 212 tcpmss_reverse_mtu(skb, PF_INET6),
217 tcphoff, 213 tcphoff,
218 sizeof(*ipv6h) + sizeof(struct tcphdr)); 214 sizeof(*ipv6h) + sizeof(struct tcphdr));
@@ -241,16 +237,13 @@ static inline bool find_syn_match(const struct xt_entry_match *m)
241 return false; 237 return false;
242} 238}
243 239
244static bool 240static bool tcpmss_tg4_check(const struct xt_tgchk_param *par)
245tcpmss_tg4_check(const char *tablename, const void *entry,
246 const struct xt_target *target, void *targinfo,
247 unsigned int hook_mask)
248{ 241{
249 const struct xt_tcpmss_info *info = targinfo; 242 const struct xt_tcpmss_info *info = par->targinfo;
250 const struct ipt_entry *e = entry; 243 const struct ipt_entry *e = par->entryinfo;
251 244
252 if (info->mss == XT_TCPMSS_CLAMP_PMTU && 245 if (info->mss == XT_TCPMSS_CLAMP_PMTU &&
253 (hook_mask & ~((1 << NF_INET_FORWARD) | 246 (par->hook_mask & ~((1 << NF_INET_FORWARD) |
254 (1 << NF_INET_LOCAL_OUT) | 247 (1 << NF_INET_LOCAL_OUT) |
255 (1 << NF_INET_POST_ROUTING))) != 0) { 248 (1 << NF_INET_POST_ROUTING))) != 0) {
256 printk("xt_TCPMSS: path-MTU clamping only supported in " 249 printk("xt_TCPMSS: path-MTU clamping only supported in "
@@ -264,16 +257,13 @@ tcpmss_tg4_check(const char *tablename, const void *entry,
264} 257}
265 258
266#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 259#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
267static bool 260static bool tcpmss_tg6_check(const struct xt_tgchk_param *par)
268tcpmss_tg6_check(const char *tablename, const void *entry,
269 const struct xt_target *target, void *targinfo,
270 unsigned int hook_mask)
271{ 261{
272 const struct xt_tcpmss_info *info = targinfo; 262 const struct xt_tcpmss_info *info = par->targinfo;
273 const struct ip6t_entry *e = entry; 263 const struct ip6t_entry *e = par->entryinfo;
274 264
275 if (info->mss == XT_TCPMSS_CLAMP_PMTU && 265 if (info->mss == XT_TCPMSS_CLAMP_PMTU &&
276 (hook_mask & ~((1 << NF_INET_FORWARD) | 266 (par->hook_mask & ~((1 << NF_INET_FORWARD) |
277 (1 << NF_INET_LOCAL_OUT) | 267 (1 << NF_INET_LOCAL_OUT) |
278 (1 << NF_INET_POST_ROUTING))) != 0) { 268 (1 << NF_INET_POST_ROUTING))) != 0) {
279 printk("xt_TCPMSS: path-MTU clamping only supported in " 269 printk("xt_TCPMSS: path-MTU clamping only supported in "
@@ -289,7 +279,7 @@ tcpmss_tg6_check(const char *tablename, const void *entry,
289 279
290static struct xt_target tcpmss_tg_reg[] __read_mostly = { 280static struct xt_target tcpmss_tg_reg[] __read_mostly = {
291 { 281 {
292 .family = AF_INET, 282 .family = NFPROTO_IPV4,
293 .name = "TCPMSS", 283 .name = "TCPMSS",
294 .checkentry = tcpmss_tg4_check, 284 .checkentry = tcpmss_tg4_check,
295 .target = tcpmss_tg4, 285 .target = tcpmss_tg4,
@@ -299,7 +289,7 @@ static struct xt_target tcpmss_tg_reg[] __read_mostly = {
299 }, 289 },
300#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 290#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
301 { 291 {
302 .family = AF_INET6, 292 .family = NFPROTO_IPV6,
303 .name = "TCPMSS", 293 .name = "TCPMSS",
304 .checkentry = tcpmss_tg6_check, 294 .checkentry = tcpmss_tg6_check,
305 .target = tcpmss_tg6, 295 .target = tcpmss_tg6,
diff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c
index 9685b6fcbc81..9dd8c8ef63eb 100644
--- a/net/netfilter/xt_TCPOPTSTRIP.c
+++ b/net/netfilter/xt_TCPOPTSTRIP.c
@@ -75,19 +75,15 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb,
75} 75}
76 76
77static unsigned int 77static unsigned int
78tcpoptstrip_tg4(struct sk_buff *skb, const struct net_device *in, 78tcpoptstrip_tg4(struct sk_buff *skb, const struct xt_target_param *par)
79 const struct net_device *out, unsigned int hooknum,
80 const struct xt_target *target, const void *targinfo)
81{ 79{
82 return tcpoptstrip_mangle_packet(skb, targinfo, ip_hdrlen(skb), 80 return tcpoptstrip_mangle_packet(skb, par->targinfo, ip_hdrlen(skb),
83 sizeof(struct iphdr) + sizeof(struct tcphdr)); 81 sizeof(struct iphdr) + sizeof(struct tcphdr));
84} 82}
85 83
86#if defined(CONFIG_IP6_NF_MANGLE) || defined(CONFIG_IP6_NF_MANGLE_MODULE) 84#if defined(CONFIG_IP6_NF_MANGLE) || defined(CONFIG_IP6_NF_MANGLE_MODULE)
87static unsigned int 85static unsigned int
88tcpoptstrip_tg6(struct sk_buff *skb, const struct net_device *in, 86tcpoptstrip_tg6(struct sk_buff *skb, const struct xt_target_param *par)
89 const struct net_device *out, unsigned int hooknum,
90 const struct xt_target *target, const void *targinfo)
91{ 87{
92 struct ipv6hdr *ipv6h = ipv6_hdr(skb); 88 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
93 int tcphoff; 89 int tcphoff;
@@ -98,7 +94,7 @@ tcpoptstrip_tg6(struct sk_buff *skb, const struct net_device *in,
98 if (tcphoff < 0) 94 if (tcphoff < 0)
99 return NF_DROP; 95 return NF_DROP;
100 96
101 return tcpoptstrip_mangle_packet(skb, targinfo, tcphoff, 97 return tcpoptstrip_mangle_packet(skb, par->targinfo, tcphoff,
102 sizeof(*ipv6h) + sizeof(struct tcphdr)); 98 sizeof(*ipv6h) + sizeof(struct tcphdr));
103} 99}
104#endif 100#endif
@@ -106,7 +102,7 @@ tcpoptstrip_tg6(struct sk_buff *skb, const struct net_device *in,
106static struct xt_target tcpoptstrip_tg_reg[] __read_mostly = { 102static struct xt_target tcpoptstrip_tg_reg[] __read_mostly = {
107 { 103 {
108 .name = "TCPOPTSTRIP", 104 .name = "TCPOPTSTRIP",
109 .family = AF_INET, 105 .family = NFPROTO_IPV4,
110 .table = "mangle", 106 .table = "mangle",
111 .proto = IPPROTO_TCP, 107 .proto = IPPROTO_TCP,
112 .target = tcpoptstrip_tg4, 108 .target = tcpoptstrip_tg4,
@@ -116,7 +112,7 @@ static struct xt_target tcpoptstrip_tg_reg[] __read_mostly = {
116#if defined(CONFIG_IP6_NF_MANGLE) || defined(CONFIG_IP6_NF_MANGLE_MODULE) 112#if defined(CONFIG_IP6_NF_MANGLE) || defined(CONFIG_IP6_NF_MANGLE_MODULE)
117 { 113 {
118 .name = "TCPOPTSTRIP", 114 .name = "TCPOPTSTRIP",
119 .family = AF_INET6, 115 .family = NFPROTO_IPV6,
120 .table = "mangle", 116 .table = "mangle",
121 .proto = IPPROTO_TCP, 117 .proto = IPPROTO_TCP,
122 .target = tcpoptstrip_tg6, 118 .target = tcpoptstrip_tg6,
diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c
new file mode 100644
index 000000000000..1340c2fa3621
--- /dev/null
+++ b/net/netfilter/xt_TPROXY.c
@@ -0,0 +1,102 @@
1/*
2 * Transparent proxy support for Linux/iptables
3 *
4 * Copyright (c) 2006-2007 BalaBit IT Ltd.
5 * Author: Balazs Scheidler, Krisztian Kovacs
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/skbuff.h>
15#include <linux/ip.h>
16#include <net/checksum.h>
17#include <net/udp.h>
18#include <net/inet_sock.h>
19
20#include <linux/netfilter/x_tables.h>
21#include <linux/netfilter_ipv4/ip_tables.h>
22#include <linux/netfilter/xt_TPROXY.h>
23
24#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
25#include <net/netfilter/nf_tproxy_core.h>
26
27static unsigned int
28tproxy_tg(struct sk_buff *skb, const struct xt_target_param *par)
29{
30 const struct iphdr *iph = ip_hdr(skb);
31 const struct xt_tproxy_target_info *tgi = par->targinfo;
32 struct udphdr _hdr, *hp;
33 struct sock *sk;
34
35 hp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_hdr), &_hdr);
36 if (hp == NULL)
37 return NF_DROP;
38
39 sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol,
40 iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr,
41 hp->source, tgi->lport ? tgi->lport : hp->dest,
42 par->in, true);
43
44 /* NOTE: assign_sock consumes our sk reference */
45 if (sk && nf_tproxy_assign_sock(skb, sk)) {
46 /* This should be in a separate target, but we don't do multiple
47 targets on the same rule yet */
48 skb->mark = (skb->mark & ~tgi->mark_mask) ^ tgi->mark_value;
49
50 pr_debug("redirecting: proto %u %08x:%u -> %08x:%u, mark: %x\n",
51 iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
52 ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark);
53 return NF_ACCEPT;
54 }
55
56 pr_debug("no socket, dropping: proto %u %08x:%u -> %08x:%u, mark: %x\n",
57 iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
58 ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark);
59 return NF_DROP;
60}
61
62static bool tproxy_tg_check(const struct xt_tgchk_param *par)
63{
64 const struct ipt_ip *i = par->entryinfo;
65
66 if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP)
67 && !(i->invflags & IPT_INV_PROTO))
68 return true;
69
70 pr_info("xt_TPROXY: Can be used only in combination with "
71 "either -p tcp or -p udp\n");
72 return false;
73}
74
75static struct xt_target tproxy_tg_reg __read_mostly = {
76 .name = "TPROXY",
77 .family = AF_INET,
78 .table = "mangle",
79 .target = tproxy_tg,
80 .targetsize = sizeof(struct xt_tproxy_target_info),
81 .checkentry = tproxy_tg_check,
82 .hooks = 1 << NF_INET_PRE_ROUTING,
83 .me = THIS_MODULE,
84};
85
86static int __init tproxy_tg_init(void)
87{
88 nf_defrag_ipv4_enable();
89 return xt_register_target(&tproxy_tg_reg);
90}
91
92static void __exit tproxy_tg_exit(void)
93{
94 xt_unregister_target(&tproxy_tg_reg);
95}
96
97module_init(tproxy_tg_init);
98module_exit(tproxy_tg_exit);
99MODULE_LICENSE("GPL");
100MODULE_AUTHOR("Krisztian Kovacs");
101MODULE_DESCRIPTION("Netfilter transparent proxy (TPROXY) target module.");
102MODULE_ALIAS("ipt_TPROXY");
diff --git a/net/netfilter/xt_TRACE.c b/net/netfilter/xt_TRACE.c
index 30dab79a3438..fbb04b86c46b 100644
--- a/net/netfilter/xt_TRACE.c
+++ b/net/netfilter/xt_TRACE.c
@@ -11,39 +11,29 @@ MODULE_ALIAS("ipt_TRACE");
11MODULE_ALIAS("ip6t_TRACE"); 11MODULE_ALIAS("ip6t_TRACE");
12 12
13static unsigned int 13static unsigned int
14trace_tg(struct sk_buff *skb, const struct net_device *in, 14trace_tg(struct sk_buff *skb, const struct xt_target_param *par)
15 const struct net_device *out, unsigned int hooknum,
16 const struct xt_target *target, const void *targinfo)
17{ 15{
18 skb->nf_trace = 1; 16 skb->nf_trace = 1;
19 return XT_CONTINUE; 17 return XT_CONTINUE;
20} 18}
21 19
22static struct xt_target trace_tg_reg[] __read_mostly = { 20static struct xt_target trace_tg_reg __read_mostly = {
23 { 21 .name = "TRACE",
24 .name = "TRACE", 22 .revision = 0,
25 .family = AF_INET, 23 .family = NFPROTO_UNSPEC,
26 .target = trace_tg, 24 .table = "raw",
27 .table = "raw", 25 .target = trace_tg,
28 .me = THIS_MODULE, 26 .me = THIS_MODULE,
29 },
30 {
31 .name = "TRACE",
32 .family = AF_INET6,
33 .target = trace_tg,
34 .table = "raw",
35 .me = THIS_MODULE,
36 },
37}; 27};
38 28
39static int __init trace_tg_init(void) 29static int __init trace_tg_init(void)
40{ 30{
41 return xt_register_targets(trace_tg_reg, ARRAY_SIZE(trace_tg_reg)); 31 return xt_register_target(&trace_tg_reg);
42} 32}
43 33
44static void __exit trace_tg_exit(void) 34static void __exit trace_tg_exit(void)
45{ 35{
46 xt_unregister_targets(trace_tg_reg, ARRAY_SIZE(trace_tg_reg)); 36 xt_unregister_target(&trace_tg_reg);
47} 37}
48 38
49module_init(trace_tg_init); 39module_init(trace_tg_init);
diff --git a/net/netfilter/xt_comment.c b/net/netfilter/xt_comment.c
index 89f47364e848..e82179832acd 100644
--- a/net/netfilter/xt_comment.c
+++ b/net/netfilter/xt_comment.c
@@ -16,40 +16,29 @@ MODULE_ALIAS("ipt_comment");
16MODULE_ALIAS("ip6t_comment"); 16MODULE_ALIAS("ip6t_comment");
17 17
18static bool 18static bool
19comment_mt(const struct sk_buff *skb, const struct net_device *in, 19comment_mt(const struct sk_buff *skb, const struct xt_match_param *par)
20 const struct net_device *out, const struct xt_match *match,
21 const void *matchinfo, int offset, unsigned int protooff,
22 bool *hotdrop)
23{ 20{
24 /* We always match */ 21 /* We always match */
25 return true; 22 return true;
26} 23}
27 24
28static struct xt_match comment_mt_reg[] __read_mostly = { 25static struct xt_match comment_mt_reg __read_mostly = {
29 { 26 .name = "comment",
30 .name = "comment", 27 .revision = 0,
31 .family = AF_INET, 28 .family = NFPROTO_UNSPEC,
32 .match = comment_mt, 29 .match = comment_mt,
33 .matchsize = sizeof(struct xt_comment_info), 30 .matchsize = sizeof(struct xt_comment_info),
34 .me = THIS_MODULE 31 .me = THIS_MODULE,
35 },
36 {
37 .name = "comment",
38 .family = AF_INET6,
39 .match = comment_mt,
40 .matchsize = sizeof(struct xt_comment_info),
41 .me = THIS_MODULE
42 },
43}; 32};
44 33
45static int __init comment_mt_init(void) 34static int __init comment_mt_init(void)
46{ 35{
47 return xt_register_matches(comment_mt_reg, ARRAY_SIZE(comment_mt_reg)); 36 return xt_register_match(&comment_mt_reg);
48} 37}
49 38
50static void __exit comment_mt_exit(void) 39static void __exit comment_mt_exit(void)
51{ 40{
52 xt_unregister_matches(comment_mt_reg, ARRAY_SIZE(comment_mt_reg)); 41 xt_unregister_match(&comment_mt_reg);
53} 42}
54 43
55module_init(comment_mt_init); 44module_init(comment_mt_init);
diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c
index 3e39c4fe1931..955e6598a7f0 100644
--- a/net/netfilter/xt_connbytes.c
+++ b/net/netfilter/xt_connbytes.c
@@ -17,12 +17,9 @@ MODULE_ALIAS("ipt_connbytes");
17MODULE_ALIAS("ip6t_connbytes"); 17MODULE_ALIAS("ip6t_connbytes");
18 18
19static bool 19static bool
20connbytes_mt(const struct sk_buff *skb, const struct net_device *in, 20connbytes_mt(const struct sk_buff *skb, const struct xt_match_param *par)
21 const struct net_device *out, const struct xt_match *match,
22 const void *matchinfo, int offset, unsigned int protoff,
23 bool *hotdrop)
24{ 21{
25 const struct xt_connbytes_info *sinfo = matchinfo; 22 const struct xt_connbytes_info *sinfo = par->matchinfo;
26 const struct nf_conn *ct; 23 const struct nf_conn *ct;
27 enum ip_conntrack_info ctinfo; 24 enum ip_conntrack_info ctinfo;
28 u_int64_t what = 0; /* initialize to make gcc happy */ 25 u_int64_t what = 0; /* initialize to make gcc happy */
@@ -95,12 +92,9 @@ connbytes_mt(const struct sk_buff *skb, const struct net_device *in,
95 return what >= sinfo->count.from; 92 return what >= sinfo->count.from;
96} 93}
97 94
98static bool 95static bool connbytes_mt_check(const struct xt_mtchk_param *par)
99connbytes_mt_check(const char *tablename, const void *ip,
100 const struct xt_match *match, void *matchinfo,
101 unsigned int hook_mask)
102{ 96{
103 const struct xt_connbytes_info *sinfo = matchinfo; 97 const struct xt_connbytes_info *sinfo = par->matchinfo;
104 98
105 if (sinfo->what != XT_CONNBYTES_PKTS && 99 if (sinfo->what != XT_CONNBYTES_PKTS &&
106 sinfo->what != XT_CONNBYTES_BYTES && 100 sinfo->what != XT_CONNBYTES_BYTES &&
@@ -112,51 +106,39 @@ connbytes_mt_check(const char *tablename, const void *ip,
112 sinfo->direction != XT_CONNBYTES_DIR_BOTH) 106 sinfo->direction != XT_CONNBYTES_DIR_BOTH)
113 return false; 107 return false;
114 108
115 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 109 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
116 printk(KERN_WARNING "can't load conntrack support for " 110 printk(KERN_WARNING "can't load conntrack support for "
117 "proto=%u\n", match->family); 111 "proto=%u\n", par->family);
118 return false; 112 return false;
119 } 113 }
120 114
121 return true; 115 return true;
122} 116}
123 117
124static void 118static void connbytes_mt_destroy(const struct xt_mtdtor_param *par)
125connbytes_mt_destroy(const struct xt_match *match, void *matchinfo)
126{ 119{
127 nf_ct_l3proto_module_put(match->family); 120 nf_ct_l3proto_module_put(par->family);
128} 121}
129 122
130static struct xt_match connbytes_mt_reg[] __read_mostly = { 123static struct xt_match connbytes_mt_reg __read_mostly = {
131 { 124 .name = "connbytes",
132 .name = "connbytes", 125 .revision = 0,
133 .family = AF_INET, 126 .family = NFPROTO_UNSPEC,
134 .checkentry = connbytes_mt_check, 127 .checkentry = connbytes_mt_check,
135 .match = connbytes_mt, 128 .match = connbytes_mt,
136 .destroy = connbytes_mt_destroy, 129 .destroy = connbytes_mt_destroy,
137 .matchsize = sizeof(struct xt_connbytes_info), 130 .matchsize = sizeof(struct xt_connbytes_info),
138 .me = THIS_MODULE 131 .me = THIS_MODULE,
139 },
140 {
141 .name = "connbytes",
142 .family = AF_INET6,
143 .checkentry = connbytes_mt_check,
144 .match = connbytes_mt,
145 .destroy = connbytes_mt_destroy,
146 .matchsize = sizeof(struct xt_connbytes_info),
147 .me = THIS_MODULE
148 },
149}; 132};
150 133
151static int __init connbytes_mt_init(void) 134static int __init connbytes_mt_init(void)
152{ 135{
153 return xt_register_matches(connbytes_mt_reg, 136 return xt_register_match(&connbytes_mt_reg);
154 ARRAY_SIZE(connbytes_mt_reg));
155} 137}
156 138
157static void __exit connbytes_mt_exit(void) 139static void __exit connbytes_mt_exit(void)
158{ 140{
159 xt_unregister_matches(connbytes_mt_reg, ARRAY_SIZE(connbytes_mt_reg)); 141 xt_unregister_match(&connbytes_mt_reg);
160} 142}
161 143
162module_init(connbytes_mt_init); 144module_init(connbytes_mt_init);
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index 70907f6baac3..7f404cc64c83 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -82,9 +82,9 @@ static inline bool already_closed(const struct nf_conn *conn)
82static inline unsigned int 82static inline unsigned int
83same_source_net(const union nf_inet_addr *addr, 83same_source_net(const union nf_inet_addr *addr,
84 const union nf_inet_addr *mask, 84 const union nf_inet_addr *mask,
85 const union nf_inet_addr *u3, unsigned int family) 85 const union nf_inet_addr *u3, u_int8_t family)
86{ 86{
87 if (family == AF_INET) { 87 if (family == NFPROTO_IPV4) {
88 return (addr->ip & mask->ip) == (u3->ip & mask->ip); 88 return (addr->ip & mask->ip) == (u3->ip & mask->ip);
89 } else { 89 } else {
90 union nf_inet_addr lh, rh; 90 union nf_inet_addr lh, rh;
@@ -114,7 +114,7 @@ static int count_them(struct xt_connlimit_data *data,
114 int matches = 0; 114 int matches = 0;
115 115
116 116
117 if (match->family == AF_INET6) 117 if (match->family == NFPROTO_IPV6)
118 hash = &data->iphash[connlimit_iphash6(addr, mask)]; 118 hash = &data->iphash[connlimit_iphash6(addr, mask)];
119 else 119 else
120 hash = &data->iphash[connlimit_iphash(addr->ip & mask->ip)]; 120 hash = &data->iphash[connlimit_iphash(addr->ip & mask->ip)];
@@ -123,7 +123,7 @@ static int count_them(struct xt_connlimit_data *data,
123 123
124 /* check the saved connections */ 124 /* check the saved connections */
125 list_for_each_entry_safe(conn, tmp, hash, list) { 125 list_for_each_entry_safe(conn, tmp, hash, list) {
126 found = __nf_conntrack_find(&conn->tuple); 126 found = __nf_conntrack_find(&init_net, &conn->tuple);
127 found_ct = NULL; 127 found_ct = NULL;
128 128
129 if (found != NULL) 129 if (found != NULL)
@@ -178,12 +178,9 @@ static int count_them(struct xt_connlimit_data *data,
178} 178}
179 179
180static bool 180static bool
181connlimit_mt(const struct sk_buff *skb, const struct net_device *in, 181connlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
182 const struct net_device *out, const struct xt_match *match,
183 const void *matchinfo, int offset, unsigned int protoff,
184 bool *hotdrop)
185{ 182{
186 const struct xt_connlimit_info *info = matchinfo; 183 const struct xt_connlimit_info *info = par->matchinfo;
187 union nf_inet_addr addr; 184 union nf_inet_addr addr;
188 struct nf_conntrack_tuple tuple; 185 struct nf_conntrack_tuple tuple;
189 const struct nf_conntrack_tuple *tuple_ptr = &tuple; 186 const struct nf_conntrack_tuple *tuple_ptr = &tuple;
@@ -195,10 +192,10 @@ connlimit_mt(const struct sk_buff *skb, const struct net_device *in,
195 if (ct != NULL) 192 if (ct != NULL)
196 tuple_ptr = &ct->tuplehash[0].tuple; 193 tuple_ptr = &ct->tuplehash[0].tuple;
197 else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), 194 else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb),
198 match->family, &tuple)) 195 par->family, &tuple))
199 goto hotdrop; 196 goto hotdrop;
200 197
201 if (match->family == AF_INET6) { 198 if (par->family == NFPROTO_IPV6) {
202 const struct ipv6hdr *iph = ipv6_hdr(skb); 199 const struct ipv6hdr *iph = ipv6_hdr(skb);
203 memcpy(&addr.ip6, &iph->saddr, sizeof(iph->saddr)); 200 memcpy(&addr.ip6, &iph->saddr, sizeof(iph->saddr));
204 } else { 201 } else {
@@ -208,40 +205,37 @@ connlimit_mt(const struct sk_buff *skb, const struct net_device *in,
208 205
209 spin_lock_bh(&info->data->lock); 206 spin_lock_bh(&info->data->lock);
210 connections = count_them(info->data, tuple_ptr, &addr, 207 connections = count_them(info->data, tuple_ptr, &addr,
211 &info->mask, match); 208 &info->mask, par->match);
212 spin_unlock_bh(&info->data->lock); 209 spin_unlock_bh(&info->data->lock);
213 210
214 if (connections < 0) { 211 if (connections < 0) {
215 /* kmalloc failed, drop it entirely */ 212 /* kmalloc failed, drop it entirely */
216 *hotdrop = true; 213 *par->hotdrop = true;
217 return false; 214 return false;
218 } 215 }
219 216
220 return (connections > info->limit) ^ info->inverse; 217 return (connections > info->limit) ^ info->inverse;
221 218
222 hotdrop: 219 hotdrop:
223 *hotdrop = true; 220 *par->hotdrop = true;
224 return false; 221 return false;
225} 222}
226 223
227static bool 224static bool connlimit_mt_check(const struct xt_mtchk_param *par)
228connlimit_mt_check(const char *tablename, const void *ip,
229 const struct xt_match *match, void *matchinfo,
230 unsigned int hook_mask)
231{ 225{
232 struct xt_connlimit_info *info = matchinfo; 226 struct xt_connlimit_info *info = par->matchinfo;
233 unsigned int i; 227 unsigned int i;
234 228
235 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 229 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
236 printk(KERN_WARNING "cannot load conntrack support for " 230 printk(KERN_WARNING "cannot load conntrack support for "
237 "address family %u\n", match->family); 231 "address family %u\n", par->family);
238 return false; 232 return false;
239 } 233 }
240 234
241 /* init private data */ 235 /* init private data */
242 info->data = kmalloc(sizeof(struct xt_connlimit_data), GFP_KERNEL); 236 info->data = kmalloc(sizeof(struct xt_connlimit_data), GFP_KERNEL);
243 if (info->data == NULL) { 237 if (info->data == NULL) {
244 nf_ct_l3proto_module_put(match->family); 238 nf_ct_l3proto_module_put(par->family);
245 return false; 239 return false;
246 } 240 }
247 241
@@ -252,16 +246,15 @@ connlimit_mt_check(const char *tablename, const void *ip,
252 return true; 246 return true;
253} 247}
254 248
255static void 249static void connlimit_mt_destroy(const struct xt_mtdtor_param *par)
256connlimit_mt_destroy(const struct xt_match *match, void *matchinfo)
257{ 250{
258 const struct xt_connlimit_info *info = matchinfo; 251 const struct xt_connlimit_info *info = par->matchinfo;
259 struct xt_connlimit_conn *conn; 252 struct xt_connlimit_conn *conn;
260 struct xt_connlimit_conn *tmp; 253 struct xt_connlimit_conn *tmp;
261 struct list_head *hash = info->data->iphash; 254 struct list_head *hash = info->data->iphash;
262 unsigned int i; 255 unsigned int i;
263 256
264 nf_ct_l3proto_module_put(match->family); 257 nf_ct_l3proto_module_put(par->family);
265 258
266 for (i = 0; i < ARRAY_SIZE(info->data->iphash); ++i) { 259 for (i = 0; i < ARRAY_SIZE(info->data->iphash); ++i) {
267 list_for_each_entry_safe(conn, tmp, &hash[i], list) { 260 list_for_each_entry_safe(conn, tmp, &hash[i], list) {
@@ -273,41 +266,30 @@ connlimit_mt_destroy(const struct xt_match *match, void *matchinfo)
273 kfree(info->data); 266 kfree(info->data);
274} 267}
275 268
276static struct xt_match connlimit_mt_reg[] __read_mostly = { 269static struct xt_match connlimit_mt_reg __read_mostly = {
277 { 270 .name = "connlimit",
278 .name = "connlimit", 271 .revision = 0,
279 .family = AF_INET, 272 .family = NFPROTO_UNSPEC,
280 .checkentry = connlimit_mt_check, 273 .checkentry = connlimit_mt_check,
281 .match = connlimit_mt, 274 .match = connlimit_mt,
282 .matchsize = sizeof(struct xt_connlimit_info), 275 .matchsize = sizeof(struct xt_connlimit_info),
283 .destroy = connlimit_mt_destroy, 276 .destroy = connlimit_mt_destroy,
284 .me = THIS_MODULE, 277 .me = THIS_MODULE,
285 },
286 {
287 .name = "connlimit",
288 .family = AF_INET6,
289 .checkentry = connlimit_mt_check,
290 .match = connlimit_mt,
291 .matchsize = sizeof(struct xt_connlimit_info),
292 .destroy = connlimit_mt_destroy,
293 .me = THIS_MODULE,
294 },
295}; 278};
296 279
297static int __init connlimit_mt_init(void) 280static int __init connlimit_mt_init(void)
298{ 281{
299 return xt_register_matches(connlimit_mt_reg, 282 return xt_register_match(&connlimit_mt_reg);
300 ARRAY_SIZE(connlimit_mt_reg));
301} 283}
302 284
303static void __exit connlimit_mt_exit(void) 285static void __exit connlimit_mt_exit(void)
304{ 286{
305 xt_unregister_matches(connlimit_mt_reg, ARRAY_SIZE(connlimit_mt_reg)); 287 xt_unregister_match(&connlimit_mt_reg);
306} 288}
307 289
308module_init(connlimit_mt_init); 290module_init(connlimit_mt_init);
309module_exit(connlimit_mt_exit); 291module_exit(connlimit_mt_exit);
310MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); 292MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
311MODULE_DESCRIPTION("Xtables: Number of connections matching"); 293MODULE_DESCRIPTION("Xtables: Number of connections matching");
312MODULE_LICENSE("GPL"); 294MODULE_LICENSE("GPL");
313MODULE_ALIAS("ipt_connlimit"); 295MODULE_ALIAS("ipt_connlimit");
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
index aaa1b96691f9..86cacab7a4a3 100644
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -34,12 +34,9 @@ MODULE_ALIAS("ipt_connmark");
34MODULE_ALIAS("ip6t_connmark"); 34MODULE_ALIAS("ip6t_connmark");
35 35
36static bool 36static bool
37connmark_mt(const struct sk_buff *skb, const struct net_device *in, 37connmark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
38 const struct net_device *out, const struct xt_match *match,
39 const void *matchinfo, int offset, unsigned int protoff,
40 bool *hotdrop)
41{ 38{
42 const struct xt_connmark_mtinfo1 *info = matchinfo; 39 const struct xt_connmark_mtinfo1 *info = par->matchinfo;
43 enum ip_conntrack_info ctinfo; 40 enum ip_conntrack_info ctinfo;
44 const struct nf_conn *ct; 41 const struct nf_conn *ct;
45 42
@@ -51,12 +48,9 @@ connmark_mt(const struct sk_buff *skb, const struct net_device *in,
51} 48}
52 49
53static bool 50static bool
54connmark_mt_v0(const struct sk_buff *skb, const struct net_device *in, 51connmark_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
55 const struct net_device *out, const struct xt_match *match,
56 const void *matchinfo, int offset, unsigned int protoff,
57 bool *hotdrop)
58{ 52{
59 const struct xt_connmark_info *info = matchinfo; 53 const struct xt_connmark_info *info = par->matchinfo;
60 const struct nf_conn *ct; 54 const struct nf_conn *ct;
61 enum ip_conntrack_info ctinfo; 55 enum ip_conntrack_info ctinfo;
62 56
@@ -67,42 +61,35 @@ connmark_mt_v0(const struct sk_buff *skb, const struct net_device *in,
67 return ((ct->mark & info->mask) == info->mark) ^ info->invert; 61 return ((ct->mark & info->mask) == info->mark) ^ info->invert;
68} 62}
69 63
70static bool 64static bool connmark_mt_check_v0(const struct xt_mtchk_param *par)
71connmark_mt_check_v0(const char *tablename, const void *ip,
72 const struct xt_match *match, void *matchinfo,
73 unsigned int hook_mask)
74{ 65{
75 const struct xt_connmark_info *cm = matchinfo; 66 const struct xt_connmark_info *cm = par->matchinfo;
76 67
77 if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) { 68 if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) {
78 printk(KERN_WARNING "connmark: only support 32bit mark\n"); 69 printk(KERN_WARNING "connmark: only support 32bit mark\n");
79 return false; 70 return false;
80 } 71 }
81 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 72 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
82 printk(KERN_WARNING "can't load conntrack support for " 73 printk(KERN_WARNING "can't load conntrack support for "
83 "proto=%u\n", match->family); 74 "proto=%u\n", par->family);
84 return false; 75 return false;
85 } 76 }
86 return true; 77 return true;
87} 78}
88 79
89static bool 80static bool connmark_mt_check(const struct xt_mtchk_param *par)
90connmark_mt_check(const char *tablename, const void *ip,
91 const struct xt_match *match, void *matchinfo,
92 unsigned int hook_mask)
93{ 81{
94 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 82 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
95 printk(KERN_WARNING "cannot load conntrack support for " 83 printk(KERN_WARNING "cannot load conntrack support for "
96 "proto=%u\n", match->family); 84 "proto=%u\n", par->family);
97 return false; 85 return false;
98 } 86 }
99 return true; 87 return true;
100} 88}
101 89
102static void 90static void connmark_mt_destroy(const struct xt_mtdtor_param *par)
103connmark_mt_destroy(const struct xt_match *match, void *matchinfo)
104{ 91{
105 nf_ct_l3proto_module_put(match->family); 92 nf_ct_l3proto_module_put(par->family);
106} 93}
107 94
108#ifdef CONFIG_COMPAT 95#ifdef CONFIG_COMPAT
@@ -140,7 +127,7 @@ static struct xt_match connmark_mt_reg[] __read_mostly = {
140 { 127 {
141 .name = "connmark", 128 .name = "connmark",
142 .revision = 0, 129 .revision = 0,
143 .family = AF_INET, 130 .family = NFPROTO_UNSPEC,
144 .checkentry = connmark_mt_check_v0, 131 .checkentry = connmark_mt_check_v0,
145 .match = connmark_mt_v0, 132 .match = connmark_mt_v0,
146 .destroy = connmark_mt_destroy, 133 .destroy = connmark_mt_destroy,
@@ -153,34 +140,9 @@ static struct xt_match connmark_mt_reg[] __read_mostly = {
153 .me = THIS_MODULE 140 .me = THIS_MODULE
154 }, 141 },
155 { 142 {
156 .name = "connmark",
157 .revision = 0,
158 .family = AF_INET6,
159 .checkentry = connmark_mt_check_v0,
160 .match = connmark_mt_v0,
161 .destroy = connmark_mt_destroy,
162 .matchsize = sizeof(struct xt_connmark_info),
163#ifdef CONFIG_COMPAT
164 .compatsize = sizeof(struct compat_xt_connmark_info),
165 .compat_from_user = connmark_mt_compat_from_user_v0,
166 .compat_to_user = connmark_mt_compat_to_user_v0,
167#endif
168 .me = THIS_MODULE
169 },
170 {
171 .name = "connmark",
172 .revision = 1,
173 .family = AF_INET,
174 .checkentry = connmark_mt_check,
175 .match = connmark_mt,
176 .matchsize = sizeof(struct xt_connmark_mtinfo1),
177 .destroy = connmark_mt_destroy,
178 .me = THIS_MODULE,
179 },
180 {
181 .name = "connmark", 143 .name = "connmark",
182 .revision = 1, 144 .revision = 1,
183 .family = AF_INET6, 145 .family = NFPROTO_UNSPEC,
184 .checkentry = connmark_mt_check, 146 .checkentry = connmark_mt_check,
185 .match = connmark_mt, 147 .match = connmark_mt,
186 .matchsize = sizeof(struct xt_connmark_mtinfo1), 148 .matchsize = sizeof(struct xt_connmark_mtinfo1),
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index d61412f58ef7..0b7139f3dd78 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -25,12 +25,9 @@ MODULE_ALIAS("ipt_conntrack");
25MODULE_ALIAS("ip6t_conntrack"); 25MODULE_ALIAS("ip6t_conntrack");
26 26
27static bool 27static bool
28conntrack_mt_v0(const struct sk_buff *skb, const struct net_device *in, 28conntrack_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
29 const struct net_device *out, const struct xt_match *match,
30 const void *matchinfo, int offset, unsigned int protoff,
31 bool *hotdrop)
32{ 29{
33 const struct xt_conntrack_info *sinfo = matchinfo; 30 const struct xt_conntrack_info *sinfo = par->matchinfo;
34 const struct nf_conn *ct; 31 const struct nf_conn *ct;
35 enum ip_conntrack_info ctinfo; 32 enum ip_conntrack_info ctinfo;
36 unsigned int statebit; 33 unsigned int statebit;
@@ -121,9 +118,9 @@ conntrack_addrcmp(const union nf_inet_addr *kaddr,
121 const union nf_inet_addr *uaddr, 118 const union nf_inet_addr *uaddr,
122 const union nf_inet_addr *umask, unsigned int l3proto) 119 const union nf_inet_addr *umask, unsigned int l3proto)
123{ 120{
124 if (l3proto == AF_INET) 121 if (l3proto == NFPROTO_IPV4)
125 return ((kaddr->ip ^ uaddr->ip) & umask->ip) == 0; 122 return ((kaddr->ip ^ uaddr->ip) & umask->ip) == 0;
126 else if (l3proto == AF_INET6) 123 else if (l3proto == NFPROTO_IPV6)
127 return ipv6_masked_addr_cmp(&kaddr->in6, &umask->in6, 124 return ipv6_masked_addr_cmp(&kaddr->in6, &umask->in6,
128 &uaddr->in6) == 0; 125 &uaddr->in6) == 0;
129 else 126 else
@@ -133,7 +130,7 @@ conntrack_addrcmp(const union nf_inet_addr *kaddr,
133static inline bool 130static inline bool
134conntrack_mt_origsrc(const struct nf_conn *ct, 131conntrack_mt_origsrc(const struct nf_conn *ct,
135 const struct xt_conntrack_mtinfo1 *info, 132 const struct xt_conntrack_mtinfo1 *info,
136 unsigned int family) 133 u_int8_t family)
137{ 134{
138 return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3, 135 return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3,
139 &info->origsrc_addr, &info->origsrc_mask, family); 136 &info->origsrc_addr, &info->origsrc_mask, family);
@@ -142,7 +139,7 @@ conntrack_mt_origsrc(const struct nf_conn *ct,
142static inline bool 139static inline bool
143conntrack_mt_origdst(const struct nf_conn *ct, 140conntrack_mt_origdst(const struct nf_conn *ct,
144 const struct xt_conntrack_mtinfo1 *info, 141 const struct xt_conntrack_mtinfo1 *info,
145 unsigned int family) 142 u_int8_t family)
146{ 143{
147 return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3, 144 return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3,
148 &info->origdst_addr, &info->origdst_mask, family); 145 &info->origdst_addr, &info->origdst_mask, family);
@@ -151,7 +148,7 @@ conntrack_mt_origdst(const struct nf_conn *ct,
151static inline bool 148static inline bool
152conntrack_mt_replsrc(const struct nf_conn *ct, 149conntrack_mt_replsrc(const struct nf_conn *ct,
153 const struct xt_conntrack_mtinfo1 *info, 150 const struct xt_conntrack_mtinfo1 *info,
154 unsigned int family) 151 u_int8_t family)
155{ 152{
156 return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3, 153 return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3,
157 &info->replsrc_addr, &info->replsrc_mask, family); 154 &info->replsrc_addr, &info->replsrc_mask, family);
@@ -160,7 +157,7 @@ conntrack_mt_replsrc(const struct nf_conn *ct,
160static inline bool 157static inline bool
161conntrack_mt_repldst(const struct nf_conn *ct, 158conntrack_mt_repldst(const struct nf_conn *ct,
162 const struct xt_conntrack_mtinfo1 *info, 159 const struct xt_conntrack_mtinfo1 *info,
163 unsigned int family) 160 u_int8_t family)
164{ 161{
165 return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3, 162 return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3,
166 &info->repldst_addr, &info->repldst_mask, family); 163 &info->repldst_addr, &info->repldst_mask, family);
@@ -205,12 +202,9 @@ ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info,
205} 202}
206 203
207static bool 204static bool
208conntrack_mt(const struct sk_buff *skb, const struct net_device *in, 205conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
209 const struct net_device *out, const struct xt_match *match,
210 const void *matchinfo, int offset, unsigned int protoff,
211 bool *hotdrop)
212{ 206{
213 const struct xt_conntrack_mtinfo1 *info = matchinfo; 207 const struct xt_conntrack_mtinfo1 *info = par->matchinfo;
214 enum ip_conntrack_info ctinfo; 208 enum ip_conntrack_info ctinfo;
215 const struct nf_conn *ct; 209 const struct nf_conn *ct;
216 unsigned int statebit; 210 unsigned int statebit;
@@ -244,22 +238,22 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
244 return false; 238 return false;
245 239
246 if (info->match_flags & XT_CONNTRACK_ORIGSRC) 240 if (info->match_flags & XT_CONNTRACK_ORIGSRC)
247 if (conntrack_mt_origsrc(ct, info, match->family) ^ 241 if (conntrack_mt_origsrc(ct, info, par->family) ^
248 !(info->invert_flags & XT_CONNTRACK_ORIGSRC)) 242 !(info->invert_flags & XT_CONNTRACK_ORIGSRC))
249 return false; 243 return false;
250 244
251 if (info->match_flags & XT_CONNTRACK_ORIGDST) 245 if (info->match_flags & XT_CONNTRACK_ORIGDST)
252 if (conntrack_mt_origdst(ct, info, match->family) ^ 246 if (conntrack_mt_origdst(ct, info, par->family) ^
253 !(info->invert_flags & XT_CONNTRACK_ORIGDST)) 247 !(info->invert_flags & XT_CONNTRACK_ORIGDST))
254 return false; 248 return false;
255 249
256 if (info->match_flags & XT_CONNTRACK_REPLSRC) 250 if (info->match_flags & XT_CONNTRACK_REPLSRC)
257 if (conntrack_mt_replsrc(ct, info, match->family) ^ 251 if (conntrack_mt_replsrc(ct, info, par->family) ^
258 !(info->invert_flags & XT_CONNTRACK_REPLSRC)) 252 !(info->invert_flags & XT_CONNTRACK_REPLSRC))
259 return false; 253 return false;
260 254
261 if (info->match_flags & XT_CONNTRACK_REPLDST) 255 if (info->match_flags & XT_CONNTRACK_REPLDST)
262 if (conntrack_mt_repldst(ct, info, match->family) ^ 256 if (conntrack_mt_repldst(ct, info, par->family) ^
263 !(info->invert_flags & XT_CONNTRACK_REPLDST)) 257 !(info->invert_flags & XT_CONNTRACK_REPLDST))
264 return false; 258 return false;
265 259
@@ -284,23 +278,19 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
284 return true; 278 return true;
285} 279}
286 280
287static bool 281static bool conntrack_mt_check(const struct xt_mtchk_param *par)
288conntrack_mt_check(const char *tablename, const void *ip,
289 const struct xt_match *match, void *matchinfo,
290 unsigned int hook_mask)
291{ 282{
292 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 283 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
293 printk(KERN_WARNING "can't load conntrack support for " 284 printk(KERN_WARNING "can't load conntrack support for "
294 "proto=%u\n", match->family); 285 "proto=%u\n", par->family);
295 return false; 286 return false;
296 } 287 }
297 return true; 288 return true;
298} 289}
299 290
300static void 291static void conntrack_mt_destroy(const struct xt_mtdtor_param *par)
301conntrack_mt_destroy(const struct xt_match *match, void *matchinfo)
302{ 292{
303 nf_ct_l3proto_module_put(match->family); 293 nf_ct_l3proto_module_put(par->family);
304} 294}
305 295
306#ifdef CONFIG_COMPAT 296#ifdef CONFIG_COMPAT
@@ -356,7 +346,7 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = {
356 { 346 {
357 .name = "conntrack", 347 .name = "conntrack",
358 .revision = 0, 348 .revision = 0,
359 .family = AF_INET, 349 .family = NFPROTO_IPV4,
360 .match = conntrack_mt_v0, 350 .match = conntrack_mt_v0,
361 .checkentry = conntrack_mt_check, 351 .checkentry = conntrack_mt_check,
362 .destroy = conntrack_mt_destroy, 352 .destroy = conntrack_mt_destroy,
@@ -371,17 +361,7 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = {
371 { 361 {
372 .name = "conntrack", 362 .name = "conntrack",
373 .revision = 1, 363 .revision = 1,
374 .family = AF_INET, 364 .family = NFPROTO_UNSPEC,
375 .matchsize = sizeof(struct xt_conntrack_mtinfo1),
376 .match = conntrack_mt,
377 .checkentry = conntrack_mt_check,
378 .destroy = conntrack_mt_destroy,
379 .me = THIS_MODULE,
380 },
381 {
382 .name = "conntrack",
383 .revision = 1,
384 .family = AF_INET6,
385 .matchsize = sizeof(struct xt_conntrack_mtinfo1), 365 .matchsize = sizeof(struct xt_conntrack_mtinfo1),
386 .match = conntrack_mt, 366 .match = conntrack_mt,
387 .checkentry = conntrack_mt_check, 367 .checkentry = conntrack_mt_check,
diff --git a/net/netfilter/xt_dccp.c b/net/netfilter/xt_dccp.c
index 8b6522186d9f..e5d3e8673287 100644
--- a/net/netfilter/xt_dccp.c
+++ b/net/netfilter/xt_dccp.c
@@ -93,20 +93,18 @@ match_option(u_int8_t option, const struct sk_buff *skb, unsigned int protoff,
93} 93}
94 94
95static bool 95static bool
96dccp_mt(const struct sk_buff *skb, const struct net_device *in, 96dccp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
97 const struct net_device *out, const struct xt_match *match,
98 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
99{ 97{
100 const struct xt_dccp_info *info = matchinfo; 98 const struct xt_dccp_info *info = par->matchinfo;
101 const struct dccp_hdr *dh; 99 const struct dccp_hdr *dh;
102 struct dccp_hdr _dh; 100 struct dccp_hdr _dh;
103 101
104 if (offset) 102 if (par->fragoff != 0)
105 return false; 103 return false;
106 104
107 dh = skb_header_pointer(skb, protoff, sizeof(_dh), &_dh); 105 dh = skb_header_pointer(skb, par->thoff, sizeof(_dh), &_dh);
108 if (dh == NULL) { 106 if (dh == NULL) {
109 *hotdrop = true; 107 *par->hotdrop = true;
110 return false; 108 return false;
111 } 109 }
112 110
@@ -118,17 +116,14 @@ dccp_mt(const struct sk_buff *skb, const struct net_device *in,
118 XT_DCCP_DEST_PORTS, info->flags, info->invflags) 116 XT_DCCP_DEST_PORTS, info->flags, info->invflags)
119 && DCCHECK(match_types(dh, info->typemask), 117 && DCCHECK(match_types(dh, info->typemask),
120 XT_DCCP_TYPE, info->flags, info->invflags) 118 XT_DCCP_TYPE, info->flags, info->invflags)
121 && DCCHECK(match_option(info->option, skb, protoff, dh, 119 && DCCHECK(match_option(info->option, skb, par->thoff, dh,
122 hotdrop), 120 par->hotdrop),
123 XT_DCCP_OPTION, info->flags, info->invflags); 121 XT_DCCP_OPTION, info->flags, info->invflags);
124} 122}
125 123
126static bool 124static bool dccp_mt_check(const struct xt_mtchk_param *par)
127dccp_mt_check(const char *tablename, const void *inf,
128 const struct xt_match *match, void *matchinfo,
129 unsigned int hook_mask)
130{ 125{
131 const struct xt_dccp_info *info = matchinfo; 126 const struct xt_dccp_info *info = par->matchinfo;
132 127
133 return !(info->flags & ~XT_DCCP_VALID_FLAGS) 128 return !(info->flags & ~XT_DCCP_VALID_FLAGS)
134 && !(info->invflags & ~XT_DCCP_VALID_FLAGS) 129 && !(info->invflags & ~XT_DCCP_VALID_FLAGS)
@@ -138,7 +133,7 @@ dccp_mt_check(const char *tablename, const void *inf,
138static struct xt_match dccp_mt_reg[] __read_mostly = { 133static struct xt_match dccp_mt_reg[] __read_mostly = {
139 { 134 {
140 .name = "dccp", 135 .name = "dccp",
141 .family = AF_INET, 136 .family = NFPROTO_IPV4,
142 .checkentry = dccp_mt_check, 137 .checkentry = dccp_mt_check,
143 .match = dccp_mt, 138 .match = dccp_mt,
144 .matchsize = sizeof(struct xt_dccp_info), 139 .matchsize = sizeof(struct xt_dccp_info),
@@ -147,7 +142,7 @@ static struct xt_match dccp_mt_reg[] __read_mostly = {
147 }, 142 },
148 { 143 {
149 .name = "dccp", 144 .name = "dccp",
150 .family = AF_INET6, 145 .family = NFPROTO_IPV6,
151 .checkentry = dccp_mt_check, 146 .checkentry = dccp_mt_check,
152 .match = dccp_mt, 147 .match = dccp_mt,
153 .matchsize = sizeof(struct xt_dccp_info), 148 .matchsize = sizeof(struct xt_dccp_info),
diff --git a/net/netfilter/xt_dscp.c b/net/netfilter/xt_dscp.c
index 26f4aab9c429..c3f8085460d7 100644
--- a/net/netfilter/xt_dscp.c
+++ b/net/netfilter/xt_dscp.c
@@ -26,61 +26,48 @@ MODULE_ALIAS("ipt_tos");
26MODULE_ALIAS("ip6t_tos"); 26MODULE_ALIAS("ip6t_tos");
27 27
28static bool 28static bool
29dscp_mt(const struct sk_buff *skb, const struct net_device *in, 29dscp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
30 const struct net_device *out, const struct xt_match *match,
31 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
32{ 30{
33 const struct xt_dscp_info *info = matchinfo; 31 const struct xt_dscp_info *info = par->matchinfo;
34 u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT; 32 u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT;
35 33
36 return (dscp == info->dscp) ^ !!info->invert; 34 return (dscp == info->dscp) ^ !!info->invert;
37} 35}
38 36
39static bool 37static bool
40dscp_mt6(const struct sk_buff *skb, const struct net_device *in, 38dscp_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
41 const struct net_device *out, const struct xt_match *match,
42 const void *matchinfo, int offset, unsigned int protoff,
43 bool *hotdrop)
44{ 39{
45 const struct xt_dscp_info *info = matchinfo; 40 const struct xt_dscp_info *info = par->matchinfo;
46 u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT; 41 u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT;
47 42
48 return (dscp == info->dscp) ^ !!info->invert; 43 return (dscp == info->dscp) ^ !!info->invert;
49} 44}
50 45
51static bool 46static bool dscp_mt_check(const struct xt_mtchk_param *par)
52dscp_mt_check(const char *tablename, const void *info,
53 const struct xt_match *match, void *matchinfo,
54 unsigned int hook_mask)
55{ 47{
56 const u_int8_t dscp = ((struct xt_dscp_info *)matchinfo)->dscp; 48 const struct xt_dscp_info *info = par->matchinfo;
57 49
58 if (dscp > XT_DSCP_MAX) { 50 if (info->dscp > XT_DSCP_MAX) {
59 printk(KERN_ERR "xt_dscp: dscp %x out of range\n", dscp); 51 printk(KERN_ERR "xt_dscp: dscp %x out of range\n", info->dscp);
60 return false; 52 return false;
61 } 53 }
62 54
63 return true; 55 return true;
64} 56}
65 57
66static bool tos_mt_v0(const struct sk_buff *skb, const struct net_device *in, 58static bool
67 const struct net_device *out, 59tos_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
68 const struct xt_match *match, const void *matchinfo,
69 int offset, unsigned int protoff, bool *hotdrop)
70{ 60{
71 const struct ipt_tos_info *info = matchinfo; 61 const struct ipt_tos_info *info = par->matchinfo;
72 62
73 return (ip_hdr(skb)->tos == info->tos) ^ info->invert; 63 return (ip_hdr(skb)->tos == info->tos) ^ info->invert;
74} 64}
75 65
76static bool tos_mt(const struct sk_buff *skb, const struct net_device *in, 66static bool tos_mt(const struct sk_buff *skb, const struct xt_match_param *par)
77 const struct net_device *out, const struct xt_match *match,
78 const void *matchinfo, int offset, unsigned int protoff,
79 bool *hotdrop)
80{ 67{
81 const struct xt_tos_match_info *info = matchinfo; 68 const struct xt_tos_match_info *info = par->matchinfo;
82 69
83 if (match->family == AF_INET) 70 if (par->match->family == NFPROTO_IPV4)
84 return ((ip_hdr(skb)->tos & info->tos_mask) == 71 return ((ip_hdr(skb)->tos & info->tos_mask) ==
85 info->tos_value) ^ !!info->invert; 72 info->tos_value) ^ !!info->invert;
86 else 73 else
@@ -91,7 +78,7 @@ static bool tos_mt(const struct sk_buff *skb, const struct net_device *in,
91static struct xt_match dscp_mt_reg[] __read_mostly = { 78static struct xt_match dscp_mt_reg[] __read_mostly = {
92 { 79 {
93 .name = "dscp", 80 .name = "dscp",
94 .family = AF_INET, 81 .family = NFPROTO_IPV4,
95 .checkentry = dscp_mt_check, 82 .checkentry = dscp_mt_check,
96 .match = dscp_mt, 83 .match = dscp_mt,
97 .matchsize = sizeof(struct xt_dscp_info), 84 .matchsize = sizeof(struct xt_dscp_info),
@@ -99,7 +86,7 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {
99 }, 86 },
100 { 87 {
101 .name = "dscp", 88 .name = "dscp",
102 .family = AF_INET6, 89 .family = NFPROTO_IPV6,
103 .checkentry = dscp_mt_check, 90 .checkentry = dscp_mt_check,
104 .match = dscp_mt6, 91 .match = dscp_mt6,
105 .matchsize = sizeof(struct xt_dscp_info), 92 .matchsize = sizeof(struct xt_dscp_info),
@@ -108,7 +95,7 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {
108 { 95 {
109 .name = "tos", 96 .name = "tos",
110 .revision = 0, 97 .revision = 0,
111 .family = AF_INET, 98 .family = NFPROTO_IPV4,
112 .match = tos_mt_v0, 99 .match = tos_mt_v0,
113 .matchsize = sizeof(struct ipt_tos_info), 100 .matchsize = sizeof(struct ipt_tos_info),
114 .me = THIS_MODULE, 101 .me = THIS_MODULE,
@@ -116,7 +103,7 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {
116 { 103 {
117 .name = "tos", 104 .name = "tos",
118 .revision = 1, 105 .revision = 1,
119 .family = AF_INET, 106 .family = NFPROTO_IPV4,
120 .match = tos_mt, 107 .match = tos_mt,
121 .matchsize = sizeof(struct xt_tos_match_info), 108 .matchsize = sizeof(struct xt_tos_match_info),
122 .me = THIS_MODULE, 109 .me = THIS_MODULE,
@@ -124,7 +111,7 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {
124 { 111 {
125 .name = "tos", 112 .name = "tos",
126 .revision = 1, 113 .revision = 1,
127 .family = AF_INET6, 114 .family = NFPROTO_IPV6,
128 .match = tos_mt, 115 .match = tos_mt,
129 .matchsize = sizeof(struct xt_tos_match_info), 116 .matchsize = sizeof(struct xt_tos_match_info),
130 .me = THIS_MODULE, 117 .me = THIS_MODULE,
diff --git a/net/netfilter/xt_esp.c b/net/netfilter/xt_esp.c
index a133eb9b23e1..609439967c2c 100644
--- a/net/netfilter/xt_esp.c
+++ b/net/netfilter/xt_esp.c
@@ -42,26 +42,23 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
42 return r; 42 return r;
43} 43}
44 44
45static bool 45static bool esp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
46esp_mt(const struct sk_buff *skb, const struct net_device *in,
47 const struct net_device *out, const struct xt_match *match,
48 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
49{ 46{
50 const struct ip_esp_hdr *eh; 47 const struct ip_esp_hdr *eh;
51 struct ip_esp_hdr _esp; 48 struct ip_esp_hdr _esp;
52 const struct xt_esp *espinfo = matchinfo; 49 const struct xt_esp *espinfo = par->matchinfo;
53 50
54 /* Must not be a fragment. */ 51 /* Must not be a fragment. */
55 if (offset) 52 if (par->fragoff != 0)
56 return false; 53 return false;
57 54
58 eh = skb_header_pointer(skb, protoff, sizeof(_esp), &_esp); 55 eh = skb_header_pointer(skb, par->thoff, sizeof(_esp), &_esp);
59 if (eh == NULL) { 56 if (eh == NULL) {
60 /* We've been asked to examine this packet, and we 57 /* We've been asked to examine this packet, and we
61 * can't. Hence, no choice but to drop. 58 * can't. Hence, no choice but to drop.
62 */ 59 */
63 duprintf("Dropping evil ESP tinygram.\n"); 60 duprintf("Dropping evil ESP tinygram.\n");
64 *hotdrop = true; 61 *par->hotdrop = true;
65 return false; 62 return false;
66 } 63 }
67 64
@@ -69,13 +66,9 @@ esp_mt(const struct sk_buff *skb, const struct net_device *in,
69 !!(espinfo->invflags & XT_ESP_INV_SPI)); 66 !!(espinfo->invflags & XT_ESP_INV_SPI));
70} 67}
71 68
72/* Called when user tries to insert an entry of this type. */ 69static bool esp_mt_check(const struct xt_mtchk_param *par)
73static bool
74esp_mt_check(const char *tablename, const void *ip_void,
75 const struct xt_match *match, void *matchinfo,
76 unsigned int hook_mask)
77{ 70{
78 const struct xt_esp *espinfo = matchinfo; 71 const struct xt_esp *espinfo = par->matchinfo;
79 72
80 if (espinfo->invflags & ~XT_ESP_INV_MASK) { 73 if (espinfo->invflags & ~XT_ESP_INV_MASK) {
81 duprintf("xt_esp: unknown flags %X\n", espinfo->invflags); 74 duprintf("xt_esp: unknown flags %X\n", espinfo->invflags);
@@ -88,7 +81,7 @@ esp_mt_check(const char *tablename, const void *ip_void,
88static struct xt_match esp_mt_reg[] __read_mostly = { 81static struct xt_match esp_mt_reg[] __read_mostly = {
89 { 82 {
90 .name = "esp", 83 .name = "esp",
91 .family = AF_INET, 84 .family = NFPROTO_IPV4,
92 .checkentry = esp_mt_check, 85 .checkentry = esp_mt_check,
93 .match = esp_mt, 86 .match = esp_mt,
94 .matchsize = sizeof(struct xt_esp), 87 .matchsize = sizeof(struct xt_esp),
@@ -97,7 +90,7 @@ static struct xt_match esp_mt_reg[] __read_mostly = {
97 }, 90 },
98 { 91 {
99 .name = "esp", 92 .name = "esp",
100 .family = AF_INET6, 93 .family = NFPROTO_IPV6,
101 .checkentry = esp_mt_check, 94 .checkentry = esp_mt_check,
102 .match = esp_mt, 95 .match = esp_mt,
103 .matchsize = sizeof(struct xt_esp), 96 .matchsize = sizeof(struct xt_esp),
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index d9418a267812..6fc4292d46e6 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -80,7 +80,7 @@ struct dsthash_ent {
80struct xt_hashlimit_htable { 80struct xt_hashlimit_htable {
81 struct hlist_node node; /* global list of all htables */ 81 struct hlist_node node; /* global list of all htables */
82 atomic_t use; 82 atomic_t use;
83 int family; 83 u_int8_t family;
84 84
85 struct hashlimit_cfg1 cfg; /* config */ 85 struct hashlimit_cfg1 cfg; /* config */
86 86
@@ -185,7 +185,7 @@ dsthash_free(struct xt_hashlimit_htable *ht, struct dsthash_ent *ent)
185} 185}
186static void htable_gc(unsigned long htlong); 186static void htable_gc(unsigned long htlong);
187 187
188static int htable_create_v0(struct xt_hashlimit_info *minfo, int family) 188static int htable_create_v0(struct xt_hashlimit_info *minfo, u_int8_t family)
189{ 189{
190 struct xt_hashlimit_htable *hinfo; 190 struct xt_hashlimit_htable *hinfo;
191 unsigned int size; 191 unsigned int size;
@@ -218,7 +218,7 @@ static int htable_create_v0(struct xt_hashlimit_info *minfo, int family)
218 hinfo->cfg.gc_interval = minfo->cfg.gc_interval; 218 hinfo->cfg.gc_interval = minfo->cfg.gc_interval;
219 hinfo->cfg.expire = minfo->cfg.expire; 219 hinfo->cfg.expire = minfo->cfg.expire;
220 220
221 if (family == AF_INET) 221 if (family == NFPROTO_IPV4)
222 hinfo->cfg.srcmask = hinfo->cfg.dstmask = 32; 222 hinfo->cfg.srcmask = hinfo->cfg.dstmask = 32;
223 else 223 else
224 hinfo->cfg.srcmask = hinfo->cfg.dstmask = 128; 224 hinfo->cfg.srcmask = hinfo->cfg.dstmask = 128;
@@ -237,11 +237,10 @@ static int htable_create_v0(struct xt_hashlimit_info *minfo, int family)
237 hinfo->family = family; 237 hinfo->family = family;
238 hinfo->rnd_initialized = 0; 238 hinfo->rnd_initialized = 0;
239 spin_lock_init(&hinfo->lock); 239 spin_lock_init(&hinfo->lock);
240 hinfo->pde = 240 hinfo->pde = proc_create_data(minfo->name, 0,
241 proc_create_data(minfo->name, 0, 241 (family == NFPROTO_IPV4) ?
242 family == AF_INET ? hashlimit_procdir4 : 242 hashlimit_procdir4 : hashlimit_procdir6,
243 hashlimit_procdir6, 243 &dl_file_ops, hinfo);
244 &dl_file_ops, hinfo);
245 if (!hinfo->pde) { 244 if (!hinfo->pde) {
246 vfree(hinfo); 245 vfree(hinfo);
247 return -1; 246 return -1;
@@ -258,8 +257,7 @@ static int htable_create_v0(struct xt_hashlimit_info *minfo, int family)
258 return 0; 257 return 0;
259} 258}
260 259
261static int htable_create(struct xt_hashlimit_mtinfo1 *minfo, 260static int htable_create(struct xt_hashlimit_mtinfo1 *minfo, u_int8_t family)
262 unsigned int family)
263{ 261{
264 struct xt_hashlimit_htable *hinfo; 262 struct xt_hashlimit_htable *hinfo;
265 unsigned int size; 263 unsigned int size;
@@ -301,11 +299,10 @@ static int htable_create(struct xt_hashlimit_mtinfo1 *minfo,
301 hinfo->rnd_initialized = 0; 299 hinfo->rnd_initialized = 0;
302 spin_lock_init(&hinfo->lock); 300 spin_lock_init(&hinfo->lock);
303 301
304 hinfo->pde = 302 hinfo->pde = proc_create_data(minfo->name, 0,
305 proc_create_data(minfo->name, 0, 303 (family == NFPROTO_IPV4) ?
306 family == AF_INET ? hashlimit_procdir4 : 304 hashlimit_procdir4 : hashlimit_procdir6,
307 hashlimit_procdir6, 305 &dl_file_ops, hinfo);
308 &dl_file_ops, hinfo);
309 if (hinfo->pde == NULL) { 306 if (hinfo->pde == NULL) {
310 vfree(hinfo); 307 vfree(hinfo);
311 return -1; 308 return -1;
@@ -371,14 +368,14 @@ static void htable_destroy(struct xt_hashlimit_htable *hinfo)
371 368
372 /* remove proc entry */ 369 /* remove proc entry */
373 remove_proc_entry(hinfo->pde->name, 370 remove_proc_entry(hinfo->pde->name,
374 hinfo->family == AF_INET ? hashlimit_procdir4 : 371 hinfo->family == NFPROTO_IPV4 ? hashlimit_procdir4 :
375 hashlimit_procdir6); 372 hashlimit_procdir6);
376 htable_selective_cleanup(hinfo, select_all); 373 htable_selective_cleanup(hinfo, select_all);
377 vfree(hinfo); 374 vfree(hinfo);
378} 375}
379 376
380static struct xt_hashlimit_htable *htable_find_get(const char *name, 377static struct xt_hashlimit_htable *htable_find_get(const char *name,
381 int family) 378 u_int8_t family)
382{ 379{
383 struct xt_hashlimit_htable *hinfo; 380 struct xt_hashlimit_htable *hinfo;
384 struct hlist_node *pos; 381 struct hlist_node *pos;
@@ -502,7 +499,7 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
502 memset(dst, 0, sizeof(*dst)); 499 memset(dst, 0, sizeof(*dst));
503 500
504 switch (hinfo->family) { 501 switch (hinfo->family) {
505 case AF_INET: 502 case NFPROTO_IPV4:
506 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP) 503 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP)
507 dst->ip.dst = maskl(ip_hdr(skb)->daddr, 504 dst->ip.dst = maskl(ip_hdr(skb)->daddr,
508 hinfo->cfg.dstmask); 505 hinfo->cfg.dstmask);
@@ -516,7 +513,7 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
516 nexthdr = ip_hdr(skb)->protocol; 513 nexthdr = ip_hdr(skb)->protocol;
517 break; 514 break;
518#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 515#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
519 case AF_INET6: 516 case NFPROTO_IPV6:
520 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP) { 517 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP) {
521 memcpy(&dst->ip6.dst, &ipv6_hdr(skb)->daddr, 518 memcpy(&dst->ip6.dst, &ipv6_hdr(skb)->daddr,
522 sizeof(dst->ip6.dst)); 519 sizeof(dst->ip6.dst));
@@ -566,19 +563,16 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
566} 563}
567 564
568static bool 565static bool
569hashlimit_mt_v0(const struct sk_buff *skb, const struct net_device *in, 566hashlimit_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
570 const struct net_device *out, const struct xt_match *match,
571 const void *matchinfo, int offset, unsigned int protoff,
572 bool *hotdrop)
573{ 567{
574 const struct xt_hashlimit_info *r = 568 const struct xt_hashlimit_info *r =
575 ((const struct xt_hashlimit_info *)matchinfo)->u.master; 569 ((const struct xt_hashlimit_info *)par->matchinfo)->u.master;
576 struct xt_hashlimit_htable *hinfo = r->hinfo; 570 struct xt_hashlimit_htable *hinfo = r->hinfo;
577 unsigned long now = jiffies; 571 unsigned long now = jiffies;
578 struct dsthash_ent *dh; 572 struct dsthash_ent *dh;
579 struct dsthash_dst dst; 573 struct dsthash_dst dst;
580 574
581 if (hashlimit_init_dst(hinfo, &dst, skb, protoff) < 0) 575 if (hashlimit_init_dst(hinfo, &dst, skb, par->thoff) < 0)
582 goto hotdrop; 576 goto hotdrop;
583 577
584 spin_lock_bh(&hinfo->lock); 578 spin_lock_bh(&hinfo->lock);
@@ -616,23 +610,20 @@ hashlimit_mt_v0(const struct sk_buff *skb, const struct net_device *in,
616 return false; 610 return false;
617 611
618hotdrop: 612hotdrop:
619 *hotdrop = true; 613 *par->hotdrop = true;
620 return false; 614 return false;
621} 615}
622 616
623static bool 617static bool
624hashlimit_mt(const struct sk_buff *skb, const struct net_device *in, 618hashlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
625 const struct net_device *out, const struct xt_match *match,
626 const void *matchinfo, int offset, unsigned int protoff,
627 bool *hotdrop)
628{ 619{
629 const struct xt_hashlimit_mtinfo1 *info = matchinfo; 620 const struct xt_hashlimit_mtinfo1 *info = par->matchinfo;
630 struct xt_hashlimit_htable *hinfo = info->hinfo; 621 struct xt_hashlimit_htable *hinfo = info->hinfo;
631 unsigned long now = jiffies; 622 unsigned long now = jiffies;
632 struct dsthash_ent *dh; 623 struct dsthash_ent *dh;
633 struct dsthash_dst dst; 624 struct dsthash_dst dst;
634 625
635 if (hashlimit_init_dst(hinfo, &dst, skb, protoff) < 0) 626 if (hashlimit_init_dst(hinfo, &dst, skb, par->thoff) < 0)
636 goto hotdrop; 627 goto hotdrop;
637 628
638 spin_lock_bh(&hinfo->lock); 629 spin_lock_bh(&hinfo->lock);
@@ -669,16 +660,13 @@ hashlimit_mt(const struct sk_buff *skb, const struct net_device *in,
669 return info->cfg.mode & XT_HASHLIMIT_INVERT; 660 return info->cfg.mode & XT_HASHLIMIT_INVERT;
670 661
671 hotdrop: 662 hotdrop:
672 *hotdrop = true; 663 *par->hotdrop = true;
673 return false; 664 return false;
674} 665}
675 666
676static bool 667static bool hashlimit_mt_check_v0(const struct xt_mtchk_param *par)
677hashlimit_mt_check_v0(const char *tablename, const void *inf,
678 const struct xt_match *match, void *matchinfo,
679 unsigned int hook_mask)
680{ 668{
681 struct xt_hashlimit_info *r = matchinfo; 669 struct xt_hashlimit_info *r = par->matchinfo;
682 670
683 /* Check for overflow. */ 671 /* Check for overflow. */
684 if (r->cfg.burst == 0 || 672 if (r->cfg.burst == 0 ||
@@ -707,8 +695,8 @@ hashlimit_mt_check_v0(const char *tablename, const void *inf,
707 * the list of htable's in htable_create(), since then we would 695 * the list of htable's in htable_create(), since then we would
708 * create duplicate proc files. -HW */ 696 * create duplicate proc files. -HW */
709 mutex_lock(&hlimit_mutex); 697 mutex_lock(&hlimit_mutex);
710 r->hinfo = htable_find_get(r->name, match->family); 698 r->hinfo = htable_find_get(r->name, par->match->family);
711 if (!r->hinfo && htable_create_v0(r, match->family) != 0) { 699 if (!r->hinfo && htable_create_v0(r, par->match->family) != 0) {
712 mutex_unlock(&hlimit_mutex); 700 mutex_unlock(&hlimit_mutex);
713 return false; 701 return false;
714 } 702 }
@@ -719,12 +707,9 @@ hashlimit_mt_check_v0(const char *tablename, const void *inf,
719 return true; 707 return true;
720} 708}
721 709
722static bool 710static bool hashlimit_mt_check(const struct xt_mtchk_param *par)
723hashlimit_mt_check(const char *tablename, const void *inf,
724 const struct xt_match *match, void *matchinfo,
725 unsigned int hook_mask)
726{ 711{
727 struct xt_hashlimit_mtinfo1 *info = matchinfo; 712 struct xt_hashlimit_mtinfo1 *info = par->matchinfo;
728 713
729 /* Check for overflow. */ 714 /* Check for overflow. */
730 if (info->cfg.burst == 0 || 715 if (info->cfg.burst == 0 ||
@@ -738,7 +723,7 @@ hashlimit_mt_check(const char *tablename, const void *inf,
738 return false; 723 return false;
739 if (info->name[sizeof(info->name)-1] != '\0') 724 if (info->name[sizeof(info->name)-1] != '\0')
740 return false; 725 return false;
741 if (match->family == AF_INET) { 726 if (par->match->family == NFPROTO_IPV4) {
742 if (info->cfg.srcmask > 32 || info->cfg.dstmask > 32) 727 if (info->cfg.srcmask > 32 || info->cfg.dstmask > 32)
743 return false; 728 return false;
744 } else { 729 } else {
@@ -753,8 +738,8 @@ hashlimit_mt_check(const char *tablename, const void *inf,
753 * the list of htable's in htable_create(), since then we would 738 * the list of htable's in htable_create(), since then we would
754 * create duplicate proc files. -HW */ 739 * create duplicate proc files. -HW */
755 mutex_lock(&hlimit_mutex); 740 mutex_lock(&hlimit_mutex);
756 info->hinfo = htable_find_get(info->name, match->family); 741 info->hinfo = htable_find_get(info->name, par->match->family);
757 if (!info->hinfo && htable_create(info, match->family) != 0) { 742 if (!info->hinfo && htable_create(info, par->match->family) != 0) {
758 mutex_unlock(&hlimit_mutex); 743 mutex_unlock(&hlimit_mutex);
759 return false; 744 return false;
760 } 745 }
@@ -763,17 +748,16 @@ hashlimit_mt_check(const char *tablename, const void *inf,
763} 748}
764 749
765static void 750static void
766hashlimit_mt_destroy_v0(const struct xt_match *match, void *matchinfo) 751hashlimit_mt_destroy_v0(const struct xt_mtdtor_param *par)
767{ 752{
768 const struct xt_hashlimit_info *r = matchinfo; 753 const struct xt_hashlimit_info *r = par->matchinfo;
769 754
770 htable_put(r->hinfo); 755 htable_put(r->hinfo);
771} 756}
772 757
773static void 758static void hashlimit_mt_destroy(const struct xt_mtdtor_param *par)
774hashlimit_mt_destroy(const struct xt_match *match, void *matchinfo)
775{ 759{
776 const struct xt_hashlimit_mtinfo1 *info = matchinfo; 760 const struct xt_hashlimit_mtinfo1 *info = par->matchinfo;
777 761
778 htable_put(info->hinfo); 762 htable_put(info->hinfo);
779} 763}
@@ -806,7 +790,7 @@ static struct xt_match hashlimit_mt_reg[] __read_mostly = {
806 { 790 {
807 .name = "hashlimit", 791 .name = "hashlimit",
808 .revision = 0, 792 .revision = 0,
809 .family = AF_INET, 793 .family = NFPROTO_IPV4,
810 .match = hashlimit_mt_v0, 794 .match = hashlimit_mt_v0,
811 .matchsize = sizeof(struct xt_hashlimit_info), 795 .matchsize = sizeof(struct xt_hashlimit_info),
812#ifdef CONFIG_COMPAT 796#ifdef CONFIG_COMPAT
@@ -821,7 +805,7 @@ static struct xt_match hashlimit_mt_reg[] __read_mostly = {
821 { 805 {
822 .name = "hashlimit", 806 .name = "hashlimit",
823 .revision = 1, 807 .revision = 1,
824 .family = AF_INET, 808 .family = NFPROTO_IPV4,
825 .match = hashlimit_mt, 809 .match = hashlimit_mt,
826 .matchsize = sizeof(struct xt_hashlimit_mtinfo1), 810 .matchsize = sizeof(struct xt_hashlimit_mtinfo1),
827 .checkentry = hashlimit_mt_check, 811 .checkentry = hashlimit_mt_check,
@@ -831,7 +815,7 @@ static struct xt_match hashlimit_mt_reg[] __read_mostly = {
831#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 815#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
832 { 816 {
833 .name = "hashlimit", 817 .name = "hashlimit",
834 .family = AF_INET6, 818 .family = NFPROTO_IPV6,
835 .match = hashlimit_mt_v0, 819 .match = hashlimit_mt_v0,
836 .matchsize = sizeof(struct xt_hashlimit_info), 820 .matchsize = sizeof(struct xt_hashlimit_info),
837#ifdef CONFIG_COMPAT 821#ifdef CONFIG_COMPAT
@@ -846,7 +830,7 @@ static struct xt_match hashlimit_mt_reg[] __read_mostly = {
846 { 830 {
847 .name = "hashlimit", 831 .name = "hashlimit",
848 .revision = 1, 832 .revision = 1,
849 .family = AF_INET6, 833 .family = NFPROTO_IPV6,
850 .match = hashlimit_mt, 834 .match = hashlimit_mt,
851 .matchsize = sizeof(struct xt_hashlimit_mtinfo1), 835 .matchsize = sizeof(struct xt_hashlimit_mtinfo1),
852 .checkentry = hashlimit_mt_check, 836 .checkentry = hashlimit_mt_check,
@@ -901,14 +885,14 @@ static void dl_seq_stop(struct seq_file *s, void *v)
901 spin_unlock_bh(&htable->lock); 885 spin_unlock_bh(&htable->lock);
902} 886}
903 887
904static int dl_seq_real_show(struct dsthash_ent *ent, int family, 888static int dl_seq_real_show(struct dsthash_ent *ent, u_int8_t family,
905 struct seq_file *s) 889 struct seq_file *s)
906{ 890{
907 /* recalculate to show accurate numbers */ 891 /* recalculate to show accurate numbers */
908 rateinfo_recalc(ent, jiffies); 892 rateinfo_recalc(ent, jiffies);
909 893
910 switch (family) { 894 switch (family) {
911 case AF_INET: 895 case NFPROTO_IPV4:
912 return seq_printf(s, "%ld %u.%u.%u.%u:%u->" 896 return seq_printf(s, "%ld %u.%u.%u.%u:%u->"
913 "%u.%u.%u.%u:%u %u %u %u\n", 897 "%u.%u.%u.%u:%u %u %u %u\n",
914 (long)(ent->expires - jiffies)/HZ, 898 (long)(ent->expires - jiffies)/HZ,
@@ -919,7 +903,7 @@ static int dl_seq_real_show(struct dsthash_ent *ent, int family,
919 ent->rateinfo.credit, ent->rateinfo.credit_cap, 903 ent->rateinfo.credit, ent->rateinfo.credit_cap,
920 ent->rateinfo.cost); 904 ent->rateinfo.cost);
921#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 905#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
922 case AF_INET6: 906 case NFPROTO_IPV6:
923 return seq_printf(s, "%ld " NIP6_FMT ":%u->" 907 return seq_printf(s, "%ld " NIP6_FMT ":%u->"
924 NIP6_FMT ":%u %u %u %u\n", 908 NIP6_FMT ":%u %u %u %u\n",
925 (long)(ent->expires - jiffies)/HZ, 909 (long)(ent->expires - jiffies)/HZ,
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c
index dada2905d66e..64fc7f277221 100644
--- a/net/netfilter/xt_helper.c
+++ b/net/netfilter/xt_helper.c
@@ -24,12 +24,9 @@ MODULE_ALIAS("ip6t_helper");
24 24
25 25
26static bool 26static bool
27helper_mt(const struct sk_buff *skb, const struct net_device *in, 27helper_mt(const struct sk_buff *skb, const struct xt_match_param *par)
28 const struct net_device *out, const struct xt_match *match,
29 const void *matchinfo, int offset, unsigned int protoff,
30 bool *hotdrop)
31{ 28{
32 const struct xt_helper_info *info = matchinfo; 29 const struct xt_helper_info *info = par->matchinfo;
33 const struct nf_conn *ct; 30 const struct nf_conn *ct;
34 const struct nf_conn_help *master_help; 31 const struct nf_conn_help *master_help;
35 const struct nf_conntrack_helper *helper; 32 const struct nf_conntrack_helper *helper;
@@ -57,56 +54,43 @@ helper_mt(const struct sk_buff *skb, const struct net_device *in,
57 return ret; 54 return ret;
58} 55}
59 56
60static bool 57static bool helper_mt_check(const struct xt_mtchk_param *par)
61helper_mt_check(const char *tablename, const void *inf,
62 const struct xt_match *match, void *matchinfo,
63 unsigned int hook_mask)
64{ 58{
65 struct xt_helper_info *info = matchinfo; 59 struct xt_helper_info *info = par->matchinfo;
66 60
67 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 61 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
68 printk(KERN_WARNING "can't load conntrack support for " 62 printk(KERN_WARNING "can't load conntrack support for "
69 "proto=%u\n", match->family); 63 "proto=%u\n", par->family);
70 return false; 64 return false;
71 } 65 }
72 info->name[29] = '\0'; 66 info->name[29] = '\0';
73 return true; 67 return true;
74} 68}
75 69
76static void helper_mt_destroy(const struct xt_match *match, void *matchinfo) 70static void helper_mt_destroy(const struct xt_mtdtor_param *par)
77{ 71{
78 nf_ct_l3proto_module_put(match->family); 72 nf_ct_l3proto_module_put(par->family);
79} 73}
80 74
81static struct xt_match helper_mt_reg[] __read_mostly = { 75static struct xt_match helper_mt_reg __read_mostly = {
82 { 76 .name = "helper",
83 .name = "helper", 77 .revision = 0,
84 .family = AF_INET, 78 .family = NFPROTO_UNSPEC,
85 .checkentry = helper_mt_check, 79 .checkentry = helper_mt_check,
86 .match = helper_mt, 80 .match = helper_mt,
87 .destroy = helper_mt_destroy, 81 .destroy = helper_mt_destroy,
88 .matchsize = sizeof(struct xt_helper_info), 82 .matchsize = sizeof(struct xt_helper_info),
89 .me = THIS_MODULE, 83 .me = THIS_MODULE,
90 },
91 {
92 .name = "helper",
93 .family = AF_INET6,
94 .checkentry = helper_mt_check,
95 .match = helper_mt,
96 .destroy = helper_mt_destroy,
97 .matchsize = sizeof(struct xt_helper_info),
98 .me = THIS_MODULE,
99 },
100}; 84};
101 85
102static int __init helper_mt_init(void) 86static int __init helper_mt_init(void)
103{ 87{
104 return xt_register_matches(helper_mt_reg, ARRAY_SIZE(helper_mt_reg)); 88 return xt_register_match(&helper_mt_reg);
105} 89}
106 90
107static void __exit helper_mt_exit(void) 91static void __exit helper_mt_exit(void)
108{ 92{
109 xt_unregister_matches(helper_mt_reg, ARRAY_SIZE(helper_mt_reg)); 93 xt_unregister_match(&helper_mt_reg);
110} 94}
111 95
112module_init(helper_mt_init); 96module_init(helper_mt_init);
diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c
index c63e9333c755..6f62c36948d9 100644
--- a/net/netfilter/xt_iprange.c
+++ b/net/netfilter/xt_iprange.c
@@ -17,12 +17,9 @@
17#include <linux/netfilter_ipv4/ipt_iprange.h> 17#include <linux/netfilter_ipv4/ipt_iprange.h>
18 18
19static bool 19static bool
20iprange_mt_v0(const struct sk_buff *skb, const struct net_device *in, 20iprange_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
21 const struct net_device *out, const struct xt_match *match,
22 const void *matchinfo, int offset, unsigned int protoff,
23 bool *hotdrop)
24{ 21{
25 const struct ipt_iprange_info *info = matchinfo; 22 const struct ipt_iprange_info *info = par->matchinfo;
26 const struct iphdr *iph = ip_hdr(skb); 23 const struct iphdr *iph = ip_hdr(skb);
27 24
28 if (info->flags & IPRANGE_SRC) { 25 if (info->flags & IPRANGE_SRC) {
@@ -55,12 +52,9 @@ iprange_mt_v0(const struct sk_buff *skb, const struct net_device *in,
55} 52}
56 53
57static bool 54static bool
58iprange_mt4(const struct sk_buff *skb, const struct net_device *in, 55iprange_mt4(const struct sk_buff *skb, const struct xt_match_param *par)
59 const struct net_device *out, const struct xt_match *match,
60 const void *matchinfo, int offset, unsigned int protoff,
61 bool *hotdrop)
62{ 56{
63 const struct xt_iprange_mtinfo *info = matchinfo; 57 const struct xt_iprange_mtinfo *info = par->matchinfo;
64 const struct iphdr *iph = ip_hdr(skb); 58 const struct iphdr *iph = ip_hdr(skb);
65 bool m; 59 bool m;
66 60
@@ -111,12 +105,9 @@ iprange_ipv6_sub(const struct in6_addr *a, const struct in6_addr *b)
111} 105}
112 106
113static bool 107static bool
114iprange_mt6(const struct sk_buff *skb, const struct net_device *in, 108iprange_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
115 const struct net_device *out, const struct xt_match *match,
116 const void *matchinfo, int offset, unsigned int protoff,
117 bool *hotdrop)
118{ 109{
119 const struct xt_iprange_mtinfo *info = matchinfo; 110 const struct xt_iprange_mtinfo *info = par->matchinfo;
120 const struct ipv6hdr *iph = ipv6_hdr(skb); 111 const struct ipv6hdr *iph = ipv6_hdr(skb);
121 bool m; 112 bool m;
122 113
@@ -141,7 +132,7 @@ static struct xt_match iprange_mt_reg[] __read_mostly = {
141 { 132 {
142 .name = "iprange", 133 .name = "iprange",
143 .revision = 0, 134 .revision = 0,
144 .family = AF_INET, 135 .family = NFPROTO_IPV4,
145 .match = iprange_mt_v0, 136 .match = iprange_mt_v0,
146 .matchsize = sizeof(struct ipt_iprange_info), 137 .matchsize = sizeof(struct ipt_iprange_info),
147 .me = THIS_MODULE, 138 .me = THIS_MODULE,
@@ -149,7 +140,7 @@ static struct xt_match iprange_mt_reg[] __read_mostly = {
149 { 140 {
150 .name = "iprange", 141 .name = "iprange",
151 .revision = 1, 142 .revision = 1,
152 .family = AF_INET, 143 .family = NFPROTO_IPV4,
153 .match = iprange_mt4, 144 .match = iprange_mt4,
154 .matchsize = sizeof(struct xt_iprange_mtinfo), 145 .matchsize = sizeof(struct xt_iprange_mtinfo),
155 .me = THIS_MODULE, 146 .me = THIS_MODULE,
@@ -157,7 +148,7 @@ static struct xt_match iprange_mt_reg[] __read_mostly = {
157 { 148 {
158 .name = "iprange", 149 .name = "iprange",
159 .revision = 1, 150 .revision = 1,
160 .family = AF_INET6, 151 .family = NFPROTO_IPV6,
161 .match = iprange_mt6, 152 .match = iprange_mt6,
162 .matchsize = sizeof(struct xt_iprange_mtinfo), 153 .matchsize = sizeof(struct xt_iprange_mtinfo),
163 .me = THIS_MODULE, 154 .me = THIS_MODULE,
diff --git a/net/netfilter/xt_length.c b/net/netfilter/xt_length.c
index b8640f972950..c4871ca6c86d 100644
--- a/net/netfilter/xt_length.c
+++ b/net/netfilter/xt_length.c
@@ -21,24 +21,18 @@ MODULE_ALIAS("ipt_length");
21MODULE_ALIAS("ip6t_length"); 21MODULE_ALIAS("ip6t_length");
22 22
23static bool 23static bool
24length_mt(const struct sk_buff *skb, const struct net_device *in, 24length_mt(const struct sk_buff *skb, const struct xt_match_param *par)
25 const struct net_device *out, const struct xt_match *match,
26 const void *matchinfo, int offset, unsigned int protoff,
27 bool *hotdrop)
28{ 25{
29 const struct xt_length_info *info = matchinfo; 26 const struct xt_length_info *info = par->matchinfo;
30 u_int16_t pktlen = ntohs(ip_hdr(skb)->tot_len); 27 u_int16_t pktlen = ntohs(ip_hdr(skb)->tot_len);
31 28
32 return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; 29 return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
33} 30}
34 31
35static bool 32static bool
36length_mt6(const struct sk_buff *skb, const struct net_device *in, 33length_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
37 const struct net_device *out, const struct xt_match *match,
38 const void *matchinfo, int offset, unsigned int protoff,
39 bool *hotdrop)
40{ 34{
41 const struct xt_length_info *info = matchinfo; 35 const struct xt_length_info *info = par->matchinfo;
42 const u_int16_t pktlen = ntohs(ipv6_hdr(skb)->payload_len) + 36 const u_int16_t pktlen = ntohs(ipv6_hdr(skb)->payload_len) +
43 sizeof(struct ipv6hdr); 37 sizeof(struct ipv6hdr);
44 38
@@ -48,14 +42,14 @@ length_mt6(const struct sk_buff *skb, const struct net_device *in,
48static struct xt_match length_mt_reg[] __read_mostly = { 42static struct xt_match length_mt_reg[] __read_mostly = {
49 { 43 {
50 .name = "length", 44 .name = "length",
51 .family = AF_INET, 45 .family = NFPROTO_IPV4,
52 .match = length_mt, 46 .match = length_mt,
53 .matchsize = sizeof(struct xt_length_info), 47 .matchsize = sizeof(struct xt_length_info),
54 .me = THIS_MODULE, 48 .me = THIS_MODULE,
55 }, 49 },
56 { 50 {
57 .name = "length", 51 .name = "length",
58 .family = AF_INET6, 52 .family = NFPROTO_IPV6,
59 .match = length_mt6, 53 .match = length_mt6,
60 .matchsize = sizeof(struct xt_length_info), 54 .matchsize = sizeof(struct xt_length_info),
61 .me = THIS_MODULE, 55 .me = THIS_MODULE,
diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c
index aad9ab8d2046..c908d69a5595 100644
--- a/net/netfilter/xt_limit.c
+++ b/net/netfilter/xt_limit.c
@@ -58,13 +58,10 @@ static DEFINE_SPINLOCK(limit_lock);
58#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ) 58#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
59 59
60static bool 60static bool
61limit_mt(const struct sk_buff *skb, const struct net_device *in, 61limit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
62 const struct net_device *out, const struct xt_match *match,
63 const void *matchinfo, int offset, unsigned int protoff,
64 bool *hotdrop)
65{ 62{
66 struct xt_rateinfo *r = 63 struct xt_rateinfo *r =
67 ((const struct xt_rateinfo *)matchinfo)->master; 64 ((const struct xt_rateinfo *)par->matchinfo)->master;
68 unsigned long now = jiffies; 65 unsigned long now = jiffies;
69 66
70 spin_lock_bh(&limit_lock); 67 spin_lock_bh(&limit_lock);
@@ -95,12 +92,9 @@ user2credits(u_int32_t user)
95 return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE; 92 return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE;
96} 93}
97 94
98static bool 95static bool limit_mt_check(const struct xt_mtchk_param *par)
99limit_mt_check(const char *tablename, const void *inf,
100 const struct xt_match *match, void *matchinfo,
101 unsigned int hook_mask)
102{ 96{
103 struct xt_rateinfo *r = matchinfo; 97 struct xt_rateinfo *r = par->matchinfo;
104 98
105 /* Check for overflow. */ 99 /* Check for overflow. */
106 if (r->burst == 0 100 if (r->burst == 0
@@ -167,43 +161,29 @@ static int limit_mt_compat_to_user(void __user *dst, void *src)
167} 161}
168#endif /* CONFIG_COMPAT */ 162#endif /* CONFIG_COMPAT */
169 163
170static struct xt_match limit_mt_reg[] __read_mostly = { 164static struct xt_match limit_mt_reg __read_mostly = {
171 { 165 .name = "limit",
172 .name = "limit", 166 .revision = 0,
173 .family = AF_INET, 167 .family = NFPROTO_UNSPEC,
174 .checkentry = limit_mt_check, 168 .match = limit_mt,
175 .match = limit_mt, 169 .checkentry = limit_mt_check,
176 .matchsize = sizeof(struct xt_rateinfo), 170 .matchsize = sizeof(struct xt_rateinfo),
177#ifdef CONFIG_COMPAT
178 .compatsize = sizeof(struct compat_xt_rateinfo),
179 .compat_from_user = limit_mt_compat_from_user,
180 .compat_to_user = limit_mt_compat_to_user,
181#endif
182 .me = THIS_MODULE,
183 },
184 {
185 .name = "limit",
186 .family = AF_INET6,
187 .checkentry = limit_mt_check,
188 .match = limit_mt,
189 .matchsize = sizeof(struct xt_rateinfo),
190#ifdef CONFIG_COMPAT 171#ifdef CONFIG_COMPAT
191 .compatsize = sizeof(struct compat_xt_rateinfo), 172 .compatsize = sizeof(struct compat_xt_rateinfo),
192 .compat_from_user = limit_mt_compat_from_user, 173 .compat_from_user = limit_mt_compat_from_user,
193 .compat_to_user = limit_mt_compat_to_user, 174 .compat_to_user = limit_mt_compat_to_user,
194#endif 175#endif
195 .me = THIS_MODULE, 176 .me = THIS_MODULE,
196 },
197}; 177};
198 178
199static int __init limit_mt_init(void) 179static int __init limit_mt_init(void)
200{ 180{
201 return xt_register_matches(limit_mt_reg, ARRAY_SIZE(limit_mt_reg)); 181 return xt_register_match(&limit_mt_reg);
202} 182}
203 183
204static void __exit limit_mt_exit(void) 184static void __exit limit_mt_exit(void)
205{ 185{
206 xt_unregister_matches(limit_mt_reg, ARRAY_SIZE(limit_mt_reg)); 186 xt_unregister_match(&limit_mt_reg);
207} 187}
208 188
209module_init(limit_mt_init); 189module_init(limit_mt_init);
diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c
index b3e96a0ec176..c2007116ce5b 100644
--- a/net/netfilter/xt_mac.c
+++ b/net/netfilter/xt_mac.c
@@ -24,12 +24,9 @@ MODULE_DESCRIPTION("Xtables: MAC address match");
24MODULE_ALIAS("ipt_mac"); 24MODULE_ALIAS("ipt_mac");
25MODULE_ALIAS("ip6t_mac"); 25MODULE_ALIAS("ip6t_mac");
26 26
27static bool 27static bool mac_mt(const struct sk_buff *skb, const struct xt_match_param *par)
28mac_mt(const struct sk_buff *skb, const struct net_device *in,
29 const struct net_device *out, const struct xt_match *match,
30 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
31{ 28{
32 const struct xt_mac_info *info = matchinfo; 29 const struct xt_mac_info *info = par->matchinfo;
33 30
34 /* Is mac pointer valid? */ 31 /* Is mac pointer valid? */
35 return skb_mac_header(skb) >= skb->head && 32 return skb_mac_header(skb) >= skb->head &&
@@ -39,37 +36,25 @@ mac_mt(const struct sk_buff *skb, const struct net_device *in,
39 ^ info->invert); 36 ^ info->invert);
40} 37}
41 38
42static struct xt_match mac_mt_reg[] __read_mostly = { 39static struct xt_match mac_mt_reg __read_mostly = {
43 { 40 .name = "mac",
44 .name = "mac", 41 .revision = 0,
45 .family = AF_INET, 42 .family = NFPROTO_UNSPEC,
46 .match = mac_mt, 43 .match = mac_mt,
47 .matchsize = sizeof(struct xt_mac_info), 44 .matchsize = sizeof(struct xt_mac_info),
48 .hooks = (1 << NF_INET_PRE_ROUTING) | 45 .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) |
49 (1 << NF_INET_LOCAL_IN) | 46 (1 << NF_INET_FORWARD),
50 (1 << NF_INET_FORWARD), 47 .me = THIS_MODULE,
51 .me = THIS_MODULE,
52 },
53 {
54 .name = "mac",
55 .family = AF_INET6,
56 .match = mac_mt,
57 .matchsize = sizeof(struct xt_mac_info),
58 .hooks = (1 << NF_INET_PRE_ROUTING) |
59 (1 << NF_INET_LOCAL_IN) |
60 (1 << NF_INET_FORWARD),
61 .me = THIS_MODULE,
62 },
63}; 48};
64 49
65static int __init mac_mt_init(void) 50static int __init mac_mt_init(void)
66{ 51{
67 return xt_register_matches(mac_mt_reg, ARRAY_SIZE(mac_mt_reg)); 52 return xt_register_match(&mac_mt_reg);
68} 53}
69 54
70static void __exit mac_mt_exit(void) 55static void __exit mac_mt_exit(void)
71{ 56{
72 xt_unregister_matches(mac_mt_reg, ARRAY_SIZE(mac_mt_reg)); 57 xt_unregister_match(&mac_mt_reg);
73} 58}
74 59
75module_init(mac_mt_init); 60module_init(mac_mt_init);
diff --git a/net/netfilter/xt_mark.c b/net/netfilter/xt_mark.c
index 9f78f6120fbd..10b9e34bbc5b 100644
--- a/net/netfilter/xt_mark.c
+++ b/net/netfilter/xt_mark.c
@@ -23,32 +23,24 @@ MODULE_ALIAS("ipt_mark");
23MODULE_ALIAS("ip6t_mark"); 23MODULE_ALIAS("ip6t_mark");
24 24
25static bool 25static bool
26mark_mt_v0(const struct sk_buff *skb, const struct net_device *in, 26mark_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
27 const struct net_device *out, const struct xt_match *match,
28 const void *matchinfo, int offset, unsigned int protoff,
29 bool *hotdrop)
30{ 27{
31 const struct xt_mark_info *info = matchinfo; 28 const struct xt_mark_info *info = par->matchinfo;
32 29
33 return ((skb->mark & info->mask) == info->mark) ^ info->invert; 30 return ((skb->mark & info->mask) == info->mark) ^ info->invert;
34} 31}
35 32
36static bool 33static bool
37mark_mt(const struct sk_buff *skb, const struct net_device *in, 34mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
38 const struct net_device *out, const struct xt_match *match,
39 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
40{ 35{
41 const struct xt_mark_mtinfo1 *info = matchinfo; 36 const struct xt_mark_mtinfo1 *info = par->matchinfo;
42 37
43 return ((skb->mark & info->mask) == info->mark) ^ info->invert; 38 return ((skb->mark & info->mask) == info->mark) ^ info->invert;
44} 39}
45 40
46static bool 41static bool mark_mt_check_v0(const struct xt_mtchk_param *par)
47mark_mt_check_v0(const char *tablename, const void *entry,
48 const struct xt_match *match, void *matchinfo,
49 unsigned int hook_mask)
50{ 42{
51 const struct xt_mark_info *minfo = matchinfo; 43 const struct xt_mark_info *minfo = par->matchinfo;
52 44
53 if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) { 45 if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) {
54 printk(KERN_WARNING "mark: only supports 32bit mark\n"); 46 printk(KERN_WARNING "mark: only supports 32bit mark\n");
@@ -92,7 +84,7 @@ static struct xt_match mark_mt_reg[] __read_mostly = {
92 { 84 {
93 .name = "mark", 85 .name = "mark",
94 .revision = 0, 86 .revision = 0,
95 .family = AF_INET, 87 .family = NFPROTO_UNSPEC,
96 .checkentry = mark_mt_check_v0, 88 .checkentry = mark_mt_check_v0,
97 .match = mark_mt_v0, 89 .match = mark_mt_v0,
98 .matchsize = sizeof(struct xt_mark_info), 90 .matchsize = sizeof(struct xt_mark_info),
@@ -104,31 +96,9 @@ static struct xt_match mark_mt_reg[] __read_mostly = {
104 .me = THIS_MODULE, 96 .me = THIS_MODULE,
105 }, 97 },
106 { 98 {
107 .name = "mark",
108 .revision = 0,
109 .family = AF_INET6,
110 .checkentry = mark_mt_check_v0,
111 .match = mark_mt_v0,
112 .matchsize = sizeof(struct xt_mark_info),
113#ifdef CONFIG_COMPAT
114 .compatsize = sizeof(struct compat_xt_mark_info),
115 .compat_from_user = mark_mt_compat_from_user_v0,
116 .compat_to_user = mark_mt_compat_to_user_v0,
117#endif
118 .me = THIS_MODULE,
119 },
120 {
121 .name = "mark",
122 .revision = 1,
123 .family = AF_INET,
124 .match = mark_mt,
125 .matchsize = sizeof(struct xt_mark_mtinfo1),
126 .me = THIS_MODULE,
127 },
128 {
129 .name = "mark", 99 .name = "mark",
130 .revision = 1, 100 .revision = 1,
131 .family = AF_INET6, 101 .family = NFPROTO_UNSPEC,
132 .match = mark_mt, 102 .match = mark_mt,
133 .matchsize = sizeof(struct xt_mark_mtinfo1), 103 .matchsize = sizeof(struct xt_mark_mtinfo1),
134 .me = THIS_MODULE, 104 .me = THIS_MODULE,
diff --git a/net/netfilter/xt_multiport.c b/net/netfilter/xt_multiport.c
index fd88c489b70e..d06bb2dd3900 100644
--- a/net/netfilter/xt_multiport.c
+++ b/net/netfilter/xt_multiport.c
@@ -95,25 +95,22 @@ ports_match_v1(const struct xt_multiport_v1 *minfo,
95} 95}
96 96
97static bool 97static bool
98multiport_mt_v0(const struct sk_buff *skb, const struct net_device *in, 98multiport_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
99 const struct net_device *out, const struct xt_match *match,
100 const void *matchinfo, int offset, unsigned int protoff,
101 bool *hotdrop)
102{ 99{
103 const __be16 *pptr; 100 const __be16 *pptr;
104 __be16 _ports[2]; 101 __be16 _ports[2];
105 const struct xt_multiport *multiinfo = matchinfo; 102 const struct xt_multiport *multiinfo = par->matchinfo;
106 103
107 if (offset) 104 if (par->fragoff != 0)
108 return false; 105 return false;
109 106
110 pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports); 107 pptr = skb_header_pointer(skb, par->thoff, sizeof(_ports), _ports);
111 if (pptr == NULL) { 108 if (pptr == NULL) {
112 /* We've been asked to examine this packet, and we 109 /* We've been asked to examine this packet, and we
113 * can't. Hence, no choice but to drop. 110 * can't. Hence, no choice but to drop.
114 */ 111 */
115 duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n"); 112 duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
116 *hotdrop = true; 113 *par->hotdrop = true;
117 return false; 114 return false;
118 } 115 }
119 116
@@ -122,25 +119,22 @@ multiport_mt_v0(const struct sk_buff *skb, const struct net_device *in,
122} 119}
123 120
124static bool 121static bool
125multiport_mt(const struct sk_buff *skb, const struct net_device *in, 122multiport_mt(const struct sk_buff *skb, const struct xt_match_param *par)
126 const struct net_device *out, const struct xt_match *match,
127 const void *matchinfo, int offset, unsigned int protoff,
128 bool *hotdrop)
129{ 123{
130 const __be16 *pptr; 124 const __be16 *pptr;
131 __be16 _ports[2]; 125 __be16 _ports[2];
132 const struct xt_multiport_v1 *multiinfo = matchinfo; 126 const struct xt_multiport_v1 *multiinfo = par->matchinfo;
133 127
134 if (offset) 128 if (par->fragoff != 0)
135 return false; 129 return false;
136 130
137 pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports); 131 pptr = skb_header_pointer(skb, par->thoff, sizeof(_ports), _ports);
138 if (pptr == NULL) { 132 if (pptr == NULL) {
139 /* We've been asked to examine this packet, and we 133 /* We've been asked to examine this packet, and we
140 * can't. Hence, no choice but to drop. 134 * can't. Hence, no choice but to drop.
141 */ 135 */
142 duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n"); 136 duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
143 *hotdrop = true; 137 *par->hotdrop = true;
144 return false; 138 return false;
145 } 139 }
146 140
@@ -164,50 +158,37 @@ check(u_int16_t proto,
164 && count <= XT_MULTI_PORTS; 158 && count <= XT_MULTI_PORTS;
165} 159}
166 160
167/* Called when user tries to insert an entry of this type. */ 161static bool multiport_mt_check_v0(const struct xt_mtchk_param *par)
168static bool
169multiport_mt_check_v0(const char *tablename, const void *info,
170 const struct xt_match *match, void *matchinfo,
171 unsigned int hook_mask)
172{ 162{
173 const struct ipt_ip *ip = info; 163 const struct ipt_ip *ip = par->entryinfo;
174 const struct xt_multiport *multiinfo = matchinfo; 164 const struct xt_multiport *multiinfo = par->matchinfo;
175 165
176 return check(ip->proto, ip->invflags, multiinfo->flags, 166 return check(ip->proto, ip->invflags, multiinfo->flags,
177 multiinfo->count); 167 multiinfo->count);
178} 168}
179 169
180static bool 170static bool multiport_mt_check(const struct xt_mtchk_param *par)
181multiport_mt_check(const char *tablename, const void *info,
182 const struct xt_match *match, void *matchinfo,
183 unsigned int hook_mask)
184{ 171{
185 const struct ipt_ip *ip = info; 172 const struct ipt_ip *ip = par->entryinfo;
186 const struct xt_multiport_v1 *multiinfo = matchinfo; 173 const struct xt_multiport_v1 *multiinfo = par->matchinfo;
187 174
188 return check(ip->proto, ip->invflags, multiinfo->flags, 175 return check(ip->proto, ip->invflags, multiinfo->flags,
189 multiinfo->count); 176 multiinfo->count);
190} 177}
191 178
192static bool 179static bool multiport_mt6_check_v0(const struct xt_mtchk_param *par)
193multiport_mt6_check_v0(const char *tablename, const void *info,
194 const struct xt_match *match, void *matchinfo,
195 unsigned int hook_mask)
196{ 180{
197 const struct ip6t_ip6 *ip = info; 181 const struct ip6t_ip6 *ip = par->entryinfo;
198 const struct xt_multiport *multiinfo = matchinfo; 182 const struct xt_multiport *multiinfo = par->matchinfo;
199 183
200 return check(ip->proto, ip->invflags, multiinfo->flags, 184 return check(ip->proto, ip->invflags, multiinfo->flags,
201 multiinfo->count); 185 multiinfo->count);
202} 186}
203 187
204static bool 188static bool multiport_mt6_check(const struct xt_mtchk_param *par)
205multiport_mt6_check(const char *tablename, const void *info,
206 const struct xt_match *match, void *matchinfo,
207 unsigned int hook_mask)
208{ 189{
209 const struct ip6t_ip6 *ip = info; 190 const struct ip6t_ip6 *ip = par->entryinfo;
210 const struct xt_multiport_v1 *multiinfo = matchinfo; 191 const struct xt_multiport_v1 *multiinfo = par->matchinfo;
211 192
212 return check(ip->proto, ip->invflags, multiinfo->flags, 193 return check(ip->proto, ip->invflags, multiinfo->flags,
213 multiinfo->count); 194 multiinfo->count);
@@ -216,7 +197,7 @@ multiport_mt6_check(const char *tablename, const void *info,
216static struct xt_match multiport_mt_reg[] __read_mostly = { 197static struct xt_match multiport_mt_reg[] __read_mostly = {
217 { 198 {
218 .name = "multiport", 199 .name = "multiport",
219 .family = AF_INET, 200 .family = NFPROTO_IPV4,
220 .revision = 0, 201 .revision = 0,
221 .checkentry = multiport_mt_check_v0, 202 .checkentry = multiport_mt_check_v0,
222 .match = multiport_mt_v0, 203 .match = multiport_mt_v0,
@@ -225,7 +206,7 @@ static struct xt_match multiport_mt_reg[] __read_mostly = {
225 }, 206 },
226 { 207 {
227 .name = "multiport", 208 .name = "multiport",
228 .family = AF_INET, 209 .family = NFPROTO_IPV4,
229 .revision = 1, 210 .revision = 1,
230 .checkentry = multiport_mt_check, 211 .checkentry = multiport_mt_check,
231 .match = multiport_mt, 212 .match = multiport_mt,
@@ -234,7 +215,7 @@ static struct xt_match multiport_mt_reg[] __read_mostly = {
234 }, 215 },
235 { 216 {
236 .name = "multiport", 217 .name = "multiport",
237 .family = AF_INET6, 218 .family = NFPROTO_IPV6,
238 .revision = 0, 219 .revision = 0,
239 .checkentry = multiport_mt6_check_v0, 220 .checkentry = multiport_mt6_check_v0,
240 .match = multiport_mt_v0, 221 .match = multiport_mt_v0,
@@ -243,7 +224,7 @@ static struct xt_match multiport_mt_reg[] __read_mostly = {
243 }, 224 },
244 { 225 {
245 .name = "multiport", 226 .name = "multiport",
246 .family = AF_INET6, 227 .family = NFPROTO_IPV6,
247 .revision = 1, 228 .revision = 1,
248 .checkentry = multiport_mt6_check, 229 .checkentry = multiport_mt6_check,
249 .match = multiport_mt, 230 .match = multiport_mt,
diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c
index 9059c16144c3..f19ebd9b78f5 100644
--- a/net/netfilter/xt_owner.c
+++ b/net/netfilter/xt_owner.c
@@ -21,12 +21,9 @@
21#include <linux/netfilter_ipv6/ip6t_owner.h> 21#include <linux/netfilter_ipv6/ip6t_owner.h>
22 22
23static bool 23static bool
24owner_mt_v0(const struct sk_buff *skb, const struct net_device *in, 24owner_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
25 const struct net_device *out, const struct xt_match *match,
26 const void *matchinfo, int offset, unsigned int protoff,
27 bool *hotdrop)
28{ 25{
29 const struct ipt_owner_info *info = matchinfo; 26 const struct ipt_owner_info *info = par->matchinfo;
30 const struct file *filp; 27 const struct file *filp;
31 28
32 if (skb->sk == NULL || skb->sk->sk_socket == NULL) 29 if (skb->sk == NULL || skb->sk->sk_socket == NULL)
@@ -50,12 +47,9 @@ owner_mt_v0(const struct sk_buff *skb, const struct net_device *in,
50} 47}
51 48
52static bool 49static bool
53owner_mt6_v0(const struct sk_buff *skb, const struct net_device *in, 50owner_mt6_v0(const struct sk_buff *skb, const struct xt_match_param *par)
54 const struct net_device *out, const struct xt_match *match,
55 const void *matchinfo, int offset, unsigned int protoff,
56 bool *hotdrop)
57{ 51{
58 const struct ip6t_owner_info *info = matchinfo; 52 const struct ip6t_owner_info *info = par->matchinfo;
59 const struct file *filp; 53 const struct file *filp;
60 54
61 if (skb->sk == NULL || skb->sk->sk_socket == NULL) 55 if (skb->sk == NULL || skb->sk->sk_socket == NULL)
@@ -79,12 +73,9 @@ owner_mt6_v0(const struct sk_buff *skb, const struct net_device *in,
79} 73}
80 74
81static bool 75static bool
82owner_mt(const struct sk_buff *skb, const struct net_device *in, 76owner_mt(const struct sk_buff *skb, const struct xt_match_param *par)
83 const struct net_device *out, const struct xt_match *match,
84 const void *matchinfo, int offset, unsigned int protoff,
85 bool *hotdrop)
86{ 77{
87 const struct xt_owner_match_info *info = matchinfo; 78 const struct xt_owner_match_info *info = par->matchinfo;
88 const struct file *filp; 79 const struct file *filp;
89 80
90 if (skb->sk == NULL || skb->sk->sk_socket == NULL) 81 if (skb->sk == NULL || skb->sk->sk_socket == NULL)
@@ -116,12 +107,9 @@ owner_mt(const struct sk_buff *skb, const struct net_device *in,
116 return true; 107 return true;
117} 108}
118 109
119static bool 110static bool owner_mt_check_v0(const struct xt_mtchk_param *par)
120owner_mt_check_v0(const char *tablename, const void *ip,
121 const struct xt_match *match, void *matchinfo,
122 unsigned int hook_mask)
123{ 111{
124 const struct ipt_owner_info *info = matchinfo; 112 const struct ipt_owner_info *info = par->matchinfo;
125 113
126 if (info->match & (IPT_OWNER_PID | IPT_OWNER_SID | IPT_OWNER_COMM)) { 114 if (info->match & (IPT_OWNER_PID | IPT_OWNER_SID | IPT_OWNER_COMM)) {
127 printk(KERN_WARNING KBUILD_MODNAME 115 printk(KERN_WARNING KBUILD_MODNAME
@@ -133,12 +121,9 @@ owner_mt_check_v0(const char *tablename, const void *ip,
133 return true; 121 return true;
134} 122}
135 123
136static bool 124static bool owner_mt6_check_v0(const struct xt_mtchk_param *par)
137owner_mt6_check_v0(const char *tablename, const void *ip,
138 const struct xt_match *match, void *matchinfo,
139 unsigned int hook_mask)
140{ 125{
141 const struct ip6t_owner_info *info = matchinfo; 126 const struct ip6t_owner_info *info = par->matchinfo;
142 127
143 if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) { 128 if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) {
144 printk(KERN_WARNING KBUILD_MODNAME 129 printk(KERN_WARNING KBUILD_MODNAME
@@ -153,7 +138,7 @@ static struct xt_match owner_mt_reg[] __read_mostly = {
153 { 138 {
154 .name = "owner", 139 .name = "owner",
155 .revision = 0, 140 .revision = 0,
156 .family = AF_INET, 141 .family = NFPROTO_IPV4,
157 .match = owner_mt_v0, 142 .match = owner_mt_v0,
158 .matchsize = sizeof(struct ipt_owner_info), 143 .matchsize = sizeof(struct ipt_owner_info),
159 .checkentry = owner_mt_check_v0, 144 .checkentry = owner_mt_check_v0,
@@ -164,7 +149,7 @@ static struct xt_match owner_mt_reg[] __read_mostly = {
164 { 149 {
165 .name = "owner", 150 .name = "owner",
166 .revision = 0, 151 .revision = 0,
167 .family = AF_INET6, 152 .family = NFPROTO_IPV6,
168 .match = owner_mt6_v0, 153 .match = owner_mt6_v0,
169 .matchsize = sizeof(struct ip6t_owner_info), 154 .matchsize = sizeof(struct ip6t_owner_info),
170 .checkentry = owner_mt6_check_v0, 155 .checkentry = owner_mt6_check_v0,
@@ -175,17 +160,7 @@ static struct xt_match owner_mt_reg[] __read_mostly = {
175 { 160 {
176 .name = "owner", 161 .name = "owner",
177 .revision = 1, 162 .revision = 1,
178 .family = AF_INET, 163 .family = NFPROTO_UNSPEC,
179 .match = owner_mt,
180 .matchsize = sizeof(struct xt_owner_match_info),
181 .hooks = (1 << NF_INET_LOCAL_OUT) |
182 (1 << NF_INET_POST_ROUTING),
183 .me = THIS_MODULE,
184 },
185 {
186 .name = "owner",
187 .revision = 1,
188 .family = AF_INET6,
189 .match = owner_mt, 164 .match = owner_mt,
190 .matchsize = sizeof(struct xt_owner_match_info), 165 .matchsize = sizeof(struct xt_owner_match_info),
191 .hooks = (1 << NF_INET_LOCAL_OUT) | 166 .hooks = (1 << NF_INET_LOCAL_OUT) |
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c
index 4ec1094bda92..1bcdfc12cf59 100644
--- a/net/netfilter/xt_physdev.c
+++ b/net/netfilter/xt_physdev.c
@@ -21,14 +21,11 @@ MODULE_ALIAS("ipt_physdev");
21MODULE_ALIAS("ip6t_physdev"); 21MODULE_ALIAS("ip6t_physdev");
22 22
23static bool 23static bool
24physdev_mt(const struct sk_buff *skb, const struct net_device *in, 24physdev_mt(const struct sk_buff *skb, const struct xt_match_param *par)
25 const struct net_device *out, const struct xt_match *match,
26 const void *matchinfo, int offset, unsigned int protoff,
27 bool *hotdrop)
28{ 25{
29 int i; 26 int i;
30 static const char nulldevname[IFNAMSIZ]; 27 static const char nulldevname[IFNAMSIZ];
31 const struct xt_physdev_info *info = matchinfo; 28 const struct xt_physdev_info *info = par->matchinfo;
32 bool ret; 29 bool ret;
33 const char *indev, *outdev; 30 const char *indev, *outdev;
34 const struct nf_bridge_info *nf_bridge; 31 const struct nf_bridge_info *nf_bridge;
@@ -94,12 +91,9 @@ match_outdev:
94 return ret ^ !(info->invert & XT_PHYSDEV_OP_OUT); 91 return ret ^ !(info->invert & XT_PHYSDEV_OP_OUT);
95} 92}
96 93
97static bool 94static bool physdev_mt_check(const struct xt_mtchk_param *par)
98physdev_mt_check(const char *tablename, const void *ip,
99 const struct xt_match *match, void *matchinfo,
100 unsigned int hook_mask)
101{ 95{
102 const struct xt_physdev_info *info = matchinfo; 96 const struct xt_physdev_info *info = par->matchinfo;
103 97
104 if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || 98 if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
105 info->bitmask & ~XT_PHYSDEV_OP_MASK) 99 info->bitmask & ~XT_PHYSDEV_OP_MASK)
@@ -107,44 +101,35 @@ physdev_mt_check(const char *tablename, const void *ip,
107 if (info->bitmask & XT_PHYSDEV_OP_OUT && 101 if (info->bitmask & XT_PHYSDEV_OP_OUT &&
108 (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) || 102 (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
109 info->invert & XT_PHYSDEV_OP_BRIDGED) && 103 info->invert & XT_PHYSDEV_OP_BRIDGED) &&
110 hook_mask & ((1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD) | 104 par->hook_mask & ((1 << NF_INET_LOCAL_OUT) |
111 (1 << NF_INET_POST_ROUTING))) { 105 (1 << NF_INET_FORWARD) | (1 << NF_INET_POST_ROUTING))) {
112 printk(KERN_WARNING "physdev match: using --physdev-out in the " 106 printk(KERN_WARNING "physdev match: using --physdev-out in the "
113 "OUTPUT, FORWARD and POSTROUTING chains for non-bridged " 107 "OUTPUT, FORWARD and POSTROUTING chains for non-bridged "
114 "traffic is not supported anymore.\n"); 108 "traffic is not supported anymore.\n");
115 if (hook_mask & (1 << NF_INET_LOCAL_OUT)) 109 if (par->hook_mask & (1 << NF_INET_LOCAL_OUT))
116 return false; 110 return false;
117 } 111 }
118 return true; 112 return true;
119} 113}
120 114
121static struct xt_match physdev_mt_reg[] __read_mostly = { 115static struct xt_match physdev_mt_reg __read_mostly = {
122 { 116 .name = "physdev",
123 .name = "physdev", 117 .revision = 0,
124 .family = AF_INET, 118 .family = NFPROTO_UNSPEC,
125 .checkentry = physdev_mt_check, 119 .checkentry = physdev_mt_check,
126 .match = physdev_mt, 120 .match = physdev_mt,
127 .matchsize = sizeof(struct xt_physdev_info), 121 .matchsize = sizeof(struct xt_physdev_info),
128 .me = THIS_MODULE, 122 .me = THIS_MODULE,
129 },
130 {
131 .name = "physdev",
132 .family = AF_INET6,
133 .checkentry = physdev_mt_check,
134 .match = physdev_mt,
135 .matchsize = sizeof(struct xt_physdev_info),
136 .me = THIS_MODULE,
137 },
138}; 123};
139 124
140static int __init physdev_mt_init(void) 125static int __init physdev_mt_init(void)
141{ 126{
142 return xt_register_matches(physdev_mt_reg, ARRAY_SIZE(physdev_mt_reg)); 127 return xt_register_match(&physdev_mt_reg);
143} 128}
144 129
145static void __exit physdev_mt_exit(void) 130static void __exit physdev_mt_exit(void)
146{ 131{
147 xt_unregister_matches(physdev_mt_reg, ARRAY_SIZE(physdev_mt_reg)); 132 xt_unregister_match(&physdev_mt_reg);
148} 133}
149 134
150module_init(physdev_mt_init); 135module_init(physdev_mt_init);
diff --git a/net/netfilter/xt_pkttype.c b/net/netfilter/xt_pkttype.c
index 7936f7e23254..69da1d3a1d85 100644
--- a/net/netfilter/xt_pkttype.c
+++ b/net/netfilter/xt_pkttype.c
@@ -23,20 +23,17 @@ MODULE_ALIAS("ipt_pkttype");
23MODULE_ALIAS("ip6t_pkttype"); 23MODULE_ALIAS("ip6t_pkttype");
24 24
25static bool 25static bool
26pkttype_mt(const struct sk_buff *skb, const struct net_device *in, 26pkttype_mt(const struct sk_buff *skb, const struct xt_match_param *par)
27 const struct net_device *out, const struct xt_match *match,
28 const void *matchinfo, int offset, unsigned int protoff,
29 bool *hotdrop)
30{ 27{
31 const struct xt_pkttype_info *info = matchinfo; 28 const struct xt_pkttype_info *info = par->matchinfo;
32 u_int8_t type; 29 u_int8_t type;
33 30
34 if (skb->pkt_type != PACKET_LOOPBACK) 31 if (skb->pkt_type != PACKET_LOOPBACK)
35 type = skb->pkt_type; 32 type = skb->pkt_type;
36 else if (match->family == AF_INET && 33 else if (par->family == NFPROTO_IPV4 &&
37 ipv4_is_multicast(ip_hdr(skb)->daddr)) 34 ipv4_is_multicast(ip_hdr(skb)->daddr))
38 type = PACKET_MULTICAST; 35 type = PACKET_MULTICAST;
39 else if (match->family == AF_INET6 && 36 else if (par->family == NFPROTO_IPV6 &&
40 ipv6_hdr(skb)->daddr.s6_addr[0] == 0xFF) 37 ipv6_hdr(skb)->daddr.s6_addr[0] == 0xFF)
41 type = PACKET_MULTICAST; 38 type = PACKET_MULTICAST;
42 else 39 else
@@ -45,31 +42,23 @@ pkttype_mt(const struct sk_buff *skb, const struct net_device *in,
45 return (type == info->pkttype) ^ info->invert; 42 return (type == info->pkttype) ^ info->invert;
46} 43}
47 44
48static struct xt_match pkttype_mt_reg[] __read_mostly = { 45static struct xt_match pkttype_mt_reg __read_mostly = {
49 { 46 .name = "pkttype",
50 .name = "pkttype", 47 .revision = 0,
51 .family = AF_INET, 48 .family = NFPROTO_UNSPEC,
52 .match = pkttype_mt, 49 .match = pkttype_mt,
53 .matchsize = sizeof(struct xt_pkttype_info), 50 .matchsize = sizeof(struct xt_pkttype_info),
54 .me = THIS_MODULE, 51 .me = THIS_MODULE,
55 },
56 {
57 .name = "pkttype",
58 .family = AF_INET6,
59 .match = pkttype_mt,
60 .matchsize = sizeof(struct xt_pkttype_info),
61 .me = THIS_MODULE,
62 },
63}; 52};
64 53
65static int __init pkttype_mt_init(void) 54static int __init pkttype_mt_init(void)
66{ 55{
67 return xt_register_matches(pkttype_mt_reg, ARRAY_SIZE(pkttype_mt_reg)); 56 return xt_register_match(&pkttype_mt_reg);
68} 57}
69 58
70static void __exit pkttype_mt_exit(void) 59static void __exit pkttype_mt_exit(void)
71{ 60{
72 xt_unregister_matches(pkttype_mt_reg, ARRAY_SIZE(pkttype_mt_reg)); 61 xt_unregister_match(&pkttype_mt_reg);
73} 62}
74 63
75module_init(pkttype_mt_init); 64module_init(pkttype_mt_init);
diff --git a/net/netfilter/xt_policy.c b/net/netfilter/xt_policy.c
index d351582b2a3d..328bd20ddd25 100644
--- a/net/netfilter/xt_policy.c
+++ b/net/netfilter/xt_policy.c
@@ -26,9 +26,9 @@ xt_addr_cmp(const union nf_inet_addr *a1, const union nf_inet_addr *m,
26 const union nf_inet_addr *a2, unsigned short family) 26 const union nf_inet_addr *a2, unsigned short family)
27{ 27{
28 switch (family) { 28 switch (family) {
29 case AF_INET: 29 case NFPROTO_IPV4:
30 return ((a1->ip ^ a2->ip) & m->ip) == 0; 30 return ((a1->ip ^ a2->ip) & m->ip) == 0;
31 case AF_INET6: 31 case NFPROTO_IPV6:
32 return ipv6_masked_addr_cmp(&a1->in6, &m->in6, &a2->in6) == 0; 32 return ipv6_masked_addr_cmp(&a1->in6, &m->in6, &a2->in6) == 0;
33 } 33 }
34 return false; 34 return false;
@@ -110,18 +110,15 @@ match_policy_out(const struct sk_buff *skb, const struct xt_policy_info *info,
110} 110}
111 111
112static bool 112static bool
113policy_mt(const struct sk_buff *skb, const struct net_device *in, 113policy_mt(const struct sk_buff *skb, const struct xt_match_param *par)
114 const struct net_device *out, const struct xt_match *match,
115 const void *matchinfo, int offset, unsigned int protoff,
116 bool *hotdrop)
117{ 114{
118 const struct xt_policy_info *info = matchinfo; 115 const struct xt_policy_info *info = par->matchinfo;
119 int ret; 116 int ret;
120 117
121 if (info->flags & XT_POLICY_MATCH_IN) 118 if (info->flags & XT_POLICY_MATCH_IN)
122 ret = match_policy_in(skb, info, match->family); 119 ret = match_policy_in(skb, info, par->match->family);
123 else 120 else
124 ret = match_policy_out(skb, info, match->family); 121 ret = match_policy_out(skb, info, par->match->family);
125 122
126 if (ret < 0) 123 if (ret < 0)
127 ret = info->flags & XT_POLICY_MATCH_NONE ? true : false; 124 ret = info->flags & XT_POLICY_MATCH_NONE ? true : false;
@@ -131,26 +128,23 @@ policy_mt(const struct sk_buff *skb, const struct net_device *in,
131 return ret; 128 return ret;
132} 129}
133 130
134static bool 131static bool policy_mt_check(const struct xt_mtchk_param *par)
135policy_mt_check(const char *tablename, const void *ip_void,
136 const struct xt_match *match, void *matchinfo,
137 unsigned int hook_mask)
138{ 132{
139 const struct xt_policy_info *info = matchinfo; 133 const struct xt_policy_info *info = par->matchinfo;
140 134
141 if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) { 135 if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) {
142 printk(KERN_ERR "xt_policy: neither incoming nor " 136 printk(KERN_ERR "xt_policy: neither incoming nor "
143 "outgoing policy selected\n"); 137 "outgoing policy selected\n");
144 return false; 138 return false;
145 } 139 }
146 if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN) 140 if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |
147 && info->flags & XT_POLICY_MATCH_OUT) { 141 (1 << NF_INET_LOCAL_IN)) && info->flags & XT_POLICY_MATCH_OUT) {
148 printk(KERN_ERR "xt_policy: output policy not valid in " 142 printk(KERN_ERR "xt_policy: output policy not valid in "
149 "PRE_ROUTING and INPUT\n"); 143 "PRE_ROUTING and INPUT\n");
150 return false; 144 return false;
151 } 145 }
152 if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT) 146 if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) |
153 && info->flags & XT_POLICY_MATCH_IN) { 147 (1 << NF_INET_LOCAL_OUT)) && info->flags & XT_POLICY_MATCH_IN) {
154 printk(KERN_ERR "xt_policy: input policy not valid in " 148 printk(KERN_ERR "xt_policy: input policy not valid in "
155 "POST_ROUTING and OUTPUT\n"); 149 "POST_ROUTING and OUTPUT\n");
156 return false; 150 return false;
@@ -165,7 +159,7 @@ policy_mt_check(const char *tablename, const void *ip_void,
165static struct xt_match policy_mt_reg[] __read_mostly = { 159static struct xt_match policy_mt_reg[] __read_mostly = {
166 { 160 {
167 .name = "policy", 161 .name = "policy",
168 .family = AF_INET, 162 .family = NFPROTO_IPV4,
169 .checkentry = policy_mt_check, 163 .checkentry = policy_mt_check,
170 .match = policy_mt, 164 .match = policy_mt,
171 .matchsize = sizeof(struct xt_policy_info), 165 .matchsize = sizeof(struct xt_policy_info),
@@ -173,7 +167,7 @@ static struct xt_match policy_mt_reg[] __read_mostly = {
173 }, 167 },
174 { 168 {
175 .name = "policy", 169 .name = "policy",
176 .family = AF_INET6, 170 .family = NFPROTO_IPV6,
177 .checkentry = policy_mt_check, 171 .checkentry = policy_mt_check,
178 .match = policy_mt, 172 .match = policy_mt,
179 .matchsize = sizeof(struct xt_policy_info), 173 .matchsize = sizeof(struct xt_policy_info),
diff --git a/net/netfilter/xt_quota.c b/net/netfilter/xt_quota.c
index 3b021d0c522a..c84fce5e0f3e 100644
--- a/net/netfilter/xt_quota.c
+++ b/net/netfilter/xt_quota.c
@@ -18,13 +18,10 @@ MODULE_ALIAS("ip6t_quota");
18static DEFINE_SPINLOCK(quota_lock); 18static DEFINE_SPINLOCK(quota_lock);
19 19
20static bool 20static bool
21quota_mt(const struct sk_buff *skb, const struct net_device *in, 21quota_mt(const struct sk_buff *skb, const struct xt_match_param *par)
22 const struct net_device *out, const struct xt_match *match,
23 const void *matchinfo, int offset, unsigned int protoff,
24 bool *hotdrop)
25{ 22{
26 struct xt_quota_info *q = 23 struct xt_quota_info *q =
27 ((const struct xt_quota_info *)matchinfo)->master; 24 ((const struct xt_quota_info *)par->matchinfo)->master;
28 bool ret = q->flags & XT_QUOTA_INVERT; 25 bool ret = q->flags & XT_QUOTA_INVERT;
29 26
30 spin_lock_bh(&quota_lock); 27 spin_lock_bh(&quota_lock);
@@ -40,12 +37,9 @@ quota_mt(const struct sk_buff *skb, const struct net_device *in,
40 return ret; 37 return ret;
41} 38}
42 39
43static bool 40static bool quota_mt_check(const struct xt_mtchk_param *par)
44quota_mt_check(const char *tablename, const void *entry,
45 const struct xt_match *match, void *matchinfo,
46 unsigned int hook_mask)
47{ 41{
48 struct xt_quota_info *q = matchinfo; 42 struct xt_quota_info *q = par->matchinfo;
49 43
50 if (q->flags & ~XT_QUOTA_MASK) 44 if (q->flags & ~XT_QUOTA_MASK)
51 return false; 45 return false;
@@ -54,33 +48,24 @@ quota_mt_check(const char *tablename, const void *entry,
54 return true; 48 return true;
55} 49}
56 50
57static struct xt_match quota_mt_reg[] __read_mostly = { 51static struct xt_match quota_mt_reg __read_mostly = {
58 { 52 .name = "quota",
59 .name = "quota", 53 .revision = 0,
60 .family = AF_INET, 54 .family = NFPROTO_UNSPEC,
61 .checkentry = quota_mt_check, 55 .match = quota_mt,
62 .match = quota_mt, 56 .checkentry = quota_mt_check,
63 .matchsize = sizeof(struct xt_quota_info), 57 .matchsize = sizeof(struct xt_quota_info),
64 .me = THIS_MODULE 58 .me = THIS_MODULE,
65 },
66 {
67 .name = "quota",
68 .family = AF_INET6,
69 .checkentry = quota_mt_check,
70 .match = quota_mt,
71 .matchsize = sizeof(struct xt_quota_info),
72 .me = THIS_MODULE
73 },
74}; 59};
75 60
76static int __init quota_mt_init(void) 61static int __init quota_mt_init(void)
77{ 62{
78 return xt_register_matches(quota_mt_reg, ARRAY_SIZE(quota_mt_reg)); 63 return xt_register_match(&quota_mt_reg);
79} 64}
80 65
81static void __exit quota_mt_exit(void) 66static void __exit quota_mt_exit(void)
82{ 67{
83 xt_unregister_matches(quota_mt_reg, ARRAY_SIZE(quota_mt_reg)); 68 xt_unregister_match(&quota_mt_reg);
84} 69}
85 70
86module_init(quota_mt_init); 71module_init(quota_mt_init);
diff --git a/net/netfilter/xt_rateest.c b/net/netfilter/xt_rateest.c
index ebd84f1b4f62..220a1d588ee0 100644
--- a/net/netfilter/xt_rateest.c
+++ b/net/netfilter/xt_rateest.c
@@ -14,16 +14,10 @@
14#include <net/netfilter/xt_rateest.h> 14#include <net/netfilter/xt_rateest.h>
15 15
16 16
17static bool xt_rateest_mt(const struct sk_buff *skb, 17static bool
18 const struct net_device *in, 18xt_rateest_mt(const struct sk_buff *skb, const struct xt_match_param *par)
19 const struct net_device *out,
20 const struct xt_match *match,
21 const void *matchinfo,
22 int offset,
23 unsigned int protoff,
24 bool *hotdrop)
25{ 19{
26 const struct xt_rateest_match_info *info = matchinfo; 20 const struct xt_rateest_match_info *info = par->matchinfo;
27 struct gnet_stats_rate_est *r; 21 struct gnet_stats_rate_est *r;
28 u_int32_t bps1, bps2, pps1, pps2; 22 u_int32_t bps1, bps2, pps1, pps2;
29 bool ret = true; 23 bool ret = true;
@@ -80,13 +74,9 @@ static bool xt_rateest_mt(const struct sk_buff *skb,
80 return ret; 74 return ret;
81} 75}
82 76
83static bool xt_rateest_mt_checkentry(const char *tablename, 77static bool xt_rateest_mt_checkentry(const struct xt_mtchk_param *par)
84 const void *ip,
85 const struct xt_match *match,
86 void *matchinfo,
87 unsigned int hook_mask)
88{ 78{
89 struct xt_rateest_match_info *info = matchinfo; 79 struct xt_rateest_match_info *info = par->matchinfo;
90 struct xt_rateest *est1, *est2; 80 struct xt_rateest *est1, *est2;
91 81
92 if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS | 82 if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS |
@@ -127,46 +117,34 @@ err1:
127 return false; 117 return false;
128} 118}
129 119
130static void xt_rateest_mt_destroy(const struct xt_match *match, 120static void xt_rateest_mt_destroy(const struct xt_mtdtor_param *par)
131 void *matchinfo)
132{ 121{
133 struct xt_rateest_match_info *info = matchinfo; 122 struct xt_rateest_match_info *info = par->matchinfo;
134 123
135 xt_rateest_put(info->est1); 124 xt_rateest_put(info->est1);
136 if (info->est2) 125 if (info->est2)
137 xt_rateest_put(info->est2); 126 xt_rateest_put(info->est2);
138} 127}
139 128
140static struct xt_match xt_rateest_match[] __read_mostly = { 129static struct xt_match xt_rateest_mt_reg __read_mostly = {
141 { 130 .name = "rateest",
142 .family = AF_INET, 131 .revision = 0,
143 .name = "rateest", 132 .family = NFPROTO_UNSPEC,
144 .match = xt_rateest_mt, 133 .match = xt_rateest_mt,
145 .checkentry = xt_rateest_mt_checkentry, 134 .checkentry = xt_rateest_mt_checkentry,
146 .destroy = xt_rateest_mt_destroy, 135 .destroy = xt_rateest_mt_destroy,
147 .matchsize = sizeof(struct xt_rateest_match_info), 136 .matchsize = sizeof(struct xt_rateest_match_info),
148 .me = THIS_MODULE, 137 .me = THIS_MODULE,
149 },
150 {
151 .family = AF_INET6,
152 .name = "rateest",
153 .match = xt_rateest_mt,
154 .checkentry = xt_rateest_mt_checkentry,
155 .destroy = xt_rateest_mt_destroy,
156 .matchsize = sizeof(struct xt_rateest_match_info),
157 .me = THIS_MODULE,
158 },
159}; 138};
160 139
161static int __init xt_rateest_mt_init(void) 140static int __init xt_rateest_mt_init(void)
162{ 141{
163 return xt_register_matches(xt_rateest_match, 142 return xt_register_match(&xt_rateest_mt_reg);
164 ARRAY_SIZE(xt_rateest_match));
165} 143}
166 144
167static void __exit xt_rateest_mt_fini(void) 145static void __exit xt_rateest_mt_fini(void)
168{ 146{
169 xt_unregister_matches(xt_rateest_match, ARRAY_SIZE(xt_rateest_match)); 147 xt_unregister_match(&xt_rateest_mt_reg);
170} 148}
171 149
172MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 150MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
diff --git a/net/netfilter/xt_realm.c b/net/netfilter/xt_realm.c
index 7df1627c536f..67419287bc7e 100644
--- a/net/netfilter/xt_realm.c
+++ b/net/netfilter/xt_realm.c
@@ -22,12 +22,9 @@ MODULE_DESCRIPTION("Xtables: Routing realm match");
22MODULE_ALIAS("ipt_realm"); 22MODULE_ALIAS("ipt_realm");
23 23
24static bool 24static bool
25realm_mt(const struct sk_buff *skb, const struct net_device *in, 25realm_mt(const struct sk_buff *skb, const struct xt_match_param *par)
26 const struct net_device *out, const struct xt_match *match,
27 const void *matchinfo, int offset, unsigned int protoff,
28 bool *hotdrop)
29{ 26{
30 const struct xt_realm_info *info = matchinfo; 27 const struct xt_realm_info *info = par->matchinfo;
31 const struct dst_entry *dst = skb->dst; 28 const struct dst_entry *dst = skb->dst;
32 29
33 return (info->id == (dst->tclassid & info->mask)) ^ info->invert; 30 return (info->id == (dst->tclassid & info->mask)) ^ info->invert;
@@ -39,7 +36,7 @@ static struct xt_match realm_mt_reg __read_mostly = {
39 .matchsize = sizeof(struct xt_realm_info), 36 .matchsize = sizeof(struct xt_realm_info),
40 .hooks = (1 << NF_INET_POST_ROUTING) | (1 << NF_INET_FORWARD) | 37 .hooks = (1 << NF_INET_POST_ROUTING) | (1 << NF_INET_FORWARD) |
41 (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_LOCAL_IN), 38 (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_LOCAL_IN),
42 .family = AF_INET, 39 .family = NFPROTO_UNSPEC,
43 .me = THIS_MODULE 40 .me = THIS_MODULE
44}; 41};
45 42
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/netfilter/xt_recent.c
index 3974d7cae5c0..4ebd4ca9a991 100644
--- a/net/ipv4/netfilter/ipt_recent.c
+++ b/net/netfilter/xt_recent.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2006 Patrick McHardy <kaber@trash.net> 2 * Copyright (c) 2006 Patrick McHardy <kaber@trash.net>
3 * Copyright © CC Computer Consultants GmbH, 2007 - 2008
3 * 4 *
4 * This program is free software; you can redistribute it and/or modify 5 * 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 * it under the terms of the GNU General Public License version 2 as
@@ -13,6 +14,8 @@
13 */ 14 */
14#include <linux/init.h> 15#include <linux/init.h>
15#include <linux/ip.h> 16#include <linux/ip.h>
17#include <linux/ipv6.h>
18#include <linux/module.h>
16#include <linux/moduleparam.h> 19#include <linux/moduleparam.h>
17#include <linux/proc_fs.h> 20#include <linux/proc_fs.h>
18#include <linux/seq_file.h> 21#include <linux/seq_file.h>
@@ -27,11 +30,14 @@
27#include <net/net_namespace.h> 30#include <net/net_namespace.h>
28 31
29#include <linux/netfilter/x_tables.h> 32#include <linux/netfilter/x_tables.h>
30#include <linux/netfilter_ipv4/ipt_recent.h> 33#include <linux/netfilter/xt_recent.h>
31 34
32MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 35MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
36MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
33MODULE_DESCRIPTION("Xtables: \"recently-seen\" host matching for IPv4"); 37MODULE_DESCRIPTION("Xtables: \"recently-seen\" host matching for IPv4");
34MODULE_LICENSE("GPL"); 38MODULE_LICENSE("GPL");
39MODULE_ALIAS("ipt_recent");
40MODULE_ALIAS("ip6t_recent");
35 41
36static unsigned int ip_list_tot = 100; 42static unsigned int ip_list_tot = 100;
37static unsigned int ip_pkt_list_tot = 20; 43static unsigned int ip_pkt_list_tot = 20;
@@ -48,14 +54,15 @@ module_param(ip_list_gid, uint, 0400);
48MODULE_PARM_DESC(ip_list_tot, "number of IPs to remember per list"); 54MODULE_PARM_DESC(ip_list_tot, "number of IPs to remember per list");
49MODULE_PARM_DESC(ip_pkt_list_tot, "number of packets per IP to remember (max. 255)"); 55MODULE_PARM_DESC(ip_pkt_list_tot, "number of packets per IP to remember (max. 255)");
50MODULE_PARM_DESC(ip_list_hash_size, "size of hash table used to look up IPs"); 56MODULE_PARM_DESC(ip_list_hash_size, "size of hash table used to look up IPs");
51MODULE_PARM_DESC(ip_list_perms, "permissions on /proc/net/ipt_recent/* files"); 57MODULE_PARM_DESC(ip_list_perms, "permissions on /proc/net/xt_recent/* files");
52MODULE_PARM_DESC(ip_list_uid,"owner of /proc/net/ipt_recent/* files"); 58MODULE_PARM_DESC(ip_list_uid,"owner of /proc/net/xt_recent/* files");
53MODULE_PARM_DESC(ip_list_gid,"owning group of /proc/net/ipt_recent/* files"); 59MODULE_PARM_DESC(ip_list_gid,"owning group of /proc/net/xt_recent/* files");
54 60
55struct recent_entry { 61struct recent_entry {
56 struct list_head list; 62 struct list_head list;
57 struct list_head lru_list; 63 struct list_head lru_list;
58 __be32 addr; 64 union nf_inet_addr addr;
65 u_int16_t family;
59 u_int8_t ttl; 66 u_int8_t ttl;
60 u_int8_t index; 67 u_int8_t index;
61 u_int16_t nstamps; 68 u_int16_t nstamps;
@@ -64,9 +71,9 @@ struct recent_entry {
64 71
65struct recent_table { 72struct recent_table {
66 struct list_head list; 73 struct list_head list;
67 char name[IPT_RECENT_NAME_LEN]; 74 char name[XT_RECENT_NAME_LEN];
68#ifdef CONFIG_PROC_FS 75#ifdef CONFIG_PROC_FS
69 struct proc_dir_entry *proc; 76 struct proc_dir_entry *proc_old, *proc;
70#endif 77#endif
71 unsigned int refcnt; 78 unsigned int refcnt;
72 unsigned int entries; 79 unsigned int entries;
@@ -79,31 +86,53 @@ static DEFINE_SPINLOCK(recent_lock);
79static DEFINE_MUTEX(recent_mutex); 86static DEFINE_MUTEX(recent_mutex);
80 87
81#ifdef CONFIG_PROC_FS 88#ifdef CONFIG_PROC_FS
82static struct proc_dir_entry *proc_dir; 89#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
83static const struct file_operations recent_fops; 90static struct proc_dir_entry *proc_old_dir;
91#endif
92static struct proc_dir_entry *recent_proc_dir;
93static const struct file_operations recent_old_fops, recent_mt_fops;
84#endif 94#endif
85 95
86static u_int32_t hash_rnd; 96static u_int32_t hash_rnd;
87static int hash_rnd_initted; 97static bool hash_rnd_initted;
98
99static unsigned int recent_entry_hash4(const union nf_inet_addr *addr)
100{
101 if (!hash_rnd_initted) {
102 get_random_bytes(&hash_rnd, sizeof(hash_rnd));
103 hash_rnd_initted = true;
104 }
105 return jhash_1word((__force u32)addr->ip, hash_rnd) &
106 (ip_list_hash_size - 1);
107}
88 108
89static unsigned int recent_entry_hash(__be32 addr) 109static unsigned int recent_entry_hash6(const union nf_inet_addr *addr)
90{ 110{
91 if (!hash_rnd_initted) { 111 if (!hash_rnd_initted) {
92 get_random_bytes(&hash_rnd, 4); 112 get_random_bytes(&hash_rnd, sizeof(hash_rnd));
93 hash_rnd_initted = 1; 113 hash_rnd_initted = true;
94 } 114 }
95 return jhash_1word((__force u32)addr, hash_rnd) & (ip_list_hash_size - 1); 115 return jhash2((u32 *)addr->ip6, ARRAY_SIZE(addr->ip6), hash_rnd) &
116 (ip_list_hash_size - 1);
96} 117}
97 118
98static struct recent_entry * 119static struct recent_entry *
99recent_entry_lookup(const struct recent_table *table, __be32 addr, u_int8_t ttl) 120recent_entry_lookup(const struct recent_table *table,
121 const union nf_inet_addr *addrp, u_int16_t family,
122 u_int8_t ttl)
100{ 123{
101 struct recent_entry *e; 124 struct recent_entry *e;
102 unsigned int h; 125 unsigned int h;
103 126
104 h = recent_entry_hash(addr); 127 if (family == NFPROTO_IPV4)
128 h = recent_entry_hash4(addrp);
129 else
130 h = recent_entry_hash6(addrp);
131
105 list_for_each_entry(e, &table->iphash[h], list) 132 list_for_each_entry(e, &table->iphash[h], list)
106 if (e->addr == addr && (ttl == e->ttl || !ttl || !e->ttl)) 133 if (e->family == family &&
134 memcmp(&e->addr, addrp, sizeof(e->addr)) == 0 &&
135 (ttl == e->ttl || ttl == 0 || e->ttl == 0))
107 return e; 136 return e;
108 return NULL; 137 return NULL;
109} 138}
@@ -117,7 +146,8 @@ static void recent_entry_remove(struct recent_table *t, struct recent_entry *e)
117} 146}
118 147
119static struct recent_entry * 148static struct recent_entry *
120recent_entry_init(struct recent_table *t, __be32 addr, u_int8_t ttl) 149recent_entry_init(struct recent_table *t, const union nf_inet_addr *addr,
150 u_int16_t family, u_int8_t ttl)
121{ 151{
122 struct recent_entry *e; 152 struct recent_entry *e;
123 153
@@ -129,12 +159,16 @@ recent_entry_init(struct recent_table *t, __be32 addr, u_int8_t ttl)
129 GFP_ATOMIC); 159 GFP_ATOMIC);
130 if (e == NULL) 160 if (e == NULL)
131 return NULL; 161 return NULL;
132 e->addr = addr; 162 memcpy(&e->addr, addr, sizeof(e->addr));
133 e->ttl = ttl; 163 e->ttl = ttl;
134 e->stamps[0] = jiffies; 164 e->stamps[0] = jiffies;
135 e->nstamps = 1; 165 e->nstamps = 1;
136 e->index = 1; 166 e->index = 1;
137 list_add_tail(&e->list, &t->iphash[recent_entry_hash(addr)]); 167 e->family = family;
168 if (family == NFPROTO_IPV4)
169 list_add_tail(&e->list, &t->iphash[recent_entry_hash4(addr)]);
170 else
171 list_add_tail(&e->list, &t->iphash[recent_entry_hash6(addr)]);
138 list_add_tail(&e->lru_list, &t->lru_list); 172 list_add_tail(&e->lru_list, &t->lru_list);
139 t->entries++; 173 t->entries++;
140 return e; 174 return e;
@@ -170,48 +204,59 @@ static void recent_table_flush(struct recent_table *t)
170} 204}
171 205
172static bool 206static bool
173recent_mt(const struct sk_buff *skb, const struct net_device *in, 207recent_mt(const struct sk_buff *skb, const struct xt_match_param *par)
174 const struct net_device *out, const struct xt_match *match,
175 const void *matchinfo, int offset, unsigned int protoff,
176 bool *hotdrop)
177{ 208{
178 const struct ipt_recent_info *info = matchinfo; 209 const struct xt_recent_mtinfo *info = par->matchinfo;
179 struct recent_table *t; 210 struct recent_table *t;
180 struct recent_entry *e; 211 struct recent_entry *e;
181 __be32 addr; 212 union nf_inet_addr addr = {};
182 u_int8_t ttl; 213 u_int8_t ttl;
183 bool ret = info->invert; 214 bool ret = info->invert;
184 215
185 if (info->side == IPT_RECENT_DEST) 216 if (par->match->family == NFPROTO_IPV4) {
186 addr = ip_hdr(skb)->daddr; 217 const struct iphdr *iph = ip_hdr(skb);
187 else 218
188 addr = ip_hdr(skb)->saddr; 219 if (info->side == XT_RECENT_DEST)
220 addr.ip = iph->daddr;
221 else
222 addr.ip = iph->saddr;
223
224 ttl = iph->ttl;
225 } else {
226 const struct ipv6hdr *iph = ipv6_hdr(skb);
227
228 if (info->side == XT_RECENT_DEST)
229 memcpy(&addr.in6, &iph->daddr, sizeof(addr.in6));
230 else
231 memcpy(&addr.in6, &iph->saddr, sizeof(addr.in6));
232
233 ttl = iph->hop_limit;
234 }
189 235
190 ttl = ip_hdr(skb)->ttl;
191 /* use TTL as seen before forwarding */ 236 /* use TTL as seen before forwarding */
192 if (out && !skb->sk) 237 if (par->out != NULL && skb->sk == NULL)
193 ttl++; 238 ttl++;
194 239
195 spin_lock_bh(&recent_lock); 240 spin_lock_bh(&recent_lock);
196 t = recent_table_lookup(info->name); 241 t = recent_table_lookup(info->name);
197 e = recent_entry_lookup(t, addr, 242 e = recent_entry_lookup(t, &addr, par->match->family,
198 info->check_set & IPT_RECENT_TTL ? ttl : 0); 243 (info->check_set & XT_RECENT_TTL) ? ttl : 0);
199 if (e == NULL) { 244 if (e == NULL) {
200 if (!(info->check_set & IPT_RECENT_SET)) 245 if (!(info->check_set & XT_RECENT_SET))
201 goto out; 246 goto out;
202 e = recent_entry_init(t, addr, ttl); 247 e = recent_entry_init(t, &addr, par->match->family, ttl);
203 if (e == NULL) 248 if (e == NULL)
204 *hotdrop = true; 249 *par->hotdrop = true;
205 ret = !ret; 250 ret = !ret;
206 goto out; 251 goto out;
207 } 252 }
208 253
209 if (info->check_set & IPT_RECENT_SET) 254 if (info->check_set & XT_RECENT_SET)
210 ret = !ret; 255 ret = !ret;
211 else if (info->check_set & IPT_RECENT_REMOVE) { 256 else if (info->check_set & XT_RECENT_REMOVE) {
212 recent_entry_remove(t, e); 257 recent_entry_remove(t, e);
213 ret = !ret; 258 ret = !ret;
214 } else if (info->check_set & (IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) { 259 } else if (info->check_set & (XT_RECENT_CHECK | XT_RECENT_UPDATE)) {
215 unsigned long time = jiffies - info->seconds * HZ; 260 unsigned long time = jiffies - info->seconds * HZ;
216 unsigned int i, hits = 0; 261 unsigned int i, hits = 0;
217 262
@@ -225,8 +270,8 @@ recent_mt(const struct sk_buff *skb, const struct net_device *in,
225 } 270 }
226 } 271 }
227 272
228 if (info->check_set & IPT_RECENT_SET || 273 if (info->check_set & XT_RECENT_SET ||
229 (info->check_set & IPT_RECENT_UPDATE && ret)) { 274 (info->check_set & XT_RECENT_UPDATE && ret)) {
230 recent_entry_update(t, e); 275 recent_entry_update(t, e);
231 e->ttl = ttl; 276 e->ttl = ttl;
232 } 277 }
@@ -235,27 +280,24 @@ out:
235 return ret; 280 return ret;
236} 281}
237 282
238static bool 283static bool recent_mt_check(const struct xt_mtchk_param *par)
239recent_mt_check(const char *tablename, const void *ip,
240 const struct xt_match *match, void *matchinfo,
241 unsigned int hook_mask)
242{ 284{
243 const struct ipt_recent_info *info = matchinfo; 285 const struct xt_recent_mtinfo *info = par->matchinfo;
244 struct recent_table *t; 286 struct recent_table *t;
245 unsigned i; 287 unsigned i;
246 bool ret = false; 288 bool ret = false;
247 289
248 if (hweight8(info->check_set & 290 if (hweight8(info->check_set &
249 (IPT_RECENT_SET | IPT_RECENT_REMOVE | 291 (XT_RECENT_SET | XT_RECENT_REMOVE |
250 IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) != 1) 292 XT_RECENT_CHECK | XT_RECENT_UPDATE)) != 1)
251 return false; 293 return false;
252 if ((info->check_set & (IPT_RECENT_SET | IPT_RECENT_REMOVE)) && 294 if ((info->check_set & (XT_RECENT_SET | XT_RECENT_REMOVE)) &&
253 (info->seconds || info->hit_count)) 295 (info->seconds || info->hit_count))
254 return false; 296 return false;
255 if (info->hit_count > ip_pkt_list_tot) 297 if (info->hit_count > ip_pkt_list_tot)
256 return false; 298 return false;
257 if (info->name[0] == '\0' || 299 if (info->name[0] == '\0' ||
258 strnlen(info->name, IPT_RECENT_NAME_LEN) == IPT_RECENT_NAME_LEN) 300 strnlen(info->name, XT_RECENT_NAME_LEN) == XT_RECENT_NAME_LEN)
259 return false; 301 return false;
260 302
261 mutex_lock(&recent_mutex); 303 mutex_lock(&recent_mutex);
@@ -276,11 +318,24 @@ recent_mt_check(const char *tablename, const void *ip,
276 for (i = 0; i < ip_list_hash_size; i++) 318 for (i = 0; i < ip_list_hash_size; i++)
277 INIT_LIST_HEAD(&t->iphash[i]); 319 INIT_LIST_HEAD(&t->iphash[i]);
278#ifdef CONFIG_PROC_FS 320#ifdef CONFIG_PROC_FS
279 t->proc = proc_create(t->name, ip_list_perms, proc_dir, &recent_fops); 321 t->proc = proc_create(t->name, ip_list_perms, recent_proc_dir,
322 &recent_mt_fops);
280 if (t->proc == NULL) { 323 if (t->proc == NULL) {
281 kfree(t); 324 kfree(t);
282 goto out; 325 goto out;
283 } 326 }
327#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
328 t->proc_old = proc_create(t->name, ip_list_perms, proc_old_dir,
329 &recent_old_fops);
330 if (t->proc_old == NULL) {
331 remove_proc_entry(t->name, proc_old_dir);
332 kfree(t);
333 goto out;
334 }
335 t->proc_old->uid = ip_list_uid;
336 t->proc_old->gid = ip_list_gid;
337 t->proc_old->data = t;
338#endif
284 t->proc->uid = ip_list_uid; 339 t->proc->uid = ip_list_uid;
285 t->proc->gid = ip_list_gid; 340 t->proc->gid = ip_list_gid;
286 t->proc->data = t; 341 t->proc->data = t;
@@ -294,9 +349,9 @@ out:
294 return ret; 349 return ret;
295} 350}
296 351
297static void recent_mt_destroy(const struct xt_match *match, void *matchinfo) 352static void recent_mt_destroy(const struct xt_mtdtor_param *par)
298{ 353{
299 const struct ipt_recent_info *info = matchinfo; 354 const struct xt_recent_mtinfo *info = par->matchinfo;
300 struct recent_table *t; 355 struct recent_table *t;
301 356
302 mutex_lock(&recent_mutex); 357 mutex_lock(&recent_mutex);
@@ -306,7 +361,10 @@ static void recent_mt_destroy(const struct xt_match *match, void *matchinfo)
306 list_del(&t->list); 361 list_del(&t->list);
307 spin_unlock_bh(&recent_lock); 362 spin_unlock_bh(&recent_lock);
308#ifdef CONFIG_PROC_FS 363#ifdef CONFIG_PROC_FS
309 remove_proc_entry(t->name, proc_dir); 364#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
365 remove_proc_entry(t->name, proc_old_dir);
366#endif
367 remove_proc_entry(t->name, recent_proc_dir);
310#endif 368#endif
311 recent_table_flush(t); 369 recent_table_flush(t);
312 kfree(t); 370 kfree(t);
@@ -316,7 +374,7 @@ static void recent_mt_destroy(const struct xt_match *match, void *matchinfo)
316 374
317#ifdef CONFIG_PROC_FS 375#ifdef CONFIG_PROC_FS
318struct recent_iter_state { 376struct recent_iter_state {
319 struct recent_table *table; 377 const struct recent_table *table;
320 unsigned int bucket; 378 unsigned int bucket;
321}; 379};
322 380
@@ -341,8 +399,8 @@ static void *recent_seq_next(struct seq_file *seq, void *v, loff_t *pos)
341{ 399{
342 struct recent_iter_state *st = seq->private; 400 struct recent_iter_state *st = seq->private;
343 const struct recent_table *t = st->table; 401 const struct recent_table *t = st->table;
344 struct recent_entry *e = v; 402 const struct recent_entry *e = v;
345 struct list_head *head = e->list.next; 403 const struct list_head *head = e->list.next;
346 404
347 while (head == &t->iphash[st->bucket]) { 405 while (head == &t->iphash[st->bucket]) {
348 if (++st->bucket >= ip_list_hash_size) 406 if (++st->bucket >= ip_list_hash_size)
@@ -365,8 +423,14 @@ static int recent_seq_show(struct seq_file *seq, void *v)
365 unsigned int i; 423 unsigned int i;
366 424
367 i = (e->index - 1) % ip_pkt_list_tot; 425 i = (e->index - 1) % ip_pkt_list_tot;
368 seq_printf(seq, "src=%u.%u.%u.%u ttl: %u last_seen: %lu oldest_pkt: %u", 426 if (e->family == NFPROTO_IPV4)
369 NIPQUAD(e->addr), e->ttl, e->stamps[i], e->index); 427 seq_printf(seq, "src=" NIPQUAD_FMT " ttl: %u last_seen: %lu "
428 "oldest_pkt: %u", NIPQUAD(e->addr.ip), e->ttl,
429 e->stamps[i], e->index);
430 else
431 seq_printf(seq, "src=" NIP6_FMT " ttl: %u last_seen: %lu "
432 "oldest_pkt: %u", NIP6(e->addr.in6), e->ttl,
433 e->stamps[i], e->index);
370 for (i = 0; i < e->nstamps; i++) 434 for (i = 0; i < e->nstamps; i++)
371 seq_printf(seq, "%s %lu", i ? "," : "", e->stamps[i]); 435 seq_printf(seq, "%s %lu", i ? "," : "", e->stamps[i]);
372 seq_printf(seq, "\n"); 436 seq_printf(seq, "\n");
@@ -393,8 +457,22 @@ static int recent_seq_open(struct inode *inode, struct file *file)
393 return 0; 457 return 0;
394} 458}
395 459
396static ssize_t recent_proc_write(struct file *file, const char __user *input, 460#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
397 size_t size, loff_t *loff) 461static int recent_old_seq_open(struct inode *inode, struct file *filp)
462{
463 static bool warned_of_old;
464
465 if (unlikely(!warned_of_old)) {
466 printk(KERN_INFO KBUILD_MODNAME ": Use of /proc/net/ipt_recent"
467 " is deprecated; use /proc/net/xt_recent.\n");
468 warned_of_old = true;
469 }
470 return recent_seq_open(inode, filp);
471}
472
473static ssize_t recent_old_proc_write(struct file *file,
474 const char __user *input,
475 size_t size, loff_t *loff)
398{ 476{
399 const struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode); 477 const struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
400 struct recent_table *t = pde->data; 478 struct recent_table *t = pde->data;
@@ -407,6 +485,7 @@ static ssize_t recent_proc_write(struct file *file, const char __user *input,
407 size = sizeof(buf); 485 size = sizeof(buf);
408 if (copy_from_user(buf, input, size)) 486 if (copy_from_user(buf, input, size))
409 return -EFAULT; 487 return -EFAULT;
488
410 while (isspace(*c)) 489 while (isspace(*c))
411 c++; 490 c++;
412 491
@@ -434,10 +513,11 @@ static ssize_t recent_proc_write(struct file *file, const char __user *input,
434 addr = in_aton(c); 513 addr = in_aton(c);
435 514
436 spin_lock_bh(&recent_lock); 515 spin_lock_bh(&recent_lock);
437 e = recent_entry_lookup(t, addr, 0); 516 e = recent_entry_lookup(t, (const void *)&addr, NFPROTO_IPV4, 0);
438 if (e == NULL) { 517 if (e == NULL) {
439 if (add) 518 if (add)
440 recent_entry_init(t, addr, 0); 519 recent_entry_init(t, (const void *)&addr,
520 NFPROTO_IPV4, 0);
441 } else { 521 } else {
442 if (add) 522 if (add)
443 recent_entry_update(t, e); 523 recent_entry_update(t, e);
@@ -448,23 +528,118 @@ static ssize_t recent_proc_write(struct file *file, const char __user *input,
448 return size; 528 return size;
449} 529}
450 530
451static const struct file_operations recent_fops = { 531static const struct file_operations recent_old_fops = {
452 .open = recent_seq_open, 532 .open = recent_old_seq_open,
453 .read = seq_read, 533 .read = seq_read,
454 .write = recent_proc_write, 534 .write = recent_old_proc_write,
455 .release = seq_release_private, 535 .release = seq_release_private,
456 .owner = THIS_MODULE, 536 .owner = THIS_MODULE,
457}; 537};
538#endif
539
540static ssize_t
541recent_mt_proc_write(struct file *file, const char __user *input,
542 size_t size, loff_t *loff)
543{
544 const struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
545 struct recent_table *t = pde->data;
546 struct recent_entry *e;
547 char buf[sizeof("+b335:1d35:1e55:dead:c0de:1715:5afe:c0de")];
548 const char *c = buf;
549 union nf_inet_addr addr;
550 u_int16_t family;
551 bool add, succ;
552
553 if (size == 0)
554 return 0;
555 if (size > sizeof(buf))
556 size = sizeof(buf);
557 if (copy_from_user(buf, input, size) != 0)
558 return -EFAULT;
559
560 /* Strict protocol! */
561 if (*loff != 0)
562 return -ESPIPE;
563 switch (*c) {
564 case '/': /* flush table */
565 spin_lock_bh(&recent_lock);
566 recent_table_flush(t);
567 spin_unlock_bh(&recent_lock);
568 return size;
569 case '-': /* remove address */
570 add = false;
571 break;
572 case '+': /* add address */
573 add = true;
574 break;
575 default:
576 printk(KERN_INFO KBUILD_MODNAME ": Need +ip, -ip or /\n");
577 return -EINVAL;
578 }
579
580 ++c;
581 --size;
582 if (strnchr(c, size, ':') != NULL) {
583 family = NFPROTO_IPV6;
584 succ = in6_pton(c, size, (void *)&addr, '\n', NULL);
585 } else {
586 family = NFPROTO_IPV4;
587 succ = in4_pton(c, size, (void *)&addr, '\n', NULL);
588 }
589
590 if (!succ) {
591 printk(KERN_INFO KBUILD_MODNAME ": illegal address written "
592 "to procfs\n");
593 return -EINVAL;
594 }
595
596 spin_lock_bh(&recent_lock);
597 e = recent_entry_lookup(t, &addr, family, 0);
598 if (e == NULL) {
599 if (add)
600 recent_entry_init(t, &addr, family, 0);
601 } else {
602 if (add)
603 recent_entry_update(t, e);
604 else
605 recent_entry_remove(t, e);
606 }
607 spin_unlock_bh(&recent_lock);
608 /* Note we removed one above */
609 *loff += size + 1;
610 return size + 1;
611}
612
613static const struct file_operations recent_mt_fops = {
614 .open = recent_seq_open,
615 .read = seq_read,
616 .write = recent_mt_proc_write,
617 .release = seq_release_private,
618 .owner = THIS_MODULE,
619};
458#endif /* CONFIG_PROC_FS */ 620#endif /* CONFIG_PROC_FS */
459 621
460static struct xt_match recent_mt_reg __read_mostly = { 622static struct xt_match recent_mt_reg[] __read_mostly = {
461 .name = "recent", 623 {
462 .family = AF_INET, 624 .name = "recent",
463 .match = recent_mt, 625 .revision = 0,
464 .matchsize = sizeof(struct ipt_recent_info), 626 .family = NFPROTO_IPV4,
465 .checkentry = recent_mt_check, 627 .match = recent_mt,
466 .destroy = recent_mt_destroy, 628 .matchsize = sizeof(struct xt_recent_mtinfo),
467 .me = THIS_MODULE, 629 .checkentry = recent_mt_check,
630 .destroy = recent_mt_destroy,
631 .me = THIS_MODULE,
632 },
633 {
634 .name = "recent",
635 .revision = 0,
636 .family = NFPROTO_IPV6,
637 .match = recent_mt,
638 .matchsize = sizeof(struct xt_recent_mtinfo),
639 .checkentry = recent_mt_check,
640 .destroy = recent_mt_destroy,
641 .me = THIS_MODULE,
642 },
468}; 643};
469 644
470static int __init recent_mt_init(void) 645static int __init recent_mt_init(void)
@@ -475,26 +650,39 @@ static int __init recent_mt_init(void)
475 return -EINVAL; 650 return -EINVAL;
476 ip_list_hash_size = 1 << fls(ip_list_tot); 651 ip_list_hash_size = 1 << fls(ip_list_tot);
477 652
478 err = xt_register_match(&recent_mt_reg); 653 err = xt_register_matches(recent_mt_reg, ARRAY_SIZE(recent_mt_reg));
479#ifdef CONFIG_PROC_FS 654#ifdef CONFIG_PROC_FS
480 if (err) 655 if (err)
481 return err; 656 return err;
482 proc_dir = proc_mkdir("ipt_recent", init_net.proc_net); 657 recent_proc_dir = proc_mkdir("xt_recent", init_net.proc_net);
483 if (proc_dir == NULL) { 658 if (recent_proc_dir == NULL) {
484 xt_unregister_match(&recent_mt_reg); 659 xt_unregister_matches(recent_mt_reg, ARRAY_SIZE(recent_mt_reg));
660 err = -ENOMEM;
661 }
662#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
663 if (err < 0)
664 return err;
665 proc_old_dir = proc_mkdir("ipt_recent", init_net.proc_net);
666 if (proc_old_dir == NULL) {
667 remove_proc_entry("xt_recent", init_net.proc_net);
668 xt_unregister_matches(recent_mt_reg, ARRAY_SIZE(recent_mt_reg));
485 err = -ENOMEM; 669 err = -ENOMEM;
486 } 670 }
487#endif 671#endif
672#endif
488 return err; 673 return err;
489} 674}
490 675
491static void __exit recent_mt_exit(void) 676static void __exit recent_mt_exit(void)
492{ 677{
493 BUG_ON(!list_empty(&tables)); 678 BUG_ON(!list_empty(&tables));
494 xt_unregister_match(&recent_mt_reg); 679 xt_unregister_matches(recent_mt_reg, ARRAY_SIZE(recent_mt_reg));
495#ifdef CONFIG_PROC_FS 680#ifdef CONFIG_PROC_FS
681#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
496 remove_proc_entry("ipt_recent", init_net.proc_net); 682 remove_proc_entry("ipt_recent", init_net.proc_net);
497#endif 683#endif
684 remove_proc_entry("xt_recent", init_net.proc_net);
685#endif
498} 686}
499 687
500module_init(recent_mt_init); 688module_init(recent_mt_init);
diff --git a/net/netfilter/xt_sctp.c b/net/netfilter/xt_sctp.c
index e6e4681fa047..e223cb43ae8e 100644
--- a/net/netfilter/xt_sctp.c
+++ b/net/netfilter/xt_sctp.c
@@ -117,23 +117,21 @@ match_packet(const struct sk_buff *skb,
117} 117}
118 118
119static bool 119static bool
120sctp_mt(const struct sk_buff *skb, const struct net_device *in, 120sctp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
121 const struct net_device *out, const struct xt_match *match,
122 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
123{ 121{
124 const struct xt_sctp_info *info = matchinfo; 122 const struct xt_sctp_info *info = par->matchinfo;
125 const sctp_sctphdr_t *sh; 123 const sctp_sctphdr_t *sh;
126 sctp_sctphdr_t _sh; 124 sctp_sctphdr_t _sh;
127 125
128 if (offset) { 126 if (par->fragoff != 0) {
129 duprintf("Dropping non-first fragment.. FIXME\n"); 127 duprintf("Dropping non-first fragment.. FIXME\n");
130 return false; 128 return false;
131 } 129 }
132 130
133 sh = skb_header_pointer(skb, protoff, sizeof(_sh), &_sh); 131 sh = skb_header_pointer(skb, par->thoff, sizeof(_sh), &_sh);
134 if (sh == NULL) { 132 if (sh == NULL) {
135 duprintf("Dropping evil TCP offset=0 tinygram.\n"); 133 duprintf("Dropping evil TCP offset=0 tinygram.\n");
136 *hotdrop = true; 134 *par->hotdrop = true;
137 return false; 135 return false;
138 } 136 }
139 duprintf("spt: %d\tdpt: %d\n", ntohs(sh->source), ntohs(sh->dest)); 137 duprintf("spt: %d\tdpt: %d\n", ntohs(sh->source), ntohs(sh->dest));
@@ -144,17 +142,14 @@ sctp_mt(const struct sk_buff *skb, const struct net_device *in,
144 && SCCHECK(ntohs(sh->dest) >= info->dpts[0] 142 && SCCHECK(ntohs(sh->dest) >= info->dpts[0]
145 && ntohs(sh->dest) <= info->dpts[1], 143 && ntohs(sh->dest) <= info->dpts[1],
146 XT_SCTP_DEST_PORTS, info->flags, info->invflags) 144 XT_SCTP_DEST_PORTS, info->flags, info->invflags)
147 && SCCHECK(match_packet(skb, protoff + sizeof (sctp_sctphdr_t), 145 && SCCHECK(match_packet(skb, par->thoff + sizeof(sctp_sctphdr_t),
148 info, hotdrop), 146 info, par->hotdrop),
149 XT_SCTP_CHUNK_TYPES, info->flags, info->invflags); 147 XT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
150} 148}
151 149
152static bool 150static bool sctp_mt_check(const struct xt_mtchk_param *par)
153sctp_mt_check(const char *tablename, const void *inf,
154 const struct xt_match *match, void *matchinfo,
155 unsigned int hook_mask)
156{ 151{
157 const struct xt_sctp_info *info = matchinfo; 152 const struct xt_sctp_info *info = par->matchinfo;
158 153
159 return !(info->flags & ~XT_SCTP_VALID_FLAGS) 154 return !(info->flags & ~XT_SCTP_VALID_FLAGS)
160 && !(info->invflags & ~XT_SCTP_VALID_FLAGS) 155 && !(info->invflags & ~XT_SCTP_VALID_FLAGS)
@@ -169,7 +164,7 @@ sctp_mt_check(const char *tablename, const void *inf,
169static struct xt_match sctp_mt_reg[] __read_mostly = { 164static struct xt_match sctp_mt_reg[] __read_mostly = {
170 { 165 {
171 .name = "sctp", 166 .name = "sctp",
172 .family = AF_INET, 167 .family = NFPROTO_IPV4,
173 .checkentry = sctp_mt_check, 168 .checkentry = sctp_mt_check,
174 .match = sctp_mt, 169 .match = sctp_mt,
175 .matchsize = sizeof(struct xt_sctp_info), 170 .matchsize = sizeof(struct xt_sctp_info),
@@ -178,7 +173,7 @@ static struct xt_match sctp_mt_reg[] __read_mostly = {
178 }, 173 },
179 { 174 {
180 .name = "sctp", 175 .name = "sctp",
181 .family = AF_INET6, 176 .family = NFPROTO_IPV6,
182 .checkentry = sctp_mt_check, 177 .checkentry = sctp_mt_check,
183 .match = sctp_mt, 178 .match = sctp_mt,
184 .matchsize = sizeof(struct xt_sctp_info), 179 .matchsize = sizeof(struct xt_sctp_info),
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c
new file mode 100644
index 000000000000..02a8fed21082
--- /dev/null
+++ b/net/netfilter/xt_socket.c
@@ -0,0 +1,185 @@
1/*
2 * Transparent proxy support for Linux/iptables
3 *
4 * Copyright (C) 2007-2008 BalaBit IT Ltd.
5 * Author: Krisztian Kovacs
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/skbuff.h>
15#include <linux/netfilter/x_tables.h>
16#include <linux/netfilter_ipv4/ip_tables.h>
17#include <net/tcp.h>
18#include <net/udp.h>
19#include <net/icmp.h>
20#include <net/sock.h>
21#include <net/inet_sock.h>
22#include <net/netfilter/nf_tproxy_core.h>
23#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
24
25#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
26#define XT_SOCKET_HAVE_CONNTRACK 1
27#include <net/netfilter/nf_conntrack.h>
28#endif
29
30static int
31extract_icmp_fields(const struct sk_buff *skb,
32 u8 *protocol,
33 __be32 *raddr,
34 __be32 *laddr,
35 __be16 *rport,
36 __be16 *lport)
37{
38 unsigned int outside_hdrlen = ip_hdrlen(skb);
39 struct iphdr *inside_iph, _inside_iph;
40 struct icmphdr *icmph, _icmph;
41 __be16 *ports, _ports[2];
42
43 icmph = skb_header_pointer(skb, outside_hdrlen,
44 sizeof(_icmph), &_icmph);
45 if (icmph == NULL)
46 return 1;
47
48 switch (icmph->type) {
49 case ICMP_DEST_UNREACH:
50 case ICMP_SOURCE_QUENCH:
51 case ICMP_REDIRECT:
52 case ICMP_TIME_EXCEEDED:
53 case ICMP_PARAMETERPROB:
54 break;
55 default:
56 return 1;
57 }
58
59 inside_iph = skb_header_pointer(skb, outside_hdrlen +
60 sizeof(struct icmphdr),
61 sizeof(_inside_iph), &_inside_iph);
62 if (inside_iph == NULL)
63 return 1;
64
65 if (inside_iph->protocol != IPPROTO_TCP &&
66 inside_iph->protocol != IPPROTO_UDP)
67 return 1;
68
69 ports = skb_header_pointer(skb, outside_hdrlen +
70 sizeof(struct icmphdr) +
71 (inside_iph->ihl << 2),
72 sizeof(_ports), &_ports);
73 if (ports == NULL)
74 return 1;
75
76 /* the inside IP packet is the one quoted from our side, thus
77 * its saddr is the local address */
78 *protocol = inside_iph->protocol;
79 *laddr = inside_iph->saddr;
80 *lport = ports[0];
81 *raddr = inside_iph->daddr;
82 *rport = ports[1];
83
84 return 0;
85}
86
87
88static bool
89socket_mt(const struct sk_buff *skb, const struct xt_match_param *par)
90{
91 const struct iphdr *iph = ip_hdr(skb);
92 struct udphdr _hdr, *hp = NULL;
93 struct sock *sk;
94 __be32 daddr, saddr;
95 __be16 dport, sport;
96 u8 protocol;
97#ifdef XT_SOCKET_HAVE_CONNTRACK
98 struct nf_conn const *ct;
99 enum ip_conntrack_info ctinfo;
100#endif
101
102 if (iph->protocol == IPPROTO_UDP || iph->protocol == IPPROTO_TCP) {
103 hp = skb_header_pointer(skb, ip_hdrlen(skb),
104 sizeof(_hdr), &_hdr);
105 if (hp == NULL)
106 return false;
107
108 protocol = iph->protocol;
109 saddr = iph->saddr;
110 sport = hp->source;
111 daddr = iph->daddr;
112 dport = hp->dest;
113
114 } else if (iph->protocol == IPPROTO_ICMP) {
115 if (extract_icmp_fields(skb, &protocol, &saddr, &daddr,
116 &sport, &dport))
117 return false;
118 } else {
119 return false;
120 }
121
122#ifdef XT_SOCKET_HAVE_CONNTRACK
123 /* Do the lookup with the original socket address in case this is a
124 * reply packet of an established SNAT-ted connection. */
125
126 ct = nf_ct_get(skb, &ctinfo);
127 if (ct && (ct != &nf_conntrack_untracked) &&
128 ((iph->protocol != IPPROTO_ICMP &&
129 ctinfo == IP_CT_IS_REPLY + IP_CT_ESTABLISHED) ||
130 (iph->protocol == IPPROTO_ICMP &&
131 ctinfo == IP_CT_IS_REPLY + IP_CT_RELATED)) &&
132 (ct->status & IPS_SRC_NAT_DONE)) {
133
134 daddr = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip;
135 dport = (iph->protocol == IPPROTO_TCP) ?
136 ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.tcp.port :
137 ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port;
138 }
139#endif
140
141 sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), protocol,
142 saddr, daddr, sport, dport, par->in, false);
143 if (sk != NULL) {
144 bool wildcard = (inet_sk(sk)->rcv_saddr == 0);
145
146 nf_tproxy_put_sock(sk);
147 if (wildcard)
148 sk = NULL;
149 }
150
151 pr_debug("socket match: proto %u %08x:%u -> %08x:%u "
152 "(orig %08x:%u) sock %p\n",
153 protocol, ntohl(saddr), ntohs(sport),
154 ntohl(daddr), ntohs(dport),
155 ntohl(iph->daddr), hp ? ntohs(hp->dest) : 0, sk);
156
157 return (sk != NULL);
158}
159
160static struct xt_match socket_mt_reg __read_mostly = {
161 .name = "socket",
162 .family = AF_INET,
163 .match = socket_mt,
164 .hooks = 1 << NF_INET_PRE_ROUTING,
165 .me = THIS_MODULE,
166};
167
168static int __init socket_mt_init(void)
169{
170 nf_defrag_ipv4_enable();
171 return xt_register_match(&socket_mt_reg);
172}
173
174static void __exit socket_mt_exit(void)
175{
176 xt_unregister_match(&socket_mt_reg);
177}
178
179module_init(socket_mt_init);
180module_exit(socket_mt_exit);
181
182MODULE_LICENSE("GPL");
183MODULE_AUTHOR("Krisztian Kovacs, Balazs Scheidler");
184MODULE_DESCRIPTION("x_tables socket match module");
185MODULE_ALIAS("ipt_socket");
diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c
index a776dc36a193..4c946cbd731f 100644
--- a/net/netfilter/xt_state.c
+++ b/net/netfilter/xt_state.c
@@ -21,12 +21,9 @@ MODULE_ALIAS("ipt_state");
21MODULE_ALIAS("ip6t_state"); 21MODULE_ALIAS("ip6t_state");
22 22
23static bool 23static bool
24state_mt(const struct sk_buff *skb, const struct net_device *in, 24state_mt(const struct sk_buff *skb, const struct xt_match_param *par)
25 const struct net_device *out, const struct xt_match *match,
26 const void *matchinfo, int offset, unsigned int protoff,
27 bool *hotdrop)
28{ 25{
29 const struct xt_state_info *sinfo = matchinfo; 26 const struct xt_state_info *sinfo = par->matchinfo;
30 enum ip_conntrack_info ctinfo; 27 enum ip_conntrack_info ctinfo;
31 unsigned int statebit; 28 unsigned int statebit;
32 29
@@ -40,28 +37,25 @@ state_mt(const struct sk_buff *skb, const struct net_device *in,
40 return (sinfo->statemask & statebit); 37 return (sinfo->statemask & statebit);
41} 38}
42 39
43static bool 40static bool state_mt_check(const struct xt_mtchk_param *par)
44state_mt_check(const char *tablename, const void *inf,
45 const struct xt_match *match, void *matchinfo,
46 unsigned int hook_mask)
47{ 41{
48 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 42 if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
49 printk(KERN_WARNING "can't load conntrack support for " 43 printk(KERN_WARNING "can't load conntrack support for "
50 "proto=%u\n", match->family); 44 "proto=%u\n", par->match->family);
51 return false; 45 return false;
52 } 46 }
53 return true; 47 return true;
54} 48}
55 49
56static void state_mt_destroy(const struct xt_match *match, void *matchinfo) 50static void state_mt_destroy(const struct xt_mtdtor_param *par)
57{ 51{
58 nf_ct_l3proto_module_put(match->family); 52 nf_ct_l3proto_module_put(par->match->family);
59} 53}
60 54
61static struct xt_match state_mt_reg[] __read_mostly = { 55static struct xt_match state_mt_reg[] __read_mostly = {
62 { 56 {
63 .name = "state", 57 .name = "state",
64 .family = AF_INET, 58 .family = NFPROTO_IPV4,
65 .checkentry = state_mt_check, 59 .checkentry = state_mt_check,
66 .match = state_mt, 60 .match = state_mt,
67 .destroy = state_mt_destroy, 61 .destroy = state_mt_destroy,
@@ -70,7 +64,7 @@ static struct xt_match state_mt_reg[] __read_mostly = {
70 }, 64 },
71 { 65 {
72 .name = "state", 66 .name = "state",
73 .family = AF_INET6, 67 .family = NFPROTO_IPV6,
74 .checkentry = state_mt_check, 68 .checkentry = state_mt_check,
75 .match = state_mt, 69 .match = state_mt,
76 .destroy = state_mt_destroy, 70 .destroy = state_mt_destroy,
diff --git a/net/netfilter/xt_statistic.c b/net/netfilter/xt_statistic.c
index 43133080da7d..0d75141139d5 100644
--- a/net/netfilter/xt_statistic.c
+++ b/net/netfilter/xt_statistic.c
@@ -25,12 +25,9 @@ MODULE_ALIAS("ip6t_statistic");
25static DEFINE_SPINLOCK(nth_lock); 25static DEFINE_SPINLOCK(nth_lock);
26 26
27static bool 27static bool
28statistic_mt(const struct sk_buff *skb, const struct net_device *in, 28statistic_mt(const struct sk_buff *skb, const struct xt_match_param *par)
29 const struct net_device *out, const struct xt_match *match,
30 const void *matchinfo, int offset, unsigned int protoff,
31 bool *hotdrop)
32{ 29{
33 struct xt_statistic_info *info = (struct xt_statistic_info *)matchinfo; 30 struct xt_statistic_info *info = (void *)par->matchinfo;
34 bool ret = info->flags & XT_STATISTIC_INVERT; 31 bool ret = info->flags & XT_STATISTIC_INVERT;
35 32
36 switch (info->mode) { 33 switch (info->mode) {
@@ -52,12 +49,9 @@ statistic_mt(const struct sk_buff *skb, const struct net_device *in,
52 return ret; 49 return ret;
53} 50}
54 51
55static bool 52static bool statistic_mt_check(const struct xt_mtchk_param *par)
56statistic_mt_check(const char *tablename, const void *entry,
57 const struct xt_match *match, void *matchinfo,
58 unsigned int hook_mask)
59{ 53{
60 struct xt_statistic_info *info = matchinfo; 54 struct xt_statistic_info *info = par->matchinfo;
61 55
62 if (info->mode > XT_STATISTIC_MODE_MAX || 56 if (info->mode > XT_STATISTIC_MODE_MAX ||
63 info->flags & ~XT_STATISTIC_MASK) 57 info->flags & ~XT_STATISTIC_MASK)
@@ -66,35 +60,24 @@ statistic_mt_check(const char *tablename, const void *entry,
66 return true; 60 return true;
67} 61}
68 62
69static struct xt_match statistic_mt_reg[] __read_mostly = { 63static struct xt_match xt_statistic_mt_reg __read_mostly = {
70 { 64 .name = "statistic",
71 .name = "statistic", 65 .revision = 0,
72 .family = AF_INET, 66 .family = NFPROTO_UNSPEC,
73 .checkentry = statistic_mt_check, 67 .match = statistic_mt,
74 .match = statistic_mt, 68 .checkentry = statistic_mt_check,
75 .matchsize = sizeof(struct xt_statistic_info), 69 .matchsize = sizeof(struct xt_statistic_info),
76 .me = THIS_MODULE, 70 .me = THIS_MODULE,
77 },
78 {
79 .name = "statistic",
80 .family = AF_INET6,
81 .checkentry = statistic_mt_check,
82 .match = statistic_mt,
83 .matchsize = sizeof(struct xt_statistic_info),
84 .me = THIS_MODULE,
85 },
86}; 71};
87 72
88static int __init statistic_mt_init(void) 73static int __init statistic_mt_init(void)
89{ 74{
90 return xt_register_matches(statistic_mt_reg, 75 return xt_register_match(&xt_statistic_mt_reg);
91 ARRAY_SIZE(statistic_mt_reg));
92} 76}
93 77
94static void __exit statistic_mt_exit(void) 78static void __exit statistic_mt_exit(void)
95{ 79{
96 xt_unregister_matches(statistic_mt_reg, 80 xt_unregister_match(&xt_statistic_mt_reg);
97 ARRAY_SIZE(statistic_mt_reg));
98} 81}
99 82
100module_init(statistic_mt_init); 83module_init(statistic_mt_init);
diff --git a/net/netfilter/xt_string.c b/net/netfilter/xt_string.c
index 4903182a062b..b4d774111311 100644
--- a/net/netfilter/xt_string.c
+++ b/net/netfilter/xt_string.c
@@ -22,18 +22,15 @@ MODULE_ALIAS("ipt_string");
22MODULE_ALIAS("ip6t_string"); 22MODULE_ALIAS("ip6t_string");
23 23
24static bool 24static bool
25string_mt(const struct sk_buff *skb, const struct net_device *in, 25string_mt(const struct sk_buff *skb, const struct xt_match_param *par)
26 const struct net_device *out, const struct xt_match *match,
27 const void *matchinfo, int offset, unsigned int protoff,
28 bool *hotdrop)
29{ 26{
30 const struct xt_string_info *conf = matchinfo; 27 const struct xt_string_info *conf = par->matchinfo;
31 struct ts_state state; 28 struct ts_state state;
32 int invert; 29 int invert;
33 30
34 memset(&state, 0, sizeof(struct ts_state)); 31 memset(&state, 0, sizeof(struct ts_state));
35 32
36 invert = (match->revision == 0 ? conf->u.v0.invert : 33 invert = (par->match->revision == 0 ? conf->u.v0.invert :
37 conf->u.v1.flags & XT_STRING_FLAG_INVERT); 34 conf->u.v1.flags & XT_STRING_FLAG_INVERT);
38 35
39 return (skb_find_text((struct sk_buff *)skb, conf->from_offset, 36 return (skb_find_text((struct sk_buff *)skb, conf->from_offset,
@@ -43,12 +40,9 @@ string_mt(const struct sk_buff *skb, const struct net_device *in,
43 40
44#define STRING_TEXT_PRIV(m) ((struct xt_string_info *)(m)) 41#define STRING_TEXT_PRIV(m) ((struct xt_string_info *)(m))
45 42
46static bool 43static bool string_mt_check(const struct xt_mtchk_param *par)
47string_mt_check(const char *tablename, const void *ip,
48 const struct xt_match *match, void *matchinfo,
49 unsigned int hook_mask)
50{ 44{
51 struct xt_string_info *conf = matchinfo; 45 struct xt_string_info *conf = par->matchinfo;
52 struct ts_config *ts_conf; 46 struct ts_config *ts_conf;
53 int flags = TS_AUTOLOAD; 47 int flags = TS_AUTOLOAD;
54 48
@@ -59,7 +53,7 @@ string_mt_check(const char *tablename, const void *ip,
59 return false; 53 return false;
60 if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE) 54 if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE)
61 return false; 55 return false;
62 if (match->revision == 1) { 56 if (par->match->revision == 1) {
63 if (conf->u.v1.flags & 57 if (conf->u.v1.flags &
64 ~(XT_STRING_FLAG_IGNORECASE | XT_STRING_FLAG_INVERT)) 58 ~(XT_STRING_FLAG_IGNORECASE | XT_STRING_FLAG_INVERT))
65 return false; 59 return false;
@@ -76,36 +70,16 @@ string_mt_check(const char *tablename, const void *ip,
76 return true; 70 return true;
77} 71}
78 72
79static void string_mt_destroy(const struct xt_match *match, void *matchinfo) 73static void string_mt_destroy(const struct xt_mtdtor_param *par)
80{ 74{
81 textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config); 75 textsearch_destroy(STRING_TEXT_PRIV(par->matchinfo)->config);
82} 76}
83 77
84static struct xt_match string_mt_reg[] __read_mostly = { 78static struct xt_match xt_string_mt_reg[] __read_mostly = {
85 {
86 .name = "string",
87 .revision = 0,
88 .family = AF_INET,
89 .checkentry = string_mt_check,
90 .match = string_mt,
91 .destroy = string_mt_destroy,
92 .matchsize = sizeof(struct xt_string_info),
93 .me = THIS_MODULE
94 },
95 {
96 .name = "string",
97 .revision = 1,
98 .family = AF_INET,
99 .checkentry = string_mt_check,
100 .match = string_mt,
101 .destroy = string_mt_destroy,
102 .matchsize = sizeof(struct xt_string_info),
103 .me = THIS_MODULE
104 },
105 { 79 {
106 .name = "string", 80 .name = "string",
107 .revision = 0, 81 .revision = 0,
108 .family = AF_INET6, 82 .family = NFPROTO_UNSPEC,
109 .checkentry = string_mt_check, 83 .checkentry = string_mt_check,
110 .match = string_mt, 84 .match = string_mt,
111 .destroy = string_mt_destroy, 85 .destroy = string_mt_destroy,
@@ -115,7 +89,7 @@ static struct xt_match string_mt_reg[] __read_mostly = {
115 { 89 {
116 .name = "string", 90 .name = "string",
117 .revision = 1, 91 .revision = 1,
118 .family = AF_INET6, 92 .family = NFPROTO_UNSPEC,
119 .checkentry = string_mt_check, 93 .checkentry = string_mt_check,
120 .match = string_mt, 94 .match = string_mt,
121 .destroy = string_mt_destroy, 95 .destroy = string_mt_destroy,
@@ -126,12 +100,13 @@ static struct xt_match string_mt_reg[] __read_mostly = {
126 100
127static int __init string_mt_init(void) 101static int __init string_mt_init(void)
128{ 102{
129 return xt_register_matches(string_mt_reg, ARRAY_SIZE(string_mt_reg)); 103 return xt_register_matches(xt_string_mt_reg,
104 ARRAY_SIZE(xt_string_mt_reg));
130} 105}
131 106
132static void __exit string_mt_exit(void) 107static void __exit string_mt_exit(void)
133{ 108{
134 xt_unregister_matches(string_mt_reg, ARRAY_SIZE(string_mt_reg)); 109 xt_unregister_matches(xt_string_mt_reg, ARRAY_SIZE(xt_string_mt_reg));
135} 110}
136 111
137module_init(string_mt_init); 112module_init(string_mt_init);
diff --git a/net/netfilter/xt_tcpmss.c b/net/netfilter/xt_tcpmss.c
index 6771bf01275b..4809b34b10f8 100644
--- a/net/netfilter/xt_tcpmss.c
+++ b/net/netfilter/xt_tcpmss.c
@@ -25,12 +25,9 @@ MODULE_ALIAS("ipt_tcpmss");
25MODULE_ALIAS("ip6t_tcpmss"); 25MODULE_ALIAS("ip6t_tcpmss");
26 26
27static bool 27static bool
28tcpmss_mt(const struct sk_buff *skb, const struct net_device *in, 28tcpmss_mt(const struct sk_buff *skb, const struct xt_match_param *par)
29 const struct net_device *out, const struct xt_match *match,
30 const void *matchinfo, int offset, unsigned int protoff,
31 bool *hotdrop)
32{ 29{
33 const struct xt_tcpmss_match_info *info = matchinfo; 30 const struct xt_tcpmss_match_info *info = par->matchinfo;
34 const struct tcphdr *th; 31 const struct tcphdr *th;
35 struct tcphdr _tcph; 32 struct tcphdr _tcph;
36 /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 33 /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
@@ -39,7 +36,7 @@ tcpmss_mt(const struct sk_buff *skb, const struct net_device *in,
39 unsigned int i, optlen; 36 unsigned int i, optlen;
40 37
41 /* If we don't have the whole header, drop packet. */ 38 /* If we don't have the whole header, drop packet. */
42 th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); 39 th = skb_header_pointer(skb, par->thoff, sizeof(_tcph), &_tcph);
43 if (th == NULL) 40 if (th == NULL)
44 goto dropit; 41 goto dropit;
45 42
@@ -52,7 +49,7 @@ tcpmss_mt(const struct sk_buff *skb, const struct net_device *in,
52 goto out; 49 goto out;
53 50
54 /* Truncated options. */ 51 /* Truncated options. */
55 op = skb_header_pointer(skb, protoff + sizeof(*th), optlen, _opt); 52 op = skb_header_pointer(skb, par->thoff + sizeof(*th), optlen, _opt);
56 if (op == NULL) 53 if (op == NULL)
57 goto dropit; 54 goto dropit;
58 55
@@ -76,14 +73,14 @@ out:
76 return info->invert; 73 return info->invert;
77 74
78dropit: 75dropit:
79 *hotdrop = true; 76 *par->hotdrop = true;
80 return false; 77 return false;
81} 78}
82 79
83static struct xt_match tcpmss_mt_reg[] __read_mostly = { 80static struct xt_match tcpmss_mt_reg[] __read_mostly = {
84 { 81 {
85 .name = "tcpmss", 82 .name = "tcpmss",
86 .family = AF_INET, 83 .family = NFPROTO_IPV4,
87 .match = tcpmss_mt, 84 .match = tcpmss_mt,
88 .matchsize = sizeof(struct xt_tcpmss_match_info), 85 .matchsize = sizeof(struct xt_tcpmss_match_info),
89 .proto = IPPROTO_TCP, 86 .proto = IPPROTO_TCP,
@@ -91,7 +88,7 @@ static struct xt_match tcpmss_mt_reg[] __read_mostly = {
91 }, 88 },
92 { 89 {
93 .name = "tcpmss", 90 .name = "tcpmss",
94 .family = AF_INET6, 91 .family = NFPROTO_IPV6,
95 .match = tcpmss_mt, 92 .match = tcpmss_mt,
96 .matchsize = sizeof(struct xt_tcpmss_match_info), 93 .matchsize = sizeof(struct xt_tcpmss_match_info),
97 .proto = IPPROTO_TCP, 94 .proto = IPPROTO_TCP,
diff --git a/net/netfilter/xt_tcpudp.c b/net/netfilter/xt_tcpudp.c
index 951b06b8d701..1ebdc4934eed 100644
--- a/net/netfilter/xt_tcpudp.c
+++ b/net/netfilter/xt_tcpudp.c
@@ -68,25 +68,22 @@ tcp_find_option(u_int8_t option,
68 return invert; 68 return invert;
69} 69}
70 70
71static bool 71static bool tcp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
72tcp_mt(const struct sk_buff *skb, const struct net_device *in,
73 const struct net_device *out, const struct xt_match *match,
74 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
75{ 72{
76 const struct tcphdr *th; 73 const struct tcphdr *th;
77 struct tcphdr _tcph; 74 struct tcphdr _tcph;
78 const struct xt_tcp *tcpinfo = matchinfo; 75 const struct xt_tcp *tcpinfo = par->matchinfo;
79 76
80 if (offset) { 77 if (par->fragoff != 0) {
81 /* To quote Alan: 78 /* To quote Alan:
82 79
83 Don't allow a fragment of TCP 8 bytes in. Nobody normal 80 Don't allow a fragment of TCP 8 bytes in. Nobody normal
84 causes this. Its a cracker trying to break in by doing a 81 causes this. Its a cracker trying to break in by doing a
85 flag overwrite to pass the direction checks. 82 flag overwrite to pass the direction checks.
86 */ 83 */
87 if (offset == 1) { 84 if (par->fragoff == 1) {
88 duprintf("Dropping evil TCP offset=1 frag.\n"); 85 duprintf("Dropping evil TCP offset=1 frag.\n");
89 *hotdrop = true; 86 *par->hotdrop = true;
90 } 87 }
91 /* Must not be a fragment. */ 88 /* Must not be a fragment. */
92 return false; 89 return false;
@@ -94,12 +91,12 @@ tcp_mt(const struct sk_buff *skb, const struct net_device *in,
94 91
95#define FWINVTCP(bool, invflg) ((bool) ^ !!(tcpinfo->invflags & (invflg))) 92#define FWINVTCP(bool, invflg) ((bool) ^ !!(tcpinfo->invflags & (invflg)))
96 93
97 th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); 94 th = skb_header_pointer(skb, par->thoff, sizeof(_tcph), &_tcph);
98 if (th == NULL) { 95 if (th == NULL) {
99 /* We've been asked to examine this packet, and we 96 /* We've been asked to examine this packet, and we
100 can't. Hence, no choice but to drop. */ 97 can't. Hence, no choice but to drop. */
101 duprintf("Dropping evil TCP offset=0 tinygram.\n"); 98 duprintf("Dropping evil TCP offset=0 tinygram.\n");
102 *hotdrop = true; 99 *par->hotdrop = true;
103 return false; 100 return false;
104 } 101 }
105 102
@@ -117,49 +114,42 @@ tcp_mt(const struct sk_buff *skb, const struct net_device *in,
117 return false; 114 return false;
118 if (tcpinfo->option) { 115 if (tcpinfo->option) {
119 if (th->doff * 4 < sizeof(_tcph)) { 116 if (th->doff * 4 < sizeof(_tcph)) {
120 *hotdrop = true; 117 *par->hotdrop = true;
121 return false; 118 return false;
122 } 119 }
123 if (!tcp_find_option(tcpinfo->option, skb, protoff, 120 if (!tcp_find_option(tcpinfo->option, skb, par->thoff,
124 th->doff*4 - sizeof(_tcph), 121 th->doff*4 - sizeof(_tcph),
125 tcpinfo->invflags & XT_TCP_INV_OPTION, 122 tcpinfo->invflags & XT_TCP_INV_OPTION,
126 hotdrop)) 123 par->hotdrop))
127 return false; 124 return false;
128 } 125 }
129 return true; 126 return true;
130} 127}
131 128
132/* Called when user tries to insert an entry of this type. */ 129static bool tcp_mt_check(const struct xt_mtchk_param *par)
133static bool
134tcp_mt_check(const char *tablename, const void *info,
135 const struct xt_match *match, void *matchinfo,
136 unsigned int hook_mask)
137{ 130{
138 const struct xt_tcp *tcpinfo = matchinfo; 131 const struct xt_tcp *tcpinfo = par->matchinfo;
139 132
140 /* Must specify no unknown invflags */ 133 /* Must specify no unknown invflags */
141 return !(tcpinfo->invflags & ~XT_TCP_INV_MASK); 134 return !(tcpinfo->invflags & ~XT_TCP_INV_MASK);
142} 135}
143 136
144static bool 137static bool udp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
145udp_mt(const struct sk_buff *skb, const struct net_device *in,
146 const struct net_device *out, const struct xt_match *match,
147 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
148{ 138{
149 const struct udphdr *uh; 139 const struct udphdr *uh;
150 struct udphdr _udph; 140 struct udphdr _udph;
151 const struct xt_udp *udpinfo = matchinfo; 141 const struct xt_udp *udpinfo = par->matchinfo;
152 142
153 /* Must not be a fragment. */ 143 /* Must not be a fragment. */
154 if (offset) 144 if (par->fragoff != 0)
155 return false; 145 return false;
156 146
157 uh = skb_header_pointer(skb, protoff, sizeof(_udph), &_udph); 147 uh = skb_header_pointer(skb, par->thoff, sizeof(_udph), &_udph);
158 if (uh == NULL) { 148 if (uh == NULL) {
159 /* We've been asked to examine this packet, and we 149 /* We've been asked to examine this packet, and we
160 can't. Hence, no choice but to drop. */ 150 can't. Hence, no choice but to drop. */
161 duprintf("Dropping evil UDP tinygram.\n"); 151 duprintf("Dropping evil UDP tinygram.\n");
162 *hotdrop = true; 152 *par->hotdrop = true;
163 return false; 153 return false;
164 } 154 }
165 155
@@ -171,13 +161,9 @@ udp_mt(const struct sk_buff *skb, const struct net_device *in,
171 !!(udpinfo->invflags & XT_UDP_INV_DSTPT)); 161 !!(udpinfo->invflags & XT_UDP_INV_DSTPT));
172} 162}
173 163
174/* Called when user tries to insert an entry of this type. */ 164static bool udp_mt_check(const struct xt_mtchk_param *par)
175static bool
176udp_mt_check(const char *tablename, const void *info,
177 const struct xt_match *match, void *matchinfo,
178 unsigned int hook_mask)
179{ 165{
180 const struct xt_udp *udpinfo = matchinfo; 166 const struct xt_udp *udpinfo = par->matchinfo;
181 167
182 /* Must specify no unknown invflags */ 168 /* Must specify no unknown invflags */
183 return !(udpinfo->invflags & ~XT_UDP_INV_MASK); 169 return !(udpinfo->invflags & ~XT_UDP_INV_MASK);
@@ -186,7 +172,7 @@ udp_mt_check(const char *tablename, const void *info,
186static struct xt_match tcpudp_mt_reg[] __read_mostly = { 172static struct xt_match tcpudp_mt_reg[] __read_mostly = {
187 { 173 {
188 .name = "tcp", 174 .name = "tcp",
189 .family = AF_INET, 175 .family = NFPROTO_IPV4,
190 .checkentry = tcp_mt_check, 176 .checkentry = tcp_mt_check,
191 .match = tcp_mt, 177 .match = tcp_mt,
192 .matchsize = sizeof(struct xt_tcp), 178 .matchsize = sizeof(struct xt_tcp),
@@ -195,7 +181,7 @@ static struct xt_match tcpudp_mt_reg[] __read_mostly = {
195 }, 181 },
196 { 182 {
197 .name = "tcp", 183 .name = "tcp",
198 .family = AF_INET6, 184 .family = NFPROTO_IPV6,
199 .checkentry = tcp_mt_check, 185 .checkentry = tcp_mt_check,
200 .match = tcp_mt, 186 .match = tcp_mt,
201 .matchsize = sizeof(struct xt_tcp), 187 .matchsize = sizeof(struct xt_tcp),
@@ -204,7 +190,7 @@ static struct xt_match tcpudp_mt_reg[] __read_mostly = {
204 }, 190 },
205 { 191 {
206 .name = "udp", 192 .name = "udp",
207 .family = AF_INET, 193 .family = NFPROTO_IPV4,
208 .checkentry = udp_mt_check, 194 .checkentry = udp_mt_check,
209 .match = udp_mt, 195 .match = udp_mt,
210 .matchsize = sizeof(struct xt_udp), 196 .matchsize = sizeof(struct xt_udp),
@@ -213,7 +199,7 @@ static struct xt_match tcpudp_mt_reg[] __read_mostly = {
213 }, 199 },
214 { 200 {
215 .name = "udp", 201 .name = "udp",
216 .family = AF_INET6, 202 .family = NFPROTO_IPV6,
217 .checkentry = udp_mt_check, 203 .checkentry = udp_mt_check,
218 .match = udp_mt, 204 .match = udp_mt,
219 .matchsize = sizeof(struct xt_udp), 205 .matchsize = sizeof(struct xt_udp),
@@ -222,7 +208,7 @@ static struct xt_match tcpudp_mt_reg[] __read_mostly = {
222 }, 208 },
223 { 209 {
224 .name = "udplite", 210 .name = "udplite",
225 .family = AF_INET, 211 .family = NFPROTO_IPV4,
226 .checkentry = udp_mt_check, 212 .checkentry = udp_mt_check,
227 .match = udp_mt, 213 .match = udp_mt,
228 .matchsize = sizeof(struct xt_udp), 214 .matchsize = sizeof(struct xt_udp),
@@ -231,7 +217,7 @@ static struct xt_match tcpudp_mt_reg[] __read_mostly = {
231 }, 217 },
232 { 218 {
233 .name = "udplite", 219 .name = "udplite",
234 .family = AF_INET6, 220 .family = NFPROTO_IPV6,
235 .checkentry = udp_mt_check, 221 .checkentry = udp_mt_check,
236 .match = udp_mt, 222 .match = udp_mt,
237 .matchsize = sizeof(struct xt_udp), 223 .matchsize = sizeof(struct xt_udp),
diff --git a/net/netfilter/xt_time.c b/net/netfilter/xt_time.c
index 307a2c3c2df4..29375ba8db73 100644
--- a/net/netfilter/xt_time.c
+++ b/net/netfilter/xt_time.c
@@ -153,11 +153,9 @@ static void localtime_3(struct xtm *r, time_t time)
153} 153}
154 154
155static bool 155static bool
156time_mt(const struct sk_buff *skb, const struct net_device *in, 156time_mt(const struct sk_buff *skb, const struct xt_match_param *par)
157 const struct net_device *out, const struct xt_match *match,
158 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
159{ 157{
160 const struct xt_time_info *info = matchinfo; 158 const struct xt_time_info *info = par->matchinfo;
161 unsigned int packet_time; 159 unsigned int packet_time;
162 struct xtm current_time; 160 struct xtm current_time;
163 s64 stamp; 161 s64 stamp;
@@ -220,12 +218,9 @@ time_mt(const struct sk_buff *skb, const struct net_device *in,
220 return true; 218 return true;
221} 219}
222 220
223static bool 221static bool time_mt_check(const struct xt_mtchk_param *par)
224time_mt_check(const char *tablename, const void *ip,
225 const struct xt_match *match, void *matchinfo,
226 unsigned int hook_mask)
227{ 222{
228 const struct xt_time_info *info = matchinfo; 223 const struct xt_time_info *info = par->matchinfo;
229 224
230 if (info->daytime_start > XT_TIME_MAX_DAYTIME || 225 if (info->daytime_start > XT_TIME_MAX_DAYTIME ||
231 info->daytime_stop > XT_TIME_MAX_DAYTIME) { 226 info->daytime_stop > XT_TIME_MAX_DAYTIME) {
@@ -237,33 +232,23 @@ time_mt_check(const char *tablename, const void *ip,
237 return true; 232 return true;
238} 233}
239 234
240static struct xt_match time_mt_reg[] __read_mostly = { 235static struct xt_match xt_time_mt_reg __read_mostly = {
241 { 236 .name = "time",
242 .name = "time", 237 .family = NFPROTO_UNSPEC,
243 .family = AF_INET, 238 .match = time_mt,
244 .match = time_mt, 239 .checkentry = time_mt_check,
245 .matchsize = sizeof(struct xt_time_info), 240 .matchsize = sizeof(struct xt_time_info),
246 .checkentry = time_mt_check, 241 .me = THIS_MODULE,
247 .me = THIS_MODULE,
248 },
249 {
250 .name = "time",
251 .family = AF_INET6,
252 .match = time_mt,
253 .matchsize = sizeof(struct xt_time_info),
254 .checkentry = time_mt_check,
255 .me = THIS_MODULE,
256 },
257}; 242};
258 243
259static int __init time_mt_init(void) 244static int __init time_mt_init(void)
260{ 245{
261 return xt_register_matches(time_mt_reg, ARRAY_SIZE(time_mt_reg)); 246 return xt_register_match(&xt_time_mt_reg);
262} 247}
263 248
264static void __exit time_mt_exit(void) 249static void __exit time_mt_exit(void)
265{ 250{
266 xt_unregister_matches(time_mt_reg, ARRAY_SIZE(time_mt_reg)); 251 xt_unregister_match(&xt_time_mt_reg);
267} 252}
268 253
269module_init(time_mt_init); 254module_init(time_mt_init);
diff --git a/net/netfilter/xt_u32.c b/net/netfilter/xt_u32.c
index 627e0f336d54..24a527624500 100644
--- a/net/netfilter/xt_u32.c
+++ b/net/netfilter/xt_u32.c
@@ -87,43 +87,32 @@ static bool u32_match_it(const struct xt_u32 *data,
87 return true; 87 return true;
88} 88}
89 89
90static bool 90static bool u32_mt(const struct sk_buff *skb, const struct xt_match_param *par)
91u32_mt(const struct sk_buff *skb, const struct net_device *in,
92 const struct net_device *out, const struct xt_match *match,
93 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
94{ 91{
95 const struct xt_u32 *data = matchinfo; 92 const struct xt_u32 *data = par->matchinfo;
96 bool ret; 93 bool ret;
97 94
98 ret = u32_match_it(data, skb); 95 ret = u32_match_it(data, skb);
99 return ret ^ data->invert; 96 return ret ^ data->invert;
100} 97}
101 98
102static struct xt_match u32_mt_reg[] __read_mostly = { 99static struct xt_match xt_u32_mt_reg __read_mostly = {
103 { 100 .name = "u32",
104 .name = "u32", 101 .revision = 0,
105 .family = AF_INET, 102 .family = NFPROTO_UNSPEC,
106 .match = u32_mt, 103 .match = u32_mt,
107 .matchsize = sizeof(struct xt_u32), 104 .matchsize = sizeof(struct xt_u32),
108 .me = THIS_MODULE, 105 .me = THIS_MODULE,
109 },
110 {
111 .name = "u32",
112 .family = AF_INET6,
113 .match = u32_mt,
114 .matchsize = sizeof(struct xt_u32),
115 .me = THIS_MODULE,
116 },
117}; 106};
118 107
119static int __init u32_mt_init(void) 108static int __init u32_mt_init(void)
120{ 109{
121 return xt_register_matches(u32_mt_reg, ARRAY_SIZE(u32_mt_reg)); 110 return xt_register_match(&xt_u32_mt_reg);
122} 111}
123 112
124static void __exit u32_mt_exit(void) 113static void __exit u32_mt_exit(void)
125{ 114{
126 xt_unregister_matches(u32_mt_reg, ARRAY_SIZE(u32_mt_reg)); 115 xt_unregister_match(&xt_u32_mt_reg);
127} 116}
128 117
129module_init(u32_mt_init); 118module_init(u32_mt_init);
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index d1263b3c96c3..0453d79ebf57 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -40,6 +40,7 @@ static struct tcf_hashinfo ipt_hash_info = {
40 40
41static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook) 41static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook)
42{ 42{
43 struct xt_tgchk_param par;
43 struct xt_target *target; 44 struct xt_target *target;
44 int ret = 0; 45 int ret = 0;
45 46
@@ -49,29 +50,30 @@ static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int
49 return -ENOENT; 50 return -ENOENT;
50 51
51 t->u.kernel.target = target; 52 t->u.kernel.target = target;
52 53 par.table = table;
53 ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), 54 par.entryinfo = NULL;
54 table, hook, 0, 0); 55 par.target = target;
55 if (ret) { 56 par.targinfo = t->data;
57 par.hook_mask = hook;
58 par.family = NFPROTO_IPV4;
59
60 ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false);
61 if (ret < 0) {
56 module_put(t->u.kernel.target->me); 62 module_put(t->u.kernel.target->me);
57 return ret; 63 return ret;
58 } 64 }
59 if (t->u.kernel.target->checkentry 65 return 0;
60 && !t->u.kernel.target->checkentry(table, NULL,
61 t->u.kernel.target, t->data,
62 hook)) {
63 module_put(t->u.kernel.target->me);
64 ret = -EINVAL;
65 }
66
67 return ret;
68} 66}
69 67
70static void ipt_destroy_target(struct ipt_entry_target *t) 68static void ipt_destroy_target(struct ipt_entry_target *t)
71{ 69{
72 if (t->u.kernel.target->destroy) 70 struct xt_tgdtor_param par = {
73 t->u.kernel.target->destroy(t->u.kernel.target, t->data); 71 .target = t->u.kernel.target,
74 module_put(t->u.kernel.target->me); 72 .targinfo = t->data,
73 };
74 if (par.target->destroy != NULL)
75 par.target->destroy(&par);
76 module_put(par.target->me);
75} 77}
76 78
77static int tcf_ipt_release(struct tcf_ipt *ipt, int bind) 79static int tcf_ipt_release(struct tcf_ipt *ipt, int bind)
@@ -196,6 +198,7 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a,
196{ 198{
197 int ret = 0, result = 0; 199 int ret = 0, result = 0;
198 struct tcf_ipt *ipt = a->priv; 200 struct tcf_ipt *ipt = a->priv;
201 struct xt_target_param par;
199 202
200 if (skb_cloned(skb)) { 203 if (skb_cloned(skb)) {
201 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) 204 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
@@ -211,10 +214,13 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a,
211 /* yes, we have to worry about both in and out dev 214 /* yes, we have to worry about both in and out dev
212 worry later - danger - this API seems to have changed 215 worry later - danger - this API seems to have changed
213 from earlier kernels */ 216 from earlier kernels */
214 ret = ipt->tcfi_t->u.kernel.target->target(skb, skb->dev, NULL, 217 par.in = skb->dev;
215 ipt->tcfi_hook, 218 par.out = NULL;
216 ipt->tcfi_t->u.kernel.target, 219 par.hooknum = ipt->tcfi_hook;
217 ipt->tcfi_t->data); 220 par.target = ipt->tcfi_t->u.kernel.target;
221 par.targinfo = ipt->tcfi_t->data;
222 ret = par.target->target(skb, &par);
223
218 switch (ret) { 224 switch (ret) {
219 case NF_ACCEPT: 225 case NF_ACCEPT:
220 result = TC_ACT_OK; 226 result = TC_ACT_OK;