diff options
author | David S. Miller <davem@davemloft.net> | 2008-10-08 12:50:38 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-10-08 12:50:38 -0400 |
commit | 364ae953a48152be11f1aa424cbfd943b7762b0d (patch) | |
tree | 6873b352af1aa2dd6baa223b951eff4d6e74b1ae /net | |
parent | 075f664689b40217539ebfe856fab73d302a15f1 (diff) | |
parent | f39a9410ed0503278fd5edc559fa019051413039 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
Diffstat (limited to 'net')
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 | ||
5 | menu "Bridge: Netfilter Configuration" | 5 | menuconfig BRIDGE_NF_EBTABLES |
6 | depends on BRIDGE && BRIDGE_NETFILTER | ||
7 | |||
8 | config 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 | |||
13 | if BRIDGE_NF_EBTABLES | ||
14 | |||
14 | # | 15 | # |
15 | # tables | 16 | # tables |
16 | # | 17 | # |
17 | config BRIDGE_EBT_BROUTE | 18 | config 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 | ||
28 | config BRIDGE_EBT_T_FILTER | 28 | config 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 | ||
38 | config BRIDGE_EBT_T_NAT | 37 | config 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 | # |
50 | config BRIDGE_EBT_802_3 | 48 | config 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 | ||
58 | config BRIDGE_EBT_AMONG | 55 | config 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 | ||
68 | config BRIDGE_EBT_ARP | 64 | config 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 | ||
77 | config BRIDGE_EBT_IP | 72 | config 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 | ||
95 | config BRIDGE_EBT_LIMIT | 89 | config 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 | ||
106 | config BRIDGE_EBT_MARK | 99 | config 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 | ||
117 | config BRIDGE_EBT_PKTTYPE | 109 | config 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 | ||
128 | config BRIDGE_EBT_STP | 119 | config 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 | ||
137 | config BRIDGE_EBT_VLAN | 127 | config 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 | ||
157 | config BRIDGE_EBT_DNAT | 146 | config 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 | ||
166 | config BRIDGE_EBT_MARK_T | 154 | config 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 | ||
177 | config BRIDGE_EBT_REDIRECT | 164 | config 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 | ||
186 | config BRIDGE_EBT_SNAT | 172 | config 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 | # |
197 | config BRIDGE_EBT_LOG | 182 | config 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 | ||
207 | config BRIDGE_EBT_ULOG | 191 | config 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 | ||
224 | config BRIDGE_EBT_NFLOG | 207 | config 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 | ||
238 | endmenu | 220 | endif # 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 | ||
15 | static int ebt_filter_802_3(const struct sk_buff *skb, const struct net_device *in, | 15 | static bool |
16 | const struct net_device *out, const void *data, unsigned int datalen) | 16 | ebt_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 | ||
39 | static struct ebt_match filter_802_3; | 39 | static bool ebt_802_3_mt_check(const struct xt_mtchk_param *par) |
40 | static 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 | ||
53 | static struct ebt_match filter_802_3 __read_mostly = { | 49 | static 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 | ||
60 | static int __init ebt_802_3_init(void) | 59 | static 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 | ||
65 | static void __exit ebt_802_3_fini(void) | 64 | static 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 | ||
70 | module_init(ebt_802_3_init); | 69 | module_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 | ||
17 | static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh, | 17 | static 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 | ||
55 | static int ebt_mac_wormhash_check_integrity(const struct ebt_mac_wormhash | 51 | static 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 | ||
134 | static int ebt_filter_among(const struct sk_buff *skb, | 130 | static bool |
135 | const struct net_device *in, | 131 | ebt_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 | ||
180 | static int ebt_among_check(const char *tablename, unsigned int hookmask, | 174 | static 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 | ||
215 | static struct ebt_match filter_among __read_mostly = { | 209 | static 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 | ||
222 | static int __init ebt_among_init(void) | 219 | static 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 | ||
227 | static void __exit ebt_among_fini(void) | 224 | static 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 | ||
232 | module_init(ebt_among_init); | 229 | module_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 | ||
18 | static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in, | 18 | static bool |
19 | const struct net_device *out, const void *data, unsigned int datalen) | 19 | ebt_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 | ||
103 | static int ebt_arp_check(const char *tablename, unsigned int hookmask, | 103 | static 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 | ||
119 | static struct ebt_match filter_arp __read_mostly = { | 117 | static 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 | ||
126 | static int __init ebt_arp_init(void) | 127 | static 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 | ||
131 | static void __exit ebt_arp_fini(void) | 132 | static 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 | ||
136 | module_init(ebt_arp_init); | 137 | module_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 | ||
18 | static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr, | 18 | static unsigned int |
19 | const struct net_device *in, const struct net_device *out, | 19 | ebt_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 | ||
61 | static int ebt_target_reply_check(const char *tablename, unsigned int hookmask, | 60 | static 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 | ||
79 | static struct ebt_target reply_target __read_mostly = { | 73 | static 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 | ||
86 | static int __init ebt_arpreply_init(void) | 85 | static 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 | ||
91 | static void __exit ebt_arpreply_fini(void) | 90 | static 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 | ||
96 | module_init(ebt_arpreply_init); | 95 | module_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 | ||
17 | static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr, | 17 | static unsigned int |
18 | const struct net_device *in, const struct net_device *out, | 18 | ebt_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 | ||
30 | static int ebt_target_dnat_check(const char *tablename, unsigned int hookmask, | 29 | static 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 | ||
49 | static struct ebt_target dnat __read_mostly = { | 49 | static 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 | ||
56 | static int __init ebt_dnat_init(void) | 61 | static 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 | ||
61 | static void __exit ebt_dnat_fini(void) | 66 | static 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 | ||
66 | module_init(ebt_dnat_init); | 71 | module_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 | ||
22 | struct tcpudphdr { | 22 | struct tcpudphdr { |
23 | __be16 src; | 23 | __be16 src; |
24 | __be16 dst; | 24 | __be16 dst; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in, | 27 | static bool |
28 | const struct net_device *out, const void *data, | 28 | ebt_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 | ||
81 | static int ebt_ip_check(const char *tablename, unsigned int hookmask, | 80 | static 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 | ||
110 | static struct ebt_match filter_ip __read_mostly = { | 107 | static 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 | ||
117 | static int __init ebt_ip_init(void) | 117 | static 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 | ||
122 | static void __exit ebt_ip_fini(void) | 122 | static 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 | ||
127 | module_init(ebt_ip_init); | 127 | module_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 | ||
25 | struct tcpudphdr { | 25 | struct tcpudphdr { |
26 | __be16 src; | 26 | __be16 src; |
27 | __be16 dst; | 27 | __be16 dst; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | static int ebt_filter_ip6(const struct sk_buff *skb, | 30 | static bool |
31 | const struct net_device *in, | 31 | ebt_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 | ||
95 | static int ebt_ip6_check(const char *tablename, unsigned int hookmask, | 93 | static 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 | ||
123 | static struct ebt_match filter_ip6 = | 119 | static 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 | ||
131 | static int __init ebt_ip6_init(void) | 129 | static 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 | ||
136 | static void __exit ebt_ip6_fini(void) | 134 | static 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 | ||
141 | module_init(ebt_ip6_init); | 139 | module_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 | ||
21 | static DEFINE_SPINLOCK(limit_lock); | 20 | static 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 | ||
34 | static int ebt_limit_match(const struct sk_buff *skb, | 33 | static bool |
35 | const struct net_device *in, const struct net_device *out, | 34 | ebt_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 | ||
69 | static int ebt_limit_check(const char *tablename, unsigned int hookmask, | 67 | static 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 | ||
93 | static struct ebt_match ebt_limit_reg __read_mostly = { | 87 | static 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 | ||
100 | static int __init ebt_limit_init(void) | 97 | static 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 | ||
105 | static void __exit ebt_limit_fini(void) | 102 | static 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 | ||
110 | module_init(ebt_limit_init); | 107 | module_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 | ||
25 | static DEFINE_SPINLOCK(ebt_log_lock); | 25 | static DEFINE_SPINLOCK(ebt_log_lock); |
26 | 26 | ||
27 | static int ebt_log_check(const char *tablename, unsigned int hookmask, | 27 | static 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 | ||
42 | struct tcpudphdr | 39 | struct 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] |
86 | static void | 83 | static void |
87 | ebt_log_packet(unsigned int pf, unsigned int hooknum, | 84 | ebt_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 | ||
197 | static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, | 194 | static unsigned int |
198 | const struct net_device *in, const struct net_device *out, | 195 | ebt_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 | ||
216 | static struct ebt_watcher log = | 213 | static 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 | ||
241 | static void __exit ebt_log_fini(void) | 240 | static 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 | ||
247 | module_init(ebt_log_init); | 246 | module_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 | ||
20 | static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr, | 21 | static unsigned int |
21 | const struct net_device *in, const struct net_device *out, | 22 | ebt_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 | ||
39 | static int ebt_target_mark_check(const char *tablename, unsigned int hookmask, | 39 | static 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 | ||
60 | static struct ebt_target mark_target __read_mostly = { | 56 | static 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 | ||
67 | static int __init ebt_mark_init(void) | 66 | static 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 | ||
72 | static void __exit ebt_mark_fini(void) | 71 | static 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 | ||
77 | module_init(ebt_mark_init); | 76 | module_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 | ||
15 | static int ebt_filter_mark(const struct sk_buff *skb, | 15 | static bool |
16 | const struct net_device *in, const struct net_device *out, const void *data, | 16 | ebt_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 | ||
26 | static int ebt_mark_check(const char *tablename, unsigned int hookmask, | 25 | static 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 | ||
42 | static struct ebt_match filter_mark __read_mostly = { | 38 | static 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 | ||
49 | static int __init ebt_mark_m_init(void) | 48 | static 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 | ||
54 | static void __exit ebt_mark_m_fini(void) | 53 | static 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 | ||
59 | module_init(ebt_mark_m_init); | 58 | module_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 | ||
21 | static void ebt_nflog(const struct sk_buff *skb, | 22 | static unsigned int |
22 | unsigned int hooknr, | 23 | ebt_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 | ||
38 | static int ebt_nflog_check(const char *tablename, | 38 | static 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 | ||
53 | static struct ebt_watcher nflog __read_mostly = { | 48 | static 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 | ||
60 | static int __init ebt_nflog_init(void) | 58 | static 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 | ||
65 | static void __exit ebt_nflog_fini(void) | 63 | static 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 | ||
70 | module_init(ebt_nflog_init); | 68 | module_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 | ||
15 | static int ebt_filter_pkttype(const struct sk_buff *skb, | 15 | static bool |
16 | const struct net_device *in, | 16 | ebt_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 | ||
26 | static int ebt_pkttype_check(const char *tablename, unsigned int hookmask, | 23 | static 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 | ||
39 | static struct ebt_match filter_pkttype __read_mostly = { | 33 | static 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 | ||
46 | static int __init ebt_pkttype_init(void) | 43 | static 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 | ||
51 | static void __exit ebt_pkttype_fini(void) | 48 | static 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 | ||
56 | module_init(ebt_pkttype_init); | 53 | module_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 | ||
18 | static int ebt_target_redirect(struct sk_buff *skb, unsigned int hooknr, | 18 | static unsigned int |
19 | const struct net_device *in, const struct net_device *out, | 19 | ebt_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 | ||
36 | static int ebt_target_redirect_check(const char *tablename, unsigned int hookmask, | 35 | static 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 | ||
54 | static struct ebt_target redirect_target __read_mostly = { | 54 | static 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 | ||
61 | static int __init ebt_redirect_init(void) | 66 | static 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 | ||
66 | static void __exit ebt_redirect_fini(void) | 71 | static 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 | ||
71 | module_init(ebt_redirect_init); | 76 | module_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 | ||
19 | static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr, | 19 | static unsigned int |
20 | const struct net_device *in, const struct net_device *out, | 20 | ebt_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 | ||
46 | static int ebt_target_snat_check(const char *tablename, unsigned int hookmask, | 45 | static 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 | ||
71 | static struct ebt_target snat __read_mostly = { | 62 | static 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 | ||
78 | static int __init ebt_snat_init(void) | 74 | static 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 | ||
83 | static void __exit ebt_snat_fini(void) | 79 | static 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 | ||
88 | module_init(ebt_snat_init); | 84 | module_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 | ||
43 | static int ebt_filter_config(const struct ebt_stp_info *info, | 43 | static 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 | ||
122 | static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in, | 122 | static bool |
123 | const struct net_device *out, const void *data, unsigned int datalen) | 123 | ebt_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 | ||
156 | static int ebt_stp_check(const char *tablename, unsigned int hookmask, | 156 | static 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 | ||
177 | static struct ebt_match filter_stp __read_mostly = { | 174 | static 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 | ||
184 | static int __init ebt_stp_init(void) | 184 | static 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 | ||
189 | static void __exit ebt_stp_fini(void) | 189 | static 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 | ||
194 | module_init(ebt_stp_init); | 194 | module_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 */ |
226 | static void ebt_log_packet(unsigned int pf, unsigned int hooknum, | 227 | static 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 | ||
248 | static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr, | 249 | static unsigned int |
249 | const struct net_device *in, const struct net_device *out, | 250 | ebt_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 | 257 | static bool ebt_ulog_tg_check(const struct xt_tgchk_param *par) | |
258 | static 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 | ||
275 | static struct ebt_watcher ulog __read_mostly = { | 272 | static 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 | ||
282 | static const struct nf_logger ebt_ulog_logger = { | 282 | static 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 | ||
288 | static int __init ebt_ulog_init(void) | 288 | static 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 | ||
42 | static int | 43 | static bool |
43 | ebt_filter_vlan(const struct sk_buff *skb, | 44 | ebt_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 | ||
89 | static int | 87 | static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par) |
90 | ebt_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 | ||
172 | static struct ebt_match filter_vlan __read_mostly = { | 160 | static 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 | ||
187 | static void __exit ebt_vlan_fini(void) | 178 | static 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 | ||
192 | module_init(ebt_vlan_init); | 183 | module_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 | ||
56 | static DEFINE_MUTEX(ebt_mutex); | 57 | static DEFINE_MUTEX(ebt_mutex); |
57 | static LIST_HEAD(ebt_tables); | 58 | static LIST_HEAD(ebt_tables); |
58 | static LIST_HEAD(ebt_targets); | ||
59 | static LIST_HEAD(ebt_matches); | ||
60 | static LIST_HEAD(ebt_watchers); | ||
61 | 59 | ||
62 | static struct ebt_target ebt_standard_target = | 60 | static 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 | ||
65 | static inline int ebt_do_watcher (struct ebt_entry_watcher *w, | 67 | static inline int |
66 | const struct sk_buff *skb, unsigned int hooknr, const struct net_device *in, | 68 | ebt_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 | ||
75 | static inline int ebt_do_match (struct ebt_entry_match *m, | 78 | static 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 | ||
83 | static inline int ebt_dev_check(char *entry, const struct net_device *device) | 86 | static 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 | ||
315 | static inline struct ebt_match * | ||
316 | find_match_lock(const char *name, int *error, struct mutex *mutex) | ||
317 | { | ||
318 | return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex); | ||
319 | } | ||
320 | |||
321 | static inline struct ebt_watcher * | ||
322 | find_watcher_lock(const char *name, int *error, struct mutex *mutex) | ||
323 | { | ||
324 | return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex); | ||
325 | } | ||
326 | |||
327 | static inline struct ebt_target * | ||
328 | find_target_lock(const char *name, int *error, struct mutex *mutex) | ||
329 | { | ||
330 | return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex); | ||
331 | } | ||
332 | |||
333 | static inline int | 332 | static inline int |
334 | ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e, | 333 | ebt_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 | ||
363 | static inline int | 366 | static inline int |
364 | ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e, | 367 | ebt_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, | |||
558 | static inline int | 566 | static inline int |
559 | ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i) | 567 | ebt_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 | ||
570 | static inline int | 583 | static inline int |
571 | ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i) | 584 | ebt_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 | ||
582 | static inline int | 600 | static inline int |
583 | ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt) | 601 | ebt_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; |
693 | cleanup_watchers: | 731 | cleanup_watchers: |
@@ -1068,87 +1106,6 @@ free_newinfo: | |||
1068 | return ret; | 1106 | return ret; |
1069 | } | 1107 | } |
1070 | 1108 | ||
1071 | int 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 | |||
1091 | void 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 | |||
1098 | int 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 | |||
1118 | void 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 | |||
1125 | int 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 | |||
1145 | void 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 | |||
1152 | int ebt_register_table(struct ebt_table *table) | 1109 | int 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) | |||
1531 | static void __exit ebtables_fini(void) | 1491 | static 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 | ||
1537 | EXPORT_SYMBOL(ebt_register_table); | 1498 | EXPORT_SYMBOL(ebt_register_table); |
1538 | EXPORT_SYMBOL(ebt_unregister_table); | 1499 | EXPORT_SYMBOL(ebt_unregister_table); |
1539 | EXPORT_SYMBOL(ebt_register_match); | ||
1540 | EXPORT_SYMBOL(ebt_unregister_match); | ||
1541 | EXPORT_SYMBOL(ebt_register_watcher); | ||
1542 | EXPORT_SYMBOL(ebt_unregister_watcher); | ||
1543 | EXPORT_SYMBOL(ebt_register_target); | ||
1544 | EXPORT_SYMBOL(ebt_unregister_target); | ||
1545 | EXPORT_SYMBOL(ebt_do_table); | 1500 | EXPORT_SYMBOL(ebt_do_table); |
1546 | module_init(ebtables_init); | 1501 | module_init(ebtables_init); |
1547 | module_exit(ebtables_fini); | 1502 | module_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; | |||
18 | static DEFINE_MUTEX(net_mutex); | 18 | static DEFINE_MUTEX(net_mutex); |
19 | 19 | ||
20 | LIST_HEAD(net_namespace_list); | 20 | LIST_HEAD(net_namespace_list); |
21 | EXPORT_SYMBOL_GPL(net_namespace_list); | ||
21 | 22 | ||
22 | struct net init_net; | 23 | struct net init_net; |
23 | EXPORT_SYMBOL(init_net); | 24 | EXPORT_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 */ |
13 | int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | 13 | int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) |
14 | { | 14 | { |
15 | struct net *net = dev_net(skb->dst->dev); | ||
15 | const struct iphdr *iph = ip_hdr(skb); | 16 | const struct iphdr *iph = ip_hdr(skb); |
16 | struct rtable *rt; | 17 | struct rtable *rt; |
17 | struct flowi fl = {}; | 18 | struct flowi fl = {}; |
@@ -19,7 +20,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
19 | unsigned int hh_len; | 20 | unsigned int hh_len; |
20 | unsigned int type; | 21 | unsigned int type; |
21 | 22 | ||
22 | type = inet_addr_type(&init_net, iph->saddr); | 23 | type = inet_addr_type(net, iph->saddr); |
23 | if (skb->sk && inet_sk(skb->sk)->transparent) | 24 | if (skb->sk && inet_sk(skb->sk)->transparent) |
24 | type = RTN_LOCAL; | 25 | type = RTN_LOCAL; |
25 | if (addr_type == RTN_UNSPEC) | 26 | if (addr_type == RTN_UNSPEC) |
@@ -36,7 +37,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
36 | fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; | 37 | fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; |
37 | fl.mark = skb->mark; | 38 | fl.mark = skb->mark; |
38 | fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; | 39 | fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; |
39 | if (ip_route_output_key(&init_net, &rt, &fl) != 0) | 40 | if (ip_route_output_key(net, &rt, &fl) != 0) |
40 | return -1; | 41 | return -1; |
41 | 42 | ||
42 | /* Drop old route. */ | 43 | /* Drop old route. */ |
@@ -46,7 +47,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
46 | /* non-local src, find valid iif to satisfy | 47 | /* non-local src, find valid iif to satisfy |
47 | * rp-filter when calling ip_route_input. */ | 48 | * rp-filter when calling ip_route_input. */ |
48 | fl.nl_u.ip4_u.daddr = iph->saddr; | 49 | fl.nl_u.ip4_u.daddr = iph->saddr; |
49 | if (ip_route_output_key(&init_net, &rt, &fl) != 0) | 50 | if (ip_route_output_key(net, &rt, &fl) != 0) |
50 | return -1; | 51 | return -1; |
51 | 52 | ||
52 | odst = skb->dst; | 53 | odst = skb->dst; |
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 90eb7cb47e77..3816e1dc9295 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -5,10 +5,15 @@ | |||
5 | menu "IP: Netfilter Configuration" | 5 | menu "IP: Netfilter Configuration" |
6 | depends on INET && NETFILTER | 6 | depends on INET && NETFILTER |
7 | 7 | ||
8 | config NF_DEFRAG_IPV4 | ||
9 | tristate | ||
10 | default n | ||
11 | |||
8 | config NF_CONNTRACK_IPV4 | 12 | config NF_CONNTRACK_IPV4 |
9 | tristate "IPv4 connection tracking support (required for NAT)" | 13 | tristate "IPv4 connection tracking support (required for NAT)" |
10 | depends on NF_CONNTRACK | 14 | depends on NF_CONNTRACK |
11 | default m if NETFILTER_ADVANCED=n | 15 | default m if NETFILTER_ADVANCED=n |
16 | select NF_DEFRAG_IPV4 | ||
12 | ---help--- | 17 | ---help--- |
13 | Connection tracking keeps a record of what packets have passed | 18 | Connection tracking keeps a record of what packets have passed |
14 | through your machine, in order to figure out how they are related | 19 | through your machine, in order to figure out how they are related |
@@ -56,23 +61,30 @@ config IP_NF_IPTABLES | |||
56 | 61 | ||
57 | To compile it as a module, choose M here. If unsure, say N. | 62 | To compile it as a module, choose M here. If unsure, say N. |
58 | 63 | ||
64 | if IP_NF_IPTABLES | ||
65 | |||
59 | # The matches. | 66 | # The matches. |
60 | config IP_NF_MATCH_RECENT | 67 | config IP_NF_MATCH_ADDRTYPE |
61 | tristate '"recent" match support' | 68 | tristate '"addrtype" address type match support' |
62 | depends on IP_NF_IPTABLES | ||
63 | depends on NETFILTER_ADVANCED | 69 | depends on NETFILTER_ADVANCED |
64 | help | 70 | help |
65 | This match is used for creating one or many lists of recently | 71 | This option allows you to match what routing thinks of an address, |
66 | used addresses and then matching against that/those list(s). | 72 | eg. UNICAST, LOCAL, BROADCAST, ... |
67 | 73 | ||
68 | Short options are available by using 'iptables -m recent -h' | 74 | If you want to compile it as a module, say M here and read |
69 | Official Website: <http://snowman.net/projects/ipt_recent/> | 75 | <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. |
76 | |||
77 | config IP_NF_MATCH_AH | ||
78 | tristate '"ah" match support' | ||
79 | depends on NETFILTER_ADVANCED | ||
80 | help | ||
81 | This match extension allows you to match a range of SPIs | ||
82 | inside AH header of IPSec packets. | ||
70 | 83 | ||
71 | To compile it as a module, choose M here. If unsure, say N. | 84 | To compile it as a module, choose M here. If unsure, say N. |
72 | 85 | ||
73 | config IP_NF_MATCH_ECN | 86 | config IP_NF_MATCH_ECN |
74 | tristate '"ecn" match support' | 87 | tristate '"ecn" match support' |
75 | depends on IP_NF_IPTABLES | ||
76 | depends on NETFILTER_ADVANCED | 88 | depends on NETFILTER_ADVANCED |
77 | help | 89 | help |
78 | This option adds a `ECN' match, which allows you to match against | 90 | This option adds a `ECN' match, which allows you to match against |
@@ -80,19 +92,8 @@ config IP_NF_MATCH_ECN | |||
80 | 92 | ||
81 | To compile it as a module, choose M here. If unsure, say N. | 93 | To compile it as a module, choose M here. If unsure, say N. |
82 | 94 | ||
83 | config IP_NF_MATCH_AH | ||
84 | tristate '"ah" match support' | ||
85 | depends on IP_NF_IPTABLES | ||
86 | depends on NETFILTER_ADVANCED | ||
87 | help | ||
88 | This match extension allows you to match a range of SPIs | ||
89 | inside AH header of IPSec packets. | ||
90 | |||
91 | To compile it as a module, choose M here. If unsure, say N. | ||
92 | |||
93 | config IP_NF_MATCH_TTL | 95 | config IP_NF_MATCH_TTL |
94 | tristate '"ttl" match support' | 96 | tristate '"ttl" match support' |
95 | depends on IP_NF_IPTABLES | ||
96 | depends on NETFILTER_ADVANCED | 97 | depends on NETFILTER_ADVANCED |
97 | help | 98 | help |
98 | This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user | 99 | This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user |
@@ -100,21 +101,9 @@ config IP_NF_MATCH_TTL | |||
100 | 101 | ||
101 | To compile it as a module, choose M here. If unsure, say N. | 102 | To compile it as a module, choose M here. If unsure, say N. |
102 | 103 | ||
103 | config IP_NF_MATCH_ADDRTYPE | ||
104 | tristate '"addrtype" address type match support' | ||
105 | depends on IP_NF_IPTABLES | ||
106 | depends on NETFILTER_ADVANCED | ||
107 | help | ||
108 | This option allows you to match what routing thinks of an address, | ||
109 | eg. UNICAST, LOCAL, BROADCAST, ... | ||
110 | |||
111 | If you want to compile it as a module, say M here and read | ||
112 | <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. | ||
113 | |||
114 | # `filter', generic and specific targets | 104 | # `filter', generic and specific targets |
115 | config IP_NF_FILTER | 105 | config IP_NF_FILTER |
116 | tristate "Packet filtering" | 106 | tristate "Packet filtering" |
117 | depends on IP_NF_IPTABLES | ||
118 | default m if NETFILTER_ADVANCED=n | 107 | default m if NETFILTER_ADVANCED=n |
119 | help | 108 | help |
120 | Packet filtering defines a table `filter', which has a series of | 109 | Packet filtering defines a table `filter', which has a series of |
@@ -136,7 +125,6 @@ config IP_NF_TARGET_REJECT | |||
136 | 125 | ||
137 | config IP_NF_TARGET_LOG | 126 | config IP_NF_TARGET_LOG |
138 | tristate "LOG target support" | 127 | tristate "LOG target support" |
139 | depends on IP_NF_IPTABLES | ||
140 | default m if NETFILTER_ADVANCED=n | 128 | default m if NETFILTER_ADVANCED=n |
141 | help | 129 | help |
142 | This option adds a `LOG' target, which allows you to create rules in | 130 | This option adds a `LOG' target, which allows you to create rules in |
@@ -146,7 +134,6 @@ config IP_NF_TARGET_LOG | |||
146 | 134 | ||
147 | config IP_NF_TARGET_ULOG | 135 | config IP_NF_TARGET_ULOG |
148 | tristate "ULOG target support" | 136 | tristate "ULOG target support" |
149 | depends on IP_NF_IPTABLES | ||
150 | default m if NETFILTER_ADVANCED=n | 137 | default m if NETFILTER_ADVANCED=n |
151 | ---help--- | 138 | ---help--- |
152 | 139 | ||
@@ -167,7 +154,7 @@ config IP_NF_TARGET_ULOG | |||
167 | # NAT + specific targets: nf_conntrack | 154 | # NAT + specific targets: nf_conntrack |
168 | config NF_NAT | 155 | config NF_NAT |
169 | tristate "Full NAT" | 156 | tristate "Full NAT" |
170 | depends on IP_NF_IPTABLES && NF_CONNTRACK_IPV4 | 157 | depends on NF_CONNTRACK_IPV4 |
171 | default m if NETFILTER_ADVANCED=n | 158 | default m if NETFILTER_ADVANCED=n |
172 | help | 159 | help |
173 | The Full NAT option allows masquerading, port forwarding and other | 160 | The Full NAT option allows masquerading, port forwarding and other |
@@ -194,26 +181,26 @@ config IP_NF_TARGET_MASQUERADE | |||
194 | 181 | ||
195 | To compile it as a module, choose M here. If unsure, say N. | 182 | To compile it as a module, choose M here. If unsure, say N. |
196 | 183 | ||
197 | config IP_NF_TARGET_REDIRECT | 184 | config IP_NF_TARGET_NETMAP |
198 | tristate "REDIRECT target support" | 185 | tristate "NETMAP target support" |
199 | depends on NF_NAT | 186 | depends on NF_NAT |
200 | depends on NETFILTER_ADVANCED | 187 | depends on NETFILTER_ADVANCED |
201 | help | 188 | help |
202 | REDIRECT is a special case of NAT: all incoming connections are | 189 | NETMAP is an implementation of static 1:1 NAT mapping of network |
203 | mapped onto the incoming interface's address, causing the packets to | 190 | addresses. It maps the network address part, while keeping the host |
204 | come to the local machine instead of passing through. This is | 191 | address part intact. |
205 | useful for transparent proxies. | ||
206 | 192 | ||
207 | To compile it as a module, choose M here. If unsure, say N. | 193 | To compile it as a module, choose M here. If unsure, say N. |
208 | 194 | ||
209 | config IP_NF_TARGET_NETMAP | 195 | config IP_NF_TARGET_REDIRECT |
210 | tristate "NETMAP target support" | 196 | tristate "REDIRECT target support" |
211 | depends on NF_NAT | 197 | depends on NF_NAT |
212 | depends on NETFILTER_ADVANCED | 198 | depends on NETFILTER_ADVANCED |
213 | help | 199 | help |
214 | NETMAP is an implementation of static 1:1 NAT mapping of network | 200 | REDIRECT is a special case of NAT: all incoming connections are |
215 | addresses. It maps the network address part, while keeping the host | 201 | mapped onto the incoming interface's address, causing the packets to |
216 | address part intact. | 202 | come to the local machine instead of passing through. This is |
203 | useful for transparent proxies. | ||
217 | 204 | ||
218 | To compile it as a module, choose M here. If unsure, say N. | 205 | To compile it as a module, choose M here. If unsure, say N. |
219 | 206 | ||
@@ -262,44 +249,43 @@ config NF_NAT_PROTO_SCTP | |||
262 | 249 | ||
263 | config NF_NAT_FTP | 250 | config NF_NAT_FTP |
264 | tristate | 251 | tristate |
265 | depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT | 252 | depends on NF_CONNTRACK && NF_NAT |
266 | default NF_NAT && NF_CONNTRACK_FTP | 253 | default NF_NAT && NF_CONNTRACK_FTP |
267 | 254 | ||
268 | config NF_NAT_IRC | 255 | config NF_NAT_IRC |
269 | tristate | 256 | tristate |
270 | depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT | 257 | depends on NF_CONNTRACK && NF_NAT |
271 | default NF_NAT && NF_CONNTRACK_IRC | 258 | default NF_NAT && NF_CONNTRACK_IRC |
272 | 259 | ||
273 | config NF_NAT_TFTP | 260 | config NF_NAT_TFTP |
274 | tristate | 261 | tristate |
275 | depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT | 262 | depends on NF_CONNTRACK && NF_NAT |
276 | default NF_NAT && NF_CONNTRACK_TFTP | 263 | default NF_NAT && NF_CONNTRACK_TFTP |
277 | 264 | ||
278 | config NF_NAT_AMANDA | 265 | config NF_NAT_AMANDA |
279 | tristate | 266 | tristate |
280 | depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT | 267 | depends on NF_CONNTRACK && NF_NAT |
281 | default NF_NAT && NF_CONNTRACK_AMANDA | 268 | default NF_NAT && NF_CONNTRACK_AMANDA |
282 | 269 | ||
283 | config NF_NAT_PPTP | 270 | config NF_NAT_PPTP |
284 | tristate | 271 | tristate |
285 | depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT | 272 | depends on NF_CONNTRACK && NF_NAT |
286 | default NF_NAT && NF_CONNTRACK_PPTP | 273 | default NF_NAT && NF_CONNTRACK_PPTP |
287 | select NF_NAT_PROTO_GRE | 274 | select NF_NAT_PROTO_GRE |
288 | 275 | ||
289 | config NF_NAT_H323 | 276 | config NF_NAT_H323 |
290 | tristate | 277 | tristate |
291 | depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT | 278 | depends on NF_CONNTRACK && NF_NAT |
292 | default NF_NAT && NF_CONNTRACK_H323 | 279 | default NF_NAT && NF_CONNTRACK_H323 |
293 | 280 | ||
294 | config NF_NAT_SIP | 281 | config NF_NAT_SIP |
295 | tristate | 282 | tristate |
296 | depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT | 283 | depends on NF_CONNTRACK && NF_NAT |
297 | default NF_NAT && NF_CONNTRACK_SIP | 284 | default NF_NAT && NF_CONNTRACK_SIP |
298 | 285 | ||
299 | # mangle + specific targets | 286 | # mangle + specific targets |
300 | config IP_NF_MANGLE | 287 | config IP_NF_MANGLE |
301 | tristate "Packet mangling" | 288 | tristate "Packet mangling" |
302 | depends on IP_NF_IPTABLES | ||
303 | default m if NETFILTER_ADVANCED=n | 289 | default m if NETFILTER_ADVANCED=n |
304 | help | 290 | help |
305 | This option adds a `mangle' table to iptables: see the man page for | 291 | This option adds a `mangle' table to iptables: see the man page for |
@@ -308,6 +294,19 @@ config IP_NF_MANGLE | |||
308 | 294 | ||
309 | To compile it as a module, choose M here. If unsure, say N. | 295 | To compile it as a module, choose M here. If unsure, say N. |
310 | 296 | ||
297 | config IP_NF_TARGET_CLUSTERIP | ||
298 | tristate "CLUSTERIP target support (EXPERIMENTAL)" | ||
299 | depends on IP_NF_MANGLE && EXPERIMENTAL | ||
300 | depends on NF_CONNTRACK_IPV4 | ||
301 | depends on NETFILTER_ADVANCED | ||
302 | select NF_CONNTRACK_MARK | ||
303 | help | ||
304 | The CLUSTERIP target allows you to build load-balancing clusters of | ||
305 | network servers without having a dedicated load-balancing | ||
306 | router/server/switch. | ||
307 | |||
308 | To compile it as a module, choose M here. If unsure, say N. | ||
309 | |||
311 | config IP_NF_TARGET_ECN | 310 | config IP_NF_TARGET_ECN |
312 | tristate "ECN target support" | 311 | tristate "ECN target support" |
313 | depends on IP_NF_MANGLE | 312 | depends on IP_NF_MANGLE |
@@ -338,23 +337,9 @@ config IP_NF_TARGET_TTL | |||
338 | 337 | ||
339 | To compile it as a module, choose M here. If unsure, say N. | 338 | To compile it as a module, choose M here. If unsure, say N. |
340 | 339 | ||
341 | config IP_NF_TARGET_CLUSTERIP | ||
342 | tristate "CLUSTERIP target support (EXPERIMENTAL)" | ||
343 | depends on IP_NF_MANGLE && EXPERIMENTAL | ||
344 | depends on NF_CONNTRACK_IPV4 | ||
345 | depends on NETFILTER_ADVANCED | ||
346 | select NF_CONNTRACK_MARK | ||
347 | help | ||
348 | The CLUSTERIP target allows you to build load-balancing clusters of | ||
349 | network servers without having a dedicated load-balancing | ||
350 | router/server/switch. | ||
351 | |||
352 | To compile it as a module, choose M here. If unsure, say N. | ||
353 | |||
354 | # raw + specific targets | 340 | # raw + specific targets |
355 | config IP_NF_RAW | 341 | config IP_NF_RAW |
356 | tristate 'raw table support (required for NOTRACK/TRACE)' | 342 | tristate 'raw table support (required for NOTRACK/TRACE)' |
357 | depends on IP_NF_IPTABLES | ||
358 | depends on NETFILTER_ADVANCED | 343 | depends on NETFILTER_ADVANCED |
359 | help | 344 | help |
360 | This option adds a `raw' table to iptables. This table is the very | 345 | This option adds a `raw' table to iptables. This table is the very |
@@ -367,7 +352,6 @@ config IP_NF_RAW | |||
367 | # security table for MAC policy | 352 | # security table for MAC policy |
368 | config IP_NF_SECURITY | 353 | config IP_NF_SECURITY |
369 | tristate "Security table" | 354 | tristate "Security table" |
370 | depends on IP_NF_IPTABLES | ||
371 | depends on SECURITY | 355 | depends on SECURITY |
372 | depends on NETFILTER_ADVANCED | 356 | depends on NETFILTER_ADVANCED |
373 | help | 357 | help |
@@ -376,6 +360,8 @@ config IP_NF_SECURITY | |||
376 | 360 | ||
377 | If unsure, say N. | 361 | If unsure, say N. |
378 | 362 | ||
363 | endif # IP_NF_IPTABLES | ||
364 | |||
379 | # ARP tables | 365 | # ARP tables |
380 | config IP_NF_ARPTABLES | 366 | config IP_NF_ARPTABLES |
381 | tristate "ARP tables support" | 367 | tristate "ARP tables support" |
@@ -388,9 +374,10 @@ config IP_NF_ARPTABLES | |||
388 | 374 | ||
389 | To compile it as a module, choose M here. If unsure, say N. | 375 | To compile it as a module, choose M here. If unsure, say N. |
390 | 376 | ||
377 | if IP_NF_ARPTABLES | ||
378 | |||
391 | config IP_NF_ARPFILTER | 379 | config IP_NF_ARPFILTER |
392 | tristate "ARP packet filtering" | 380 | tristate "ARP packet filtering" |
393 | depends on IP_NF_ARPTABLES | ||
394 | help | 381 | help |
395 | ARP packet filtering defines a table `filter', which has a series of | 382 | ARP packet filtering defines a table `filter', which has a series of |
396 | rules for simple ARP packet filtering at local input and | 383 | rules for simple ARP packet filtering at local input and |
@@ -401,10 +388,11 @@ config IP_NF_ARPFILTER | |||
401 | 388 | ||
402 | config IP_NF_ARP_MANGLE | 389 | config IP_NF_ARP_MANGLE |
403 | tristate "ARP payload mangling" | 390 | tristate "ARP payload mangling" |
404 | depends on IP_NF_ARPTABLES | ||
405 | help | 391 | help |
406 | Allows altering the ARP packet payload: source and destination | 392 | Allows altering the ARP packet payload: source and destination |
407 | hardware and network addresses. | 393 | hardware and network addresses. |
408 | 394 | ||
395 | endif # IP_NF_ARPTABLES | ||
396 | |||
409 | endmenu | 397 | endmenu |
410 | 398 | ||
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 3f31291f37ce..5f9b650d90fc 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
@@ -18,6 +18,9 @@ obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o | |||
18 | 18 | ||
19 | obj-$(CONFIG_NF_NAT) += nf_nat.o | 19 | obj-$(CONFIG_NF_NAT) += nf_nat.o |
20 | 20 | ||
21 | # defrag | ||
22 | obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o | ||
23 | |||
21 | # NAT helpers (nf_conntrack) | 24 | # NAT helpers (nf_conntrack) |
22 | obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o | 25 | obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o |
23 | obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o | 26 | obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o |
@@ -48,7 +51,6 @@ obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o | |||
48 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o | 51 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o |
49 | obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o | 52 | obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o |
50 | obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o | 53 | obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o |
51 | obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o | ||
52 | obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o | 54 | obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o |
53 | 55 | ||
54 | # targets | 56 | # targets |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 03e83a65aec5..8d70d29f1ccf 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -200,15 +200,12 @@ static inline int arp_checkentry(const struct arpt_arp *arp) | |||
200 | return 1; | 200 | return 1; |
201 | } | 201 | } |
202 | 202 | ||
203 | static unsigned int arpt_error(struct sk_buff *skb, | 203 | static unsigned int |
204 | const struct net_device *in, | 204 | arpt_error(struct sk_buff *skb, const struct xt_target_param *par) |
205 | const struct net_device *out, | ||
206 | unsigned int hooknum, | ||
207 | const struct xt_target *target, | ||
208 | const void *targinfo) | ||
209 | { | 205 | { |
210 | if (net_ratelimit()) | 206 | if (net_ratelimit()) |
211 | printk("arp_tables: error: '%s'\n", (char *)targinfo); | 207 | printk("arp_tables: error: '%s'\n", |
208 | (const char *)par->targinfo); | ||
212 | 209 | ||
213 | return NF_DROP; | 210 | return NF_DROP; |
214 | } | 211 | } |
@@ -232,6 +229,7 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
232 | const char *indev, *outdev; | 229 | const char *indev, *outdev; |
233 | void *table_base; | 230 | void *table_base; |
234 | const struct xt_table_info *private; | 231 | const struct xt_table_info *private; |
232 | struct xt_target_param tgpar; | ||
235 | 233 | ||
236 | if (!pskb_may_pull(skb, arp_hdr_len(skb->dev))) | 234 | if (!pskb_may_pull(skb, arp_hdr_len(skb->dev))) |
237 | return NF_DROP; | 235 | return NF_DROP; |
@@ -245,6 +243,11 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
245 | e = get_entry(table_base, private->hook_entry[hook]); | 243 | e = get_entry(table_base, private->hook_entry[hook]); |
246 | back = get_entry(table_base, private->underflow[hook]); | 244 | back = get_entry(table_base, private->underflow[hook]); |
247 | 245 | ||
246 | tgpar.in = in; | ||
247 | tgpar.out = out; | ||
248 | tgpar.hooknum = hook; | ||
249 | tgpar.family = NFPROTO_ARP; | ||
250 | |||
248 | arp = arp_hdr(skb); | 251 | arp = arp_hdr(skb); |
249 | do { | 252 | do { |
250 | if (arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) { | 253 | if (arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) { |
@@ -290,11 +293,10 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
290 | /* Targets which reenter must return | 293 | /* Targets which reenter must return |
291 | * abs. verdicts | 294 | * abs. verdicts |
292 | */ | 295 | */ |
296 | tgpar.target = t->u.kernel.target; | ||
297 | tgpar.targinfo = t->data; | ||
293 | verdict = t->u.kernel.target->target(skb, | 298 | verdict = t->u.kernel.target->target(skb, |
294 | in, out, | 299 | &tgpar); |
295 | hook, | ||
296 | t->u.kernel.target, | ||
297 | t->data); | ||
298 | 300 | ||
299 | /* Target might have changed stuff. */ | 301 | /* Target might have changed stuff. */ |
300 | arp = arp_hdr(skb); | 302 | arp = arp_hdr(skb); |
@@ -456,23 +458,24 @@ static inline int check_entry(struct arpt_entry *e, const char *name) | |||
456 | 458 | ||
457 | static inline int check_target(struct arpt_entry *e, const char *name) | 459 | static inline int check_target(struct arpt_entry *e, const char *name) |
458 | { | 460 | { |
459 | struct arpt_entry_target *t; | 461 | struct arpt_entry_target *t = arpt_get_target(e); |
460 | struct xt_target *target; | ||
461 | int ret; | 462 | int ret; |
462 | 463 | struct xt_tgchk_param par = { | |
463 | t = arpt_get_target(e); | 464 | .table = name, |
464 | target = t->u.kernel.target; | 465 | .entryinfo = e, |
465 | 466 | .target = t->u.kernel.target, | |
466 | ret = xt_check_target(target, NF_ARP, t->u.target_size - sizeof(*t), | 467 | .targinfo = t->data, |
467 | name, e->comefrom, 0, 0); | 468 | .hook_mask = e->comefrom, |
468 | if (!ret && t->u.kernel.target->checkentry | 469 | .family = NFPROTO_ARP, |
469 | && !t->u.kernel.target->checkentry(name, e, target, t->data, | 470 | }; |
470 | e->comefrom)) { | 471 | |
472 | ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false); | ||
473 | if (ret < 0) { | ||
471 | duprintf("arp_tables: check failed for `%s'.\n", | 474 | duprintf("arp_tables: check failed for `%s'.\n", |
472 | t->u.kernel.target->name); | 475 | t->u.kernel.target->name); |
473 | ret = -EINVAL; | 476 | return ret; |
474 | } | 477 | } |
475 | return ret; | 478 | return 0; |
476 | } | 479 | } |
477 | 480 | ||
478 | static inline int | 481 | static inline int |
@@ -488,7 +491,8 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size, | |||
488 | return ret; | 491 | return ret; |
489 | 492 | ||
490 | t = arpt_get_target(e); | 493 | t = arpt_get_target(e); |
491 | target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, | 494 | target = try_then_request_module(xt_find_target(NFPROTO_ARP, |
495 | t->u.user.name, | ||
492 | t->u.user.revision), | 496 | t->u.user.revision), |
493 | "arpt_%s", t->u.user.name); | 497 | "arpt_%s", t->u.user.name); |
494 | if (IS_ERR(target) || !target) { | 498 | if (IS_ERR(target) || !target) { |
@@ -554,15 +558,19 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, | |||
554 | 558 | ||
555 | static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i) | 559 | static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i) |
556 | { | 560 | { |
561 | struct xt_tgdtor_param par; | ||
557 | struct arpt_entry_target *t; | 562 | struct arpt_entry_target *t; |
558 | 563 | ||
559 | if (i && (*i)-- == 0) | 564 | if (i && (*i)-- == 0) |
560 | return 1; | 565 | return 1; |
561 | 566 | ||
562 | t = arpt_get_target(e); | 567 | t = arpt_get_target(e); |
563 | if (t->u.kernel.target->destroy) | 568 | par.target = t->u.kernel.target; |
564 | t->u.kernel.target->destroy(t->u.kernel.target, t->data); | 569 | par.targinfo = t->data; |
565 | module_put(t->u.kernel.target->me); | 570 | par.family = NFPROTO_ARP; |
571 | if (par.target->destroy != NULL) | ||
572 | par.target->destroy(&par); | ||
573 | module_put(par.target->me); | ||
566 | return 0; | 574 | return 0; |
567 | } | 575 | } |
568 | 576 | ||
@@ -788,7 +796,7 @@ static void compat_standard_from_user(void *dst, void *src) | |||
788 | int v = *(compat_int_t *)src; | 796 | int v = *(compat_int_t *)src; |
789 | 797 | ||
790 | if (v > 0) | 798 | if (v > 0) |
791 | v += xt_compat_calc_jump(NF_ARP, v); | 799 | v += xt_compat_calc_jump(NFPROTO_ARP, v); |
792 | memcpy(dst, &v, sizeof(v)); | 800 | memcpy(dst, &v, sizeof(v)); |
793 | } | 801 | } |
794 | 802 | ||
@@ -797,7 +805,7 @@ static int compat_standard_to_user(void __user *dst, void *src) | |||
797 | compat_int_t cv = *(int *)src; | 805 | compat_int_t cv = *(int *)src; |
798 | 806 | ||
799 | if (cv > 0) | 807 | if (cv > 0) |
800 | cv -= xt_compat_calc_jump(NF_ARP, cv); | 808 | cv -= xt_compat_calc_jump(NFPROTO_ARP, cv); |
801 | return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0; | 809 | return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0; |
802 | } | 810 | } |
803 | 811 | ||
@@ -815,7 +823,7 @@ static int compat_calc_entry(struct arpt_entry *e, | |||
815 | t = arpt_get_target(e); | 823 | t = arpt_get_target(e); |
816 | off += xt_compat_target_offset(t->u.kernel.target); | 824 | off += xt_compat_target_offset(t->u.kernel.target); |
817 | newinfo->size -= off; | 825 | newinfo->size -= off; |
818 | ret = xt_compat_add_offset(NF_ARP, entry_offset, off); | 826 | ret = xt_compat_add_offset(NFPROTO_ARP, entry_offset, off); |
819 | if (ret) | 827 | if (ret) |
820 | return ret; | 828 | return ret; |
821 | 829 | ||
@@ -866,9 +874,9 @@ static int get_info(struct net *net, void __user *user, int *len, int compat) | |||
866 | name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; | 874 | name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; |
867 | #ifdef CONFIG_COMPAT | 875 | #ifdef CONFIG_COMPAT |
868 | if (compat) | 876 | if (compat) |
869 | xt_compat_lock(NF_ARP); | 877 | xt_compat_lock(NFPROTO_ARP); |
870 | #endif | 878 | #endif |
871 | t = try_then_request_module(xt_find_table_lock(net, NF_ARP, name), | 879 | t = try_then_request_module(xt_find_table_lock(net, NFPROTO_ARP, name), |
872 | "arptable_%s", name); | 880 | "arptable_%s", name); |
873 | if (t && !IS_ERR(t)) { | 881 | if (t && !IS_ERR(t)) { |
874 | struct arpt_getinfo info; | 882 | struct arpt_getinfo info; |
@@ -878,7 +886,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat) | |||
878 | if (compat) { | 886 | if (compat) { |
879 | struct xt_table_info tmp; | 887 | struct xt_table_info tmp; |
880 | ret = compat_table_info(private, &tmp); | 888 | ret = compat_table_info(private, &tmp); |
881 | xt_compat_flush_offsets(NF_ARP); | 889 | xt_compat_flush_offsets(NFPROTO_ARP); |
882 | private = &tmp; | 890 | private = &tmp; |
883 | } | 891 | } |
884 | #endif | 892 | #endif |
@@ -901,7 +909,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat) | |||
901 | ret = t ? PTR_ERR(t) : -ENOENT; | 909 | ret = t ? PTR_ERR(t) : -ENOENT; |
902 | #ifdef CONFIG_COMPAT | 910 | #ifdef CONFIG_COMPAT |
903 | if (compat) | 911 | if (compat) |
904 | xt_compat_unlock(NF_ARP); | 912 | xt_compat_unlock(NFPROTO_ARP); |
905 | #endif | 913 | #endif |
906 | return ret; | 914 | return ret; |
907 | } | 915 | } |
@@ -925,7 +933,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr, | |||
925 | return -EINVAL; | 933 | return -EINVAL; |
926 | } | 934 | } |
927 | 935 | ||
928 | t = xt_find_table_lock(net, NF_ARP, get.name); | 936 | t = xt_find_table_lock(net, NFPROTO_ARP, get.name); |
929 | if (t && !IS_ERR(t)) { | 937 | if (t && !IS_ERR(t)) { |
930 | const struct xt_table_info *private = t->private; | 938 | const struct xt_table_info *private = t->private; |
931 | 939 | ||
@@ -967,7 +975,7 @@ static int __do_replace(struct net *net, const char *name, | |||
967 | goto out; | 975 | goto out; |
968 | } | 976 | } |
969 | 977 | ||
970 | t = try_then_request_module(xt_find_table_lock(net, NF_ARP, name), | 978 | t = try_then_request_module(xt_find_table_lock(net, NFPROTO_ARP, name), |
971 | "arptable_%s", name); | 979 | "arptable_%s", name); |
972 | if (!t || IS_ERR(t)) { | 980 | if (!t || IS_ERR(t)) { |
973 | ret = t ? PTR_ERR(t) : -ENOENT; | 981 | ret = t ? PTR_ERR(t) : -ENOENT; |
@@ -1134,7 +1142,7 @@ static int do_add_counters(struct net *net, void __user *user, unsigned int len, | |||
1134 | goto free; | 1142 | goto free; |
1135 | } | 1143 | } |
1136 | 1144 | ||
1137 | t = xt_find_table_lock(net, NF_ARP, name); | 1145 | t = xt_find_table_lock(net, NFPROTO_ARP, name); |
1138 | if (!t || IS_ERR(t)) { | 1146 | if (!t || IS_ERR(t)) { |
1139 | ret = t ? PTR_ERR(t) : -ENOENT; | 1147 | ret = t ? PTR_ERR(t) : -ENOENT; |
1140 | goto free; | 1148 | goto free; |
@@ -1218,7 +1226,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, | |||
1218 | entry_offset = (void *)e - (void *)base; | 1226 | entry_offset = (void *)e - (void *)base; |
1219 | 1227 | ||
1220 | t = compat_arpt_get_target(e); | 1228 | t = compat_arpt_get_target(e); |
1221 | target = try_then_request_module(xt_find_target(NF_ARP, | 1229 | target = try_then_request_module(xt_find_target(NFPROTO_ARP, |
1222 | t->u.user.name, | 1230 | t->u.user.name, |
1223 | t->u.user.revision), | 1231 | t->u.user.revision), |
1224 | "arpt_%s", t->u.user.name); | 1232 | "arpt_%s", t->u.user.name); |
@@ -1232,7 +1240,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, | |||
1232 | 1240 | ||
1233 | off += xt_compat_target_offset(target); | 1241 | off += xt_compat_target_offset(target); |
1234 | *size += off; | 1242 | *size += off; |
1235 | ret = xt_compat_add_offset(NF_ARP, entry_offset, off); | 1243 | ret = xt_compat_add_offset(NFPROTO_ARP, entry_offset, off); |
1236 | if (ret) | 1244 | if (ret) |
1237 | goto release_target; | 1245 | goto release_target; |
1238 | 1246 | ||
@@ -1333,7 +1341,7 @@ static int translate_compat_table(const char *name, | |||
1333 | 1341 | ||
1334 | duprintf("translate_compat_table: size %u\n", info->size); | 1342 | duprintf("translate_compat_table: size %u\n", info->size); |
1335 | j = 0; | 1343 | j = 0; |
1336 | xt_compat_lock(NF_ARP); | 1344 | xt_compat_lock(NFPROTO_ARP); |
1337 | /* Walk through entries, checking offsets. */ | 1345 | /* Walk through entries, checking offsets. */ |
1338 | ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, | 1346 | ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, |
1339 | check_compat_entry_size_and_hooks, | 1347 | check_compat_entry_size_and_hooks, |
@@ -1383,8 +1391,8 @@ static int translate_compat_table(const char *name, | |||
1383 | ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, | 1391 | ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, |
1384 | compat_copy_entry_from_user, | 1392 | compat_copy_entry_from_user, |
1385 | &pos, &size, name, newinfo, entry1); | 1393 | &pos, &size, name, newinfo, entry1); |
1386 | xt_compat_flush_offsets(NF_ARP); | 1394 | xt_compat_flush_offsets(NFPROTO_ARP); |
1387 | xt_compat_unlock(NF_ARP); | 1395 | xt_compat_unlock(NFPROTO_ARP); |
1388 | if (ret) | 1396 | if (ret) |
1389 | goto free_newinfo; | 1397 | goto free_newinfo; |
1390 | 1398 | ||
@@ -1420,8 +1428,8 @@ out: | |||
1420 | COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); | 1428 | COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); |
1421 | return ret; | 1429 | return ret; |
1422 | out_unlock: | 1430 | out_unlock: |
1423 | xt_compat_flush_offsets(NF_ARP); | 1431 | xt_compat_flush_offsets(NFPROTO_ARP); |
1424 | xt_compat_unlock(NF_ARP); | 1432 | xt_compat_unlock(NFPROTO_ARP); |
1425 | goto out; | 1433 | goto out; |
1426 | } | 1434 | } |
1427 | 1435 | ||
@@ -1607,8 +1615,8 @@ static int compat_get_entries(struct net *net, | |||
1607 | return -EINVAL; | 1615 | return -EINVAL; |
1608 | } | 1616 | } |
1609 | 1617 | ||
1610 | xt_compat_lock(NF_ARP); | 1618 | xt_compat_lock(NFPROTO_ARP); |
1611 | t = xt_find_table_lock(net, NF_ARP, get.name); | 1619 | t = xt_find_table_lock(net, NFPROTO_ARP, get.name); |
1612 | if (t && !IS_ERR(t)) { | 1620 | if (t && !IS_ERR(t)) { |
1613 | const struct xt_table_info *private = t->private; | 1621 | const struct xt_table_info *private = t->private; |
1614 | struct xt_table_info info; | 1622 | struct xt_table_info info; |
@@ -1623,13 +1631,13 @@ static int compat_get_entries(struct net *net, | |||
1623 | private->size, get.size); | 1631 | private->size, get.size); |
1624 | ret = -EAGAIN; | 1632 | ret = -EAGAIN; |
1625 | } | 1633 | } |
1626 | xt_compat_flush_offsets(NF_ARP); | 1634 | xt_compat_flush_offsets(NFPROTO_ARP); |
1627 | module_put(t->me); | 1635 | module_put(t->me); |
1628 | xt_table_unlock(t); | 1636 | xt_table_unlock(t); |
1629 | } else | 1637 | } else |
1630 | ret = t ? PTR_ERR(t) : -ENOENT; | 1638 | ret = t ? PTR_ERR(t) : -ENOENT; |
1631 | 1639 | ||
1632 | xt_compat_unlock(NF_ARP); | 1640 | xt_compat_unlock(NFPROTO_ARP); |
1633 | return ret; | 1641 | return ret; |
1634 | } | 1642 | } |
1635 | 1643 | ||
@@ -1709,7 +1717,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len | |||
1709 | break; | 1717 | break; |
1710 | } | 1718 | } |
1711 | 1719 | ||
1712 | try_then_request_module(xt_find_revision(NF_ARP, rev.name, | 1720 | try_then_request_module(xt_find_revision(NFPROTO_ARP, rev.name, |
1713 | rev.revision, 1, &ret), | 1721 | rev.revision, 1, &ret), |
1714 | "arpt_%s", rev.name); | 1722 | "arpt_%s", rev.name); |
1715 | break; | 1723 | break; |
@@ -1787,7 +1795,7 @@ void arpt_unregister_table(struct xt_table *table) | |||
1787 | static struct xt_target arpt_standard_target __read_mostly = { | 1795 | static struct xt_target arpt_standard_target __read_mostly = { |
1788 | .name = ARPT_STANDARD_TARGET, | 1796 | .name = ARPT_STANDARD_TARGET, |
1789 | .targetsize = sizeof(int), | 1797 | .targetsize = sizeof(int), |
1790 | .family = NF_ARP, | 1798 | .family = NFPROTO_ARP, |
1791 | #ifdef CONFIG_COMPAT | 1799 | #ifdef CONFIG_COMPAT |
1792 | .compatsize = sizeof(compat_int_t), | 1800 | .compatsize = sizeof(compat_int_t), |
1793 | .compat_from_user = compat_standard_from_user, | 1801 | .compat_from_user = compat_standard_from_user, |
@@ -1799,7 +1807,7 @@ static struct xt_target arpt_error_target __read_mostly = { | |||
1799 | .name = ARPT_ERROR_TARGET, | 1807 | .name = ARPT_ERROR_TARGET, |
1800 | .target = arpt_error, | 1808 | .target = arpt_error, |
1801 | .targetsize = ARPT_FUNCTION_MAXNAMELEN, | 1809 | .targetsize = ARPT_FUNCTION_MAXNAMELEN, |
1802 | .family = NF_ARP, | 1810 | .family = NFPROTO_ARP, |
1803 | }; | 1811 | }; |
1804 | 1812 | ||
1805 | static struct nf_sockopt_ops arpt_sockopts = { | 1813 | static struct nf_sockopt_ops arpt_sockopts = { |
@@ -1821,12 +1829,12 @@ static struct nf_sockopt_ops arpt_sockopts = { | |||
1821 | 1829 | ||
1822 | static int __net_init arp_tables_net_init(struct net *net) | 1830 | static int __net_init arp_tables_net_init(struct net *net) |
1823 | { | 1831 | { |
1824 | return xt_proto_init(net, NF_ARP); | 1832 | return xt_proto_init(net, NFPROTO_ARP); |
1825 | } | 1833 | } |
1826 | 1834 | ||
1827 | static void __net_exit arp_tables_net_exit(struct net *net) | 1835 | static void __net_exit arp_tables_net_exit(struct net *net) |
1828 | { | 1836 | { |
1829 | xt_proto_fini(net, NF_ARP); | 1837 | xt_proto_fini(net, NFPROTO_ARP); |
1830 | } | 1838 | } |
1831 | 1839 | ||
1832 | static struct pernet_operations arp_tables_net_ops = { | 1840 | static struct pernet_operations arp_tables_net_ops = { |
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c index a385959d2655..b0d5b1d0a769 100644 --- a/net/ipv4/netfilter/arpt_mangle.c +++ b/net/ipv4/netfilter/arpt_mangle.c | |||
@@ -9,12 +9,9 @@ MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); | |||
9 | MODULE_DESCRIPTION("arptables arp payload mangle target"); | 9 | MODULE_DESCRIPTION("arptables arp payload mangle target"); |
10 | 10 | ||
11 | static unsigned int | 11 | static unsigned int |
12 | target(struct sk_buff *skb, | 12 | target(struct sk_buff *skb, const struct xt_target_param *par) |
13 | const struct net_device *in, const struct net_device *out, | ||
14 | unsigned int hooknum, const struct xt_target *target, | ||
15 | const void *targinfo) | ||
16 | { | 13 | { |
17 | const struct arpt_mangle *mangle = targinfo; | 14 | const struct arpt_mangle *mangle = par->targinfo; |
18 | const struct arphdr *arp; | 15 | const struct arphdr *arp; |
19 | unsigned char *arpptr; | 16 | unsigned char *arpptr; |
20 | int pln, hln; | 17 | int pln, hln; |
@@ -57,11 +54,9 @@ target(struct sk_buff *skb, | |||
57 | return mangle->target; | 54 | return mangle->target; |
58 | } | 55 | } |
59 | 56 | ||
60 | static bool | 57 | static bool checkentry(const struct xt_tgchk_param *par) |
61 | checkentry(const char *tablename, const void *e, const struct xt_target *target, | ||
62 | void *targinfo, unsigned int hook_mask) | ||
63 | { | 58 | { |
64 | const struct arpt_mangle *mangle = targinfo; | 59 | const struct arpt_mangle *mangle = par->targinfo; |
65 | 60 | ||
66 | if (mangle->flags & ~ARPT_MANGLE_MASK || | 61 | if (mangle->flags & ~ARPT_MANGLE_MASK || |
67 | !(mangle->flags & ARPT_MANGLE_MASK)) | 62 | !(mangle->flags & ARPT_MANGLE_MASK)) |
@@ -75,7 +70,7 @@ checkentry(const char *tablename, const void *e, const struct xt_target *target, | |||
75 | 70 | ||
76 | static struct xt_target arpt_mangle_reg __read_mostly = { | 71 | static struct xt_target arpt_mangle_reg __read_mostly = { |
77 | .name = "mangle", | 72 | .name = "mangle", |
78 | .family = NF_ARP, | 73 | .family = NFPROTO_ARP, |
79 | .target = target, | 74 | .target = target, |
80 | .targetsize = sizeof(struct arpt_mangle), | 75 | .targetsize = sizeof(struct arpt_mangle), |
81 | .checkentry = checkentry, | 76 | .checkentry = checkentry, |
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c index 082f5dd3156c..bee3d117661a 100644 --- a/net/ipv4/netfilter/arptable_filter.c +++ b/net/ipv4/netfilter/arptable_filter.c | |||
@@ -51,7 +51,7 @@ static struct xt_table packet_filter = { | |||
51 | .lock = __RW_LOCK_UNLOCKED(packet_filter.lock), | 51 | .lock = __RW_LOCK_UNLOCKED(packet_filter.lock), |
52 | .private = NULL, | 52 | .private = NULL, |
53 | .me = THIS_MODULE, | 53 | .me = THIS_MODULE, |
54 | .af = NF_ARP, | 54 | .af = NFPROTO_ARP, |
55 | }; | 55 | }; |
56 | 56 | ||
57 | /* The work comes in here from netfilter.c */ | 57 | /* The work comes in here from netfilter.c */ |
@@ -89,21 +89,21 @@ static struct nf_hook_ops arpt_ops[] __read_mostly = { | |||
89 | { | 89 | { |
90 | .hook = arpt_in_hook, | 90 | .hook = arpt_in_hook, |
91 | .owner = THIS_MODULE, | 91 | .owner = THIS_MODULE, |
92 | .pf = NF_ARP, | 92 | .pf = NFPROTO_ARP, |
93 | .hooknum = NF_ARP_IN, | 93 | .hooknum = NF_ARP_IN, |
94 | .priority = NF_IP_PRI_FILTER, | 94 | .priority = NF_IP_PRI_FILTER, |
95 | }, | 95 | }, |
96 | { | 96 | { |
97 | .hook = arpt_out_hook, | 97 | .hook = arpt_out_hook, |
98 | .owner = THIS_MODULE, | 98 | .owner = THIS_MODULE, |
99 | .pf = NF_ARP, | 99 | .pf = NFPROTO_ARP, |
100 | .hooknum = NF_ARP_OUT, | 100 | .hooknum = NF_ARP_OUT, |
101 | .priority = NF_IP_PRI_FILTER, | 101 | .priority = NF_IP_PRI_FILTER, |
102 | }, | 102 | }, |
103 | { | 103 | { |
104 | .hook = arpt_forward_hook, | 104 | .hook = arpt_forward_hook, |
105 | .owner = THIS_MODULE, | 105 | .owner = THIS_MODULE, |
106 | .pf = NF_ARP, | 106 | .pf = NFPROTO_ARP, |
107 | .hooknum = NF_ARP_FORWARD, | 107 | .hooknum = NF_ARP_FORWARD, |
108 | .priority = NF_IP_PRI_FILTER, | 108 | .priority = NF_IP_PRI_FILTER, |
109 | }, | 109 | }, |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 4e7c719445c2..213fb27debc1 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -171,31 +171,25 @@ ip_checkentry(const struct ipt_ip *ip) | |||
171 | } | 171 | } |
172 | 172 | ||
173 | static unsigned int | 173 | static unsigned int |
174 | ipt_error(struct sk_buff *skb, | 174 | ipt_error(struct sk_buff *skb, const struct xt_target_param *par) |
175 | const struct net_device *in, | ||
176 | const struct net_device *out, | ||
177 | unsigned int hooknum, | ||
178 | const struct xt_target *target, | ||
179 | const void *targinfo) | ||
180 | { | 175 | { |
181 | if (net_ratelimit()) | 176 | if (net_ratelimit()) |
182 | printk("ip_tables: error: `%s'\n", (char *)targinfo); | 177 | printk("ip_tables: error: `%s'\n", |
178 | (const char *)par->targinfo); | ||
183 | 179 | ||
184 | return NF_DROP; | 180 | return NF_DROP; |
185 | } | 181 | } |
186 | 182 | ||
187 | /* Performance critical - called for every packet */ | 183 | /* Performance critical - called for every packet */ |
188 | static inline bool | 184 | static inline bool |
189 | do_match(struct ipt_entry_match *m, | 185 | do_match(struct ipt_entry_match *m, const struct sk_buff *skb, |
190 | const struct sk_buff *skb, | 186 | struct xt_match_param *par) |
191 | const struct net_device *in, | ||
192 | const struct net_device *out, | ||
193 | int offset, | ||
194 | bool *hotdrop) | ||
195 | { | 187 | { |
188 | par->match = m->u.kernel.match; | ||
189 | par->matchinfo = m->data; | ||
190 | |||
196 | /* Stop iteration if it doesn't match */ | 191 | /* Stop iteration if it doesn't match */ |
197 | if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data, | 192 | if (!m->u.kernel.match->match(skb, par)) |
198 | offset, ip_hdrlen(skb), hotdrop)) | ||
199 | return true; | 193 | return true; |
200 | else | 194 | else |
201 | return false; | 195 | return false; |
@@ -326,7 +320,6 @@ ipt_do_table(struct sk_buff *skb, | |||
326 | struct xt_table *table) | 320 | struct xt_table *table) |
327 | { | 321 | { |
328 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); | 322 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); |
329 | u_int16_t offset; | ||
330 | const struct iphdr *ip; | 323 | const struct iphdr *ip; |
331 | u_int16_t datalen; | 324 | u_int16_t datalen; |
332 | bool hotdrop = false; | 325 | bool hotdrop = false; |
@@ -336,6 +329,8 @@ ipt_do_table(struct sk_buff *skb, | |||
336 | void *table_base; | 329 | void *table_base; |
337 | struct ipt_entry *e, *back; | 330 | struct ipt_entry *e, *back; |
338 | struct xt_table_info *private; | 331 | struct xt_table_info *private; |
332 | struct xt_match_param mtpar; | ||
333 | struct xt_target_param tgpar; | ||
339 | 334 | ||
340 | /* Initialization */ | 335 | /* Initialization */ |
341 | ip = ip_hdr(skb); | 336 | ip = ip_hdr(skb); |
@@ -348,7 +343,13 @@ ipt_do_table(struct sk_buff *skb, | |||
348 | * things we don't know, ie. tcp syn flag or ports). If the | 343 | * things we don't know, ie. tcp syn flag or ports). If the |
349 | * rule is also a fragment-specific rule, non-fragments won't | 344 | * rule is also a fragment-specific rule, non-fragments won't |
350 | * match it. */ | 345 | * match it. */ |
351 | offset = ntohs(ip->frag_off) & IP_OFFSET; | 346 | mtpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; |
347 | mtpar.thoff = ip_hdrlen(skb); | ||
348 | mtpar.hotdrop = &hotdrop; | ||
349 | mtpar.in = tgpar.in = in; | ||
350 | mtpar.out = tgpar.out = out; | ||
351 | mtpar.family = tgpar.family = NFPROTO_IPV4; | ||
352 | tgpar.hooknum = hook; | ||
352 | 353 | ||
353 | read_lock_bh(&table->lock); | 354 | read_lock_bh(&table->lock); |
354 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); | 355 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); |
@@ -362,12 +363,11 @@ ipt_do_table(struct sk_buff *skb, | |||
362 | do { | 363 | do { |
363 | IP_NF_ASSERT(e); | 364 | IP_NF_ASSERT(e); |
364 | IP_NF_ASSERT(back); | 365 | IP_NF_ASSERT(back); |
365 | if (ip_packet_match(ip, indev, outdev, &e->ip, offset)) { | 366 | if (ip_packet_match(ip, indev, outdev, |
367 | &e->ip, mtpar.fragoff)) { | ||
366 | struct ipt_entry_target *t; | 368 | struct ipt_entry_target *t; |
367 | 369 | ||
368 | if (IPT_MATCH_ITERATE(e, do_match, | 370 | if (IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) |
369 | skb, in, out, | ||
370 | offset, &hotdrop) != 0) | ||
371 | goto no_match; | 371 | goto no_match; |
372 | 372 | ||
373 | ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); | 373 | ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); |
@@ -413,16 +413,14 @@ ipt_do_table(struct sk_buff *skb, | |||
413 | } else { | 413 | } else { |
414 | /* Targets which reenter must return | 414 | /* Targets which reenter must return |
415 | abs. verdicts */ | 415 | abs. verdicts */ |
416 | tgpar.target = t->u.kernel.target; | ||
417 | tgpar.targinfo = t->data; | ||
416 | #ifdef CONFIG_NETFILTER_DEBUG | 418 | #ifdef CONFIG_NETFILTER_DEBUG |
417 | ((struct ipt_entry *)table_base)->comefrom | 419 | ((struct ipt_entry *)table_base)->comefrom |
418 | = 0xeeeeeeec; | 420 | = 0xeeeeeeec; |
419 | #endif | 421 | #endif |
420 | verdict = t->u.kernel.target->target(skb, | 422 | verdict = t->u.kernel.target->target(skb, |
421 | in, out, | 423 | &tgpar); |
422 | hook, | ||
423 | t->u.kernel.target, | ||
424 | t->data); | ||
425 | |||
426 | #ifdef CONFIG_NETFILTER_DEBUG | 424 | #ifdef CONFIG_NETFILTER_DEBUG |
427 | if (((struct ipt_entry *)table_base)->comefrom | 425 | if (((struct ipt_entry *)table_base)->comefrom |
428 | != 0xeeeeeeec | 426 | != 0xeeeeeeec |
@@ -575,12 +573,17 @@ mark_source_chains(struct xt_table_info *newinfo, | |||
575 | static int | 573 | static int |
576 | cleanup_match(struct ipt_entry_match *m, unsigned int *i) | 574 | cleanup_match(struct ipt_entry_match *m, unsigned int *i) |
577 | { | 575 | { |
576 | struct xt_mtdtor_param par; | ||
577 | |||
578 | if (i && (*i)-- == 0) | 578 | if (i && (*i)-- == 0) |
579 | return 1; | 579 | return 1; |
580 | 580 | ||
581 | if (m->u.kernel.match->destroy) | 581 | par.match = m->u.kernel.match; |
582 | m->u.kernel.match->destroy(m->u.kernel.match, m->data); | 582 | par.matchinfo = m->data; |
583 | module_put(m->u.kernel.match->me); | 583 | par.family = NFPROTO_IPV4; |
584 | if (par.match->destroy != NULL) | ||
585 | par.match->destroy(&par); | ||
586 | module_put(par.match->me); | ||
584 | return 0; | 587 | return 0; |
585 | } | 588 | } |
586 | 589 | ||
@@ -606,34 +609,28 @@ check_entry(struct ipt_entry *e, const char *name) | |||
606 | } | 609 | } |
607 | 610 | ||
608 | static int | 611 | static int |
609 | check_match(struct ipt_entry_match *m, const char *name, | 612 | check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par, |
610 | const struct ipt_ip *ip, | 613 | unsigned int *i) |
611 | unsigned int hookmask, unsigned int *i) | ||
612 | { | 614 | { |
613 | struct xt_match *match; | 615 | const struct ipt_ip *ip = par->entryinfo; |
614 | int ret; | 616 | int ret; |
615 | 617 | ||
616 | match = m->u.kernel.match; | 618 | par->match = m->u.kernel.match; |
617 | ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m), | 619 | par->matchinfo = m->data; |
618 | name, hookmask, ip->proto, | 620 | |
619 | ip->invflags & IPT_INV_PROTO); | 621 | ret = xt_check_match(par, m->u.match_size - sizeof(*m), |
620 | if (!ret && m->u.kernel.match->checkentry | 622 | ip->proto, ip->invflags & IPT_INV_PROTO); |
621 | && !m->u.kernel.match->checkentry(name, ip, match, m->data, | 623 | if (ret < 0) { |
622 | hookmask)) { | ||
623 | duprintf("ip_tables: check failed for `%s'.\n", | 624 | duprintf("ip_tables: check failed for `%s'.\n", |
624 | m->u.kernel.match->name); | 625 | par.match->name); |
625 | ret = -EINVAL; | 626 | return ret; |
626 | } | 627 | } |
627 | if (!ret) | 628 | ++*i; |
628 | (*i)++; | 629 | return 0; |
629 | return ret; | ||
630 | } | 630 | } |
631 | 631 | ||
632 | static int | 632 | static int |
633 | find_check_match(struct ipt_entry_match *m, | 633 | find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par, |
634 | const char *name, | ||
635 | const struct ipt_ip *ip, | ||
636 | unsigned int hookmask, | ||
637 | unsigned int *i) | 634 | unsigned int *i) |
638 | { | 635 | { |
639 | struct xt_match *match; | 636 | struct xt_match *match; |
@@ -648,7 +645,7 @@ find_check_match(struct ipt_entry_match *m, | |||
648 | } | 645 | } |
649 | m->u.kernel.match = match; | 646 | m->u.kernel.match = match; |
650 | 647 | ||
651 | ret = check_match(m, name, ip, hookmask, i); | 648 | ret = check_match(m, par, i); |
652 | if (ret) | 649 | if (ret) |
653 | goto err; | 650 | goto err; |
654 | 651 | ||
@@ -660,23 +657,25 @@ err: | |||
660 | 657 | ||
661 | static int check_target(struct ipt_entry *e, const char *name) | 658 | static int check_target(struct ipt_entry *e, const char *name) |
662 | { | 659 | { |
663 | struct ipt_entry_target *t; | 660 | struct ipt_entry_target *t = ipt_get_target(e); |
664 | struct xt_target *target; | 661 | struct xt_tgchk_param par = { |
662 | .table = name, | ||
663 | .entryinfo = e, | ||
664 | .target = t->u.kernel.target, | ||
665 | .targinfo = t->data, | ||
666 | .hook_mask = e->comefrom, | ||
667 | .family = NFPROTO_IPV4, | ||
668 | }; | ||
665 | int ret; | 669 | int ret; |
666 | 670 | ||
667 | t = ipt_get_target(e); | 671 | ret = xt_check_target(&par, t->u.target_size - sizeof(*t), |
668 | target = t->u.kernel.target; | 672 | e->ip.proto, e->ip.invflags & IPT_INV_PROTO); |
669 | ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), | 673 | if (ret < 0) { |
670 | name, e->comefrom, e->ip.proto, | ||
671 | e->ip.invflags & IPT_INV_PROTO); | ||
672 | if (!ret && t->u.kernel.target->checkentry | ||
673 | && !t->u.kernel.target->checkentry(name, e, target, t->data, | ||
674 | e->comefrom)) { | ||
675 | duprintf("ip_tables: check failed for `%s'.\n", | 674 | duprintf("ip_tables: check failed for `%s'.\n", |
676 | t->u.kernel.target->name); | 675 | t->u.kernel.target->name); |
677 | ret = -EINVAL; | 676 | return ret; |
678 | } | 677 | } |
679 | return ret; | 678 | return 0; |
680 | } | 679 | } |
681 | 680 | ||
682 | static int | 681 | static int |
@@ -687,14 +686,18 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size, | |||
687 | struct xt_target *target; | 686 | struct xt_target *target; |
688 | int ret; | 687 | int ret; |
689 | unsigned int j; | 688 | unsigned int j; |
689 | struct xt_mtchk_param mtpar; | ||
690 | 690 | ||
691 | ret = check_entry(e, name); | 691 | ret = check_entry(e, name); |
692 | if (ret) | 692 | if (ret) |
693 | return ret; | 693 | return ret; |
694 | 694 | ||
695 | j = 0; | 695 | j = 0; |
696 | ret = IPT_MATCH_ITERATE(e, find_check_match, name, &e->ip, | 696 | mtpar.table = name; |
697 | e->comefrom, &j); | 697 | mtpar.entryinfo = &e->ip; |
698 | mtpar.hook_mask = e->comefrom; | ||
699 | mtpar.family = NFPROTO_IPV4; | ||
700 | ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j); | ||
698 | if (ret != 0) | 701 | if (ret != 0) |
699 | goto cleanup_matches; | 702 | goto cleanup_matches; |
700 | 703 | ||
@@ -769,6 +772,7 @@ check_entry_size_and_hooks(struct ipt_entry *e, | |||
769 | static int | 772 | static int |
770 | cleanup_entry(struct ipt_entry *e, unsigned int *i) | 773 | cleanup_entry(struct ipt_entry *e, unsigned int *i) |
771 | { | 774 | { |
775 | struct xt_tgdtor_param par; | ||
772 | struct ipt_entry_target *t; | 776 | struct ipt_entry_target *t; |
773 | 777 | ||
774 | if (i && (*i)-- == 0) | 778 | if (i && (*i)-- == 0) |
@@ -777,9 +781,13 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i) | |||
777 | /* Cleanup all matches */ | 781 | /* Cleanup all matches */ |
778 | IPT_MATCH_ITERATE(e, cleanup_match, NULL); | 782 | IPT_MATCH_ITERATE(e, cleanup_match, NULL); |
779 | t = ipt_get_target(e); | 783 | t = ipt_get_target(e); |
780 | if (t->u.kernel.target->destroy) | 784 | |
781 | t->u.kernel.target->destroy(t->u.kernel.target, t->data); | 785 | par.target = t->u.kernel.target; |
782 | module_put(t->u.kernel.target->me); | 786 | par.targinfo = t->data; |
787 | par.family = NFPROTO_IPV4; | ||
788 | if (par.target->destroy != NULL) | ||
789 | par.target->destroy(&par); | ||
790 | module_put(par.target->me); | ||
783 | return 0; | 791 | return 0; |
784 | } | 792 | } |
785 | 793 | ||
@@ -1648,12 +1656,16 @@ static int | |||
1648 | compat_check_entry(struct ipt_entry *e, const char *name, | 1656 | compat_check_entry(struct ipt_entry *e, const char *name, |
1649 | unsigned int *i) | 1657 | unsigned int *i) |
1650 | { | 1658 | { |
1659 | struct xt_mtchk_param mtpar; | ||
1651 | unsigned int j; | 1660 | unsigned int j; |
1652 | int ret; | 1661 | int ret; |
1653 | 1662 | ||
1654 | j = 0; | 1663 | j = 0; |
1655 | ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, | 1664 | mtpar.table = name; |
1656 | e->comefrom, &j); | 1665 | mtpar.entryinfo = &e->ip; |
1666 | mtpar.hook_mask = e->comefrom; | ||
1667 | mtpar.family = NFPROTO_IPV4; | ||
1668 | ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j); | ||
1657 | if (ret) | 1669 | if (ret) |
1658 | goto cleanup_matches; | 1670 | goto cleanup_matches; |
1659 | 1671 | ||
@@ -2121,30 +2133,23 @@ icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code, | |||
2121 | } | 2133 | } |
2122 | 2134 | ||
2123 | static bool | 2135 | static bool |
2124 | icmp_match(const struct sk_buff *skb, | 2136 | icmp_match(const struct sk_buff *skb, const struct xt_match_param *par) |
2125 | const struct net_device *in, | ||
2126 | const struct net_device *out, | ||
2127 | const struct xt_match *match, | ||
2128 | const void *matchinfo, | ||
2129 | int offset, | ||
2130 | unsigned int protoff, | ||
2131 | bool *hotdrop) | ||
2132 | { | 2137 | { |
2133 | const struct icmphdr *ic; | 2138 | const struct icmphdr *ic; |
2134 | struct icmphdr _icmph; | 2139 | struct icmphdr _icmph; |
2135 | const struct ipt_icmp *icmpinfo = matchinfo; | 2140 | const struct ipt_icmp *icmpinfo = par->matchinfo; |
2136 | 2141 | ||
2137 | /* Must not be a fragment. */ | 2142 | /* Must not be a fragment. */ |
2138 | if (offset) | 2143 | if (par->fragoff != 0) |
2139 | return false; | 2144 | return false; |
2140 | 2145 | ||
2141 | ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph); | 2146 | ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph); |
2142 | if (ic == NULL) { | 2147 | if (ic == NULL) { |
2143 | /* We've been asked to examine this packet, and we | 2148 | /* We've been asked to examine this packet, and we |
2144 | * can't. Hence, no choice but to drop. | 2149 | * can't. Hence, no choice but to drop. |
2145 | */ | 2150 | */ |
2146 | duprintf("Dropping evil ICMP tinygram.\n"); | 2151 | duprintf("Dropping evil ICMP tinygram.\n"); |
2147 | *hotdrop = true; | 2152 | *par->hotdrop = true; |
2148 | return false; | 2153 | return false; |
2149 | } | 2154 | } |
2150 | 2155 | ||
@@ -2155,15 +2160,9 @@ icmp_match(const struct sk_buff *skb, | |||
2155 | !!(icmpinfo->invflags&IPT_ICMP_INV)); | 2160 | !!(icmpinfo->invflags&IPT_ICMP_INV)); |
2156 | } | 2161 | } |
2157 | 2162 | ||
2158 | /* Called when user tries to insert an entry of this type. */ | 2163 | static bool icmp_checkentry(const struct xt_mtchk_param *par) |
2159 | static bool | ||
2160 | icmp_checkentry(const char *tablename, | ||
2161 | const void *entry, | ||
2162 | const struct xt_match *match, | ||
2163 | void *matchinfo, | ||
2164 | unsigned int hook_mask) | ||
2165 | { | 2164 | { |
2166 | const struct ipt_icmp *icmpinfo = matchinfo; | 2165 | const struct ipt_icmp *icmpinfo = par->matchinfo; |
2167 | 2166 | ||
2168 | /* Must specify no unknown invflags */ | 2167 | /* Must specify no unknown invflags */ |
2169 | return !(icmpinfo->invflags & ~IPT_ICMP_INV); | 2168 | return !(icmpinfo->invflags & ~IPT_ICMP_INV); |
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index fafe8ebb4c55..7ac1677419a9 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -281,11 +281,9 @@ clusterip_responsible(const struct clusterip_config *config, u_int32_t hash) | |||
281 | ***********************************************************************/ | 281 | ***********************************************************************/ |
282 | 282 | ||
283 | static unsigned int | 283 | static unsigned int |
284 | clusterip_tg(struct sk_buff *skb, const struct net_device *in, | 284 | clusterip_tg(struct sk_buff *skb, const struct xt_target_param *par) |
285 | const struct net_device *out, unsigned int hooknum, | ||
286 | const struct xt_target *target, const void *targinfo) | ||
287 | { | 285 | { |
288 | const struct ipt_clusterip_tgt_info *cipinfo = targinfo; | 286 | const struct ipt_clusterip_tgt_info *cipinfo = par->targinfo; |
289 | struct nf_conn *ct; | 287 | struct nf_conn *ct; |
290 | enum ip_conntrack_info ctinfo; | 288 | enum ip_conntrack_info ctinfo; |
291 | u_int32_t hash; | 289 | u_int32_t hash; |
@@ -349,13 +347,10 @@ clusterip_tg(struct sk_buff *skb, const struct net_device *in, | |||
349 | return XT_CONTINUE; | 347 | return XT_CONTINUE; |
350 | } | 348 | } |
351 | 349 | ||
352 | static bool | 350 | static bool clusterip_tg_check(const struct xt_tgchk_param *par) |
353 | clusterip_tg_check(const char *tablename, const void *e_void, | ||
354 | const struct xt_target *target, void *targinfo, | ||
355 | unsigned int hook_mask) | ||
356 | { | 351 | { |
357 | struct ipt_clusterip_tgt_info *cipinfo = targinfo; | 352 | struct ipt_clusterip_tgt_info *cipinfo = par->targinfo; |
358 | const struct ipt_entry *e = e_void; | 353 | const struct ipt_entry *e = par->entryinfo; |
359 | 354 | ||
360 | struct clusterip_config *config; | 355 | struct clusterip_config *config; |
361 | 356 | ||
@@ -406,9 +401,9 @@ clusterip_tg_check(const char *tablename, const void *e_void, | |||
406 | } | 401 | } |
407 | cipinfo->config = config; | 402 | cipinfo->config = config; |
408 | 403 | ||
409 | if (nf_ct_l3proto_try_module_get(target->family) < 0) { | 404 | if (nf_ct_l3proto_try_module_get(par->target->family) < 0) { |
410 | printk(KERN_WARNING "can't load conntrack support for " | 405 | printk(KERN_WARNING "can't load conntrack support for " |
411 | "proto=%u\n", target->family); | 406 | "proto=%u\n", par->target->family); |
412 | return false; | 407 | return false; |
413 | } | 408 | } |
414 | 409 | ||
@@ -416,9 +411,9 @@ clusterip_tg_check(const char *tablename, const void *e_void, | |||
416 | } | 411 | } |
417 | 412 | ||
418 | /* drop reference count of cluster config when rule is deleted */ | 413 | /* drop reference count of cluster config when rule is deleted */ |
419 | static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo) | 414 | static void clusterip_tg_destroy(const struct xt_tgdtor_param *par) |
420 | { | 415 | { |
421 | const struct ipt_clusterip_tgt_info *cipinfo = targinfo; | 416 | const struct ipt_clusterip_tgt_info *cipinfo = par->targinfo; |
422 | 417 | ||
423 | /* if no more entries are referencing the config, remove it | 418 | /* if no more entries are referencing the config, remove it |
424 | * from the list and destroy the proc entry */ | 419 | * from the list and destroy the proc entry */ |
@@ -426,7 +421,7 @@ static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo) | |||
426 | 421 | ||
427 | clusterip_config_put(cipinfo->config); | 422 | clusterip_config_put(cipinfo->config); |
428 | 423 | ||
429 | nf_ct_l3proto_module_put(target->family); | 424 | nf_ct_l3proto_module_put(par->target->family); |
430 | } | 425 | } |
431 | 426 | ||
432 | #ifdef CONFIG_COMPAT | 427 | #ifdef CONFIG_COMPAT |
@@ -445,7 +440,7 @@ struct compat_ipt_clusterip_tgt_info | |||
445 | 440 | ||
446 | static struct xt_target clusterip_tg_reg __read_mostly = { | 441 | static struct xt_target clusterip_tg_reg __read_mostly = { |
447 | .name = "CLUSTERIP", | 442 | .name = "CLUSTERIP", |
448 | .family = AF_INET, | 443 | .family = NFPROTO_IPV4, |
449 | .target = clusterip_tg, | 444 | .target = clusterip_tg, |
450 | .checkentry = clusterip_tg_check, | 445 | .checkentry = clusterip_tg_check, |
451 | .destroy = clusterip_tg_destroy, | 446 | .destroy = clusterip_tg_destroy, |
@@ -546,7 +541,7 @@ arp_mangle(unsigned int hook, | |||
546 | 541 | ||
547 | static struct nf_hook_ops cip_arp_ops __read_mostly = { | 542 | static struct nf_hook_ops cip_arp_ops __read_mostly = { |
548 | .hook = arp_mangle, | 543 | .hook = arp_mangle, |
549 | .pf = NF_ARP, | 544 | .pf = NFPROTO_ARP, |
550 | .hooknum = NF_ARP_OUT, | 545 | .hooknum = NF_ARP_OUT, |
551 | .priority = -1 | 546 | .priority = -1 |
552 | }; | 547 | }; |
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c index d60139c134ca..f7e2fa0974dc 100644 --- a/net/ipv4/netfilter/ipt_ECN.c +++ b/net/ipv4/netfilter/ipt_ECN.c | |||
@@ -77,11 +77,9 @@ set_ect_tcp(struct sk_buff *skb, const struct ipt_ECN_info *einfo) | |||
77 | } | 77 | } |
78 | 78 | ||
79 | static unsigned int | 79 | static unsigned int |
80 | ecn_tg(struct sk_buff *skb, const struct net_device *in, | 80 | ecn_tg(struct sk_buff *skb, const struct xt_target_param *par) |
81 | const struct net_device *out, unsigned int hooknum, | ||
82 | const struct xt_target *target, const void *targinfo) | ||
83 | { | 81 | { |
84 | const struct ipt_ECN_info *einfo = targinfo; | 82 | const struct ipt_ECN_info *einfo = par->targinfo; |
85 | 83 | ||
86 | if (einfo->operation & IPT_ECN_OP_SET_IP) | 84 | if (einfo->operation & IPT_ECN_OP_SET_IP) |
87 | if (!set_ect_ip(skb, einfo)) | 85 | if (!set_ect_ip(skb, einfo)) |
@@ -95,13 +93,10 @@ ecn_tg(struct sk_buff *skb, const struct net_device *in, | |||
95 | return XT_CONTINUE; | 93 | return XT_CONTINUE; |
96 | } | 94 | } |
97 | 95 | ||
98 | static bool | 96 | static bool ecn_tg_check(const struct xt_tgchk_param *par) |
99 | ecn_tg_check(const char *tablename, const void *e_void, | ||
100 | const struct xt_target *target, void *targinfo, | ||
101 | unsigned int hook_mask) | ||
102 | { | 97 | { |
103 | const struct ipt_ECN_info *einfo = targinfo; | 98 | const struct ipt_ECN_info *einfo = par->targinfo; |
104 | const struct ipt_entry *e = e_void; | 99 | const struct ipt_entry *e = par->entryinfo; |
105 | 100 | ||
106 | if (einfo->operation & IPT_ECN_OP_MASK) { | 101 | if (einfo->operation & IPT_ECN_OP_MASK) { |
107 | printk(KERN_WARNING "ECN: unsupported ECN operation %x\n", | 102 | printk(KERN_WARNING "ECN: unsupported ECN operation %x\n", |
@@ -124,7 +119,7 @@ ecn_tg_check(const char *tablename, const void *e_void, | |||
124 | 119 | ||
125 | static struct xt_target ecn_tg_reg __read_mostly = { | 120 | static struct xt_target ecn_tg_reg __read_mostly = { |
126 | .name = "ECN", | 121 | .name = "ECN", |
127 | .family = AF_INET, | 122 | .family = NFPROTO_IPV4, |
128 | .target = ecn_tg, | 123 | .target = ecn_tg, |
129 | .targetsize = sizeof(struct ipt_ECN_info), | 124 | .targetsize = sizeof(struct ipt_ECN_info), |
130 | .table = "mangle", | 125 | .table = "mangle", |
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index 0af14137137b..fc6ce04a3e35 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c | |||
@@ -375,7 +375,7 @@ static struct nf_loginfo default_loginfo = { | |||
375 | }; | 375 | }; |
376 | 376 | ||
377 | static void | 377 | static void |
378 | ipt_log_packet(unsigned int pf, | 378 | ipt_log_packet(u_int8_t pf, |
379 | unsigned int hooknum, | 379 | unsigned int hooknum, |
380 | const struct sk_buff *skb, | 380 | const struct sk_buff *skb, |
381 | const struct net_device *in, | 381 | const struct net_device *in, |
@@ -426,28 +426,23 @@ ipt_log_packet(unsigned int pf, | |||
426 | } | 426 | } |
427 | 427 | ||
428 | static unsigned int | 428 | static unsigned int |
429 | log_tg(struct sk_buff *skb, const struct net_device *in, | 429 | log_tg(struct sk_buff *skb, const struct xt_target_param *par) |
430 | const struct net_device *out, unsigned int hooknum, | ||
431 | const struct xt_target *target, const void *targinfo) | ||
432 | { | 430 | { |
433 | const struct ipt_log_info *loginfo = targinfo; | 431 | const struct ipt_log_info *loginfo = par->targinfo; |
434 | struct nf_loginfo li; | 432 | struct nf_loginfo li; |
435 | 433 | ||
436 | li.type = NF_LOG_TYPE_LOG; | 434 | li.type = NF_LOG_TYPE_LOG; |
437 | li.u.log.level = loginfo->level; | 435 | li.u.log.level = loginfo->level; |
438 | li.u.log.logflags = loginfo->logflags; | 436 | li.u.log.logflags = loginfo->logflags; |
439 | 437 | ||
440 | ipt_log_packet(PF_INET, hooknum, skb, in, out, &li, | 438 | ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in, par->out, &li, |
441 | loginfo->prefix); | 439 | loginfo->prefix); |
442 | return XT_CONTINUE; | 440 | return XT_CONTINUE; |
443 | } | 441 | } |
444 | 442 | ||
445 | static bool | 443 | static bool log_tg_check(const struct xt_tgchk_param *par) |
446 | log_tg_check(const char *tablename, const void *e, | ||
447 | const struct xt_target *target, void *targinfo, | ||
448 | unsigned int hook_mask) | ||
449 | { | 444 | { |
450 | const struct ipt_log_info *loginfo = targinfo; | 445 | const struct ipt_log_info *loginfo = par->targinfo; |
451 | 446 | ||
452 | if (loginfo->level >= 8) { | 447 | if (loginfo->level >= 8) { |
453 | pr_debug("LOG: level %u >= 8\n", loginfo->level); | 448 | pr_debug("LOG: level %u >= 8\n", loginfo->level); |
@@ -463,7 +458,7 @@ log_tg_check(const char *tablename, const void *e, | |||
463 | 458 | ||
464 | static struct xt_target log_tg_reg __read_mostly = { | 459 | static struct xt_target log_tg_reg __read_mostly = { |
465 | .name = "LOG", | 460 | .name = "LOG", |
466 | .family = AF_INET, | 461 | .family = NFPROTO_IPV4, |
467 | .target = log_tg, | 462 | .target = log_tg, |
468 | .targetsize = sizeof(struct ipt_log_info), | 463 | .targetsize = sizeof(struct ipt_log_info), |
469 | .checkentry = log_tg_check, | 464 | .checkentry = log_tg_check, |
@@ -483,7 +478,7 @@ static int __init log_tg_init(void) | |||
483 | ret = xt_register_target(&log_tg_reg); | 478 | ret = xt_register_target(&log_tg_reg); |
484 | if (ret < 0) | 479 | if (ret < 0) |
485 | return ret; | 480 | return ret; |
486 | nf_log_register(PF_INET, &ipt_log_logger); | 481 | nf_log_register(NFPROTO_IPV4, &ipt_log_logger); |
487 | return 0; | 482 | return 0; |
488 | } | 483 | } |
489 | 484 | ||
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c index 0841aefaa503..f389f60cb105 100644 --- a/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c | |||
@@ -31,12 +31,9 @@ MODULE_DESCRIPTION("Xtables: automatic-address SNAT"); | |||
31 | static DEFINE_RWLOCK(masq_lock); | 31 | static DEFINE_RWLOCK(masq_lock); |
32 | 32 | ||
33 | /* FIXME: Multiple targets. --RR */ | 33 | /* FIXME: Multiple targets. --RR */ |
34 | static bool | 34 | static bool masquerade_tg_check(const struct xt_tgchk_param *par) |
35 | masquerade_tg_check(const char *tablename, const void *e, | ||
36 | const struct xt_target *target, void *targinfo, | ||
37 | unsigned int hook_mask) | ||
38 | { | 35 | { |
39 | const struct nf_nat_multi_range_compat *mr = targinfo; | 36 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
40 | 37 | ||
41 | if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { | 38 | if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { |
42 | pr_debug("masquerade_check: bad MAP_IPS.\n"); | 39 | pr_debug("masquerade_check: bad MAP_IPS.\n"); |
@@ -50,9 +47,7 @@ masquerade_tg_check(const char *tablename, const void *e, | |||
50 | } | 47 | } |
51 | 48 | ||
52 | static unsigned int | 49 | static unsigned int |
53 | masquerade_tg(struct sk_buff *skb, const struct net_device *in, | 50 | masquerade_tg(struct sk_buff *skb, const struct xt_target_param *par) |
54 | const struct net_device *out, unsigned int hooknum, | ||
55 | const struct xt_target *target, const void *targinfo) | ||
56 | { | 51 | { |
57 | struct nf_conn *ct; | 52 | struct nf_conn *ct; |
58 | struct nf_conn_nat *nat; | 53 | struct nf_conn_nat *nat; |
@@ -62,7 +57,7 @@ masquerade_tg(struct sk_buff *skb, const struct net_device *in, | |||
62 | const struct rtable *rt; | 57 | const struct rtable *rt; |
63 | __be32 newsrc; | 58 | __be32 newsrc; |
64 | 59 | ||
65 | NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING); | 60 | NF_CT_ASSERT(par->hooknum == NF_INET_POST_ROUTING); |
66 | 61 | ||
67 | ct = nf_ct_get(skb, &ctinfo); | 62 | ct = nf_ct_get(skb, &ctinfo); |
68 | nat = nfct_nat(ct); | 63 | nat = nfct_nat(ct); |
@@ -76,16 +71,16 @@ masquerade_tg(struct sk_buff *skb, const struct net_device *in, | |||
76 | if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip == 0) | 71 | if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip == 0) |
77 | return NF_ACCEPT; | 72 | return NF_ACCEPT; |
78 | 73 | ||
79 | mr = targinfo; | 74 | mr = par->targinfo; |
80 | rt = skb->rtable; | 75 | rt = skb->rtable; |
81 | newsrc = inet_select_addr(out, rt->rt_gateway, RT_SCOPE_UNIVERSE); | 76 | newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE); |
82 | if (!newsrc) { | 77 | if (!newsrc) { |
83 | printk("MASQUERADE: %s ate my IP address\n", out->name); | 78 | printk("MASQUERADE: %s ate my IP address\n", par->out->name); |
84 | return NF_DROP; | 79 | return NF_DROP; |
85 | } | 80 | } |
86 | 81 | ||
87 | write_lock_bh(&masq_lock); | 82 | write_lock_bh(&masq_lock); |
88 | nat->masq_index = out->ifindex; | 83 | nat->masq_index = par->out->ifindex; |
89 | write_unlock_bh(&masq_lock); | 84 | write_unlock_bh(&masq_lock); |
90 | 85 | ||
91 | /* Transfer from original range. */ | 86 | /* Transfer from original range. */ |
@@ -119,9 +114,7 @@ static int masq_device_event(struct notifier_block *this, | |||
119 | void *ptr) | 114 | void *ptr) |
120 | { | 115 | { |
121 | const struct net_device *dev = ptr; | 116 | const struct net_device *dev = ptr; |
122 | 117 | struct net *net = dev_net(dev); | |
123 | if (!net_eq(dev_net(dev), &init_net)) | ||
124 | return NOTIFY_DONE; | ||
125 | 118 | ||
126 | if (event == NETDEV_DOWN) { | 119 | if (event == NETDEV_DOWN) { |
127 | /* Device was downed. Search entire table for | 120 | /* Device was downed. Search entire table for |
@@ -129,7 +122,8 @@ static int masq_device_event(struct notifier_block *this, | |||
129 | and forget them. */ | 122 | and forget them. */ |
130 | NF_CT_ASSERT(dev->ifindex != 0); | 123 | NF_CT_ASSERT(dev->ifindex != 0); |
131 | 124 | ||
132 | nf_ct_iterate_cleanup(device_cmp, (void *)(long)dev->ifindex); | 125 | nf_ct_iterate_cleanup(net, device_cmp, |
126 | (void *)(long)dev->ifindex); | ||
133 | } | 127 | } |
134 | 128 | ||
135 | return NOTIFY_DONE; | 129 | return NOTIFY_DONE; |
@@ -153,7 +147,7 @@ static struct notifier_block masq_inet_notifier = { | |||
153 | 147 | ||
154 | static struct xt_target masquerade_tg_reg __read_mostly = { | 148 | static struct xt_target masquerade_tg_reg __read_mostly = { |
155 | .name = "MASQUERADE", | 149 | .name = "MASQUERADE", |
156 | .family = AF_INET, | 150 | .family = NFPROTO_IPV4, |
157 | .target = masquerade_tg, | 151 | .target = masquerade_tg, |
158 | .targetsize = sizeof(struct nf_nat_multi_range_compat), | 152 | .targetsize = sizeof(struct nf_nat_multi_range_compat), |
159 | .table = "nat", | 153 | .table = "nat", |
diff --git a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c index 6739abfd1521..7c29582d4ec8 100644 --- a/net/ipv4/netfilter/ipt_NETMAP.c +++ b/net/ipv4/netfilter/ipt_NETMAP.c | |||
@@ -22,12 +22,9 @@ MODULE_LICENSE("GPL"); | |||
22 | MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>"); | 22 | MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>"); |
23 | MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets"); | 23 | MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets"); |
24 | 24 | ||
25 | static bool | 25 | static bool netmap_tg_check(const struct xt_tgchk_param *par) |
26 | netmap_tg_check(const char *tablename, const void *e, | ||
27 | const struct xt_target *target, void *targinfo, | ||
28 | unsigned int hook_mask) | ||
29 | { | 26 | { |
30 | const struct nf_nat_multi_range_compat *mr = targinfo; | 27 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
31 | 28 | ||
32 | if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) { | 29 | if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) { |
33 | pr_debug("NETMAP:check: bad MAP_IPS.\n"); | 30 | pr_debug("NETMAP:check: bad MAP_IPS.\n"); |
@@ -41,24 +38,23 @@ netmap_tg_check(const char *tablename, const void *e, | |||
41 | } | 38 | } |
42 | 39 | ||
43 | static unsigned int | 40 | static unsigned int |
44 | netmap_tg(struct sk_buff *skb, const struct net_device *in, | 41 | netmap_tg(struct sk_buff *skb, const struct xt_target_param *par) |
45 | const struct net_device *out, unsigned int hooknum, | ||
46 | const struct xt_target *target, const void *targinfo) | ||
47 | { | 42 | { |
48 | struct nf_conn *ct; | 43 | struct nf_conn *ct; |
49 | enum ip_conntrack_info ctinfo; | 44 | enum ip_conntrack_info ctinfo; |
50 | __be32 new_ip, netmask; | 45 | __be32 new_ip, netmask; |
51 | const struct nf_nat_multi_range_compat *mr = targinfo; | 46 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
52 | struct nf_nat_range newrange; | 47 | struct nf_nat_range newrange; |
53 | 48 | ||
54 | NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING | 49 | NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING || |
55 | || hooknum == NF_INET_POST_ROUTING | 50 | par->hooknum == NF_INET_POST_ROUTING || |
56 | || hooknum == NF_INET_LOCAL_OUT); | 51 | par->hooknum == NF_INET_LOCAL_OUT); |
57 | ct = nf_ct_get(skb, &ctinfo); | 52 | ct = nf_ct_get(skb, &ctinfo); |
58 | 53 | ||
59 | netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip); | 54 | netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip); |
60 | 55 | ||
61 | if (hooknum == NF_INET_PRE_ROUTING || hooknum == NF_INET_LOCAL_OUT) | 56 | if (par->hooknum == NF_INET_PRE_ROUTING || |
57 | par->hooknum == NF_INET_LOCAL_OUT) | ||
62 | new_ip = ip_hdr(skb)->daddr & ~netmask; | 58 | new_ip = ip_hdr(skb)->daddr & ~netmask; |
63 | else | 59 | else |
64 | new_ip = ip_hdr(skb)->saddr & ~netmask; | 60 | new_ip = ip_hdr(skb)->saddr & ~netmask; |
@@ -70,12 +66,12 @@ netmap_tg(struct sk_buff *skb, const struct net_device *in, | |||
70 | mr->range[0].min, mr->range[0].max }); | 66 | mr->range[0].min, mr->range[0].max }); |
71 | 67 | ||
72 | /* Hand modified range to generic setup. */ | 68 | /* Hand modified range to generic setup. */ |
73 | return nf_nat_setup_info(ct, &newrange, HOOK2MANIP(hooknum)); | 69 | return nf_nat_setup_info(ct, &newrange, HOOK2MANIP(par->hooknum)); |
74 | } | 70 | } |
75 | 71 | ||
76 | static struct xt_target netmap_tg_reg __read_mostly = { | 72 | static struct xt_target netmap_tg_reg __read_mostly = { |
77 | .name = "NETMAP", | 73 | .name = "NETMAP", |
78 | .family = AF_INET, | 74 | .family = NFPROTO_IPV4, |
79 | .target = netmap_tg, | 75 | .target = netmap_tg, |
80 | .targetsize = sizeof(struct nf_nat_multi_range_compat), | 76 | .targetsize = sizeof(struct nf_nat_multi_range_compat), |
81 | .table = "nat", | 77 | .table = "nat", |
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c index 5c6292449d13..698e5e78685b 100644 --- a/net/ipv4/netfilter/ipt_REDIRECT.c +++ b/net/ipv4/netfilter/ipt_REDIRECT.c | |||
@@ -26,12 +26,9 @@ MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); | |||
26 | MODULE_DESCRIPTION("Xtables: Connection redirection to localhost"); | 26 | MODULE_DESCRIPTION("Xtables: Connection redirection to localhost"); |
27 | 27 | ||
28 | /* FIXME: Take multiple ranges --RR */ | 28 | /* FIXME: Take multiple ranges --RR */ |
29 | static bool | 29 | static bool redirect_tg_check(const struct xt_tgchk_param *par) |
30 | redirect_tg_check(const char *tablename, const void *e, | ||
31 | const struct xt_target *target, void *targinfo, | ||
32 | unsigned int hook_mask) | ||
33 | { | 30 | { |
34 | const struct nf_nat_multi_range_compat *mr = targinfo; | 31 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
35 | 32 | ||
36 | if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { | 33 | if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { |
37 | pr_debug("redirect_check: bad MAP_IPS.\n"); | 34 | pr_debug("redirect_check: bad MAP_IPS.\n"); |
@@ -45,24 +42,22 @@ redirect_tg_check(const char *tablename, const void *e, | |||
45 | } | 42 | } |
46 | 43 | ||
47 | static unsigned int | 44 | static unsigned int |
48 | redirect_tg(struct sk_buff *skb, const struct net_device *in, | 45 | redirect_tg(struct sk_buff *skb, const struct xt_target_param *par) |
49 | const struct net_device *out, unsigned int hooknum, | ||
50 | const struct xt_target *target, const void *targinfo) | ||
51 | { | 46 | { |
52 | struct nf_conn *ct; | 47 | struct nf_conn *ct; |
53 | enum ip_conntrack_info ctinfo; | 48 | enum ip_conntrack_info ctinfo; |
54 | __be32 newdst; | 49 | __be32 newdst; |
55 | const struct nf_nat_multi_range_compat *mr = targinfo; | 50 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
56 | struct nf_nat_range newrange; | 51 | struct nf_nat_range newrange; |
57 | 52 | ||
58 | NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING | 53 | NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING || |
59 | || hooknum == NF_INET_LOCAL_OUT); | 54 | par->hooknum == NF_INET_LOCAL_OUT); |
60 | 55 | ||
61 | ct = nf_ct_get(skb, &ctinfo); | 56 | ct = nf_ct_get(skb, &ctinfo); |
62 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); | 57 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); |
63 | 58 | ||
64 | /* Local packets: make them go to loopback */ | 59 | /* Local packets: make them go to loopback */ |
65 | if (hooknum == NF_INET_LOCAL_OUT) | 60 | if (par->hooknum == NF_INET_LOCAL_OUT) |
66 | newdst = htonl(0x7F000001); | 61 | newdst = htonl(0x7F000001); |
67 | else { | 62 | else { |
68 | struct in_device *indev; | 63 | struct in_device *indev; |
@@ -92,7 +87,7 @@ redirect_tg(struct sk_buff *skb, const struct net_device *in, | |||
92 | 87 | ||
93 | static struct xt_target redirect_tg_reg __read_mostly = { | 88 | static struct xt_target redirect_tg_reg __read_mostly = { |
94 | .name = "REDIRECT", | 89 | .name = "REDIRECT", |
95 | .family = AF_INET, | 90 | .family = NFPROTO_IPV4, |
96 | .target = redirect_tg, | 91 | .target = redirect_tg, |
97 | .targetsize = sizeof(struct nf_nat_multi_range_compat), | 92 | .targetsize = sizeof(struct nf_nat_multi_range_compat), |
98 | .table = "nat", | 93 | .table = "nat", |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 2639872849da..0b4b6e0ff2b9 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -136,11 +136,9 @@ static inline void send_unreach(struct sk_buff *skb_in, int code) | |||
136 | } | 136 | } |
137 | 137 | ||
138 | static unsigned int | 138 | static unsigned int |
139 | reject_tg(struct sk_buff *skb, const struct net_device *in, | 139 | reject_tg(struct sk_buff *skb, const struct xt_target_param *par) |
140 | const struct net_device *out, unsigned int hooknum, | ||
141 | const struct xt_target *target, const void *targinfo) | ||
142 | { | 140 | { |
143 | const struct ipt_reject_info *reject = targinfo; | 141 | const struct ipt_reject_info *reject = par->targinfo; |
144 | 142 | ||
145 | /* WARNING: This code causes reentry within iptables. | 143 | /* WARNING: This code causes reentry within iptables. |
146 | This means that the iptables jump stack is now crap. We | 144 | This means that the iptables jump stack is now crap. We |
@@ -168,7 +166,7 @@ reject_tg(struct sk_buff *skb, const struct net_device *in, | |||
168 | send_unreach(skb, ICMP_PKT_FILTERED); | 166 | send_unreach(skb, ICMP_PKT_FILTERED); |
169 | break; | 167 | break; |
170 | case IPT_TCP_RESET: | 168 | case IPT_TCP_RESET: |
171 | send_reset(skb, hooknum); | 169 | send_reset(skb, par->hooknum); |
172 | case IPT_ICMP_ECHOREPLY: | 170 | case IPT_ICMP_ECHOREPLY: |
173 | /* Doesn't happen. */ | 171 | /* Doesn't happen. */ |
174 | break; | 172 | break; |
@@ -177,13 +175,10 @@ reject_tg(struct sk_buff *skb, const struct net_device *in, | |||
177 | return NF_DROP; | 175 | return NF_DROP; |
178 | } | 176 | } |
179 | 177 | ||
180 | static bool | 178 | static bool reject_tg_check(const struct xt_tgchk_param *par) |
181 | reject_tg_check(const char *tablename, const void *e_void, | ||
182 | const struct xt_target *target, void *targinfo, | ||
183 | unsigned int hook_mask) | ||
184 | { | 179 | { |
185 | const struct ipt_reject_info *rejinfo = targinfo; | 180 | const struct ipt_reject_info *rejinfo = par->targinfo; |
186 | const struct ipt_entry *e = e_void; | 181 | const struct ipt_entry *e = par->entryinfo; |
187 | 182 | ||
188 | if (rejinfo->with == IPT_ICMP_ECHOREPLY) { | 183 | if (rejinfo->with == IPT_ICMP_ECHOREPLY) { |
189 | printk("ipt_REJECT: ECHOREPLY no longer supported.\n"); | 184 | printk("ipt_REJECT: ECHOREPLY no longer supported.\n"); |
@@ -201,7 +196,7 @@ reject_tg_check(const char *tablename, const void *e_void, | |||
201 | 196 | ||
202 | static struct xt_target reject_tg_reg __read_mostly = { | 197 | static struct xt_target reject_tg_reg __read_mostly = { |
203 | .name = "REJECT", | 198 | .name = "REJECT", |
204 | .family = AF_INET, | 199 | .family = NFPROTO_IPV4, |
205 | .target = reject_tg, | 200 | .target = reject_tg, |
206 | .targetsize = sizeof(struct ipt_reject_info), | 201 | .targetsize = sizeof(struct ipt_reject_info), |
207 | .table = "filter", | 202 | .table = "filter", |
diff --git a/net/ipv4/netfilter/ipt_TTL.c b/net/ipv4/netfilter/ipt_TTL.c index 30eed65e7338..6d76aae90cc0 100644 --- a/net/ipv4/netfilter/ipt_TTL.c +++ b/net/ipv4/netfilter/ipt_TTL.c | |||
@@ -20,12 +20,10 @@ MODULE_DESCRIPTION("Xtables: IPv4 TTL field modification target"); | |||
20 | MODULE_LICENSE("GPL"); | 20 | MODULE_LICENSE("GPL"); |
21 | 21 | ||
22 | static unsigned int | 22 | static unsigned int |
23 | ttl_tg(struct sk_buff *skb, const struct net_device *in, | 23 | ttl_tg(struct sk_buff *skb, const struct xt_target_param *par) |
24 | const struct net_device *out, unsigned int hooknum, | ||
25 | const struct xt_target *target, const void *targinfo) | ||
26 | { | 24 | { |
27 | struct iphdr *iph; | 25 | struct iphdr *iph; |
28 | const struct ipt_TTL_info *info = targinfo; | 26 | const struct ipt_TTL_info *info = par->targinfo; |
29 | int new_ttl; | 27 | int new_ttl; |
30 | 28 | ||
31 | if (!skb_make_writable(skb, skb->len)) | 29 | if (!skb_make_writable(skb, skb->len)) |
@@ -61,12 +59,9 @@ ttl_tg(struct sk_buff *skb, const struct net_device *in, | |||
61 | return XT_CONTINUE; | 59 | return XT_CONTINUE; |
62 | } | 60 | } |
63 | 61 | ||
64 | static bool | 62 | static bool ttl_tg_check(const struct xt_tgchk_param *par) |
65 | ttl_tg_check(const char *tablename, const void *e, | ||
66 | const struct xt_target *target, void *targinfo, | ||
67 | unsigned int hook_mask) | ||
68 | { | 63 | { |
69 | const struct ipt_TTL_info *info = targinfo; | 64 | const struct ipt_TTL_info *info = par->targinfo; |
70 | 65 | ||
71 | if (info->mode > IPT_TTL_MAXMODE) { | 66 | if (info->mode > IPT_TTL_MAXMODE) { |
72 | printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n", | 67 | printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n", |
@@ -80,7 +75,7 @@ ttl_tg_check(const char *tablename, const void *e, | |||
80 | 75 | ||
81 | static struct xt_target ttl_tg_reg __read_mostly = { | 76 | static struct xt_target ttl_tg_reg __read_mostly = { |
82 | .name = "TTL", | 77 | .name = "TTL", |
83 | .family = AF_INET, | 78 | .family = NFPROTO_IPV4, |
84 | .target = ttl_tg, | 79 | .target = ttl_tg, |
85 | .targetsize = sizeof(struct ipt_TTL_info), | 80 | .targetsize = sizeof(struct ipt_TTL_info), |
86 | .table = "mangle", | 81 | .table = "mangle", |
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index b192756c6d0d..18a2826b57c6 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c | |||
@@ -281,18 +281,14 @@ alloc_failure: | |||
281 | } | 281 | } |
282 | 282 | ||
283 | static unsigned int | 283 | static unsigned int |
284 | ulog_tg(struct sk_buff *skb, const struct net_device *in, | 284 | ulog_tg(struct sk_buff *skb, const struct xt_target_param *par) |
285 | const struct net_device *out, unsigned int hooknum, | ||
286 | const struct xt_target *target, const void *targinfo) | ||
287 | { | 285 | { |
288 | struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo; | 286 | ipt_ulog_packet(par->hooknum, skb, par->in, par->out, |
289 | 287 | par->targinfo, NULL); | |
290 | ipt_ulog_packet(hooknum, skb, in, out, loginfo, NULL); | ||
291 | |||
292 | return XT_CONTINUE; | 288 | return XT_CONTINUE; |
293 | } | 289 | } |
294 | 290 | ||
295 | static void ipt_logfn(unsigned int pf, | 291 | static void ipt_logfn(u_int8_t pf, |
296 | unsigned int hooknum, | 292 | unsigned int hooknum, |
297 | const struct sk_buff *skb, | 293 | const struct sk_buff *skb, |
298 | const struct net_device *in, | 294 | const struct net_device *in, |
@@ -317,12 +313,9 @@ static void ipt_logfn(unsigned int pf, | |||
317 | ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); | 313 | ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); |
318 | } | 314 | } |
319 | 315 | ||
320 | static bool | 316 | static bool ulog_tg_check(const struct xt_tgchk_param *par) |
321 | ulog_tg_check(const char *tablename, const void *e, | ||
322 | const struct xt_target *target, void *targinfo, | ||
323 | unsigned int hookmask) | ||
324 | { | 317 | { |
325 | const struct ipt_ulog_info *loginfo = targinfo; | 318 | const struct ipt_ulog_info *loginfo = par->targinfo; |
326 | 319 | ||
327 | if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') { | 320 | if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') { |
328 | pr_debug("ipt_ULOG: prefix term %i\n", | 321 | pr_debug("ipt_ULOG: prefix term %i\n", |
@@ -374,7 +367,7 @@ static int ulog_tg_compat_to_user(void __user *dst, void *src) | |||
374 | 367 | ||
375 | static struct xt_target ulog_tg_reg __read_mostly = { | 368 | static struct xt_target ulog_tg_reg __read_mostly = { |
376 | .name = "ULOG", | 369 | .name = "ULOG", |
377 | .family = AF_INET, | 370 | .family = NFPROTO_IPV4, |
378 | .target = ulog_tg, | 371 | .target = ulog_tg, |
379 | .targetsize = sizeof(struct ipt_ulog_info), | 372 | .targetsize = sizeof(struct ipt_ulog_info), |
380 | .checkentry = ulog_tg_check, | 373 | .checkentry = ulog_tg_check, |
@@ -419,7 +412,7 @@ static int __init ulog_tg_init(void) | |||
419 | return ret; | 412 | return ret; |
420 | } | 413 | } |
421 | if (nflog) | 414 | if (nflog) |
422 | nf_log_register(PF_INET, &ipt_ulog_logger); | 415 | nf_log_register(NFPROTO_IPV4, &ipt_ulog_logger); |
423 | 416 | ||
424 | return 0; | 417 | return 0; |
425 | } | 418 | } |
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c index 462a22c97877..88762f02779d 100644 --- a/net/ipv4/netfilter/ipt_addrtype.c +++ b/net/ipv4/netfilter/ipt_addrtype.c | |||
@@ -30,12 +30,9 @@ static inline bool match_type(const struct net_device *dev, __be32 addr, | |||
30 | } | 30 | } |
31 | 31 | ||
32 | static bool | 32 | static bool |
33 | addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in, | 33 | addrtype_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par) |
34 | const struct net_device *out, const struct xt_match *match, | ||
35 | const void *matchinfo, int offset, unsigned int protoff, | ||
36 | bool *hotdrop) | ||
37 | { | 34 | { |
38 | const struct ipt_addrtype_info *info = matchinfo; | 35 | const struct ipt_addrtype_info *info = par->matchinfo; |
39 | const struct iphdr *iph = ip_hdr(skb); | 36 | const struct iphdr *iph = ip_hdr(skb); |
40 | bool ret = true; | 37 | bool ret = true; |
41 | 38 | ||
@@ -50,20 +47,17 @@ addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in, | |||
50 | } | 47 | } |
51 | 48 | ||
52 | static bool | 49 | static bool |
53 | addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in, | 50 | addrtype_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par) |
54 | const struct net_device *out, const struct xt_match *match, | ||
55 | const void *matchinfo, int offset, unsigned int protoff, | ||
56 | bool *hotdrop) | ||
57 | { | 51 | { |
58 | const struct ipt_addrtype_info_v1 *info = matchinfo; | 52 | const struct ipt_addrtype_info_v1 *info = par->matchinfo; |
59 | const struct iphdr *iph = ip_hdr(skb); | 53 | const struct iphdr *iph = ip_hdr(skb); |
60 | const struct net_device *dev = NULL; | 54 | const struct net_device *dev = NULL; |
61 | bool ret = true; | 55 | bool ret = true; |
62 | 56 | ||
63 | if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) | 57 | if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) |
64 | dev = in; | 58 | dev = par->in; |
65 | else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) | 59 | else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) |
66 | dev = out; | 60 | dev = par->out; |
67 | 61 | ||
68 | if (info->source) | 62 | if (info->source) |
69 | ret &= match_type(dev, iph->saddr, info->source) ^ | 63 | ret &= match_type(dev, iph->saddr, info->source) ^ |
@@ -74,12 +68,9 @@ addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in, | |||
74 | return ret; | 68 | return ret; |
75 | } | 69 | } |
76 | 70 | ||
77 | static bool | 71 | static bool addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par) |
78 | addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void, | ||
79 | const struct xt_match *match, void *matchinfo, | ||
80 | unsigned int hook_mask) | ||
81 | { | 72 | { |
82 | struct ipt_addrtype_info_v1 *info = matchinfo; | 73 | struct ipt_addrtype_info_v1 *info = par->matchinfo; |
83 | 74 | ||
84 | if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN && | 75 | if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN && |
85 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { | 76 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { |
@@ -88,14 +79,16 @@ addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void, | |||
88 | return false; | 79 | return false; |
89 | } | 80 | } |
90 | 81 | ||
91 | if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN) && | 82 | if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) | |
83 | (1 << NF_INET_LOCAL_IN)) && | ||
92 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { | 84 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { |
93 | printk(KERN_ERR "ipt_addrtype: output interface limitation " | 85 | printk(KERN_ERR "ipt_addrtype: output interface limitation " |
94 | "not valid in PRE_ROUTING and INPUT\n"); | 86 | "not valid in PRE_ROUTING and INPUT\n"); |
95 | return false; | 87 | return false; |
96 | } | 88 | } |
97 | 89 | ||
98 | if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT) && | 90 | if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) | |
91 | (1 << NF_INET_LOCAL_OUT)) && | ||
99 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { | 92 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { |
100 | printk(KERN_ERR "ipt_addrtype: input interface limitation " | 93 | printk(KERN_ERR "ipt_addrtype: input interface limitation " |
101 | "not valid in POST_ROUTING and OUTPUT\n"); | 94 | "not valid in POST_ROUTING and OUTPUT\n"); |
@@ -108,14 +101,14 @@ addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void, | |||
108 | static struct xt_match addrtype_mt_reg[] __read_mostly = { | 101 | static struct xt_match addrtype_mt_reg[] __read_mostly = { |
109 | { | 102 | { |
110 | .name = "addrtype", | 103 | .name = "addrtype", |
111 | .family = AF_INET, | 104 | .family = NFPROTO_IPV4, |
112 | .match = addrtype_mt_v0, | 105 | .match = addrtype_mt_v0, |
113 | .matchsize = sizeof(struct ipt_addrtype_info), | 106 | .matchsize = sizeof(struct ipt_addrtype_info), |
114 | .me = THIS_MODULE | 107 | .me = THIS_MODULE |
115 | }, | 108 | }, |
116 | { | 109 | { |
117 | .name = "addrtype", | 110 | .name = "addrtype", |
118 | .family = AF_INET, | 111 | .family = NFPROTO_IPV4, |
119 | .revision = 1, | 112 | .revision = 1, |
120 | .match = addrtype_mt_v1, | 113 | .match = addrtype_mt_v1, |
121 | .checkentry = addrtype_mt_checkentry_v1, | 114 | .checkentry = addrtype_mt_checkentry_v1, |
diff --git a/net/ipv4/netfilter/ipt_ah.c b/net/ipv4/netfilter/ipt_ah.c index e977989629c7..0104c0b399de 100644 --- a/net/ipv4/netfilter/ipt_ah.c +++ b/net/ipv4/netfilter/ipt_ah.c | |||
@@ -36,27 +36,23 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert) | |||
36 | return r; | 36 | return r; |
37 | } | 37 | } |
38 | 38 | ||
39 | static bool | 39 | static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
40 | ah_mt(const struct sk_buff *skb, const struct net_device *in, | ||
41 | const struct net_device *out, const struct xt_match *match, | ||
42 | const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) | ||
43 | { | 40 | { |
44 | struct ip_auth_hdr _ahdr; | 41 | struct ip_auth_hdr _ahdr; |
45 | const struct ip_auth_hdr *ah; | 42 | const struct ip_auth_hdr *ah; |
46 | const struct ipt_ah *ahinfo = matchinfo; | 43 | const struct ipt_ah *ahinfo = par->matchinfo; |
47 | 44 | ||
48 | /* Must not be a fragment. */ | 45 | /* Must not be a fragment. */ |
49 | if (offset) | 46 | if (par->fragoff != 0) |
50 | return false; | 47 | return false; |
51 | 48 | ||
52 | ah = skb_header_pointer(skb, protoff, | 49 | ah = skb_header_pointer(skb, par->thoff, sizeof(_ahdr), &_ahdr); |
53 | sizeof(_ahdr), &_ahdr); | ||
54 | if (ah == NULL) { | 50 | if (ah == NULL) { |
55 | /* We've been asked to examine this packet, and we | 51 | /* We've been asked to examine this packet, and we |
56 | * can't. Hence, no choice but to drop. | 52 | * can't. Hence, no choice but to drop. |
57 | */ | 53 | */ |
58 | duprintf("Dropping evil AH tinygram.\n"); | 54 | duprintf("Dropping evil AH tinygram.\n"); |
59 | *hotdrop = true; | 55 | *par->hotdrop = true; |
60 | return 0; | 56 | return 0; |
61 | } | 57 | } |
62 | 58 | ||
@@ -65,13 +61,9 @@ ah_mt(const struct sk_buff *skb, const struct net_device *in, | |||
65 | !!(ahinfo->invflags & IPT_AH_INV_SPI)); | 61 | !!(ahinfo->invflags & IPT_AH_INV_SPI)); |
66 | } | 62 | } |
67 | 63 | ||
68 | /* Called when user tries to insert an entry of this type. */ | 64 | static bool ah_mt_check(const struct xt_mtchk_param *par) |
69 | static bool | ||
70 | ah_mt_check(const char *tablename, const void *ip_void, | ||
71 | const struct xt_match *match, void *matchinfo, | ||
72 | unsigned int hook_mask) | ||
73 | { | 65 | { |
74 | const struct ipt_ah *ahinfo = matchinfo; | 66 | const struct ipt_ah *ahinfo = par->matchinfo; |
75 | 67 | ||
76 | /* Must specify no unknown invflags */ | 68 | /* Must specify no unknown invflags */ |
77 | if (ahinfo->invflags & ~IPT_AH_INV_MASK) { | 69 | if (ahinfo->invflags & ~IPT_AH_INV_MASK) { |
@@ -83,7 +75,7 @@ ah_mt_check(const char *tablename, const void *ip_void, | |||
83 | 75 | ||
84 | static struct xt_match ah_mt_reg __read_mostly = { | 76 | static struct xt_match ah_mt_reg __read_mostly = { |
85 | .name = "ah", | 77 | .name = "ah", |
86 | .family = AF_INET, | 78 | .family = NFPROTO_IPV4, |
87 | .match = ah_mt, | 79 | .match = ah_mt, |
88 | .matchsize = sizeof(struct ipt_ah), | 80 | .matchsize = sizeof(struct ipt_ah), |
89 | .proto = IPPROTO_AH, | 81 | .proto = IPPROTO_AH, |
diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c index 749de8284ce5..6289b64144c6 100644 --- a/net/ipv4/netfilter/ipt_ecn.c +++ b/net/ipv4/netfilter/ipt_ecn.c | |||
@@ -67,12 +67,9 @@ static inline bool match_tcp(const struct sk_buff *skb, | |||
67 | return true; | 67 | return true; |
68 | } | 68 | } |
69 | 69 | ||
70 | static bool | 70 | static bool ecn_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
71 | ecn_mt(const struct sk_buff *skb, const struct net_device *in, | ||
72 | const struct net_device *out, const struct xt_match *match, | ||
73 | const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) | ||
74 | { | 71 | { |
75 | const struct ipt_ecn_info *info = matchinfo; | 72 | const struct ipt_ecn_info *info = par->matchinfo; |
76 | 73 | ||
77 | if (info->operation & IPT_ECN_OP_MATCH_IP) | 74 | if (info->operation & IPT_ECN_OP_MATCH_IP) |
78 | if (!match_ip(skb, info)) | 75 | if (!match_ip(skb, info)) |
@@ -81,20 +78,17 @@ ecn_mt(const struct sk_buff *skb, const struct net_device *in, | |||
81 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) { | 78 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) { |
82 | if (ip_hdr(skb)->protocol != IPPROTO_TCP) | 79 | if (ip_hdr(skb)->protocol != IPPROTO_TCP) |
83 | return false; | 80 | return false; |
84 | if (!match_tcp(skb, info, hotdrop)) | 81 | if (!match_tcp(skb, info, par->hotdrop)) |
85 | return false; | 82 | return false; |
86 | } | 83 | } |
87 | 84 | ||
88 | return true; | 85 | return true; |
89 | } | 86 | } |
90 | 87 | ||
91 | static bool | 88 | static bool ecn_mt_check(const struct xt_mtchk_param *par) |
92 | ecn_mt_check(const char *tablename, const void *ip_void, | ||
93 | const struct xt_match *match, void *matchinfo, | ||
94 | unsigned int hook_mask) | ||
95 | { | 89 | { |
96 | const struct ipt_ecn_info *info = matchinfo; | 90 | const struct ipt_ecn_info *info = par->matchinfo; |
97 | const struct ipt_ip *ip = ip_void; | 91 | const struct ipt_ip *ip = par->entryinfo; |
98 | 92 | ||
99 | if (info->operation & IPT_ECN_OP_MATCH_MASK) | 93 | if (info->operation & IPT_ECN_OP_MATCH_MASK) |
100 | return false; | 94 | return false; |
@@ -114,7 +108,7 @@ ecn_mt_check(const char *tablename, const void *ip_void, | |||
114 | 108 | ||
115 | static struct xt_match ecn_mt_reg __read_mostly = { | 109 | static struct xt_match ecn_mt_reg __read_mostly = { |
116 | .name = "ecn", | 110 | .name = "ecn", |
117 | .family = AF_INET, | 111 | .family = NFPROTO_IPV4, |
118 | .match = ecn_mt, | 112 | .match = ecn_mt, |
119 | .matchsize = sizeof(struct ipt_ecn_info), | 113 | .matchsize = sizeof(struct ipt_ecn_info), |
120 | .checkentry = ecn_mt_check, | 114 | .checkentry = ecn_mt_check, |
diff --git a/net/ipv4/netfilter/ipt_ttl.c b/net/ipv4/netfilter/ipt_ttl.c index e0b8caeb710c..297f1cbf4ff5 100644 --- a/net/ipv4/netfilter/ipt_ttl.c +++ b/net/ipv4/netfilter/ipt_ttl.c | |||
@@ -18,12 +18,9 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | |||
18 | MODULE_DESCRIPTION("Xtables: IPv4 TTL field match"); | 18 | MODULE_DESCRIPTION("Xtables: IPv4 TTL field match"); |
19 | MODULE_LICENSE("GPL"); | 19 | MODULE_LICENSE("GPL"); |
20 | 20 | ||
21 | static bool | 21 | static bool ttl_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
22 | ttl_mt(const struct sk_buff *skb, const struct net_device *in, | ||
23 | const struct net_device *out, const struct xt_match *match, | ||
24 | const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) | ||
25 | { | 22 | { |
26 | const struct ipt_ttl_info *info = matchinfo; | 23 | const struct ipt_ttl_info *info = par->matchinfo; |
27 | const u8 ttl = ip_hdr(skb)->ttl; | 24 | const u8 ttl = ip_hdr(skb)->ttl; |
28 | 25 | ||
29 | switch (info->mode) { | 26 | switch (info->mode) { |
@@ -46,7 +43,7 @@ ttl_mt(const struct sk_buff *skb, const struct net_device *in, | |||
46 | 43 | ||
47 | static struct xt_match ttl_mt_reg __read_mostly = { | 44 | static struct xt_match ttl_mt_reg __read_mostly = { |
48 | .name = "ttl", | 45 | .name = "ttl", |
49 | .family = AF_INET, | 46 | .family = NFPROTO_IPV4, |
50 | .match = ttl_mt, | 47 | .match = ttl_mt, |
51 | .matchsize = sizeof(struct ipt_ttl_info), | 48 | .matchsize = sizeof(struct ipt_ttl_info), |
52 | .me = THIS_MODULE, | 49 | .me = THIS_MODULE, |
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 1ea677dcf845..c9224310ebae 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c | |||
@@ -70,7 +70,7 @@ ipt_local_in_hook(unsigned int hook, | |||
70 | int (*okfn)(struct sk_buff *)) | 70 | int (*okfn)(struct sk_buff *)) |
71 | { | 71 | { |
72 | return ipt_do_table(skb, hook, in, out, | 72 | return ipt_do_table(skb, hook, in, out, |
73 | nf_local_in_net(in, out)->ipv4.iptable_filter); | 73 | dev_net(in)->ipv4.iptable_filter); |
74 | } | 74 | } |
75 | 75 | ||
76 | static unsigned int | 76 | static unsigned int |
@@ -81,7 +81,7 @@ ipt_hook(unsigned int hook, | |||
81 | int (*okfn)(struct sk_buff *)) | 81 | int (*okfn)(struct sk_buff *)) |
82 | { | 82 | { |
83 | return ipt_do_table(skb, hook, in, out, | 83 | return ipt_do_table(skb, hook, in, out, |
84 | nf_forward_net(in, out)->ipv4.iptable_filter); | 84 | dev_net(in)->ipv4.iptable_filter); |
85 | } | 85 | } |
86 | 86 | ||
87 | static unsigned int | 87 | static unsigned int |
@@ -101,7 +101,7 @@ ipt_local_out_hook(unsigned int hook, | |||
101 | } | 101 | } |
102 | 102 | ||
103 | return ipt_do_table(skb, hook, in, out, | 103 | return ipt_do_table(skb, hook, in, out, |
104 | nf_local_out_net(in, out)->ipv4.iptable_filter); | 104 | dev_net(out)->ipv4.iptable_filter); |
105 | } | 105 | } |
106 | 106 | ||
107 | static struct nf_hook_ops ipt_ops[] __read_mostly = { | 107 | static struct nf_hook_ops ipt_ops[] __read_mostly = { |
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index da59182f2226..69f2c4287146 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c | |||
@@ -81,7 +81,7 @@ ipt_pre_routing_hook(unsigned int hook, | |||
81 | int (*okfn)(struct sk_buff *)) | 81 | int (*okfn)(struct sk_buff *)) |
82 | { | 82 | { |
83 | return ipt_do_table(skb, hook, in, out, | 83 | return ipt_do_table(skb, hook, in, out, |
84 | nf_pre_routing_net(in, out)->ipv4.iptable_mangle); | 84 | dev_net(in)->ipv4.iptable_mangle); |
85 | } | 85 | } |
86 | 86 | ||
87 | static unsigned int | 87 | static unsigned int |
@@ -92,7 +92,7 @@ ipt_post_routing_hook(unsigned int hook, | |||
92 | int (*okfn)(struct sk_buff *)) | 92 | int (*okfn)(struct sk_buff *)) |
93 | { | 93 | { |
94 | return ipt_do_table(skb, hook, in, out, | 94 | return ipt_do_table(skb, hook, in, out, |
95 | nf_post_routing_net(in, out)->ipv4.iptable_mangle); | 95 | dev_net(out)->ipv4.iptable_mangle); |
96 | } | 96 | } |
97 | 97 | ||
98 | static unsigned int | 98 | static unsigned int |
@@ -103,7 +103,7 @@ ipt_local_in_hook(unsigned int hook, | |||
103 | int (*okfn)(struct sk_buff *)) | 103 | int (*okfn)(struct sk_buff *)) |
104 | { | 104 | { |
105 | return ipt_do_table(skb, hook, in, out, | 105 | return ipt_do_table(skb, hook, in, out, |
106 | nf_local_in_net(in, out)->ipv4.iptable_mangle); | 106 | dev_net(in)->ipv4.iptable_mangle); |
107 | } | 107 | } |
108 | 108 | ||
109 | static unsigned int | 109 | static unsigned int |
@@ -114,7 +114,7 @@ ipt_forward_hook(unsigned int hook, | |||
114 | int (*okfn)(struct sk_buff *)) | 114 | int (*okfn)(struct sk_buff *)) |
115 | { | 115 | { |
116 | return ipt_do_table(skb, hook, in, out, | 116 | return ipt_do_table(skb, hook, in, out, |
117 | nf_forward_net(in, out)->ipv4.iptable_mangle); | 117 | dev_net(in)->ipv4.iptable_mangle); |
118 | } | 118 | } |
119 | 119 | ||
120 | static unsigned int | 120 | static unsigned int |
@@ -147,7 +147,7 @@ ipt_local_hook(unsigned int hook, | |||
147 | tos = iph->tos; | 147 | tos = iph->tos; |
148 | 148 | ||
149 | ret = ipt_do_table(skb, hook, in, out, | 149 | ret = ipt_do_table(skb, hook, in, out, |
150 | nf_local_out_net(in, out)->ipv4.iptable_mangle); | 150 | dev_net(out)->ipv4.iptable_mangle); |
151 | /* Reroute for ANY change. */ | 151 | /* Reroute for ANY change. */ |
152 | if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) { | 152 | if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) { |
153 | iph = ip_hdr(skb); | 153 | iph = ip_hdr(skb); |
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index fddce7754b72..8faebfe638f1 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c | |||
@@ -53,7 +53,7 @@ ipt_hook(unsigned int hook, | |||
53 | int (*okfn)(struct sk_buff *)) | 53 | int (*okfn)(struct sk_buff *)) |
54 | { | 54 | { |
55 | return ipt_do_table(skb, hook, in, out, | 55 | return ipt_do_table(skb, hook, in, out, |
56 | nf_pre_routing_net(in, out)->ipv4.iptable_raw); | 56 | dev_net(in)->ipv4.iptable_raw); |
57 | } | 57 | } |
58 | 58 | ||
59 | static unsigned int | 59 | static unsigned int |
@@ -72,7 +72,7 @@ ipt_local_hook(unsigned int hook, | |||
72 | return NF_ACCEPT; | 72 | return NF_ACCEPT; |
73 | } | 73 | } |
74 | return ipt_do_table(skb, hook, in, out, | 74 | return ipt_do_table(skb, hook, in, out, |
75 | nf_local_out_net(in, out)->ipv4.iptable_raw); | 75 | dev_net(out)->ipv4.iptable_raw); |
76 | } | 76 | } |
77 | 77 | ||
78 | /* 'raw' is the very first table. */ | 78 | /* 'raw' is the very first table. */ |
diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c index db6d312128e1..36f3be3cc428 100644 --- a/net/ipv4/netfilter/iptable_security.c +++ b/net/ipv4/netfilter/iptable_security.c | |||
@@ -73,7 +73,7 @@ ipt_local_in_hook(unsigned int hook, | |||
73 | int (*okfn)(struct sk_buff *)) | 73 | int (*okfn)(struct sk_buff *)) |
74 | { | 74 | { |
75 | return ipt_do_table(skb, hook, in, out, | 75 | return ipt_do_table(skb, hook, in, out, |
76 | nf_local_in_net(in, out)->ipv4.iptable_security); | 76 | dev_net(in)->ipv4.iptable_security); |
77 | } | 77 | } |
78 | 78 | ||
79 | static unsigned int | 79 | static unsigned int |
@@ -84,7 +84,7 @@ ipt_forward_hook(unsigned int hook, | |||
84 | int (*okfn)(struct sk_buff *)) | 84 | int (*okfn)(struct sk_buff *)) |
85 | { | 85 | { |
86 | return ipt_do_table(skb, hook, in, out, | 86 | return ipt_do_table(skb, hook, in, out, |
87 | nf_forward_net(in, out)->ipv4.iptable_security); | 87 | dev_net(in)->ipv4.iptable_security); |
88 | } | 88 | } |
89 | 89 | ||
90 | static unsigned int | 90 | static unsigned int |
@@ -103,7 +103,7 @@ ipt_local_out_hook(unsigned int hook, | |||
103 | return NF_ACCEPT; | 103 | return NF_ACCEPT; |
104 | } | 104 | } |
105 | return ipt_do_table(skb, hook, in, out, | 105 | return ipt_do_table(skb, hook, in, out, |
106 | nf_local_out_net(in, out)->ipv4.iptable_security); | 106 | dev_net(out)->ipv4.iptable_security); |
107 | } | 107 | } |
108 | 108 | ||
109 | static struct nf_hook_ops ipt_ops[] __read_mostly = { | 109 | static struct nf_hook_ops ipt_ops[] __read_mostly = { |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 5a955c440364..4a7c35275396 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
@@ -1,3 +1,4 @@ | |||
1 | |||
1 | /* (C) 1999-2001 Paul `Rusty' Russell | 2 | /* (C) 1999-2001 Paul `Rusty' Russell |
2 | * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> | 3 | * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> |
3 | * | 4 | * |
@@ -24,6 +25,7 @@ | |||
24 | #include <net/netfilter/nf_conntrack_core.h> | 25 | #include <net/netfilter/nf_conntrack_core.h> |
25 | #include <net/netfilter/ipv4/nf_conntrack_ipv4.h> | 26 | #include <net/netfilter/ipv4/nf_conntrack_ipv4.h> |
26 | #include <net/netfilter/nf_nat_helper.h> | 27 | #include <net/netfilter/nf_nat_helper.h> |
28 | #include <net/netfilter/ipv4/nf_defrag_ipv4.h> | ||
27 | 29 | ||
28 | int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, | 30 | int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, |
29 | struct nf_conn *ct, | 31 | struct nf_conn *ct, |
@@ -63,23 +65,6 @@ static int ipv4_print_tuple(struct seq_file *s, | |||
63 | NIPQUAD(tuple->dst.u3.ip)); | 65 | NIPQUAD(tuple->dst.u3.ip)); |
64 | } | 66 | } |
65 | 67 | ||
66 | /* Returns new sk_buff, or NULL */ | ||
67 | static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user) | ||
68 | { | ||
69 | int err; | ||
70 | |||
71 | skb_orphan(skb); | ||
72 | |||
73 | local_bh_disable(); | ||
74 | err = ip_defrag(skb, user); | ||
75 | local_bh_enable(); | ||
76 | |||
77 | if (!err) | ||
78 | ip_send_check(ip_hdr(skb)); | ||
79 | |||
80 | return err; | ||
81 | } | ||
82 | |||
83 | static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, | 68 | static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, |
84 | unsigned int *dataoff, u_int8_t *protonum) | 69 | unsigned int *dataoff, u_int8_t *protonum) |
85 | { | 70 | { |
@@ -144,35 +129,13 @@ out: | |||
144 | return nf_conntrack_confirm(skb); | 129 | return nf_conntrack_confirm(skb); |
145 | } | 130 | } |
146 | 131 | ||
147 | static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, | ||
148 | struct sk_buff *skb, | ||
149 | const struct net_device *in, | ||
150 | const struct net_device *out, | ||
151 | int (*okfn)(struct sk_buff *)) | ||
152 | { | ||
153 | /* Previously seen (loopback)? Ignore. Do this before | ||
154 | fragment check. */ | ||
155 | if (skb->nfct) | ||
156 | return NF_ACCEPT; | ||
157 | |||
158 | /* Gather fragments. */ | ||
159 | if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { | ||
160 | if (nf_ct_ipv4_gather_frags(skb, | ||
161 | hooknum == NF_INET_PRE_ROUTING ? | ||
162 | IP_DEFRAG_CONNTRACK_IN : | ||
163 | IP_DEFRAG_CONNTRACK_OUT)) | ||
164 | return NF_STOLEN; | ||
165 | } | ||
166 | return NF_ACCEPT; | ||
167 | } | ||
168 | |||
169 | static unsigned int ipv4_conntrack_in(unsigned int hooknum, | 132 | static unsigned int ipv4_conntrack_in(unsigned int hooknum, |
170 | struct sk_buff *skb, | 133 | struct sk_buff *skb, |
171 | const struct net_device *in, | 134 | const struct net_device *in, |
172 | const struct net_device *out, | 135 | const struct net_device *out, |
173 | int (*okfn)(struct sk_buff *)) | 136 | int (*okfn)(struct sk_buff *)) |
174 | { | 137 | { |
175 | return nf_conntrack_in(PF_INET, hooknum, skb); | 138 | return nf_conntrack_in(dev_net(in), PF_INET, hooknum, skb); |
176 | } | 139 | } |
177 | 140 | ||
178 | static unsigned int ipv4_conntrack_local(unsigned int hooknum, | 141 | static unsigned int ipv4_conntrack_local(unsigned int hooknum, |
@@ -188,20 +151,13 @@ static unsigned int ipv4_conntrack_local(unsigned int hooknum, | |||
188 | printk("ipt_hook: happy cracking.\n"); | 151 | printk("ipt_hook: happy cracking.\n"); |
189 | return NF_ACCEPT; | 152 | return NF_ACCEPT; |
190 | } | 153 | } |
191 | return nf_conntrack_in(PF_INET, hooknum, skb); | 154 | return nf_conntrack_in(dev_net(out), PF_INET, hooknum, skb); |
192 | } | 155 | } |
193 | 156 | ||
194 | /* Connection tracking may drop packets, but never alters them, so | 157 | /* Connection tracking may drop packets, but never alters them, so |
195 | make it the first hook. */ | 158 | make it the first hook. */ |
196 | static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = { | 159 | static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = { |
197 | { | 160 | { |
198 | .hook = ipv4_conntrack_defrag, | ||
199 | .owner = THIS_MODULE, | ||
200 | .pf = PF_INET, | ||
201 | .hooknum = NF_INET_PRE_ROUTING, | ||
202 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, | ||
203 | }, | ||
204 | { | ||
205 | .hook = ipv4_conntrack_in, | 161 | .hook = ipv4_conntrack_in, |
206 | .owner = THIS_MODULE, | 162 | .owner = THIS_MODULE, |
207 | .pf = PF_INET, | 163 | .pf = PF_INET, |
@@ -209,13 +165,6 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = { | |||
209 | .priority = NF_IP_PRI_CONNTRACK, | 165 | .priority = NF_IP_PRI_CONNTRACK, |
210 | }, | 166 | }, |
211 | { | 167 | { |
212 | .hook = ipv4_conntrack_defrag, | ||
213 | .owner = THIS_MODULE, | ||
214 | .pf = PF_INET, | ||
215 | .hooknum = NF_INET_LOCAL_OUT, | ||
216 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, | ||
217 | }, | ||
218 | { | ||
219 | .hook = ipv4_conntrack_local, | 168 | .hook = ipv4_conntrack_local, |
220 | .owner = THIS_MODULE, | 169 | .owner = THIS_MODULE, |
221 | .pf = PF_INET, | 170 | .pf = PF_INET, |
@@ -254,7 +203,7 @@ static ctl_table ip_ct_sysctl_table[] = { | |||
254 | { | 203 | { |
255 | .ctl_name = NET_IPV4_NF_CONNTRACK_COUNT, | 204 | .ctl_name = NET_IPV4_NF_CONNTRACK_COUNT, |
256 | .procname = "ip_conntrack_count", | 205 | .procname = "ip_conntrack_count", |
257 | .data = &nf_conntrack_count, | 206 | .data = &init_net.ct.count, |
258 | .maxlen = sizeof(int), | 207 | .maxlen = sizeof(int), |
259 | .mode = 0444, | 208 | .mode = 0444, |
260 | .proc_handler = &proc_dointvec, | 209 | .proc_handler = &proc_dointvec, |
@@ -270,7 +219,7 @@ static ctl_table ip_ct_sysctl_table[] = { | |||
270 | { | 219 | { |
271 | .ctl_name = NET_IPV4_NF_CONNTRACK_CHECKSUM, | 220 | .ctl_name = NET_IPV4_NF_CONNTRACK_CHECKSUM, |
272 | .procname = "ip_conntrack_checksum", | 221 | .procname = "ip_conntrack_checksum", |
273 | .data = &nf_conntrack_checksum, | 222 | .data = &init_net.ct.sysctl_checksum, |
274 | .maxlen = sizeof(int), | 223 | .maxlen = sizeof(int), |
275 | .mode = 0644, | 224 | .mode = 0644, |
276 | .proc_handler = &proc_dointvec, | 225 | .proc_handler = &proc_dointvec, |
@@ -278,7 +227,7 @@ static ctl_table ip_ct_sysctl_table[] = { | |||
278 | { | 227 | { |
279 | .ctl_name = NET_IPV4_NF_CONNTRACK_LOG_INVALID, | 228 | .ctl_name = NET_IPV4_NF_CONNTRACK_LOG_INVALID, |
280 | .procname = "ip_conntrack_log_invalid", | 229 | .procname = "ip_conntrack_log_invalid", |
281 | .data = &nf_ct_log_invalid, | 230 | .data = &init_net.ct.sysctl_log_invalid, |
282 | .maxlen = sizeof(unsigned int), | 231 | .maxlen = sizeof(unsigned int), |
283 | .mode = 0644, | 232 | .mode = 0644, |
284 | .proc_handler = &proc_dointvec_minmax, | 233 | .proc_handler = &proc_dointvec_minmax, |
@@ -323,7 +272,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len) | |||
323 | return -EINVAL; | 272 | return -EINVAL; |
324 | } | 273 | } |
325 | 274 | ||
326 | h = nf_conntrack_find_get(&tuple); | 275 | h = nf_conntrack_find_get(sock_net(sk), &tuple); |
327 | if (h) { | 276 | if (h) { |
328 | struct sockaddr_in sin; | 277 | struct sockaddr_in sin; |
329 | struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h); | 278 | struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h); |
@@ -422,6 +371,7 @@ static int __init nf_conntrack_l3proto_ipv4_init(void) | |||
422 | int ret = 0; | 371 | int ret = 0; |
423 | 372 | ||
424 | need_conntrack(); | 373 | need_conntrack(); |
374 | nf_defrag_ipv4_enable(); | ||
425 | 375 | ||
426 | ret = nf_register_sockopt(&so_getorigdst); | 376 | ret = nf_register_sockopt(&so_getorigdst); |
427 | if (ret < 0) { | 377 | if (ret < 0) { |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c index 3a020720e40b..313ebf00ee36 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | |||
@@ -21,18 +21,20 @@ | |||
21 | #include <net/netfilter/nf_conntrack_acct.h> | 21 | #include <net/netfilter/nf_conntrack_acct.h> |
22 | 22 | ||
23 | struct ct_iter_state { | 23 | struct ct_iter_state { |
24 | struct seq_net_private p; | ||
24 | unsigned int bucket; | 25 | unsigned int bucket; |
25 | }; | 26 | }; |
26 | 27 | ||
27 | static struct hlist_node *ct_get_first(struct seq_file *seq) | 28 | static struct hlist_node *ct_get_first(struct seq_file *seq) |
28 | { | 29 | { |
30 | struct net *net = seq_file_net(seq); | ||
29 | struct ct_iter_state *st = seq->private; | 31 | struct ct_iter_state *st = seq->private; |
30 | struct hlist_node *n; | 32 | struct hlist_node *n; |
31 | 33 | ||
32 | for (st->bucket = 0; | 34 | for (st->bucket = 0; |
33 | st->bucket < nf_conntrack_htable_size; | 35 | st->bucket < nf_conntrack_htable_size; |
34 | st->bucket++) { | 36 | st->bucket++) { |
35 | n = rcu_dereference(nf_conntrack_hash[st->bucket].first); | 37 | n = rcu_dereference(net->ct.hash[st->bucket].first); |
36 | if (n) | 38 | if (n) |
37 | return n; | 39 | return n; |
38 | } | 40 | } |
@@ -42,13 +44,14 @@ static struct hlist_node *ct_get_first(struct seq_file *seq) | |||
42 | static struct hlist_node *ct_get_next(struct seq_file *seq, | 44 | static struct hlist_node *ct_get_next(struct seq_file *seq, |
43 | struct hlist_node *head) | 45 | struct hlist_node *head) |
44 | { | 46 | { |
47 | struct net *net = seq_file_net(seq); | ||
45 | struct ct_iter_state *st = seq->private; | 48 | struct ct_iter_state *st = seq->private; |
46 | 49 | ||
47 | head = rcu_dereference(head->next); | 50 | head = rcu_dereference(head->next); |
48 | while (head == NULL) { | 51 | while (head == NULL) { |
49 | if (++st->bucket >= nf_conntrack_htable_size) | 52 | if (++st->bucket >= nf_conntrack_htable_size) |
50 | return NULL; | 53 | return NULL; |
51 | head = rcu_dereference(nf_conntrack_hash[st->bucket].first); | 54 | head = rcu_dereference(net->ct.hash[st->bucket].first); |
52 | } | 55 | } |
53 | return head; | 56 | return head; |
54 | } | 57 | } |
@@ -158,8 +161,8 @@ static const struct seq_operations ct_seq_ops = { | |||
158 | 161 | ||
159 | static int ct_open(struct inode *inode, struct file *file) | 162 | static int ct_open(struct inode *inode, struct file *file) |
160 | { | 163 | { |
161 | return seq_open_private(file, &ct_seq_ops, | 164 | return seq_open_net(inode, file, &ct_seq_ops, |
162 | sizeof(struct ct_iter_state)); | 165 | sizeof(struct ct_iter_state)); |
163 | } | 166 | } |
164 | 167 | ||
165 | static const struct file_operations ct_file_ops = { | 168 | static const struct file_operations ct_file_ops = { |
@@ -167,21 +170,23 @@ static const struct file_operations ct_file_ops = { | |||
167 | .open = ct_open, | 170 | .open = ct_open, |
168 | .read = seq_read, | 171 | .read = seq_read, |
169 | .llseek = seq_lseek, | 172 | .llseek = seq_lseek, |
170 | .release = seq_release_private, | 173 | .release = seq_release_net, |
171 | }; | 174 | }; |
172 | 175 | ||
173 | /* expects */ | 176 | /* expects */ |
174 | struct ct_expect_iter_state { | 177 | struct ct_expect_iter_state { |
178 | struct seq_net_private p; | ||
175 | unsigned int bucket; | 179 | unsigned int bucket; |
176 | }; | 180 | }; |
177 | 181 | ||
178 | static struct hlist_node *ct_expect_get_first(struct seq_file *seq) | 182 | static struct hlist_node *ct_expect_get_first(struct seq_file *seq) |
179 | { | 183 | { |
184 | struct net *net = seq_file_net(seq); | ||
180 | struct ct_expect_iter_state *st = seq->private; | 185 | struct ct_expect_iter_state *st = seq->private; |
181 | struct hlist_node *n; | 186 | struct hlist_node *n; |
182 | 187 | ||
183 | for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) { | 188 | for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) { |
184 | n = rcu_dereference(nf_ct_expect_hash[st->bucket].first); | 189 | n = rcu_dereference(net->ct.expect_hash[st->bucket].first); |
185 | if (n) | 190 | if (n) |
186 | return n; | 191 | return n; |
187 | } | 192 | } |
@@ -191,13 +196,14 @@ static struct hlist_node *ct_expect_get_first(struct seq_file *seq) | |||
191 | static struct hlist_node *ct_expect_get_next(struct seq_file *seq, | 196 | static struct hlist_node *ct_expect_get_next(struct seq_file *seq, |
192 | struct hlist_node *head) | 197 | struct hlist_node *head) |
193 | { | 198 | { |
199 | struct net *net = seq_file_net(seq); | ||
194 | struct ct_expect_iter_state *st = seq->private; | 200 | struct ct_expect_iter_state *st = seq->private; |
195 | 201 | ||
196 | head = rcu_dereference(head->next); | 202 | head = rcu_dereference(head->next); |
197 | while (head == NULL) { | 203 | while (head == NULL) { |
198 | if (++st->bucket >= nf_ct_expect_hsize) | 204 | if (++st->bucket >= nf_ct_expect_hsize) |
199 | return NULL; | 205 | return NULL; |
200 | head = rcu_dereference(nf_ct_expect_hash[st->bucket].first); | 206 | head = rcu_dereference(net->ct.expect_hash[st->bucket].first); |
201 | } | 207 | } |
202 | return head; | 208 | return head; |
203 | } | 209 | } |
@@ -265,8 +271,8 @@ static const struct seq_operations exp_seq_ops = { | |||
265 | 271 | ||
266 | static int exp_open(struct inode *inode, struct file *file) | 272 | static int exp_open(struct inode *inode, struct file *file) |
267 | { | 273 | { |
268 | return seq_open_private(file, &exp_seq_ops, | 274 | return seq_open_net(inode, file, &exp_seq_ops, |
269 | sizeof(struct ct_expect_iter_state)); | 275 | sizeof(struct ct_expect_iter_state)); |
270 | } | 276 | } |
271 | 277 | ||
272 | static const struct file_operations ip_exp_file_ops = { | 278 | static const struct file_operations ip_exp_file_ops = { |
@@ -274,11 +280,12 @@ static const struct file_operations ip_exp_file_ops = { | |||
274 | .open = exp_open, | 280 | .open = exp_open, |
275 | .read = seq_read, | 281 | .read = seq_read, |
276 | .llseek = seq_lseek, | 282 | .llseek = seq_lseek, |
277 | .release = seq_release_private, | 283 | .release = seq_release_net, |
278 | }; | 284 | }; |
279 | 285 | ||
280 | static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) | 286 | static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) |
281 | { | 287 | { |
288 | struct net *net = seq_file_net(seq); | ||
282 | int cpu; | 289 | int cpu; |
283 | 290 | ||
284 | if (*pos == 0) | 291 | if (*pos == 0) |
@@ -288,7 +295,7 @@ static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) | |||
288 | if (!cpu_possible(cpu)) | 295 | if (!cpu_possible(cpu)) |
289 | continue; | 296 | continue; |
290 | *pos = cpu+1; | 297 | *pos = cpu+1; |
291 | return &per_cpu(nf_conntrack_stat, cpu); | 298 | return per_cpu_ptr(net->ct.stat, cpu); |
292 | } | 299 | } |
293 | 300 | ||
294 | return NULL; | 301 | return NULL; |
@@ -296,13 +303,14 @@ static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) | |||
296 | 303 | ||
297 | static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 304 | static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
298 | { | 305 | { |
306 | struct net *net = seq_file_net(seq); | ||
299 | int cpu; | 307 | int cpu; |
300 | 308 | ||
301 | for (cpu = *pos; cpu < NR_CPUS; ++cpu) { | 309 | for (cpu = *pos; cpu < NR_CPUS; ++cpu) { |
302 | if (!cpu_possible(cpu)) | 310 | if (!cpu_possible(cpu)) |
303 | continue; | 311 | continue; |
304 | *pos = cpu+1; | 312 | *pos = cpu+1; |
305 | return &per_cpu(nf_conntrack_stat, cpu); | 313 | return per_cpu_ptr(net->ct.stat, cpu); |
306 | } | 314 | } |
307 | 315 | ||
308 | return NULL; | 316 | return NULL; |
@@ -314,7 +322,8 @@ static void ct_cpu_seq_stop(struct seq_file *seq, void *v) | |||
314 | 322 | ||
315 | static int ct_cpu_seq_show(struct seq_file *seq, void *v) | 323 | static int ct_cpu_seq_show(struct seq_file *seq, void *v) |
316 | { | 324 | { |
317 | unsigned int nr_conntracks = atomic_read(&nf_conntrack_count); | 325 | struct net *net = seq_file_net(seq); |
326 | unsigned int nr_conntracks = atomic_read(&net->ct.count); | ||
318 | const struct ip_conntrack_stat *st = v; | 327 | const struct ip_conntrack_stat *st = v; |
319 | 328 | ||
320 | if (v == SEQ_START_TOKEN) { | 329 | if (v == SEQ_START_TOKEN) { |
@@ -354,7 +363,8 @@ static const struct seq_operations ct_cpu_seq_ops = { | |||
354 | 363 | ||
355 | static int ct_cpu_seq_open(struct inode *inode, struct file *file) | 364 | static int ct_cpu_seq_open(struct inode *inode, struct file *file) |
356 | { | 365 | { |
357 | return seq_open(file, &ct_cpu_seq_ops); | 366 | return seq_open_net(inode, file, &ct_cpu_seq_ops, |
367 | sizeof(struct seq_net_private)); | ||
358 | } | 368 | } |
359 | 369 | ||
360 | static const struct file_operations ct_cpu_seq_fops = { | 370 | static const struct file_operations ct_cpu_seq_fops = { |
@@ -362,39 +372,54 @@ static const struct file_operations ct_cpu_seq_fops = { | |||
362 | .open = ct_cpu_seq_open, | 372 | .open = ct_cpu_seq_open, |
363 | .read = seq_read, | 373 | .read = seq_read, |
364 | .llseek = seq_lseek, | 374 | .llseek = seq_lseek, |
365 | .release = seq_release, | 375 | .release = seq_release_net, |
366 | }; | 376 | }; |
367 | 377 | ||
368 | int __init nf_conntrack_ipv4_compat_init(void) | 378 | static int __net_init ip_conntrack_net_init(struct net *net) |
369 | { | 379 | { |
370 | struct proc_dir_entry *proc, *proc_exp, *proc_stat; | 380 | struct proc_dir_entry *proc, *proc_exp, *proc_stat; |
371 | 381 | ||
372 | proc = proc_net_fops_create(&init_net, "ip_conntrack", 0440, &ct_file_ops); | 382 | proc = proc_net_fops_create(net, "ip_conntrack", 0440, &ct_file_ops); |
373 | if (!proc) | 383 | if (!proc) |
374 | goto err1; | 384 | goto err1; |
375 | 385 | ||
376 | proc_exp = proc_net_fops_create(&init_net, "ip_conntrack_expect", 0440, | 386 | proc_exp = proc_net_fops_create(net, "ip_conntrack_expect", 0440, |
377 | &ip_exp_file_ops); | 387 | &ip_exp_file_ops); |
378 | if (!proc_exp) | 388 | if (!proc_exp) |
379 | goto err2; | 389 | goto err2; |
380 | 390 | ||
381 | proc_stat = proc_create("ip_conntrack", S_IRUGO, | 391 | proc_stat = proc_create("ip_conntrack", S_IRUGO, |
382 | init_net.proc_net_stat, &ct_cpu_seq_fops); | 392 | net->proc_net_stat, &ct_cpu_seq_fops); |
383 | if (!proc_stat) | 393 | if (!proc_stat) |
384 | goto err3; | 394 | goto err3; |
385 | return 0; | 395 | return 0; |
386 | 396 | ||
387 | err3: | 397 | err3: |
388 | proc_net_remove(&init_net, "ip_conntrack_expect"); | 398 | proc_net_remove(net, "ip_conntrack_expect"); |
389 | err2: | 399 | err2: |
390 | proc_net_remove(&init_net, "ip_conntrack"); | 400 | proc_net_remove(net, "ip_conntrack"); |
391 | err1: | 401 | err1: |
392 | return -ENOMEM; | 402 | return -ENOMEM; |
393 | } | 403 | } |
394 | 404 | ||
405 | static void __net_exit ip_conntrack_net_exit(struct net *net) | ||
406 | { | ||
407 | remove_proc_entry("ip_conntrack", net->proc_net_stat); | ||
408 | proc_net_remove(net, "ip_conntrack_expect"); | ||
409 | proc_net_remove(net, "ip_conntrack"); | ||
410 | } | ||
411 | |||
412 | static struct pernet_operations ip_conntrack_net_ops = { | ||
413 | .init = ip_conntrack_net_init, | ||
414 | .exit = ip_conntrack_net_exit, | ||
415 | }; | ||
416 | |||
417 | int __init nf_conntrack_ipv4_compat_init(void) | ||
418 | { | ||
419 | return register_pernet_subsys(&ip_conntrack_net_ops); | ||
420 | } | ||
421 | |||
395 | void __exit nf_conntrack_ipv4_compat_fini(void) | 422 | void __exit nf_conntrack_ipv4_compat_fini(void) |
396 | { | 423 | { |
397 | remove_proc_entry("ip_conntrack", init_net.proc_net_stat); | 424 | unregister_pernet_subsys(&ip_conntrack_net_ops); |
398 | proc_net_remove(&init_net, "ip_conntrack_expect"); | ||
399 | proc_net_remove(&init_net, "ip_conntrack"); | ||
400 | } | 425 | } |
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 97791048fa9b..4e8879220222 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c | |||
@@ -79,7 +79,7 @@ static int icmp_packet(struct nf_conn *ct, | |||
79 | const struct sk_buff *skb, | 79 | const struct sk_buff *skb, |
80 | unsigned int dataoff, | 80 | unsigned int dataoff, |
81 | enum ip_conntrack_info ctinfo, | 81 | enum ip_conntrack_info ctinfo, |
82 | int pf, | 82 | u_int8_t pf, |
83 | unsigned int hooknum) | 83 | unsigned int hooknum) |
84 | { | 84 | { |
85 | /* Try to delete connection immediately after all replies: | 85 | /* Try to delete connection immediately after all replies: |
@@ -91,7 +91,7 @@ static int icmp_packet(struct nf_conn *ct, | |||
91 | nf_ct_kill_acct(ct, ctinfo, skb); | 91 | nf_ct_kill_acct(ct, ctinfo, skb); |
92 | } else { | 92 | } else { |
93 | atomic_inc(&ct->proto.icmp.count); | 93 | atomic_inc(&ct->proto.icmp.count); |
94 | nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb); | 94 | nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct); |
95 | nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout); | 95 | nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout); |
96 | } | 96 | } |
97 | 97 | ||
@@ -123,7 +123,7 @@ static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb, | |||
123 | 123 | ||
124 | /* Returns conntrack if it dealt with ICMP, and filled in skb fields */ | 124 | /* Returns conntrack if it dealt with ICMP, and filled in skb fields */ |
125 | static int | 125 | static int |
126 | icmp_error_message(struct sk_buff *skb, | 126 | icmp_error_message(struct net *net, struct sk_buff *skb, |
127 | enum ip_conntrack_info *ctinfo, | 127 | enum ip_conntrack_info *ctinfo, |
128 | unsigned int hooknum) | 128 | unsigned int hooknum) |
129 | { | 129 | { |
@@ -155,7 +155,7 @@ icmp_error_message(struct sk_buff *skb, | |||
155 | 155 | ||
156 | *ctinfo = IP_CT_RELATED; | 156 | *ctinfo = IP_CT_RELATED; |
157 | 157 | ||
158 | h = nf_conntrack_find_get(&innertuple); | 158 | h = nf_conntrack_find_get(net, &innertuple); |
159 | if (!h) { | 159 | if (!h) { |
160 | pr_debug("icmp_error_message: no match\n"); | 160 | pr_debug("icmp_error_message: no match\n"); |
161 | return -NF_ACCEPT; | 161 | return -NF_ACCEPT; |
@@ -172,8 +172,8 @@ icmp_error_message(struct sk_buff *skb, | |||
172 | 172 | ||
173 | /* Small and modified version of icmp_rcv */ | 173 | /* Small and modified version of icmp_rcv */ |
174 | static int | 174 | static int |
175 | icmp_error(struct sk_buff *skb, unsigned int dataoff, | 175 | icmp_error(struct net *net, struct sk_buff *skb, unsigned int dataoff, |
176 | enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum) | 176 | enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum) |
177 | { | 177 | { |
178 | const struct icmphdr *icmph; | 178 | const struct icmphdr *icmph; |
179 | struct icmphdr _ih; | 179 | struct icmphdr _ih; |
@@ -181,16 +181,16 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff, | |||
181 | /* Not enough header? */ | 181 | /* Not enough header? */ |
182 | icmph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_ih), &_ih); | 182 | icmph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_ih), &_ih); |
183 | if (icmph == NULL) { | 183 | if (icmph == NULL) { |
184 | if (LOG_INVALID(IPPROTO_ICMP)) | 184 | if (LOG_INVALID(net, IPPROTO_ICMP)) |
185 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, | 185 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
186 | "nf_ct_icmp: short packet "); | 186 | "nf_ct_icmp: short packet "); |
187 | return -NF_ACCEPT; | 187 | return -NF_ACCEPT; |
188 | } | 188 | } |
189 | 189 | ||
190 | /* See ip_conntrack_proto_tcp.c */ | 190 | /* See ip_conntrack_proto_tcp.c */ |
191 | if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && | 191 | if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && |
192 | nf_ip_checksum(skb, hooknum, dataoff, 0)) { | 192 | nf_ip_checksum(skb, hooknum, dataoff, 0)) { |
193 | if (LOG_INVALID(IPPROTO_ICMP)) | 193 | if (LOG_INVALID(net, IPPROTO_ICMP)) |
194 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, | 194 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
195 | "nf_ct_icmp: bad HW ICMP checksum "); | 195 | "nf_ct_icmp: bad HW ICMP checksum "); |
196 | return -NF_ACCEPT; | 196 | return -NF_ACCEPT; |
@@ -203,7 +203,7 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff, | |||
203 | * discarded. | 203 | * discarded. |
204 | */ | 204 | */ |
205 | if (icmph->type > NR_ICMP_TYPES) { | 205 | if (icmph->type > NR_ICMP_TYPES) { |
206 | if (LOG_INVALID(IPPROTO_ICMP)) | 206 | if (LOG_INVALID(net, IPPROTO_ICMP)) |
207 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, | 207 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
208 | "nf_ct_icmp: invalid ICMP type "); | 208 | "nf_ct_icmp: invalid ICMP type "); |
209 | return -NF_ACCEPT; | 209 | return -NF_ACCEPT; |
@@ -217,7 +217,7 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff, | |||
217 | && icmph->type != ICMP_REDIRECT) | 217 | && icmph->type != ICMP_REDIRECT) |
218 | return NF_ACCEPT; | 218 | return NF_ACCEPT; |
219 | 219 | ||
220 | return icmp_error_message(skb, ctinfo, hooknum); | 220 | return icmp_error_message(net, skb, ctinfo, hooknum); |
221 | } | 221 | } |
222 | 222 | ||
223 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 223 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) |
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c new file mode 100644 index 000000000000..aa2c50a180f7 --- /dev/null +++ b/net/ipv4/netfilter/nf_defrag_ipv4.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* (C) 1999-2001 Paul `Rusty' Russell | ||
2 | * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/types.h> | ||
10 | #include <linux/ip.h> | ||
11 | #include <linux/netfilter.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/skbuff.h> | ||
14 | #include <net/route.h> | ||
15 | #include <net/ip.h> | ||
16 | |||
17 | #include <linux/netfilter_ipv4.h> | ||
18 | #include <net/netfilter/ipv4/nf_defrag_ipv4.h> | ||
19 | |||
20 | /* Returns new sk_buff, or NULL */ | ||
21 | static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user) | ||
22 | { | ||
23 | int err; | ||
24 | |||
25 | skb_orphan(skb); | ||
26 | |||
27 | local_bh_disable(); | ||
28 | err = ip_defrag(skb, user); | ||
29 | local_bh_enable(); | ||
30 | |||
31 | if (!err) | ||
32 | ip_send_check(ip_hdr(skb)); | ||
33 | |||
34 | return err; | ||
35 | } | ||
36 | |||
37 | static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, | ||
38 | struct sk_buff *skb, | ||
39 | const struct net_device *in, | ||
40 | const struct net_device *out, | ||
41 | int (*okfn)(struct sk_buff *)) | ||
42 | { | ||
43 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | ||
44 | /* Previously seen (loopback)? Ignore. Do this before | ||
45 | fragment check. */ | ||
46 | if (skb->nfct) | ||
47 | return NF_ACCEPT; | ||
48 | #endif | ||
49 | |||
50 | /* Gather fragments. */ | ||
51 | if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { | ||
52 | if (nf_ct_ipv4_gather_frags(skb, | ||
53 | hooknum == NF_INET_PRE_ROUTING ? | ||
54 | IP_DEFRAG_CONNTRACK_IN : | ||
55 | IP_DEFRAG_CONNTRACK_OUT)) | ||
56 | return NF_STOLEN; | ||
57 | } | ||
58 | return NF_ACCEPT; | ||
59 | } | ||
60 | |||
61 | static struct nf_hook_ops ipv4_defrag_ops[] = { | ||
62 | { | ||
63 | .hook = ipv4_conntrack_defrag, | ||
64 | .owner = THIS_MODULE, | ||
65 | .pf = PF_INET, | ||
66 | .hooknum = NF_INET_PRE_ROUTING, | ||
67 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, | ||
68 | }, | ||
69 | { | ||
70 | .hook = ipv4_conntrack_defrag, | ||
71 | .owner = THIS_MODULE, | ||
72 | .pf = PF_INET, | ||
73 | .hooknum = NF_INET_LOCAL_OUT, | ||
74 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, | ||
75 | }, | ||
76 | }; | ||
77 | |||
78 | static int __init nf_defrag_init(void) | ||
79 | { | ||
80 | return nf_register_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops)); | ||
81 | } | ||
82 | |||
83 | static void __exit nf_defrag_fini(void) | ||
84 | { | ||
85 | nf_unregister_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops)); | ||
86 | } | ||
87 | |||
88 | void nf_defrag_ipv4_enable(void) | ||
89 | { | ||
90 | } | ||
91 | EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable); | ||
92 | |||
93 | module_init(nf_defrag_init); | ||
94 | module_exit(nf_defrag_fini); | ||
95 | |||
96 | MODULE_LICENSE("GPL"); | ||
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 6c6a3cba8d50..2ac9eaf1a8c9 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c | |||
@@ -37,9 +37,6 @@ static struct nf_conntrack_l3proto *l3proto __read_mostly; | |||
37 | 37 | ||
38 | /* Calculated at init based on memory size */ | 38 | /* Calculated at init based on memory size */ |
39 | static unsigned int nf_nat_htable_size __read_mostly; | 39 | static unsigned int nf_nat_htable_size __read_mostly; |
40 | static int nf_nat_vmalloced; | ||
41 | |||
42 | static struct hlist_head *bysource __read_mostly; | ||
43 | 40 | ||
44 | #define MAX_IP_NAT_PROTO 256 | 41 | #define MAX_IP_NAT_PROTO 256 |
45 | static const struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO] | 42 | static const struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO] |
@@ -145,7 +142,8 @@ same_src(const struct nf_conn *ct, | |||
145 | 142 | ||
146 | /* Only called for SRC manip */ | 143 | /* Only called for SRC manip */ |
147 | static int | 144 | static int |
148 | find_appropriate_src(const struct nf_conntrack_tuple *tuple, | 145 | find_appropriate_src(struct net *net, |
146 | const struct nf_conntrack_tuple *tuple, | ||
149 | struct nf_conntrack_tuple *result, | 147 | struct nf_conntrack_tuple *result, |
150 | const struct nf_nat_range *range) | 148 | const struct nf_nat_range *range) |
151 | { | 149 | { |
@@ -155,7 +153,7 @@ find_appropriate_src(const struct nf_conntrack_tuple *tuple, | |||
155 | const struct hlist_node *n; | 153 | const struct hlist_node *n; |
156 | 154 | ||
157 | rcu_read_lock(); | 155 | rcu_read_lock(); |
158 | hlist_for_each_entry_rcu(nat, n, &bysource[h], bysource) { | 156 | hlist_for_each_entry_rcu(nat, n, &net->ipv4.nat_bysource[h], bysource) { |
159 | ct = nat->ct; | 157 | ct = nat->ct; |
160 | if (same_src(ct, tuple)) { | 158 | if (same_src(ct, tuple)) { |
161 | /* Copy source part from reply tuple. */ | 159 | /* Copy source part from reply tuple. */ |
@@ -231,6 +229,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, | |||
231 | struct nf_conn *ct, | 229 | struct nf_conn *ct, |
232 | enum nf_nat_manip_type maniptype) | 230 | enum nf_nat_manip_type maniptype) |
233 | { | 231 | { |
232 | struct net *net = nf_ct_net(ct); | ||
234 | const struct nf_nat_protocol *proto; | 233 | const struct nf_nat_protocol *proto; |
235 | 234 | ||
236 | /* 1) If this srcip/proto/src-proto-part is currently mapped, | 235 | /* 1) If this srcip/proto/src-proto-part is currently mapped, |
@@ -242,7 +241,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, | |||
242 | manips not an issue. */ | 241 | manips not an issue. */ |
243 | if (maniptype == IP_NAT_MANIP_SRC && | 242 | if (maniptype == IP_NAT_MANIP_SRC && |
244 | !(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) { | 243 | !(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) { |
245 | if (find_appropriate_src(orig_tuple, tuple, range)) { | 244 | if (find_appropriate_src(net, orig_tuple, tuple, range)) { |
246 | pr_debug("get_unique_tuple: Found current src map\n"); | 245 | pr_debug("get_unique_tuple: Found current src map\n"); |
247 | if (!nf_nat_used_tuple(tuple, ct)) | 246 | if (!nf_nat_used_tuple(tuple, ct)) |
248 | return; | 247 | return; |
@@ -283,6 +282,7 @@ nf_nat_setup_info(struct nf_conn *ct, | |||
283 | const struct nf_nat_range *range, | 282 | const struct nf_nat_range *range, |
284 | enum nf_nat_manip_type maniptype) | 283 | enum nf_nat_manip_type maniptype) |
285 | { | 284 | { |
285 | struct net *net = nf_ct_net(ct); | ||
286 | struct nf_conntrack_tuple curr_tuple, new_tuple; | 286 | struct nf_conntrack_tuple curr_tuple, new_tuple; |
287 | struct nf_conn_nat *nat; | 287 | struct nf_conn_nat *nat; |
288 | int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK); | 288 | int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK); |
@@ -334,7 +334,8 @@ nf_nat_setup_info(struct nf_conn *ct, | |||
334 | /* nf_conntrack_alter_reply might re-allocate exntension aera */ | 334 | /* nf_conntrack_alter_reply might re-allocate exntension aera */ |
335 | nat = nfct_nat(ct); | 335 | nat = nfct_nat(ct); |
336 | nat->ct = ct; | 336 | nat->ct = ct; |
337 | hlist_add_head_rcu(&nat->bysource, &bysource[srchash]); | 337 | hlist_add_head_rcu(&nat->bysource, |
338 | &net->ipv4.nat_bysource[srchash]); | ||
338 | spin_unlock_bh(&nf_nat_lock); | 339 | spin_unlock_bh(&nf_nat_lock); |
339 | } | 340 | } |
340 | 341 | ||
@@ -583,6 +584,40 @@ static struct nf_ct_ext_type nat_extend __read_mostly = { | |||
583 | .flags = NF_CT_EXT_F_PREALLOC, | 584 | .flags = NF_CT_EXT_F_PREALLOC, |
584 | }; | 585 | }; |
585 | 586 | ||
587 | static int __net_init nf_nat_net_init(struct net *net) | ||
588 | { | ||
589 | net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size, | ||
590 | &net->ipv4.nat_vmalloced); | ||
591 | if (!net->ipv4.nat_bysource) | ||
592 | return -ENOMEM; | ||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | /* Clear NAT section of all conntracks, in case we're loaded again. */ | ||
597 | static int clean_nat(struct nf_conn *i, void *data) | ||
598 | { | ||
599 | struct nf_conn_nat *nat = nfct_nat(i); | ||
600 | |||
601 | if (!nat) | ||
602 | return 0; | ||
603 | memset(nat, 0, sizeof(*nat)); | ||
604 | i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST); | ||
605 | return 0; | ||
606 | } | ||
607 | |||
608 | static void __net_exit nf_nat_net_exit(struct net *net) | ||
609 | { | ||
610 | nf_ct_iterate_cleanup(net, &clean_nat, NULL); | ||
611 | synchronize_rcu(); | ||
612 | nf_ct_free_hashtable(net->ipv4.nat_bysource, net->ipv4.nat_vmalloced, | ||
613 | nf_nat_htable_size); | ||
614 | } | ||
615 | |||
616 | static struct pernet_operations nf_nat_net_ops = { | ||
617 | .init = nf_nat_net_init, | ||
618 | .exit = nf_nat_net_exit, | ||
619 | }; | ||
620 | |||
586 | static int __init nf_nat_init(void) | 621 | static int __init nf_nat_init(void) |
587 | { | 622 | { |
588 | size_t i; | 623 | size_t i; |
@@ -599,12 +634,9 @@ static int __init nf_nat_init(void) | |||
599 | /* Leave them the same for the moment. */ | 634 | /* Leave them the same for the moment. */ |
600 | nf_nat_htable_size = nf_conntrack_htable_size; | 635 | nf_nat_htable_size = nf_conntrack_htable_size; |
601 | 636 | ||
602 | bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size, | 637 | ret = register_pernet_subsys(&nf_nat_net_ops); |
603 | &nf_nat_vmalloced); | 638 | if (ret < 0) |
604 | if (!bysource) { | ||
605 | ret = -ENOMEM; | ||
606 | goto cleanup_extend; | 639 | goto cleanup_extend; |
607 | } | ||
608 | 640 | ||
609 | /* Sew in builtin protocols. */ | 641 | /* Sew in builtin protocols. */ |
610 | spin_lock_bh(&nf_nat_lock); | 642 | spin_lock_bh(&nf_nat_lock); |
@@ -629,23 +661,9 @@ static int __init nf_nat_init(void) | |||
629 | return ret; | 661 | return ret; |
630 | } | 662 | } |
631 | 663 | ||
632 | /* Clear NAT section of all conntracks, in case we're loaded again. */ | ||
633 | static int clean_nat(struct nf_conn *i, void *data) | ||
634 | { | ||
635 | struct nf_conn_nat *nat = nfct_nat(i); | ||
636 | |||
637 | if (!nat) | ||
638 | return 0; | ||
639 | memset(nat, 0, sizeof(*nat)); | ||
640 | i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST); | ||
641 | return 0; | ||
642 | } | ||
643 | |||
644 | static void __exit nf_nat_cleanup(void) | 664 | static void __exit nf_nat_cleanup(void) |
645 | { | 665 | { |
646 | nf_ct_iterate_cleanup(&clean_nat, NULL); | 666 | unregister_pernet_subsys(&nf_nat_net_ops); |
647 | synchronize_rcu(); | ||
648 | nf_ct_free_hashtable(bysource, nf_nat_vmalloced, nf_nat_htable_size); | ||
649 | nf_ct_l3proto_put(l3proto); | 667 | nf_ct_l3proto_put(l3proto); |
650 | nf_ct_extend_unregister(&nat_extend); | 668 | nf_ct_extend_unregister(&nat_extend); |
651 | rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL); | 669 | rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL); |
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c index 112dcfa12900..cf7a42bf9820 100644 --- a/net/ipv4/netfilter/nf_nat_helper.c +++ b/net/ipv4/netfilter/nf_nat_helper.c | |||
@@ -193,7 +193,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb, | |||
193 | nf_conntrack_tcp_update(skb, ip_hdrlen(skb), | 193 | nf_conntrack_tcp_update(skb, ip_hdrlen(skb), |
194 | ct, CTINFO2DIR(ctinfo)); | 194 | ct, CTINFO2DIR(ctinfo)); |
195 | 195 | ||
196 | nf_conntrack_event_cache(IPCT_NATSEQADJ, skb); | 196 | nf_conntrack_event_cache(IPCT_NATSEQADJ, ct); |
197 | } | 197 | } |
198 | return 1; | 198 | return 1; |
199 | } | 199 | } |
diff --git a/net/ipv4/netfilter/nf_nat_pptp.c b/net/ipv4/netfilter/nf_nat_pptp.c index da3d91a5ef5c..9eb171056c63 100644 --- a/net/ipv4/netfilter/nf_nat_pptp.c +++ b/net/ipv4/netfilter/nf_nat_pptp.c | |||
@@ -40,6 +40,7 @@ MODULE_ALIAS("ip_nat_pptp"); | |||
40 | static void pptp_nat_expected(struct nf_conn *ct, | 40 | static void pptp_nat_expected(struct nf_conn *ct, |
41 | struct nf_conntrack_expect *exp) | 41 | struct nf_conntrack_expect *exp) |
42 | { | 42 | { |
43 | struct net *net = nf_ct_net(ct); | ||
43 | const struct nf_conn *master = ct->master; | 44 | const struct nf_conn *master = ct->master; |
44 | struct nf_conntrack_expect *other_exp; | 45 | struct nf_conntrack_expect *other_exp; |
45 | struct nf_conntrack_tuple t; | 46 | struct nf_conntrack_tuple t; |
@@ -73,7 +74,7 @@ static void pptp_nat_expected(struct nf_conn *ct, | |||
73 | 74 | ||
74 | pr_debug("trying to unexpect other dir: "); | 75 | pr_debug("trying to unexpect other dir: "); |
75 | nf_ct_dump_tuple_ip(&t); | 76 | nf_ct_dump_tuple_ip(&t); |
76 | other_exp = nf_ct_expect_find_get(&t); | 77 | other_exp = nf_ct_expect_find_get(net, &t); |
77 | if (other_exp) { | 78 | if (other_exp) { |
78 | nf_ct_unexpect_related(other_exp); | 79 | nf_ct_unexpect_related(other_exp); |
79 | nf_ct_expect_put(other_exp); | 80 | nf_ct_expect_put(other_exp); |
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c index e8b4d0d4439e..bea54a685109 100644 --- a/net/ipv4/netfilter/nf_nat_rule.c +++ b/net/ipv4/netfilter/nf_nat_rule.c | |||
@@ -33,7 +33,7 @@ static struct | |||
33 | struct ipt_replace repl; | 33 | struct ipt_replace repl; |
34 | struct ipt_standard entries[3]; | 34 | struct ipt_standard entries[3]; |
35 | struct ipt_error term; | 35 | struct ipt_error term; |
36 | } nat_initial_table __initdata = { | 36 | } nat_initial_table __net_initdata = { |
37 | .repl = { | 37 | .repl = { |
38 | .name = "nat", | 38 | .name = "nat", |
39 | .valid_hooks = NAT_VALID_HOOKS, | 39 | .valid_hooks = NAT_VALID_HOOKS, |
@@ -58,47 +58,42 @@ static struct | |||
58 | .term = IPT_ERROR_INIT, /* ERROR */ | 58 | .term = IPT_ERROR_INIT, /* ERROR */ |
59 | }; | 59 | }; |
60 | 60 | ||
61 | static struct xt_table __nat_table = { | 61 | static struct xt_table nat_table = { |
62 | .name = "nat", | 62 | .name = "nat", |
63 | .valid_hooks = NAT_VALID_HOOKS, | 63 | .valid_hooks = NAT_VALID_HOOKS, |
64 | .lock = __RW_LOCK_UNLOCKED(__nat_table.lock), | 64 | .lock = __RW_LOCK_UNLOCKED(__nat_table.lock), |
65 | .me = THIS_MODULE, | 65 | .me = THIS_MODULE, |
66 | .af = AF_INET, | 66 | .af = AF_INET, |
67 | }; | 67 | }; |
68 | static struct xt_table *nat_table; | ||
69 | 68 | ||
70 | /* Source NAT */ | 69 | /* Source NAT */ |
71 | static unsigned int ipt_snat_target(struct sk_buff *skb, | 70 | static unsigned int |
72 | const struct net_device *in, | 71 | ipt_snat_target(struct sk_buff *skb, const struct xt_target_param *par) |
73 | const struct net_device *out, | ||
74 | unsigned int hooknum, | ||
75 | const struct xt_target *target, | ||
76 | const void *targinfo) | ||
77 | { | 72 | { |
78 | struct nf_conn *ct; | 73 | struct nf_conn *ct; |
79 | enum ip_conntrack_info ctinfo; | 74 | enum ip_conntrack_info ctinfo; |
80 | const struct nf_nat_multi_range_compat *mr = targinfo; | 75 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
81 | 76 | ||
82 | NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING); | 77 | NF_CT_ASSERT(par->hooknum == NF_INET_POST_ROUTING); |
83 | 78 | ||
84 | ct = nf_ct_get(skb, &ctinfo); | 79 | ct = nf_ct_get(skb, &ctinfo); |
85 | 80 | ||
86 | /* Connection must be valid and new. */ | 81 | /* Connection must be valid and new. */ |
87 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || | 82 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || |
88 | ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)); | 83 | ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)); |
89 | NF_CT_ASSERT(out); | 84 | NF_CT_ASSERT(par->out != NULL); |
90 | 85 | ||
91 | return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC); | 86 | return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC); |
92 | } | 87 | } |
93 | 88 | ||
94 | /* Before 2.6.11 we did implicit source NAT if required. Warn about change. */ | 89 | /* Before 2.6.11 we did implicit source NAT if required. Warn about change. */ |
95 | static void warn_if_extra_mangle(__be32 dstip, __be32 srcip) | 90 | static void warn_if_extra_mangle(struct net *net, __be32 dstip, __be32 srcip) |
96 | { | 91 | { |
97 | static int warned = 0; | 92 | static int warned = 0; |
98 | struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } }; | 93 | struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } }; |
99 | struct rtable *rt; | 94 | struct rtable *rt; |
100 | 95 | ||
101 | if (ip_route_output_key(&init_net, &rt, &fl) != 0) | 96 | if (ip_route_output_key(net, &rt, &fl) != 0) |
102 | return; | 97 | return; |
103 | 98 | ||
104 | if (rt->rt_src != srcip && !warned) { | 99 | if (rt->rt_src != srcip && !warned) { |
@@ -110,40 +105,32 @@ static void warn_if_extra_mangle(__be32 dstip, __be32 srcip) | |||
110 | ip_rt_put(rt); | 105 | ip_rt_put(rt); |
111 | } | 106 | } |
112 | 107 | ||
113 | static unsigned int ipt_dnat_target(struct sk_buff *skb, | 108 | static unsigned int |
114 | const struct net_device *in, | 109 | ipt_dnat_target(struct sk_buff *skb, const struct xt_target_param *par) |
115 | const struct net_device *out, | ||
116 | unsigned int hooknum, | ||
117 | const struct xt_target *target, | ||
118 | const void *targinfo) | ||
119 | { | 110 | { |
120 | struct nf_conn *ct; | 111 | struct nf_conn *ct; |
121 | enum ip_conntrack_info ctinfo; | 112 | enum ip_conntrack_info ctinfo; |
122 | const struct nf_nat_multi_range_compat *mr = targinfo; | 113 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
123 | 114 | ||
124 | NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING || | 115 | NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING || |
125 | hooknum == NF_INET_LOCAL_OUT); | 116 | par->hooknum == NF_INET_LOCAL_OUT); |
126 | 117 | ||
127 | ct = nf_ct_get(skb, &ctinfo); | 118 | ct = nf_ct_get(skb, &ctinfo); |
128 | 119 | ||
129 | /* Connection must be valid and new. */ | 120 | /* Connection must be valid and new. */ |
130 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); | 121 | NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); |
131 | 122 | ||
132 | if (hooknum == NF_INET_LOCAL_OUT && | 123 | if (par->hooknum == NF_INET_LOCAL_OUT && |
133 | mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) | 124 | mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) |
134 | warn_if_extra_mangle(ip_hdr(skb)->daddr, | 125 | warn_if_extra_mangle(dev_net(par->out), ip_hdr(skb)->daddr, |
135 | mr->range[0].min_ip); | 126 | mr->range[0].min_ip); |
136 | 127 | ||
137 | return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST); | 128 | return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST); |
138 | } | 129 | } |
139 | 130 | ||
140 | static bool ipt_snat_checkentry(const char *tablename, | 131 | static bool ipt_snat_checkentry(const struct xt_tgchk_param *par) |
141 | const void *entry, | ||
142 | const struct xt_target *target, | ||
143 | void *targinfo, | ||
144 | unsigned int hook_mask) | ||
145 | { | 132 | { |
146 | const struct nf_nat_multi_range_compat *mr = targinfo; | 133 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
147 | 134 | ||
148 | /* Must be a valid range */ | 135 | /* Must be a valid range */ |
149 | if (mr->rangesize != 1) { | 136 | if (mr->rangesize != 1) { |
@@ -153,13 +140,9 @@ static bool ipt_snat_checkentry(const char *tablename, | |||
153 | return true; | 140 | return true; |
154 | } | 141 | } |
155 | 142 | ||
156 | static bool ipt_dnat_checkentry(const char *tablename, | 143 | static bool ipt_dnat_checkentry(const struct xt_tgchk_param *par) |
157 | const void *entry, | ||
158 | const struct xt_target *target, | ||
159 | void *targinfo, | ||
160 | unsigned int hook_mask) | ||
161 | { | 144 | { |
162 | const struct nf_nat_multi_range_compat *mr = targinfo; | 145 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
163 | 146 | ||
164 | /* Must be a valid range */ | 147 | /* Must be a valid range */ |
165 | if (mr->rangesize != 1) { | 148 | if (mr->rangesize != 1) { |
@@ -194,9 +177,10 @@ int nf_nat_rule_find(struct sk_buff *skb, | |||
194 | const struct net_device *out, | 177 | const struct net_device *out, |
195 | struct nf_conn *ct) | 178 | struct nf_conn *ct) |
196 | { | 179 | { |
180 | struct net *net = nf_ct_net(ct); | ||
197 | int ret; | 181 | int ret; |
198 | 182 | ||
199 | ret = ipt_do_table(skb, hooknum, in, out, nat_table); | 183 | ret = ipt_do_table(skb, hooknum, in, out, net->ipv4.nat_table); |
200 | 184 | ||
201 | if (ret == NF_ACCEPT) { | 185 | if (ret == NF_ACCEPT) { |
202 | if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum))) | 186 | if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum))) |
@@ -226,14 +210,32 @@ static struct xt_target ipt_dnat_reg __read_mostly = { | |||
226 | .family = AF_INET, | 210 | .family = AF_INET, |
227 | }; | 211 | }; |
228 | 212 | ||
213 | static int __net_init nf_nat_rule_net_init(struct net *net) | ||
214 | { | ||
215 | net->ipv4.nat_table = ipt_register_table(net, &nat_table, | ||
216 | &nat_initial_table.repl); | ||
217 | if (IS_ERR(net->ipv4.nat_table)) | ||
218 | return PTR_ERR(net->ipv4.nat_table); | ||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | static void __net_exit nf_nat_rule_net_exit(struct net *net) | ||
223 | { | ||
224 | ipt_unregister_table(net->ipv4.nat_table); | ||
225 | } | ||
226 | |||
227 | static struct pernet_operations nf_nat_rule_net_ops = { | ||
228 | .init = nf_nat_rule_net_init, | ||
229 | .exit = nf_nat_rule_net_exit, | ||
230 | }; | ||
231 | |||
229 | int __init nf_nat_rule_init(void) | 232 | int __init nf_nat_rule_init(void) |
230 | { | 233 | { |
231 | int ret; | 234 | int ret; |
232 | 235 | ||
233 | nat_table = ipt_register_table(&init_net, &__nat_table, | 236 | ret = register_pernet_subsys(&nf_nat_rule_net_ops); |
234 | &nat_initial_table.repl); | 237 | if (ret != 0) |
235 | if (IS_ERR(nat_table)) | 238 | goto out; |
236 | return PTR_ERR(nat_table); | ||
237 | ret = xt_register_target(&ipt_snat_reg); | 239 | ret = xt_register_target(&ipt_snat_reg); |
238 | if (ret != 0) | 240 | if (ret != 0) |
239 | goto unregister_table; | 241 | goto unregister_table; |
@@ -247,8 +249,8 @@ int __init nf_nat_rule_init(void) | |||
247 | unregister_snat: | 249 | unregister_snat: |
248 | xt_unregister_target(&ipt_snat_reg); | 250 | xt_unregister_target(&ipt_snat_reg); |
249 | unregister_table: | 251 | unregister_table: |
250 | ipt_unregister_table(nat_table); | 252 | unregister_pernet_subsys(&nf_nat_rule_net_ops); |
251 | 253 | out: | |
252 | return ret; | 254 | return ret; |
253 | } | 255 | } |
254 | 256 | ||
@@ -256,5 +258,5 @@ void nf_nat_rule_cleanup(void) | |||
256 | { | 258 | { |
257 | xt_unregister_target(&ipt_dnat_reg); | 259 | xt_unregister_target(&ipt_dnat_reg); |
258 | xt_unregister_target(&ipt_snat_reg); | 260 | xt_unregister_target(&ipt_snat_reg); |
259 | ipt_unregister_table(nat_table); | 261 | unregister_pernet_subsys(&nf_nat_rule_net_ops); |
260 | } | 262 | } |
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 | ||
58 | if IP6_NF_IPTABLES | ||
59 | |||
58 | # The simple matches. | 60 | # The simple matches. |
59 | config IP6_NF_MATCH_RT | 61 | config 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 | ||
69 | config IP6_NF_MATCH_OPTS | 69 | config 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 | ||
79 | config IP6_NF_MATCH_FRAG | 79 | config 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 | ||
88 | config 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 | |||
89 | config IP6_NF_MATCH_HL | 97 | config 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 | ||
99 | config IP6_NF_MATCH_IPV6HEADER | 106 | config 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 | ||
109 | config 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 | |||
118 | config IP6_NF_MATCH_MH | 115 | config 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 | ||
127 | config IP6_NF_MATCH_EUI64 | 123 | config 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 |
139 | config IP6_NF_FILTER | 133 | config 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 | ||
150 | config IP6_NF_TARGET_LOG | 142 | config 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 | ||
171 | config IP6_NF_MANGLE | 163 | config 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 | ||
199 | config IP6_NF_RAW | 190 | config 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 |
212 | config IP6_NF_SECURITY | 202 | config 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 | ||
212 | endif # IP6_NF_IPTABLES | ||
213 | |||
223 | endmenu | 214 | endmenu |
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 | ||
202 | static unsigned int | 202 | static unsigned int |
203 | ip6t_error(struct sk_buff *skb, | 203 | ip6t_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 */ |
217 | static inline bool | 213 | static inline bool |
218 | do_match(struct ip6t_entry_match *m, | 214 | do_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, | |||
602 | static int | 598 | static int |
603 | cleanup_match(struct ip6t_entry_match *m, unsigned int *i) | 599 | cleanup_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 | ||
635 | static int check_match(struct ip6t_entry_match *m, const char *name, | 636 | static 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 | ||
658 | static int | 656 | static int |
659 | find_check_match(struct ip6t_entry_match *m, | 657 | find_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 | ||
687 | static int check_target(struct ip6t_entry *e, const char *name) | 682 | static 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 | ||
708 | static int | 706 | static 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, | |||
795 | static int | 797 | static int |
796 | cleanup_entry(struct ip6t_entry *e, unsigned int *i) | 798 | cleanup_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 | ||
2148 | static bool | 2159 | static bool |
2149 | icmp6_match(const struct sk_buff *skb, | 2160 | icmp6_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. */ |
2184 | static bool | 2188 | static bool icmp6_checkentry(const struct xt_mtchk_param *par) |
2185 | icmp6_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"); | |||
19 | MODULE_LICENSE("GPL"); | 19 | MODULE_LICENSE("GPL"); |
20 | 20 | ||
21 | static unsigned int | 21 | static unsigned int |
22 | hl_tg6(struct sk_buff *skb, const struct net_device *in, | 22 | hl_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 | ||
59 | static bool | 57 | static bool hl_tg6_check(const struct xt_tgchk_param *par) |
60 | hl_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 | ||
79 | static struct xt_target hl_tg6_reg __read_mostly = { | 74 | static 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 | ||
387 | static void | 387 | static void |
388 | ip6t_log_packet(unsigned int pf, | 388 | ip6t_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 | ||
440 | static unsigned int | 440 | static unsigned int |
441 | log_tg6(struct sk_buff *skb, const struct net_device *in, | 441 | log_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 | ||
457 | static bool | 456 | static bool log_tg6_check(const struct xt_tgchk_param *par) |
458 | log_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 | ||
476 | static struct xt_target log_tg6_reg __read_mostly = { | 472 | static 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"); | |||
35 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
36 | 36 | ||
37 | /* Send RST reply */ | 37 | /* Send RST reply */ |
38 | static void send_reset(struct sk_buff *oldskb) | 38 | static 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 | ||
165 | static inline void | 165 | static inline void |
166 | send_unreach(struct sk_buff *skb_in, unsigned char code, unsigned int hooknum) | 166 | send_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 | ||
174 | static unsigned int | 175 | static unsigned int |
175 | reject_tg6(struct sk_buff *skb, const struct net_device *in, | 176 | reject_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 | ||
216 | static bool | 216 | static bool reject_tg6_check(const struct xt_tgchk_param *par) |
217 | reject_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 | ||
238 | static struct xt_target reject_tg6_reg __read_mostly = { | 235 | static 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 | ||
39 | static bool | 39 | static bool ah_mt6(const struct sk_buff *skb, const struct xt_match_param *par) |
40 | ah_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. */ | 93 | static bool ah_mt6_check(const struct xt_mtchk_param *par) |
97 | static bool | ||
98 | ah_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 | ||
111 | static struct xt_match ah_mt6_reg __read_mostly = { | 104 | static 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"); | |||
20 | MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); | 20 | MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); |
21 | 21 | ||
22 | static bool | 22 | static bool |
23 | eui64_mt6(const struct sk_buff *skb, const struct net_device *in, | 23 | eui64_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 | ||
61 | static struct xt_match eui64_mt6_reg __read_mostly = { | 58 | static 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 | ||
37 | static bool | 37 | static bool |
38 | frag_mt6(const struct sk_buff *skb, const struct net_device *in, | 38 | frag_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. */ | 110 | static bool frag_mt6_check(const struct xt_mtchk_param *par) |
114 | static bool | ||
115 | frag_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 | ||
128 | static struct xt_match frag_mt6_reg __read_mostly = { | 121 | static 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 | ||
44 | static bool | 44 | static bool |
45 | hbh_mt6(const struct sk_buff *skb, const struct net_device *in, | 45 | hbh_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. */ | 163 | static bool hbh_mt6_check(const struct xt_mtchk_param *par) |
167 | static bool | ||
168 | hbh_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, | |||
187 | static struct xt_match hbh_mt6_reg[] __read_mostly = { | 180 | static 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>"); | |||
19 | MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field match"); | 19 | MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field match"); |
20 | MODULE_LICENSE("GPL"); | 20 | MODULE_LICENSE("GPL"); |
21 | 21 | ||
22 | static bool | 22 | static bool hl_mt6(const struct sk_buff *skb, const struct xt_match_param *par) |
23 | hl_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 | ||
52 | static struct xt_match hl_mt6_reg __read_mostly = { | 49 | static 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"); | |||
27 | MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); | 27 | MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); |
28 | 28 | ||
29 | static bool | 29 | static bool |
30 | ipv6header_mt6(const struct sk_buff *skb, const struct net_device *in, | 30 | ipv6header_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 | ||
124 | static bool | 121 | static bool ipv6header_mt6_check(const struct xt_mtchk_param *par) |
125 | ipv6header_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 | ||
139 | static struct xt_match ipv6header_mt6_reg __read_mostly = { | 133 | static 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 | ||
40 | static bool | 40 | static bool mh_mt6(const struct sk_buff *skb, const struct xt_match_param *par) |
41 | mh_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. */ | 70 | static bool mh_mt6_check(const struct xt_mtchk_param *par) |
74 | static bool | ||
75 | mh_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 | ||
85 | static struct xt_match mh_mt6_reg __read_mostly = { | 78 | static 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 | ||
39 | static bool | 39 | static bool rt_mt6(const struct sk_buff *skb, const struct xt_match_param *par) |
40 | rt_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. */ | 189 | static bool rt_mt6_check(const struct xt_mtchk_param *par) |
193 | static bool | ||
194 | rt_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 | ||
215 | static struct xt_match rt_mt6_reg __read_mostly = { | 208 | static 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 | ||
74 | static unsigned int | 74 | static 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 | ||
85 | static unsigned int | 85 | static 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 | ||
106 | static struct nf_hook_ops ip6t_ops[] __read_mostly = { | 106 | static 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. */ |
69 | static unsigned int | 69 | static unsigned int |
70 | ip6t_route_hook(unsigned int hook, | 70 | ip6t_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 | ||
79 | static unsigned int | 80 | static unsigned int |
80 | ip6t_local_hook(unsigned int hook, | 81 | ip6t_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 | |||
91 | static unsigned int | ||
92 | ip6t_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 | ||
123 | static struct nf_hook_ops ip6t_ops[] __read_mostly = { | 136 | static 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. */ |
47 | static unsigned int | 47 | static unsigned int |
48 | ip6t_hook(unsigned int hook, | 48 | ip6t_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 | |||
58 | static unsigned int | ||
59 | ip6t_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 | ||
57 | static struct nf_hook_ops ip6t_ops[] __read_mostly = { | 69 | static 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 | ||
78 | static unsigned int | 78 | static 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 | ||
89 | static unsigned int | 89 | static 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 | ||
101 | static struct nf_hook_ops ip6t_ops[] __read_mostly = { | 101 | static 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 | ||
214 | static unsigned int ipv6_conntrack_in(unsigned int hooknum, | 214 | static 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 | |||
240 | static 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 | ||
241 | static unsigned int ipv6_conntrack_local(unsigned int hooknum, | 249 | static 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 | ||
256 | static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { | 264 | static 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 | ||
124 | static int | 124 | static int |
125 | icmpv6_error_message(struct sk_buff *skb, | 125 | icmpv6_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 | ||
174 | static int | 175 | static int |
175 | icmpv6_error(struct sk_buff *skb, unsigned int dataoff, | 176 | icmpv6_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 | ||
41 | if NF_CONNTRACK | ||
42 | |||
41 | config NF_CT_ACCT | 43 | config 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 | |||
63 | config NF_CONNTRACK_MARK | 64 | config 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 | ||
73 | config NF_CONNTRACK_SECMARK | 73 | config 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 | ||
86 | config NF_CONNTRACK_EVENTS | 86 | config 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 | ||
97 | config NF_CT_PROTO_DCCP | 96 | config 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 | ||
108 | config NF_CT_PROTO_GRE | 107 | config NF_CT_PROTO_GRE |
109 | tristate | 108 | tristate |
110 | depends on NF_CONNTRACK | ||
111 | 109 | ||
112 | config NF_CT_PROTO_SCTP | 110 | config 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 | ||
124 | config NF_CT_PROTO_UDPLITE | 122 | config 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 | ||
135 | config NF_CONNTRACK_AMANDA | 132 | config 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 | ||
151 | config NF_CONNTRACK_FTP | 147 | config 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 | ||
166 | config NF_CONNTRACK_H323 | 161 | config 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 | ||
186 | config NF_CONNTRACK_IRC | 181 | config 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 | ||
202 | config NF_CONNTRACK_NETBIOS_NS | 196 | config 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 | ||
222 | config NF_CONNTRACK_PPTP | 215 | config 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 | ||
242 | config NF_CONNTRACK_SANE | 234 | config 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 | ||
256 | config NF_CONNTRACK_SIP | 248 | config 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 | ||
269 | config NF_CONNTRACK_TFTP | 260 | config 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 | ||
281 | config NF_CT_NETLINK | 271 | config 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 | ||
280 | config 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 | |||
294 | endif # NF_CONNTRACK | ||
295 | |||
290 | config NETFILTER_XTABLES | 296 | config 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 | ||
303 | if NETFILTER_XTABLES | ||
304 | |||
297 | # alphabetically ordered list of targets | 305 | # alphabetically ordered list of targets |
298 | 306 | ||
299 | config NETFILTER_XT_TARGET_CLASSIFY | 307 | config 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 | ||
312 | config NETFILTER_XT_TARGET_CONNMARK | 319 | config 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 | ||
333 | config 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 | |||
328 | config NETFILTER_XT_TARGET_DSCP | 345 | config 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 | ||
345 | config NETFILTER_XT_TARGET_MARK | 361 | config 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 | ||
359 | config 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 | |||
371 | config NETFILTER_XT_TARGET_NFLOG | 374 | config 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 | ||
385 | config 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 | |||
383 | config NETFILTER_XT_TARGET_NOTRACK | 396 | config 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 | ||
398 | config NETFILTER_XT_TARGET_RATEEST | 410 | config 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 | ||
420 | config 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 | |||
409 | config NETFILTER_XT_TARGET_TRACE | 435 | config 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 | ||
422 | config NETFILTER_XT_TARGET_SECMARK | 447 | config 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 | ||
432 | config 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 | |||
444 | config NETFILTER_XT_TARGET_TCPMSS | 457 | config 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 | ||
471 | config NETFILTER_XT_TARGET_TCPOPTSTRIP | 484 | config 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 | ||
480 | config NETFILTER_XT_MATCH_COMMENT | 493 | config 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 | ||
491 | config NETFILTER_XT_MATCH_CONNBYTES | 503 | config 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 | ||
504 | config NETFILTER_XT_MATCH_CONNLIMIT | 515 | config 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 | ||
513 | config NETFILTER_XT_MATCH_CONNMARK | 523 | config 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 | ||
527 | config NETFILTER_XT_MATCH_CONNTRACK | 536 | config 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 | ||
541 | config NETFILTER_XT_MATCH_DCCP | 549 | config 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 | ||
554 | config NETFILTER_XT_MATCH_DSCP | 561 | config 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 | ||
570 | config NETFILTER_XT_MATCH_ESP | 576 | config 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 | ||
585 | config 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 | |||
580 | config NETFILTER_XT_MATCH_HELPER | 600 | config 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 | ||
591 | config NETFILTER_XT_MATCH_IPRANGE | 610 | config 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 | ||
602 | config NETFILTER_XT_MATCH_LENGTH | 620 | config 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 | ||
612 | config NETFILTER_XT_MATCH_LIMIT | 629 | config 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 | ||
623 | config NETFILTER_XT_MATCH_MAC | 639 | config 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 | ||
633 | config NETFILTER_XT_MATCH_MARK | 648 | config 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 | ||
658 | config 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 | |||
644 | config NETFILTER_XT_MATCH_OWNER | 668 | config 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 | ||
653 | config NETFILTER_XT_MATCH_POLICY | 676 | config 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 | ||
664 | config 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 | |||
675 | config NETFILTER_XT_MATCH_PHYSDEV | 687 | config 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 | ||
685 | config NETFILTER_XT_MATCH_PKTTYPE | 697 | config 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 | ||
698 | config NETFILTER_XT_MATCH_QUOTA | 709 | config 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 | ||
709 | config NETFILTER_XT_MATCH_RATEEST | 719 | config 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 | ||
720 | config NETFILTER_XT_MATCH_REALM | 729 | config 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 | ||
743 | config 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 | |||
753 | config 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 | |||
735 | config NETFILTER_XT_MATCH_SCTP | 760 | config 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 | ||
773 | config 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 | |||
748 | config NETFILTER_XT_MATCH_STATE | 788 | config 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 | ||
760 | config NETFILTER_XT_MATCH_STATISTIC | 799 | config 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 | ||
770 | config NETFILTER_XT_MATCH_STRING | 808 | config 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 | ||
784 | config NETFILTER_XT_MATCH_TCPMSS | 821 | config 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 | ||
795 | config NETFILTER_XT_MATCH_TIME | 831 | config 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 | ||
810 | config NETFILTER_XT_MATCH_U32 | 845 | config 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 | ||
824 | config NETFILTER_XT_MATCH_HASHLIMIT | 858 | endif # 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 | ||
839 | endmenu | 860 | endmenu |
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 | |||
34 | obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o | 34 | obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o |
35 | obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o | 35 | obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o |
36 | 36 | ||
37 | # transparent proxy support | ||
38 | obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o | ||
39 | |||
37 | # generic X tables | 40 | # generic X tables |
38 | obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o | 41 | obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o |
39 | 42 | ||
@@ -48,6 +51,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o | |||
48 | obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o | 51 | obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o |
49 | obj-$(CONFIG_NETFILTER_XT_TARGET_RATEEST) += xt_RATEEST.o | 52 | obj-$(CONFIG_NETFILTER_XT_TARGET_RATEEST) += xt_RATEEST.o |
50 | obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o | 53 | obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o |
54 | obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o | ||
51 | obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o | 55 | obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o |
52 | obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o | 56 | obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o |
53 | obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o | 57 | obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o |
@@ -76,7 +80,9 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o | |||
76 | obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o | 80 | obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o |
77 | obj-$(CONFIG_NETFILTER_XT_MATCH_RATEEST) += xt_rateest.o | 81 | obj-$(CONFIG_NETFILTER_XT_MATCH_RATEEST) += xt_rateest.o |
78 | obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o | 82 | obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o |
83 | obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT) += xt_recent.o | ||
79 | obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o | 84 | obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o |
85 | obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o | ||
80 | obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o | 86 | obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o |
81 | obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o | 87 | obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o |
82 | obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o | 88 | obj-$(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 | ||
27 | static DEFINE_MUTEX(afinfo_mutex); | 27 | static DEFINE_MUTEX(afinfo_mutex); |
28 | 28 | ||
29 | const struct nf_afinfo *nf_afinfo[NPROTO] __read_mostly; | 29 | const struct nf_afinfo *nf_afinfo[NFPROTO_NUMPROTO] __read_mostly; |
30 | EXPORT_SYMBOL(nf_afinfo); | 30 | EXPORT_SYMBOL(nf_afinfo); |
31 | 31 | ||
32 | int nf_register_afinfo(const struct nf_afinfo *afinfo) | 32 | int nf_register_afinfo(const struct nf_afinfo *afinfo) |
@@ -51,7 +51,7 @@ void nf_unregister_afinfo(const struct nf_afinfo *afinfo) | |||
51 | } | 51 | } |
52 | EXPORT_SYMBOL_GPL(nf_unregister_afinfo); | 52 | EXPORT_SYMBOL_GPL(nf_unregister_afinfo); |
53 | 53 | ||
54 | struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS] __read_mostly; | 54 | struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] __read_mostly; |
55 | EXPORT_SYMBOL(nf_hooks); | 55 | EXPORT_SYMBOL(nf_hooks); |
56 | static DEFINE_MUTEX(nf_hook_mutex); | 56 | static DEFINE_MUTEX(nf_hook_mutex); |
57 | 57 | ||
@@ -113,7 +113,7 @@ EXPORT_SYMBOL(nf_unregister_hooks); | |||
113 | 113 | ||
114 | unsigned int nf_iterate(struct list_head *head, | 114 | unsigned 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. */ |
158 | int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb, | 158 | int 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); | |||
264 | void __init netfilter_init(void) | 256 | void __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 | ||
25 | int nf_ct_acct __read_mostly = NF_CT_ACCT_DEFAULT; | 25 | static int nf_ct_acct __read_mostly = NF_CT_ACCT_DEFAULT; |
26 | EXPORT_SYMBOL_GPL(nf_ct_acct); | ||
27 | 26 | ||
28 | module_param_named(acct, nf_ct_acct, bool, 0644); | 27 | module_param_named(acct, nf_ct_acct, bool, 0644); |
29 | MODULE_PARM_DESC(acct, "Enable connection tracking flow accounting."); | 28 | MODULE_PARM_DESC(acct, "Enable connection tracking flow accounting."); |
30 | 29 | ||
31 | #ifdef CONFIG_SYSCTL | 30 | #ifdef CONFIG_SYSCTL |
32 | static struct ctl_table_header *acct_sysctl_header; | ||
33 | static struct ctl_table acct_sysctl_table[] = { | 31 | static 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 | ||
67 | int nf_conntrack_acct_init(void) | 65 | #ifdef CONFIG_SYSCTL |
66 | static 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 | 85 | out_register: |
84 | acct_sysctl_header = register_sysctl_paths(nf_net_netfilter_sysctl_path, | 86 | kfree(table); |
85 | acct_sysctl_table); | 87 | out: |
88 | return -ENOMEM; | ||
89 | } | ||
86 | 90 | ||
87 | if (!acct_sysctl_header) { | 91 | static 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 | ||
100 | static int nf_conntrack_acct_init_sysctl(struct net *net) | ||
101 | { | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static void nf_conntrack_acct_fini_sysctl(struct net *net) | ||
106 | { | ||
107 | } | ||
108 | #endif | ||
109 | |||
110 | int 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 | |||
136 | out_sysctl: | ||
137 | if (net_eq(net, &init_net)) | ||
138 | nf_ct_extend_unregister(&acct_extend); | ||
139 | out_extend_register: | ||
140 | return ret; | ||
96 | } | 141 | } |
97 | 142 | ||
98 | void nf_conntrack_acct_fini(void) | 143 | void 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 @@ | |||
44 | DEFINE_SPINLOCK(nf_conntrack_lock); | 44 | DEFINE_SPINLOCK(nf_conntrack_lock); |
45 | EXPORT_SYMBOL_GPL(nf_conntrack_lock); | 45 | EXPORT_SYMBOL_GPL(nf_conntrack_lock); |
46 | 46 | ||
47 | /* nf_conntrack_standalone needs this */ | ||
48 | atomic_t nf_conntrack_count = ATOMIC_INIT(0); | ||
49 | EXPORT_SYMBOL_GPL(nf_conntrack_count); | ||
50 | |||
51 | unsigned int nf_conntrack_htable_size __read_mostly; | 47 | unsigned int nf_conntrack_htable_size __read_mostly; |
52 | EXPORT_SYMBOL_GPL(nf_conntrack_htable_size); | 48 | EXPORT_SYMBOL_GPL(nf_conntrack_htable_size); |
53 | 49 | ||
54 | int nf_conntrack_max __read_mostly; | 50 | int nf_conntrack_max __read_mostly; |
55 | EXPORT_SYMBOL_GPL(nf_conntrack_max); | 51 | EXPORT_SYMBOL_GPL(nf_conntrack_max); |
56 | 52 | ||
57 | struct hlist_head *nf_conntrack_hash __read_mostly; | ||
58 | EXPORT_SYMBOL_GPL(nf_conntrack_hash); | ||
59 | |||
60 | struct nf_conn nf_conntrack_untracked __read_mostly; | 53 | struct nf_conn nf_conntrack_untracked __read_mostly; |
61 | EXPORT_SYMBOL_GPL(nf_conntrack_untracked); | 54 | EXPORT_SYMBOL_GPL(nf_conntrack_untracked); |
62 | 55 | ||
63 | unsigned int nf_ct_log_invalid __read_mostly; | ||
64 | HLIST_HEAD(unconfirmed); | ||
65 | static int nf_conntrack_vmalloc __read_mostly; | ||
66 | static struct kmem_cache *nf_conntrack_cachep __read_mostly; | 56 | static struct kmem_cache *nf_conntrack_cachep __read_mostly; |
67 | 57 | ||
68 | DEFINE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat); | ||
69 | EXPORT_PER_CPU_SYMBOL(nf_conntrack_stat); | ||
70 | |||
71 | static int nf_conntrack_hash_rnd_initted; | 58 | static int nf_conntrack_hash_rnd_initted; |
72 | static unsigned int nf_conntrack_hash_rnd; | 59 | static unsigned int nf_conntrack_hash_rnd; |
73 | 60 | ||
@@ -180,6 +167,7 @@ static void | |||
180 | destroy_conntrack(struct nf_conntrack *nfct) | 167 | destroy_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) | |||
225 | static void death_by_timeout(unsigned long ul_conntrack) | 213 | static 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 | ||
248 | struct nf_conntrack_tuple_hash * | 237 | struct 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. */ |
274 | struct nf_conntrack_tuple_hash * | 263 | struct nf_conntrack_tuple_hash * |
275 | nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple) | 264 | nf_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 | ||
303 | void nf_conntrack_hash_insert(struct nf_conn *ct) | 294 | void 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 | ||
388 | out: | 381 | out: |
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 | |||
398 | nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, | 391 | nf_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. */ |
428 | static noinline int early_drop(unsigned int hash) | 422 | static 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 | ||
467 | struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, | 461 | struct 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); | |||
512 | static void nf_conntrack_free_rcu(struct rcu_head *head) | 510 | static 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 | ||
521 | void nf_conntrack_free(struct nf_conn *ct) | 520 | void 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. */ |
530 | static struct nf_conntrack_tuple_hash * | 529 | static struct nf_conntrack_tuple_hash * |
531 | init_conntrack(const struct nf_conntrack_tuple *tuple, | 530 | init_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 */ |
610 | static inline struct nf_conn * | 611 | static inline struct nf_conn * |
611 | resolve_normal_ct(struct sk_buff *skb, | 612 | resolve_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 | ||
667 | unsigned int | 669 | unsigned int |
668 | nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff *skb) | 670 | nf_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 | } |
851 | EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct); | 856 | EXPORT_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! */ |
940 | static struct nf_conn * | 945 | static struct nf_conn * |
941 | get_next_corpse(int (*iter)(struct nf_conn *i, void *data), | 946 | get_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 | ||
969 | void | 974 | void nf_ct_iterate_cleanup(struct net *net, |
970 | nf_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 | } |
999 | EXPORT_SYMBOL_GPL(nf_ct_free_hashtable); | 1005 | EXPORT_SYMBOL_GPL(nf_ct_free_hashtable); |
1000 | 1006 | ||
1001 | void nf_conntrack_flush(void) | 1007 | void 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 | } |
1005 | EXPORT_SYMBOL_GPL(nf_conntrack_flush); | 1011 | EXPORT_SYMBOL_GPL(nf_conntrack_flush); |
1006 | 1012 | ||
1007 | /* Mishearing the voices in his head, our hero wonders how he's | 1013 | static void nf_conntrack_cleanup_init_net(void) |
1008 | supposed to kill the mall. */ | ||
1009 | void 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(); | 1020 | static 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(); | 1043 | void 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 | ||
1041 | struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced) | 1061 | struct 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); | |||
1120 | module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint, | 1140 | module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint, |
1121 | &nf_conntrack_htable_size, 0600); | 1141 | &nf_conntrack_htable_size, 0600); |
1122 | 1142 | ||
1123 | int __init nf_conntrack_init(void) | 1143 | static 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 */ | 1190 | err_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); | 1192 | err_proto: |
1193 | kmem_cache_destroy(nf_conntrack_cachep); | ||
1194 | err_cache: | ||
1195 | return ret; | ||
1196 | } | ||
1197 | |||
1198 | static 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 | ||
1194 | out_fini_helper: | 1237 | err_acct: |
1195 | nf_conntrack_helper_fini(); | 1238 | nf_conntrack_expect_fini(net); |
1196 | out_fini_expect: | 1239 | err_expect: |
1197 | nf_conntrack_expect_fini(); | 1240 | nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc, |
1198 | out_fini_proto: | ||
1199 | nf_conntrack_proto_fini(); | ||
1200 | err_free_conntrack_slab: | ||
1201 | kmem_cache_destroy(nf_conntrack_cachep); | ||
1202 | err_free_hash: | ||
1203 | nf_ct_free_hashtable(nf_conntrack_hash, nf_conntrack_vmalloc, | ||
1204 | nf_conntrack_htable_size); | 1241 | nf_conntrack_htable_size); |
1205 | err_out: | 1242 | err_hash: |
1206 | return -ENOMEM; | 1243 | nf_conntrack_ecache_fini(net); |
1244 | err_ecache: | ||
1245 | free_percpu(net->ct.stat); | ||
1246 | err_stat: | ||
1247 | return ret; | ||
1248 | } | ||
1249 | |||
1250 | int 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 | |||
1270 | out_net: | ||
1271 | if (net_eq(net, &init_net)) | ||
1272 | nf_conntrack_cleanup_init_net(); | ||
1273 | out_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); | |||
29 | ATOMIC_NOTIFIER_HEAD(nf_ct_expect_chain); | 29 | ATOMIC_NOTIFIER_HEAD(nf_ct_expect_chain); |
30 | EXPORT_SYMBOL_GPL(nf_ct_expect_chain); | 30 | EXPORT_SYMBOL_GPL(nf_ct_expect_chain); |
31 | 31 | ||
32 | DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache); | ||
33 | EXPORT_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 */ |
37 | static inline void | 34 | static 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 */ |
52 | void nf_ct_deliver_cached_events(const struct nf_conn *ct) | 49 | void 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 */ |
65 | void __nf_ct_event_cache_init(struct nf_conn *ct) | 63 | void __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 */ |
82 | void nf_ct_event_cache_flush(void) | 81 | void 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 | ||
93 | int 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 | |||
101 | void nf_conntrack_ecache_fini(struct net *net) | ||
102 | { | ||
103 | free_percpu(net->ct.ecache); | ||
104 | } | ||
105 | |||
94 | int nf_conntrack_register_notifier(struct notifier_block *nb) | 106 | int 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 | ||
31 | struct hlist_head *nf_ct_expect_hash __read_mostly; | ||
32 | EXPORT_SYMBOL_GPL(nf_ct_expect_hash); | ||
33 | |||
34 | unsigned int nf_ct_expect_hsize __read_mostly; | 31 | unsigned int nf_ct_expect_hsize __read_mostly; |
35 | EXPORT_SYMBOL_GPL(nf_ct_expect_hsize); | 32 | EXPORT_SYMBOL_GPL(nf_ct_expect_hsize); |
36 | 33 | ||
37 | static unsigned int nf_ct_expect_hash_rnd __read_mostly; | 34 | static unsigned int nf_ct_expect_hash_rnd __read_mostly; |
38 | static unsigned int nf_ct_expect_count; | ||
39 | unsigned int nf_ct_expect_max __read_mostly; | 35 | unsigned int nf_ct_expect_max __read_mostly; |
40 | static int nf_ct_expect_hash_rnd_initted __read_mostly; | 36 | static int nf_ct_expect_hash_rnd_initted __read_mostly; |
41 | static int nf_ct_expect_vmalloc; | ||
42 | 37 | ||
43 | static struct kmem_cache *nf_ct_expect_cachep __read_mostly; | 38 | static 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; | |||
46 | void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) | 41 | void 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 | } |
62 | EXPORT_SYMBOL_GPL(nf_ct_unlink_expect); | 58 | EXPORT_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 | ||
89 | struct nf_conntrack_expect * | 85 | struct 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. */ |
109 | struct nf_conntrack_expect * | 105 | struct nf_conntrack_expect * |
110 | nf_ct_expect_find_get(const struct nf_conntrack_tuple *tuple) | 106 | nf_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. */ |
126 | struct nf_conntrack_expect * | 122 | struct nf_conntrack_expect * |
127 | nf_ct_find_expectation(const struct nf_conntrack_tuple *tuple) | 123 | nf_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) | |||
241 | EXPORT_SYMBOL_GPL(nf_ct_expect_alloc); | 237 | EXPORT_SYMBOL_GPL(nf_ct_expect_alloc); |
242 | 238 | ||
243 | void nf_ct_expect_init(struct nf_conntrack_expect *exp, unsigned int class, | 239 | void 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); | |||
311 | static void nf_ct_expect_insert(struct nf_conntrack_expect *exp) | 307 | static 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 |
427 | struct ct_expect_iter_state { | 425 | struct ct_expect_iter_state { |
426 | struct seq_net_private p; | ||
428 | unsigned int bucket; | 427 | unsigned int bucket; |
429 | }; | 428 | }; |
430 | 429 | ||
431 | static struct hlist_node *ct_expect_get_first(struct seq_file *seq) | 430 | static 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) | |||
444 | static struct hlist_node *ct_expect_get_next(struct seq_file *seq, | 444 | static 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 | ||
525 | static int exp_open(struct inode *inode, struct file *file) | 526 | static 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 | ||
540 | static int __init exp_proc_init(void) | 541 | static 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 | ||
552 | static void exp_proc_remove(void) | 553 | static 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 | ||
559 | module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0600); | 560 | module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0600); |
560 | 561 | ||
561 | int __init nf_conntrack_expect_init(void) | 562 | int 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 | ||
589 | err3: | 595 | err3: |
590 | kmem_cache_destroy(nf_ct_expect_cachep); | 596 | if (net_eq(net, &init_net)) |
597 | kmem_cache_destroy(nf_ct_expect_cachep); | ||
591 | err2: | 598 | err2: |
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); |
594 | err1: | 601 | err1: |
595 | return err; | 602 | return err; |
596 | } | 603 | } |
597 | 604 | ||
598 | void nf_conntrack_expect_fini(void) | 605 | void 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. */ |
321 | static void update_nl_seq(u32 nl_seq, struct nf_ct_ftp_master *info, int dir, | 321 | static 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 */ |
711 | static int callforward_do_filter(const union nf_inet_addr *src, | 711 | static 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 | } |
124 | EXPORT_SYMBOL_GPL(nf_conntrack_helper_register); | 124 | EXPORT_SYMBOL_GPL(nf_conntrack_helper_register); |
125 | 125 | ||
126 | void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) | 126 | static 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 | |||
156 | void 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 | } |
167 | EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister); | 175 | EXPORT_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]++) { |
551 | restart: | 551 | restart: |
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) | |||
1458 | static int | 1458 | static int |
1459 | ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) | 1459 | ctnetlink_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]++) { |
1469 | restart: | 1470 | restart: |
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); | |||
98 | static void pptp_expectfn(struct nf_conn *ct, | 98 | static 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 | ||
137 | static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t) | 138 | static 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 */ |
169 | static void pptp_destroy_siblings(struct nf_conn *ct) | 171 | static 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 | ||
600 | static void nf_conntrack_pptp_net_exit(struct net *net) | ||
601 | { | ||
602 | nf_ct_gre_keymap_flush(net); | ||
603 | } | ||
604 | |||
605 | static struct pernet_operations nf_conntrack_pptp_net_ops = { | ||
606 | .exit = nf_conntrack_pptp_net_exit, | ||
607 | }; | ||
608 | |||
597 | static int __init nf_conntrack_pptp_init(void) | 609 | static 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 | ||
602 | static void __exit nf_conntrack_pptp_fini(void) | 622 | static 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 | ||
608 | module_init(nf_conntrack_pptp_init); | 628 | module_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 | ||
208 | void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto) | 208 | void 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 | } |
224 | EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister); | 227 | EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister); |
225 | 228 | ||
@@ -316,6 +319,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register); | |||
316 | 319 | ||
317 | void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto) | 320 | void 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 | } |
333 | EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister); | 339 | EXPORT_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, | |||
418 | static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb, | 418 | static 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 | ||
447 | out_invalid: | 448 | out_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 | ||
462 | static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb, | 463 | static 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 | ||
548 | static int dccp_error(struct sk_buff *skb, unsigned int dataoff, | 550 | static 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 | ||
592 | out_invalid: | 594 | out_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 | ||
43 | static DEFINE_RWLOCK(nf_ct_gre_lock); | 46 | static int proto_gre_net_id; |
44 | static LIST_HEAD(gre_keymap_list); | 47 | struct netns_proto_gre { |
48 | rwlock_t keymap_lock; | ||
49 | struct list_head keymap_list; | ||
50 | }; | ||
45 | 51 | ||
46 | void nf_ct_gre_keymap_flush(void) | 52 | void 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 | } |
57 | EXPORT_SYMBOL(nf_ct_gre_keymap_flush); | 64 | EXPORT_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 */ |
70 | static __be16 gre_keymap_lookup(struct nf_conntrack_tuple *t) | 77 | static __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) | |||
91 | int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, | 99 | int 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 */ |
131 | void nf_ct_gre_keymap_destroy(struct nf_conn *ct) | 141 | void 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 | } |
150 | EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_destroy); | 162 | EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_destroy); |
151 | 163 | ||
@@ -164,6 +176,7 @@ static bool gre_invert_tuple(struct nf_conntrack_tuple *tuple, | |||
164 | static bool gre_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, | 176 | static 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 | ||
301 | static 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 | |||
318 | static 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 | |||
326 | static struct pernet_operations proto_gre_net_ops = { | ||
327 | .init = proto_gre_net_init, | ||
328 | .exit = proto_gre_net_exit, | ||
329 | }; | ||
330 | |||
288 | static int __init nf_ct_proto_gre_init(void) | 331 | static 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 | ||
293 | static void nf_ct_proto_gre_fini(void) | 344 | static 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 | ||
299 | module_init(nf_ct_proto_gre_init); | 350 | module_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. */ |
749 | static int tcp_error(struct sk_buff *skb, | 750 | static 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 | ||
92 | static int udp_error(struct sk_buff *skb, unsigned int dataoff, | 92 | static 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 | ||
92 | static int udplite_error(struct sk_buff *skb, unsigned int dataoff, | 92 | static 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, | |||
40 | EXPORT_SYMBOL_GPL(print_tuple); | 40 | EXPORT_SYMBOL_GPL(print_tuple); |
41 | 41 | ||
42 | struct ct_iter_state { | 42 | struct ct_iter_state { |
43 | struct seq_net_private p; | ||
43 | unsigned int bucket; | 44 | unsigned int bucket; |
44 | }; | 45 | }; |
45 | 46 | ||
46 | static struct hlist_node *ct_get_first(struct seq_file *seq) | 47 | static 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) | |||
61 | static struct hlist_node *ct_get_next(struct seq_file *seq, | 63 | static 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 | ||
178 | static int ct_open(struct inode *inode, struct file *file) | 181 | static 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 | ||
192 | static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) | 195 | static 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 | ||
209 | static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 213 | static 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 | ||
227 | static int ct_cpu_seq_show(struct seq_file *seq, void *v) | 232 | static 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 | ||
267 | static int ct_cpu_seq_open(struct inode *inode, struct file *file) | 273 | static 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 | ||
272 | static const struct file_operations ct_cpu_seq_fops = { | 279 | static 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 | ||
280 | static int nf_conntrack_standalone_init_proc(void) | 287 | static 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 | ||
294 | out_stat_nf_conntrack: | 301 | out_stat_nf_conntrack: |
295 | proc_net_remove(&init_net, "nf_conntrack"); | 302 | proc_net_remove(net, "nf_conntrack"); |
296 | out_nf_conntrack: | 303 | out_nf_conntrack: |
297 | return -ENOMEM; | 304 | return -ENOMEM; |
298 | } | 305 | } |
299 | 306 | ||
300 | static void nf_conntrack_standalone_fini_proc(void) | 307 | static 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 |
306 | static int nf_conntrack_standalone_init_proc(void) | 313 | static int nf_conntrack_standalone_init_proc(struct net *net) |
307 | { | 314 | { |
308 | return 0; | 315 | return 0; |
309 | } | 316 | } |
310 | 317 | ||
311 | static void nf_conntrack_standalone_fini_proc(void) | 318 | static 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 | ||
318 | int nf_conntrack_checksum __read_mostly = 1; | ||
319 | EXPORT_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 */ |
323 | static int log_invalid_proto_min = 0; | 327 | static int log_invalid_proto_min = 0; |
324 | static int log_invalid_proto_max = 255; | 328 | static int log_invalid_proto_max = 255; |
325 | 329 | ||
326 | static struct ctl_table_header *nf_ct_sysctl_header; | ||
327 | static struct ctl_table_header *nf_ct_netfilter_header; | 330 | static struct ctl_table_header *nf_ct_netfilter_header; |
328 | 331 | ||
329 | static ctl_table nf_ct_sysctl_table[] = { | 332 | static 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 | ||
403 | EXPORT_SYMBOL_GPL(nf_ct_log_invalid); | 406 | static int nf_conntrack_standalone_init_sysctl(struct net *net) |
404 | |||
405 | static 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 | ||
420 | out_unregister_netfilter: | 433 | out_unregister_netfilter: |
421 | unregister_sysctl_table(nf_ct_netfilter_header); | 434 | kfree(table); |
435 | out_kmemdup: | ||
436 | if (net_eq(net, &init_net)) | ||
437 | unregister_sysctl_table(nf_ct_netfilter_header); | ||
422 | out: | 438 | out: |
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 | ||
427 | static void nf_conntrack_standalone_fini_sysctl(void) | 443 | static 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 |
433 | static int nf_conntrack_standalone_init_sysctl(void) | 454 | static int nf_conntrack_standalone_init_sysctl(struct net *net) |
434 | { | 455 | { |
435 | return 0; | 456 | return 0; |
436 | } | 457 | } |
437 | 458 | ||
438 | static void nf_conntrack_standalone_fini_sysctl(void) | 459 | static void nf_conntrack_standalone_fini_sysctl(struct net *net) |
439 | { | 460 | { |
440 | } | 461 | } |
441 | #endif /* CONFIG_SYSCTL */ | 462 | #endif /* CONFIG_SYSCTL */ |
442 | 463 | ||
443 | static int __init nf_conntrack_standalone_init(void) | 464 | static 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 | ||
458 | out_sysctl: | 481 | out_sysctl: |
459 | nf_conntrack_standalone_fini_proc(); | 482 | nf_conntrack_standalone_fini_proc(net); |
460 | out_proc: | 483 | out_proc: |
461 | nf_conntrack_cleanup(); | 484 | nf_conntrack_cleanup(net); |
462 | out: | 485 | out_init: |
463 | return ret; | 486 | return ret; |
464 | } | 487 | } |
465 | 488 | ||
489 | static 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 | |||
496 | static struct pernet_operations nf_conntrack_net_ops = { | ||
497 | .init = nf_conntrack_net_init, | ||
498 | .exit = nf_conntrack_net_exit, | ||
499 | }; | ||
500 | |||
501 | static int __init nf_conntrack_standalone_init(void) | ||
502 | { | ||
503 | return register_pernet_subsys(&nf_conntrack_net_ops); | ||
504 | } | ||
505 | |||
466 | static void __exit nf_conntrack_standalone_fini(void) | 506 | static 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 | ||
473 | module_init(nf_conntrack_standalone_init); | 511 | module_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 */ |
16 | extern unsigned int nf_iterate(struct list_head *head, | 16 | extern 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 */ |
26 | extern int nf_queue(struct sk_buff *skb, | 26 | extern 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 | ||
18 | static const struct nf_logger *nf_loggers[NPROTO] __read_mostly; | 18 | static const struct nf_logger *nf_loggers[NFPROTO_NUMPROTO] __read_mostly; |
19 | static DEFINE_MUTEX(nf_log_mutex); | 19 | static 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. */ |
23 | int nf_log_register(int pf, const struct nf_logger *logger) | 23 | int 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 | } |
46 | EXPORT_SYMBOL(nf_log_register); | 46 | EXPORT_SYMBOL(nf_log_register); |
47 | 47 | ||
48 | void nf_log_unregister_pf(int pf) | 48 | void 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 | } |
74 | EXPORT_SYMBOL(nf_log_unregister); | 74 | EXPORT_SYMBOL(nf_log_unregister); |
75 | 75 | ||
76 | void nf_log_packet(int pf, | 76 | void 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 | */ |
19 | static const struct nf_queue_handler *queue_handler[NPROTO]; | 19 | static const struct nf_queue_handler *queue_handler[NFPROTO_NUMPROTO] __read_mostly; |
20 | 20 | ||
21 | static DEFINE_MUTEX(queue_handler_mutex); | 21 | static 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. */ |
25 | int nf_register_queue_handler(int pf, const struct nf_queue_handler *qh) | 25 | int 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) | |||
45 | EXPORT_SYMBOL(nf_register_queue_handler); | 45 | EXPORT_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 */ |
48 | int nf_unregister_queue_handler(int pf, const struct nf_queue_handler *qh) | 48 | int 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 | ||
68 | void nf_unregister_queue_handlers(const struct nf_queue_handler *qh) | 68 | void 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 | */ |
108 | static int __nf_queue(struct sk_buff *skb, | 108 | static 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 | ||
192 | int nf_queue(struct sk_buff *skb, | 192 | int 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 |
286 | static void *seq_start(struct seq_file *seq, loff_t *pos) | 286 | static 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 | } |
61 | EXPORT_SYMBOL(nf_unregister_sockopt); | 61 | EXPORT_SYMBOL(nf_unregister_sockopt); |
62 | 62 | ||
63 | static struct nf_sockopt_ops *nf_sockopt_find(struct sock *sk, int pf, | 63 | static 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() */ |
99 | static int nf_sockopt(struct sock *sk, int pf, int val, | 96 | static 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 | ||
118 | int nf_setsockopt(struct sock *sk, int pf, int val, char __user *opt, | 115 | int 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 | } |
123 | EXPORT_SYMBOL(nf_setsockopt); | 120 | EXPORT_SYMBOL(nf_setsockopt); |
124 | 121 | ||
125 | int nf_getsockopt(struct sock *sk, int pf, int val, char __user *opt, int *len) | 122 | int 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 | } |
129 | EXPORT_SYMBOL(nf_getsockopt); | 127 | EXPORT_SYMBOL(nf_getsockopt); |
130 | 128 | ||
131 | #ifdef CONFIG_COMPAT | 129 | #ifdef CONFIG_COMPAT |
132 | static int compat_nf_sockopt(struct sock *sk, int pf, int val, | 130 | static 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 | ||
158 | int compat_nf_setsockopt(struct sock *sk, int pf, | 156 | int 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 | } |
163 | EXPORT_SYMBOL(compat_nf_setsockopt); | 161 | EXPORT_SYMBOL(compat_nf_setsockopt); |
164 | 162 | ||
165 | int compat_nf_getsockopt(struct sock *sk, int pf, | 163 | int 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 | |||
22 | struct sock * | ||
23 | nf_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 | } | ||
56 | EXPORT_SYMBOL_GPL(nf_tproxy_get_sock_v4); | ||
57 | |||
58 | static void | ||
59 | nf_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 */ | ||
71 | int | ||
72 | nf_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 | } | ||
83 | EXPORT_SYMBOL_GPL(nf_tproxy_assign_sock); | ||
84 | |||
85 | static 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 | |||
92 | module_init(nf_tproxy_init); | ||
93 | |||
94 | MODULE_LICENSE("GPL"); | ||
95 | MODULE_AUTHOR("Krisztian Kovacs"); | ||
96 | MODULE_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 */ |
536 | static void | 536 | static void |
537 | nfulnl_log_packet(unsigned int pf, | 537 | nfulnl_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 | ||
31 | MODULE_LICENSE("GPL"); | 31 | MODULE_LICENSE("GPL"); |
32 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | 32 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); |
33 | MODULE_DESCRIPTION("[ip,ip6,arp]_tables backend module"); | 33 | MODULE_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 | ||
61 | static const char *const xt_prefix[NPROTO] = { | 61 | static 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. */ |
68 | int | 70 | int |
69 | xt_register_target(struct xt_target *target) | 71 | xt_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); | |||
82 | void | 85 | void |
83 | xt_unregister_target(struct xt_target *target) | 86 | xt_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); | |||
123 | int | 126 | int |
124 | xt_register_match(struct xt_match *match) | 127 | xt_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); | |||
139 | void | 143 | void |
140 | xt_unregister_match(struct xt_match *match) | 144 | xt_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. */ |
188 | struct xt_match *xt_find_match(int af, const char *name, u8 revision) | 192 | struct 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 | } |
210 | EXPORT_SYMBOL(xt_find_match); | 219 | EXPORT_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. */ |
213 | struct xt_target *xt_find_target(int af, const char *name, u8 revision) | 222 | struct 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 | } |
235 | EXPORT_SYMBOL(xt_find_target); | 249 | EXPORT_SYMBOL(xt_find_target); |
236 | 250 | ||
237 | struct xt_target *xt_request_find_target(int af, const char *name, u8 revision) | 251 | struct 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 | } |
247 | EXPORT_SYMBOL_GPL(xt_request_find_target); | 261 | EXPORT_SYMBOL_GPL(xt_request_find_target); |
248 | 262 | ||
249 | static int match_revfn(int af, const char *name, u8 revision, int *bestp) | 263 | static 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 | ||
265 | static int target_revfn(int af, const char *name, u8 revision, int *bestp) | 279 | static 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) */ |
282 | int xt_find_revision(int af, const char *name, u8 revision, int target, | 296 | int 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 | } |
308 | EXPORT_SYMBOL_GPL(xt_find_revision); | 322 | EXPORT_SYMBOL_GPL(xt_find_revision); |
309 | 323 | ||
310 | int xt_check_match(const struct xt_match *match, unsigned short family, | 324 | int 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 | } |
337 | EXPORT_SYMBOL_GPL(xt_check_match); | 361 | EXPORT_SYMBOL_GPL(xt_check_match); |
338 | 362 | ||
339 | #ifdef CONFIG_COMPAT | 363 | #ifdef CONFIG_COMPAT |
340 | int xt_compat_add_offset(int af, unsigned int offset, short delta) | 364 | int 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 | } |
360 | EXPORT_SYMBOL_GPL(xt_compat_add_offset); | 384 | EXPORT_SYMBOL_GPL(xt_compat_add_offset); |
361 | 385 | ||
362 | void xt_compat_flush_offsets(int af) | 386 | void 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 | } |
374 | EXPORT_SYMBOL_GPL(xt_compat_flush_offsets); | 398 | EXPORT_SYMBOL_GPL(xt_compat_flush_offsets); |
375 | 399 | ||
376 | short xt_compat_calc_jump(int af, unsigned int offset) | 400 | short 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, | |||
448 | EXPORT_SYMBOL_GPL(xt_compat_match_to_user); | 472 | EXPORT_SYMBOL_GPL(xt_compat_match_to_user); |
449 | #endif /* CONFIG_COMPAT */ | 473 | #endif /* CONFIG_COMPAT */ |
450 | 474 | ||
451 | int xt_check_target(const struct xt_target *target, unsigned short family, | 475 | int 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 | } |
479 | EXPORT_SYMBOL_GPL(xt_check_target); | 507 | EXPORT_SYMBOL_GPL(xt_check_target); |
@@ -590,7 +618,8 @@ void xt_free_table_info(struct xt_table_info *info) | |||
590 | EXPORT_SYMBOL(xt_free_table_info); | 618 | EXPORT_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. */ |
593 | struct xt_table *xt_find_table_lock(struct net *net, int af, const char *name) | 621 | struct 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) | |||
612 | EXPORT_SYMBOL_GPL(xt_table_unlock); | 641 | EXPORT_SYMBOL_GPL(xt_table_unlock); |
613 | 642 | ||
614 | #ifdef CONFIG_COMPAT | 643 | #ifdef CONFIG_COMPAT |
615 | void xt_compat_lock(int af) | 644 | void 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 | } |
619 | EXPORT_SYMBOL_GPL(xt_compat_lock); | 648 | EXPORT_SYMBOL_GPL(xt_compat_lock); |
620 | 649 | ||
621 | void xt_compat_unlock(int af) | 650 | void 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 |
723 | struct xt_names_priv { | 752 | struct 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 | }; |
727 | static void *xt_table_seq_start(struct seq_file *seq, loff_t *pos) | 756 | static 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) | |||
746 | static void xt_table_seq_stop(struct seq_file *seq, void *v) | 775 | static 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 | ||
925 | int xt_proto_init(struct net *net, int af) | 954 | int 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 | } |
975 | EXPORT_SYMBOL_GPL(xt_proto_init); | 1004 | EXPORT_SYMBOL_GPL(xt_proto_init); |
976 | 1005 | ||
977 | void xt_proto_fini(struct net *net, int af) | 1006 | void 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"); | |||
27 | MODULE_ALIAS("ip6t_CLASSIFY"); | 27 | MODULE_ALIAS("ip6t_CLASSIFY"); |
28 | 28 | ||
29 | static unsigned int | 29 | static unsigned int |
30 | classify_tg(struct sk_buff *skb, const struct net_device *in, | 30 | classify_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 | ||
40 | static struct xt_target classify_tg_reg[] __read_mostly = { | 38 | static 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 | ||
65 | static int __init classify_tg_init(void) | 50 | static 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 | ||
71 | static void __exit classify_tg_exit(void) | 55 | static 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 | ||
76 | module_init(classify_tg_init); | 60 | module_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 | ||
38 | static unsigned int | 38 | static unsigned int |
39 | connmark_tg_v0(struct sk_buff *skb, const struct net_device *in, | 39 | connmark_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 | ||
79 | static unsigned int | 77 | static unsigned int |
80 | connmark_tg(struct sk_buff *skb, const struct net_device *in, | 78 | connmark_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 | ||
119 | static bool | 115 | static bool connmark_tg_check_v0(const struct xt_tgchk_param *par) |
120 | connmark_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 | ||
146 | static bool | 139 | static bool connmark_tg_check(const struct xt_tgchk_param *par) |
147 | connmark_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 | ||
159 | static void | 149 | static void connmark_tg_destroy(const struct xt_tgdtor_param *par) |
160 | connmark_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 | ||
67 | static unsigned int | 67 | static unsigned int |
68 | connsecmark_tg(struct sk_buff *skb, const struct net_device *in, | 68 | connsecmark_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 | ||
90 | static bool | 88 | static bool connsecmark_tg_check(const struct xt_tgchk_param *par) |
91 | connsecmark_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 | ||
121 | static void | 117 | static void connsecmark_tg_destroy(const struct xt_tgdtor_param *par) |
122 | connsecmark_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 | ||
127 | static struct xt_target connsecmark_tg_reg[] __read_mostly = { | 122 | static 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 | ||
148 | static int __init connsecmark_tg_init(void) | 133 | static 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 | ||
154 | static void __exit connsecmark_tg_exit(void) | 138 | static 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 | ||
160 | module_init(connsecmark_tg_init); | 143 | module_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"); | |||
29 | MODULE_ALIAS("ip6t_TOS"); | 29 | MODULE_ALIAS("ip6t_TOS"); |
30 | 30 | ||
31 | static unsigned int | 31 | static unsigned int |
32 | dscp_tg(struct sk_buff *skb, const struct net_device *in, | 32 | dscp_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 | ||
50 | static unsigned int | 48 | static unsigned int |
51 | dscp_tg6(struct sk_buff *skb, const struct net_device *in, | 49 | dscp_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 | ||
68 | static bool | 64 | static bool dscp_tg_check(const struct xt_tgchk_param *par) |
69 | dscp_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 | ||
82 | static unsigned int | 75 | static unsigned int |
83 | tos_tg_v0(struct sk_buff *skb, const struct net_device *in, | 76 | tos_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 | ||
104 | static bool | 95 | static bool tos_tg_check_v0(const struct xt_tgchk_param *par) |
105 | tos_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 | ||
121 | static unsigned int | 110 | static unsigned int |
122 | tos_tg(struct sk_buff *skb, const struct net_device *in, | 111 | tos_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 | ||
143 | static unsigned int | 130 | static unsigned int |
144 | tos_tg6(struct sk_buff *skb, const struct net_device *in, | 131 | tos_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, | |||
165 | static struct xt_target dscp_tg_reg[] __read_mostly = { | 150 | static 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"); | |||
25 | MODULE_ALIAS("ip6t_MARK"); | 25 | MODULE_ALIAS("ip6t_MARK"); |
26 | 26 | ||
27 | static unsigned int | 27 | static unsigned int |
28 | mark_tg_v0(struct sk_buff *skb, const struct net_device *in, | 28 | mark_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 | ||
38 | static unsigned int | 36 | static unsigned int |
39 | mark_tg_v1(struct sk_buff *skb, const struct net_device *in, | 37 | mark_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 | ||
64 | static unsigned int | 60 | static unsigned int |
65 | mark_tg(struct sk_buff *skb, const struct net_device *in, | 61 | mark_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 | ||
75 | static bool | 69 | static bool mark_tg_check_v0(const struct xt_tgchk_param *par) |
76 | mark_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 | ||
89 | static bool | 80 | static bool mark_tg_check_v1(const struct xt_tgchk_param *par) |
90 | mark_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) | |||
161 | static struct xt_target mark_tg_reg[] __read_mostly = { | 149 | static 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"); | |||
21 | MODULE_ALIAS("ip6t_NFLOG"); | 21 | MODULE_ALIAS("ip6t_NFLOG"); |
22 | 22 | ||
23 | static unsigned int | 23 | static unsigned int |
24 | nflog_tg(struct sk_buff *skb, const struct net_device *in, | 24 | nflog_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 | ||
41 | static bool | 39 | static bool nflog_tg_check(const struct xt_tgchk_param *par) |
42 | nflog_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 | ||
55 | static struct xt_target nflog_tg_reg[] __read_mostly = { | 50 | static 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 | ||
74 | static int __init nflog_tg_init(void) | 60 | static 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 | ||
79 | static void __exit nflog_tg_exit(void) | 65 | static 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 | ||
84 | module_init(nflog_tg_init); | 70 | module_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"); | |||
24 | MODULE_ALIAS("arpt_NFQUEUE"); | 24 | MODULE_ALIAS("arpt_NFQUEUE"); |
25 | 25 | ||
26 | static unsigned int | 26 | static unsigned int |
27 | nfqueue_tg(struct sk_buff *skb, const struct net_device *in, | 27 | nfqueue_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, | |||
36 | static struct xt_target nfqueue_tg_reg[] __read_mostly = { | 34 | static 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"); | |||
13 | MODULE_ALIAS("ip6t_NOTRACK"); | 13 | MODULE_ALIAS("ip6t_NOTRACK"); |
14 | 14 | ||
15 | static unsigned int | 15 | static unsigned int |
16 | notrack_tg(struct sk_buff *skb, const struct net_device *in, | 16 | notrack_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 | ||
35 | static struct xt_target notrack_tg_reg[] __read_mostly = { | 33 | static 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 | ||
52 | static int __init notrack_tg_init(void) | 42 | static 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(¬rack_tg_reg); |
55 | } | 45 | } |
56 | 46 | ||
57 | static void __exit notrack_tg_exit(void) | 47 | static void __exit notrack_tg_exit(void) |
58 | { | 48 | { |
59 | xt_unregister_targets(notrack_tg_reg, ARRAY_SIZE(notrack_tg_reg)); | 49 | xt_unregister_target(¬rack_tg_reg); |
60 | } | 50 | } |
61 | 51 | ||
62 | module_init(notrack_tg_init); | 52 | module_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) | |||
71 | EXPORT_SYMBOL_GPL(xt_rateest_put); | 71 | EXPORT_SYMBOL_GPL(xt_rateest_put); |
72 | 72 | ||
73 | static unsigned int | 73 | static unsigned int |
74 | xt_rateest_tg(struct sk_buff *skb, | 74 | xt_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 | ||
92 | static bool | 87 | static bool xt_rateest_tg_checkentry(const struct xt_tgchk_param *par) |
93 | xt_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 | ||
152 | static void xt_rateest_tg_destroy(const struct xt_target *target, | 142 | static 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 | ||
160 | static struct xt_target xt_rateest_target[] __read_mostly = { | 149 | static 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 | ||
181 | static int __init xt_rateest_tg_init(void) | 160 | static 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 | ||
193 | static void __exit xt_rateest_tg_fini(void) | 171 | static 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"); | |||
29 | static u8 mode; | 29 | static u8 mode; |
30 | 30 | ||
31 | static unsigned int | 31 | static unsigned int |
32 | secmark_tg(struct sk_buff *skb, const struct net_device *in, | 32 | secmark_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 | ||
85 | static bool | 83 | static bool secmark_tg_check(const struct xt_tgchk_param *par) |
86 | secmark_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 | ||
120 | static void secmark_tg_destroy(const struct xt_target *target, void *targinfo) | 116 | static 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 | ||
128 | static struct xt_target secmark_tg_reg[] __read_mostly = { | 124 | static 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 | ||
149 | static int __init secmark_tg_init(void) | 135 | static 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 | ||
154 | static void __exit secmark_tg_exit(void) | 140 | static 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 | ||
159 | module_init(secmark_tg_init); | 145 | module_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 | ||
176 | static unsigned int | 176 | static unsigned int |
177 | tcpmss_tg4(struct sk_buff *skb, const struct net_device *in, | 177 | tcpmss_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) |
201 | static unsigned int | 199 | static unsigned int |
202 | tcpmss_tg6(struct sk_buff *skb, const struct net_device *in, | 200 | tcpmss_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 | ||
244 | static bool | 240 | static bool tcpmss_tg4_check(const struct xt_tgchk_param *par) |
245 | tcpmss_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) |
267 | static bool | 260 | static bool tcpmss_tg6_check(const struct xt_tgchk_param *par) |
268 | tcpmss_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 | ||
290 | static struct xt_target tcpmss_tg_reg[] __read_mostly = { | 280 | static 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 | ||
77 | static unsigned int | 77 | static unsigned int |
78 | tcpoptstrip_tg4(struct sk_buff *skb, const struct net_device *in, | 78 | tcpoptstrip_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) |
87 | static unsigned int | 85 | static unsigned int |
88 | tcpoptstrip_tg6(struct sk_buff *skb, const struct net_device *in, | 86 | tcpoptstrip_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, | |||
106 | static struct xt_target tcpoptstrip_tg_reg[] __read_mostly = { | 102 | static 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 | |||
27 | static unsigned int | ||
28 | tproxy_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 | |||
62 | static 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 | |||
75 | static 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 | |||
86 | static int __init tproxy_tg_init(void) | ||
87 | { | ||
88 | nf_defrag_ipv4_enable(); | ||
89 | return xt_register_target(&tproxy_tg_reg); | ||
90 | } | ||
91 | |||
92 | static void __exit tproxy_tg_exit(void) | ||
93 | { | ||
94 | xt_unregister_target(&tproxy_tg_reg); | ||
95 | } | ||
96 | |||
97 | module_init(tproxy_tg_init); | ||
98 | module_exit(tproxy_tg_exit); | ||
99 | MODULE_LICENSE("GPL"); | ||
100 | MODULE_AUTHOR("Krisztian Kovacs"); | ||
101 | MODULE_DESCRIPTION("Netfilter transparent proxy (TPROXY) target module."); | ||
102 | MODULE_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"); | |||
11 | MODULE_ALIAS("ip6t_TRACE"); | 11 | MODULE_ALIAS("ip6t_TRACE"); |
12 | 12 | ||
13 | static unsigned int | 13 | static unsigned int |
14 | trace_tg(struct sk_buff *skb, const struct net_device *in, | 14 | trace_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 | ||
22 | static struct xt_target trace_tg_reg[] __read_mostly = { | 20 | static 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 | ||
39 | static int __init trace_tg_init(void) | 29 | static 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 | ||
44 | static void __exit trace_tg_exit(void) | 34 | static 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 | ||
49 | module_init(trace_tg_init); | 39 | module_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"); | |||
16 | MODULE_ALIAS("ip6t_comment"); | 16 | MODULE_ALIAS("ip6t_comment"); |
17 | 17 | ||
18 | static bool | 18 | static bool |
19 | comment_mt(const struct sk_buff *skb, const struct net_device *in, | 19 | comment_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 | ||
28 | static struct xt_match comment_mt_reg[] __read_mostly = { | 25 | static 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 | ||
45 | static int __init comment_mt_init(void) | 34 | static 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 | ||
50 | static void __exit comment_mt_exit(void) | 39 | static 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 | ||
55 | module_init(comment_mt_init); | 44 | module_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"); | |||
17 | MODULE_ALIAS("ip6t_connbytes"); | 17 | MODULE_ALIAS("ip6t_connbytes"); |
18 | 18 | ||
19 | static bool | 19 | static bool |
20 | connbytes_mt(const struct sk_buff *skb, const struct net_device *in, | 20 | connbytes_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 | ||
98 | static bool | 95 | static bool connbytes_mt_check(const struct xt_mtchk_param *par) |
99 | connbytes_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 | ||
124 | static void | 118 | static void connbytes_mt_destroy(const struct xt_mtdtor_param *par) |
125 | connbytes_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 | ||
130 | static struct xt_match connbytes_mt_reg[] __read_mostly = { | 123 | static 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 | ||
151 | static int __init connbytes_mt_init(void) | 134 | static 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 | ||
157 | static void __exit connbytes_mt_exit(void) | 139 | static 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 | ||
162 | module_init(connbytes_mt_init); | 144 | module_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) | |||
82 | static inline unsigned int | 82 | static inline unsigned int |
83 | same_source_net(const union nf_inet_addr *addr, | 83 | same_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 | ||
180 | static bool | 180 | static bool |
181 | connlimit_mt(const struct sk_buff *skb, const struct net_device *in, | 181 | connlimit_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 | ||
227 | static bool | 224 | static bool connlimit_mt_check(const struct xt_mtchk_param *par) |
228 | connlimit_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 | ||
255 | static void | 249 | static void connlimit_mt_destroy(const struct xt_mtdtor_param *par) |
256 | connlimit_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 | ||
276 | static struct xt_match connlimit_mt_reg[] __read_mostly = { | 269 | static 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 | ||
297 | static int __init connlimit_mt_init(void) | 280 | static 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 | ||
303 | static void __exit connlimit_mt_exit(void) | 285 | static 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 | ||
308 | module_init(connlimit_mt_init); | 290 | module_init(connlimit_mt_init); |
309 | module_exit(connlimit_mt_exit); | 291 | module_exit(connlimit_mt_exit); |
310 | MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); | 292 | MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>"); |
311 | MODULE_DESCRIPTION("Xtables: Number of connections matching"); | 293 | MODULE_DESCRIPTION("Xtables: Number of connections matching"); |
312 | MODULE_LICENSE("GPL"); | 294 | MODULE_LICENSE("GPL"); |
313 | MODULE_ALIAS("ipt_connlimit"); | 295 | MODULE_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"); | |||
34 | MODULE_ALIAS("ip6t_connmark"); | 34 | MODULE_ALIAS("ip6t_connmark"); |
35 | 35 | ||
36 | static bool | 36 | static bool |
37 | connmark_mt(const struct sk_buff *skb, const struct net_device *in, | 37 | connmark_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 | ||
53 | static bool | 50 | static bool |
54 | connmark_mt_v0(const struct sk_buff *skb, const struct net_device *in, | 51 | connmark_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 | ||
70 | static bool | 64 | static bool connmark_mt_check_v0(const struct xt_mtchk_param *par) |
71 | connmark_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 | ||
89 | static bool | 80 | static bool connmark_mt_check(const struct xt_mtchk_param *par) |
90 | connmark_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 | ||
102 | static void | 90 | static void connmark_mt_destroy(const struct xt_mtdtor_param *par) |
103 | connmark_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"); | |||
25 | MODULE_ALIAS("ip6t_conntrack"); | 25 | MODULE_ALIAS("ip6t_conntrack"); |
26 | 26 | ||
27 | static bool | 27 | static bool |
28 | conntrack_mt_v0(const struct sk_buff *skb, const struct net_device *in, | 28 | conntrack_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, | |||
133 | static inline bool | 130 | static inline bool |
134 | conntrack_mt_origsrc(const struct nf_conn *ct, | 131 | conntrack_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, | |||
142 | static inline bool | 139 | static inline bool |
143 | conntrack_mt_origdst(const struct nf_conn *ct, | 140 | conntrack_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, | |||
151 | static inline bool | 148 | static inline bool |
152 | conntrack_mt_replsrc(const struct nf_conn *ct, | 149 | conntrack_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, | |||
160 | static inline bool | 157 | static inline bool |
161 | conntrack_mt_repldst(const struct nf_conn *ct, | 158 | conntrack_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 | ||
207 | static bool | 204 | static bool |
208 | conntrack_mt(const struct sk_buff *skb, const struct net_device *in, | 205 | conntrack_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 | ||
287 | static bool | 281 | static bool conntrack_mt_check(const struct xt_mtchk_param *par) |
288 | conntrack_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 | ||
300 | static void | 291 | static void conntrack_mt_destroy(const struct xt_mtdtor_param *par) |
301 | conntrack_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 | ||
95 | static bool | 95 | static bool |
96 | dccp_mt(const struct sk_buff *skb, const struct net_device *in, | 96 | dccp_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 | ||
126 | static bool | 124 | static bool dccp_mt_check(const struct xt_mtchk_param *par) |
127 | dccp_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, | |||
138 | static struct xt_match dccp_mt_reg[] __read_mostly = { | 133 | static 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"); | |||
26 | MODULE_ALIAS("ip6t_tos"); | 26 | MODULE_ALIAS("ip6t_tos"); |
27 | 27 | ||
28 | static bool | 28 | static bool |
29 | dscp_mt(const struct sk_buff *skb, const struct net_device *in, | 29 | dscp_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 | ||
39 | static bool | 37 | static bool |
40 | dscp_mt6(const struct sk_buff *skb, const struct net_device *in, | 38 | dscp_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 | ||
51 | static bool | 46 | static bool dscp_mt_check(const struct xt_mtchk_param *par) |
52 | dscp_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 | ||
66 | static bool tos_mt_v0(const struct sk_buff *skb, const struct net_device *in, | 58 | static bool |
67 | const struct net_device *out, | 59 | tos_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 | ||
76 | static bool tos_mt(const struct sk_buff *skb, const struct net_device *in, | 66 | static 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, | |||
91 | static struct xt_match dscp_mt_reg[] __read_mostly = { | 78 | static 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 | ||
45 | static bool | 45 | static bool esp_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
46 | esp_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. */ | 69 | static bool esp_mt_check(const struct xt_mtchk_param *par) |
73 | static bool | ||
74 | esp_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, | |||
88 | static struct xt_match esp_mt_reg[] __read_mostly = { | 81 | static 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 { | |||
80 | struct xt_hashlimit_htable { | 80 | struct 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 | } |
186 | static void htable_gc(unsigned long htlong); | 186 | static void htable_gc(unsigned long htlong); |
187 | 187 | ||
188 | static int htable_create_v0(struct xt_hashlimit_info *minfo, int family) | 188 | static 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 | ||
261 | static int htable_create(struct xt_hashlimit_mtinfo1 *minfo, | 260 | static 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 | ||
380 | static struct xt_hashlimit_htable *htable_find_get(const char *name, | 377 | static 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 | ||
568 | static bool | 565 | static bool |
569 | hashlimit_mt_v0(const struct sk_buff *skb, const struct net_device *in, | 566 | hashlimit_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 | ||
618 | hotdrop: | 612 | hotdrop: |
619 | *hotdrop = true; | 613 | *par->hotdrop = true; |
620 | return false; | 614 | return false; |
621 | } | 615 | } |
622 | 616 | ||
623 | static bool | 617 | static bool |
624 | hashlimit_mt(const struct sk_buff *skb, const struct net_device *in, | 618 | hashlimit_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 | ||
676 | static bool | 667 | static bool hashlimit_mt_check_v0(const struct xt_mtchk_param *par) |
677 | hashlimit_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 | ||
722 | static bool | 710 | static bool hashlimit_mt_check(const struct xt_mtchk_param *par) |
723 | hashlimit_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 | ||
765 | static void | 750 | static void |
766 | hashlimit_mt_destroy_v0(const struct xt_match *match, void *matchinfo) | 751 | hashlimit_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 | ||
773 | static void | 758 | static void hashlimit_mt_destroy(const struct xt_mtdtor_param *par) |
774 | hashlimit_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 | ||
904 | static int dl_seq_real_show(struct dsthash_ent *ent, int family, | 888 | static 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 | ||
26 | static bool | 26 | static bool |
27 | helper_mt(const struct sk_buff *skb, const struct net_device *in, | 27 | helper_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 | ||
60 | static bool | 57 | static bool helper_mt_check(const struct xt_mtchk_param *par) |
61 | helper_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 | ||
76 | static void helper_mt_destroy(const struct xt_match *match, void *matchinfo) | 70 | static 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 | ||
81 | static struct xt_match helper_mt_reg[] __read_mostly = { | 75 | static 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 | ||
102 | static int __init helper_mt_init(void) | 86 | static 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 | ||
107 | static void __exit helper_mt_exit(void) | 91 | static 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 | ||
112 | module_init(helper_mt_init); | 96 | module_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 | ||
19 | static bool | 19 | static bool |
20 | iprange_mt_v0(const struct sk_buff *skb, const struct net_device *in, | 20 | iprange_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 | ||
57 | static bool | 54 | static bool |
58 | iprange_mt4(const struct sk_buff *skb, const struct net_device *in, | 55 | iprange_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 | ||
113 | static bool | 107 | static bool |
114 | iprange_mt6(const struct sk_buff *skb, const struct net_device *in, | 108 | iprange_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"); | |||
21 | MODULE_ALIAS("ip6t_length"); | 21 | MODULE_ALIAS("ip6t_length"); |
22 | 22 | ||
23 | static bool | 23 | static bool |
24 | length_mt(const struct sk_buff *skb, const struct net_device *in, | 24 | length_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 | ||
35 | static bool | 32 | static bool |
36 | length_mt6(const struct sk_buff *skb, const struct net_device *in, | 33 | length_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, | |||
48 | static struct xt_match length_mt_reg[] __read_mostly = { | 42 | static 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 | ||
60 | static bool | 60 | static bool |
61 | limit_mt(const struct sk_buff *skb, const struct net_device *in, | 61 | limit_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 | ||
98 | static bool | 95 | static bool limit_mt_check(const struct xt_mtchk_param *par) |
99 | limit_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 | ||
170 | static struct xt_match limit_mt_reg[] __read_mostly = { | 164 | static 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 | ||
199 | static int __init limit_mt_init(void) | 179 | static 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 | ||
204 | static void __exit limit_mt_exit(void) | 184 | static 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 | ||
209 | module_init(limit_mt_init); | 189 | module_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"); | |||
24 | MODULE_ALIAS("ipt_mac"); | 24 | MODULE_ALIAS("ipt_mac"); |
25 | MODULE_ALIAS("ip6t_mac"); | 25 | MODULE_ALIAS("ip6t_mac"); |
26 | 26 | ||
27 | static bool | 27 | static bool mac_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
28 | mac_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 | ||
42 | static struct xt_match mac_mt_reg[] __read_mostly = { | 39 | static 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 | ||
65 | static int __init mac_mt_init(void) | 50 | static 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 | ||
70 | static void __exit mac_mt_exit(void) | 55 | static 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 | ||
75 | module_init(mac_mt_init); | 60 | module_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"); | |||
23 | MODULE_ALIAS("ip6t_mark"); | 23 | MODULE_ALIAS("ip6t_mark"); |
24 | 24 | ||
25 | static bool | 25 | static bool |
26 | mark_mt_v0(const struct sk_buff *skb, const struct net_device *in, | 26 | mark_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 | ||
36 | static bool | 33 | static bool |
37 | mark_mt(const struct sk_buff *skb, const struct net_device *in, | 34 | mark_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 | ||
46 | static bool | 41 | static bool mark_mt_check_v0(const struct xt_mtchk_param *par) |
47 | mark_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 | ||
97 | static bool | 97 | static bool |
98 | multiport_mt_v0(const struct sk_buff *skb, const struct net_device *in, | 98 | multiport_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 | ||
124 | static bool | 121 | static bool |
125 | multiport_mt(const struct sk_buff *skb, const struct net_device *in, | 122 | multiport_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. */ | 161 | static bool multiport_mt_check_v0(const struct xt_mtchk_param *par) |
168 | static bool | ||
169 | multiport_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 | ||
180 | static bool | 170 | static bool multiport_mt_check(const struct xt_mtchk_param *par) |
181 | multiport_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 | ||
192 | static bool | 179 | static bool multiport_mt6_check_v0(const struct xt_mtchk_param *par) |
193 | multiport_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 | ||
204 | static bool | 188 | static bool multiport_mt6_check(const struct xt_mtchk_param *par) |
205 | multiport_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, | |||
216 | static struct xt_match multiport_mt_reg[] __read_mostly = { | 197 | static 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 | ||
23 | static bool | 23 | static bool |
24 | owner_mt_v0(const struct sk_buff *skb, const struct net_device *in, | 24 | owner_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 | ||
52 | static bool | 49 | static bool |
53 | owner_mt6_v0(const struct sk_buff *skb, const struct net_device *in, | 50 | owner_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 | ||
81 | static bool | 75 | static bool |
82 | owner_mt(const struct sk_buff *skb, const struct net_device *in, | 76 | owner_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 | ||
119 | static bool | 110 | static bool owner_mt_check_v0(const struct xt_mtchk_param *par) |
120 | owner_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 | ||
136 | static bool | 124 | static bool owner_mt6_check_v0(const struct xt_mtchk_param *par) |
137 | owner_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"); | |||
21 | MODULE_ALIAS("ip6t_physdev"); | 21 | MODULE_ALIAS("ip6t_physdev"); |
22 | 22 | ||
23 | static bool | 23 | static bool |
24 | physdev_mt(const struct sk_buff *skb, const struct net_device *in, | 24 | physdev_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 | ||
97 | static bool | 94 | static bool physdev_mt_check(const struct xt_mtchk_param *par) |
98 | physdev_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 | ||
121 | static struct xt_match physdev_mt_reg[] __read_mostly = { | 115 | static 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 | ||
140 | static int __init physdev_mt_init(void) | 125 | static 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 | ||
145 | static void __exit physdev_mt_exit(void) | 130 | static 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 | ||
150 | module_init(physdev_mt_init); | 135 | module_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"); | |||
23 | MODULE_ALIAS("ip6t_pkttype"); | 23 | MODULE_ALIAS("ip6t_pkttype"); |
24 | 24 | ||
25 | static bool | 25 | static bool |
26 | pkttype_mt(const struct sk_buff *skb, const struct net_device *in, | 26 | pkttype_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 | ||
48 | static struct xt_match pkttype_mt_reg[] __read_mostly = { | 45 | static 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 | ||
65 | static int __init pkttype_mt_init(void) | 54 | static 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 | ||
70 | static void __exit pkttype_mt_exit(void) | 59 | static 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 | ||
75 | module_init(pkttype_mt_init); | 64 | module_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 | ||
112 | static bool | 112 | static bool |
113 | policy_mt(const struct sk_buff *skb, const struct net_device *in, | 113 | policy_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 | ||
134 | static bool | 131 | static bool policy_mt_check(const struct xt_mtchk_param *par) |
135 | policy_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, | |||
165 | static struct xt_match policy_mt_reg[] __read_mostly = { | 159 | static 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"); | |||
18 | static DEFINE_SPINLOCK(quota_lock); | 18 | static DEFINE_SPINLOCK(quota_lock); |
19 | 19 | ||
20 | static bool | 20 | static bool |
21 | quota_mt(const struct sk_buff *skb, const struct net_device *in, | 21 | quota_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("a_lock); | 27 | spin_lock_bh("a_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 | ||
43 | static bool | 40 | static bool quota_mt_check(const struct xt_mtchk_param *par) |
44 | quota_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 | ||
57 | static struct xt_match quota_mt_reg[] __read_mostly = { | 51 | static 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 | ||
76 | static int __init quota_mt_init(void) | 61 | static 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("a_mt_reg); |
79 | } | 64 | } |
80 | 65 | ||
81 | static void __exit quota_mt_exit(void) | 66 | static void __exit quota_mt_exit(void) |
82 | { | 67 | { |
83 | xt_unregister_matches(quota_mt_reg, ARRAY_SIZE(quota_mt_reg)); | 68 | xt_unregister_match("a_mt_reg); |
84 | } | 69 | } |
85 | 70 | ||
86 | module_init(quota_mt_init); | 71 | module_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 | ||
17 | static bool xt_rateest_mt(const struct sk_buff *skb, | 17 | static bool |
18 | const struct net_device *in, | 18 | xt_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 | ||
83 | static bool xt_rateest_mt_checkentry(const char *tablename, | 77 | static 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 | ||
130 | static void xt_rateest_mt_destroy(const struct xt_match *match, | 120 | static 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 | ||
140 | static struct xt_match xt_rateest_match[] __read_mostly = { | 129 | static 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 | ||
161 | static int __init xt_rateest_mt_init(void) | 140 | static 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 | ||
167 | static void __exit xt_rateest_mt_fini(void) | 145 | static 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 | ||
172 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | 150 | MODULE_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"); | |||
22 | MODULE_ALIAS("ipt_realm"); | 22 | MODULE_ALIAS("ipt_realm"); |
23 | 23 | ||
24 | static bool | 24 | static bool |
25 | realm_mt(const struct sk_buff *skb, const struct net_device *in, | 25 | realm_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 | ||
32 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | 35 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); |
36 | MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); | ||
33 | MODULE_DESCRIPTION("Xtables: \"recently-seen\" host matching for IPv4"); | 37 | MODULE_DESCRIPTION("Xtables: \"recently-seen\" host matching for IPv4"); |
34 | MODULE_LICENSE("GPL"); | 38 | MODULE_LICENSE("GPL"); |
39 | MODULE_ALIAS("ipt_recent"); | ||
40 | MODULE_ALIAS("ip6t_recent"); | ||
35 | 41 | ||
36 | static unsigned int ip_list_tot = 100; | 42 | static unsigned int ip_list_tot = 100; |
37 | static unsigned int ip_pkt_list_tot = 20; | 43 | static unsigned int ip_pkt_list_tot = 20; |
@@ -48,14 +54,15 @@ module_param(ip_list_gid, uint, 0400); | |||
48 | MODULE_PARM_DESC(ip_list_tot, "number of IPs to remember per list"); | 54 | MODULE_PARM_DESC(ip_list_tot, "number of IPs to remember per list"); |
49 | MODULE_PARM_DESC(ip_pkt_list_tot, "number of packets per IP to remember (max. 255)"); | 55 | MODULE_PARM_DESC(ip_pkt_list_tot, "number of packets per IP to remember (max. 255)"); |
50 | MODULE_PARM_DESC(ip_list_hash_size, "size of hash table used to look up IPs"); | 56 | MODULE_PARM_DESC(ip_list_hash_size, "size of hash table used to look up IPs"); |
51 | MODULE_PARM_DESC(ip_list_perms, "permissions on /proc/net/ipt_recent/* files"); | 57 | MODULE_PARM_DESC(ip_list_perms, "permissions on /proc/net/xt_recent/* files"); |
52 | MODULE_PARM_DESC(ip_list_uid,"owner of /proc/net/ipt_recent/* files"); | 58 | MODULE_PARM_DESC(ip_list_uid,"owner of /proc/net/xt_recent/* files"); |
53 | MODULE_PARM_DESC(ip_list_gid,"owning group of /proc/net/ipt_recent/* files"); | 59 | MODULE_PARM_DESC(ip_list_gid,"owning group of /proc/net/xt_recent/* files"); |
54 | 60 | ||
55 | struct recent_entry { | 61 | struct 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 | ||
65 | struct recent_table { | 72 | struct 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); | |||
79 | static DEFINE_MUTEX(recent_mutex); | 86 | static DEFINE_MUTEX(recent_mutex); |
80 | 87 | ||
81 | #ifdef CONFIG_PROC_FS | 88 | #ifdef CONFIG_PROC_FS |
82 | static struct proc_dir_entry *proc_dir; | 89 | #ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT |
83 | static const struct file_operations recent_fops; | 90 | static struct proc_dir_entry *proc_old_dir; |
91 | #endif | ||
92 | static struct proc_dir_entry *recent_proc_dir; | ||
93 | static const struct file_operations recent_old_fops, recent_mt_fops; | ||
84 | #endif | 94 | #endif |
85 | 95 | ||
86 | static u_int32_t hash_rnd; | 96 | static u_int32_t hash_rnd; |
87 | static int hash_rnd_initted; | 97 | static bool hash_rnd_initted; |
98 | |||
99 | static 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 | ||
89 | static unsigned int recent_entry_hash(__be32 addr) | 109 | static 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 | ||
98 | static struct recent_entry * | 119 | static struct recent_entry * |
99 | recent_entry_lookup(const struct recent_table *table, __be32 addr, u_int8_t ttl) | 120 | recent_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 | ||
119 | static struct recent_entry * | 148 | static struct recent_entry * |
120 | recent_entry_init(struct recent_table *t, __be32 addr, u_int8_t ttl) | 149 | recent_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 | ||
172 | static bool | 206 | static bool |
173 | recent_mt(const struct sk_buff *skb, const struct net_device *in, | 207 | recent_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 | ||
238 | static bool | 283 | static bool recent_mt_check(const struct xt_mtchk_param *par) |
239 | recent_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 | ||
297 | static void recent_mt_destroy(const struct xt_match *match, void *matchinfo) | 352 | static 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 |
318 | struct recent_iter_state { | 376 | struct 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 | ||
396 | static 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) | 461 | static 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 | |||
473 | static 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 | ||
451 | static const struct file_operations recent_fops = { | 531 | static 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 | |||
540 | static ssize_t | ||
541 | recent_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 | |||
613 | static 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 | ||
460 | static struct xt_match recent_mt_reg __read_mostly = { | 622 | static 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 | ||
470 | static int __init recent_mt_init(void) | 645 | static 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 | ||
491 | static void __exit recent_mt_exit(void) | 676 | static 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 | ||
500 | module_init(recent_mt_init); | 688 | module_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 | ||
119 | static bool | 119 | static bool |
120 | sctp_mt(const struct sk_buff *skb, const struct net_device *in, | 120 | sctp_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 | ||
152 | static bool | 150 | static bool sctp_mt_check(const struct xt_mtchk_param *par) |
153 | sctp_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, | |||
169 | static struct xt_match sctp_mt_reg[] __read_mostly = { | 164 | static 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 | |||
30 | static int | ||
31 | extract_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 | |||
88 | static bool | ||
89 | socket_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 | |||
160 | static 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 | |||
168 | static int __init socket_mt_init(void) | ||
169 | { | ||
170 | nf_defrag_ipv4_enable(); | ||
171 | return xt_register_match(&socket_mt_reg); | ||
172 | } | ||
173 | |||
174 | static void __exit socket_mt_exit(void) | ||
175 | { | ||
176 | xt_unregister_match(&socket_mt_reg); | ||
177 | } | ||
178 | |||
179 | module_init(socket_mt_init); | ||
180 | module_exit(socket_mt_exit); | ||
181 | |||
182 | MODULE_LICENSE("GPL"); | ||
183 | MODULE_AUTHOR("Krisztian Kovacs, Balazs Scheidler"); | ||
184 | MODULE_DESCRIPTION("x_tables socket match module"); | ||
185 | MODULE_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"); | |||
21 | MODULE_ALIAS("ip6t_state"); | 21 | MODULE_ALIAS("ip6t_state"); |
22 | 22 | ||
23 | static bool | 23 | static bool |
24 | state_mt(const struct sk_buff *skb, const struct net_device *in, | 24 | state_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 | ||
43 | static bool | 40 | static bool state_mt_check(const struct xt_mtchk_param *par) |
44 | state_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 | ||
56 | static void state_mt_destroy(const struct xt_match *match, void *matchinfo) | 50 | static 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 | ||
61 | static struct xt_match state_mt_reg[] __read_mostly = { | 55 | static 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"); | |||
25 | static DEFINE_SPINLOCK(nth_lock); | 25 | static DEFINE_SPINLOCK(nth_lock); |
26 | 26 | ||
27 | static bool | 27 | static bool |
28 | statistic_mt(const struct sk_buff *skb, const struct net_device *in, | 28 | statistic_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 | ||
55 | static bool | 52 | static bool statistic_mt_check(const struct xt_mtchk_param *par) |
56 | statistic_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 | ||
69 | static struct xt_match statistic_mt_reg[] __read_mostly = { | 63 | static 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 | ||
88 | static int __init statistic_mt_init(void) | 73 | static 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 | ||
94 | static void __exit statistic_mt_exit(void) | 78 | static 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 | ||
100 | module_init(statistic_mt_init); | 83 | module_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"); | |||
22 | MODULE_ALIAS("ip6t_string"); | 22 | MODULE_ALIAS("ip6t_string"); |
23 | 23 | ||
24 | static bool | 24 | static bool |
25 | string_mt(const struct sk_buff *skb, const struct net_device *in, | 25 | string_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 | ||
46 | static bool | 43 | static bool string_mt_check(const struct xt_mtchk_param *par) |
47 | string_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 | ||
79 | static void string_mt_destroy(const struct xt_match *match, void *matchinfo) | 73 | static 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 | ||
84 | static struct xt_match string_mt_reg[] __read_mostly = { | 78 | static 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 | ||
127 | static int __init string_mt_init(void) | 101 | static 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 | ||
132 | static void __exit string_mt_exit(void) | 107 | static 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 | ||
137 | module_init(string_mt_init); | 112 | module_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"); | |||
25 | MODULE_ALIAS("ip6t_tcpmss"); | 25 | MODULE_ALIAS("ip6t_tcpmss"); |
26 | 26 | ||
27 | static bool | 27 | static bool |
28 | tcpmss_mt(const struct sk_buff *skb, const struct net_device *in, | 28 | tcpmss_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 | ||
78 | dropit: | 75 | dropit: |
79 | *hotdrop = true; | 76 | *par->hotdrop = true; |
80 | return false; | 77 | return false; |
81 | } | 78 | } |
82 | 79 | ||
83 | static struct xt_match tcpmss_mt_reg[] __read_mostly = { | 80 | static 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 | ||
71 | static bool | 71 | static bool tcp_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
72 | tcp_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. */ | 129 | static bool tcp_mt_check(const struct xt_mtchk_param *par) |
133 | static bool | ||
134 | tcp_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 | ||
144 | static bool | 137 | static bool udp_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
145 | udp_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. */ | 164 | static bool udp_mt_check(const struct xt_mtchk_param *par) |
175 | static bool | ||
176 | udp_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, | |||
186 | static struct xt_match tcpudp_mt_reg[] __read_mostly = { | 172 | static 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 | ||
155 | static bool | 155 | static bool |
156 | time_mt(const struct sk_buff *skb, const struct net_device *in, | 156 | time_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 | ||
223 | static bool | 221 | static bool time_mt_check(const struct xt_mtchk_param *par) |
224 | time_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 | ||
240 | static struct xt_match time_mt_reg[] __read_mostly = { | 235 | static 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 | ||
259 | static int __init time_mt_init(void) | 244 | static 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 | ||
264 | static void __exit time_mt_exit(void) | 249 | static 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 | ||
269 | module_init(time_mt_init); | 254 | module_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 | ||
90 | static bool | 90 | static bool u32_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
91 | u32_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 | ||
102 | static struct xt_match u32_mt_reg[] __read_mostly = { | 99 | static 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 | ||
119 | static int __init u32_mt_init(void) | 108 | static 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 | ||
124 | static void __exit u32_mt_exit(void) | 113 | static 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 | ||
129 | module_init(u32_mt_init); | 118 | module_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 | ||
41 | static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook) | 41 | static 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 | ||
70 | static void ipt_destroy_target(struct ipt_entry_target *t) | 68 | static 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 | ||
77 | static int tcf_ipt_release(struct tcf_ipt *ipt, int bind) | 79 | static 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; |