aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-08-22 21:48:21 -0400
committerDavid S. Miller <davem@davemloft.net>2012-08-22 21:48:52 -0400
commitbf277b0ccea7d2422b85e232017ce3fddbe9c49c (patch)
tree252232255b8a6024eccf2fea668bb89de5ae3073 /net
parentbba6ec7e4963e30366359686f34e5bdb00b1a066 (diff)
parent90efbed18a30d78145419cdbd44f9ec152efeb16 (diff)
Merge git://1984.lsi.us.es/nf-next
Pablo Neira Ayuso says: ==================== This is the first batch of Netfilter and IPVS updates for your net-next tree. Mostly cleanups for the Netfilter side. They are: * Remove unnecessary RTNL locking now that we have support for namespace in nf_conntrack, from Patrick McHardy. * Cleanup to eliminate unnecessary goto in the initialization path of several Netfilter tables, from Jean Sacren. * Another cleanup from Wu Fengguang, this time to PTR_RET instead of if IS_ERR then return PTR_ERR. * Use list_for_each_entry_continue_rcu in nf_iterate, from Michael Wang. * Add pmtu_disc sysctl option to disable PMTU in their tunneling transmitter, from Julian Anastasov. * Generalize application protocol registration in IPVS and modify IPVS FTP helper to use it, from Julian Anastasov. * update Kconfig. The IPVS FTP helper depends on the Netfilter FTP helper for NAT support, from Julian Anastasov. * Add logic to update PMTU for IPIP packets in IPVS, again from Julian Anastasov. * A couple of sparse warning fixes for IPVS and Netfilter from Claudiu Ghioc and Patrick McHardy respectively. Patrick's IPv6 NAT changes will follow after this batch, I need to flush this batch first before refreshing my tree. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/bridge/netfilter/ebtable_filter.c4
-rw-r--r--net/bridge/netfilter/ebtable_nat.c4
-rw-r--r--net/ipv4/netfilter/iptable_filter.c10
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c10
-rw-r--r--net/ipv4/netfilter/iptable_raw.c10
-rw-r--r--net/ipv4/netfilter/iptable_security.c5
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c4
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c4
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c4
-rw-r--r--net/ipv6/netfilter/ip6table_security.c5
-rw-r--r--net/netfilter/core.c10
-rw-r--r--net/netfilter/ipvs/Kconfig3
-rw-r--r--net/netfilter/ipvs/ip_vs_app.c58
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c76
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c16
-rw-r--r--net/netfilter/ipvs/ip_vs_ftp.c21
-rw-r--r--net/netfilter/ipvs/ip_vs_xmit.c83
-rw-r--r--net/netfilter/nf_conntrack_proto.c5
-rw-r--r--net/netfilter/nfnetlink_acct.c4
-rw-r--r--net/netfilter/nfnetlink_cthelper.c2
-rw-r--r--net/netfilter/xt_NFQUEUE.c8
-rw-r--r--net/netfilter/xt_osf.c2
22 files changed, 219 insertions, 129 deletions
diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
index 42e6bd094574..3c2e9dced9e0 100644
--- a/net/bridge/netfilter/ebtable_filter.c
+++ b/net/bridge/netfilter/ebtable_filter.c
@@ -100,9 +100,7 @@ static struct nf_hook_ops ebt_ops_filter[] __read_mostly = {
100static int __net_init frame_filter_net_init(struct net *net) 100static int __net_init frame_filter_net_init(struct net *net)
101{ 101{
102 net->xt.frame_filter = ebt_register_table(net, &frame_filter); 102 net->xt.frame_filter = ebt_register_table(net, &frame_filter);
103 if (IS_ERR(net->xt.frame_filter)) 103 return PTR_RET(net->xt.frame_filter);
104 return PTR_ERR(net->xt.frame_filter);
105 return 0;
106} 104}
107 105
108static void __net_exit frame_filter_net_exit(struct net *net) 106static void __net_exit frame_filter_net_exit(struct net *net)
diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
index 6dc2f878ae05..10871bc77908 100644
--- a/net/bridge/netfilter/ebtable_nat.c
+++ b/net/bridge/netfilter/ebtable_nat.c
@@ -100,9 +100,7 @@ static struct nf_hook_ops ebt_ops_nat[] __read_mostly = {
100static int __net_init frame_nat_net_init(struct net *net) 100static int __net_init frame_nat_net_init(struct net *net)
101{ 101{
102 net->xt.frame_nat = ebt_register_table(net, &frame_nat); 102 net->xt.frame_nat = ebt_register_table(net, &frame_nat);
103 if (IS_ERR(net->xt.frame_nat)) 103 return PTR_RET(net->xt.frame_nat);
104 return PTR_ERR(net->xt.frame_nat);
105 return 0;
106} 104}
107 105
108static void __net_exit frame_nat_net_exit(struct net *net) 106static void __net_exit frame_nat_net_exit(struct net *net)
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
index 851acec852d2..6b3da5cf54e9 100644
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -69,9 +69,7 @@ static int __net_init iptable_filter_net_init(struct net *net)
69 net->ipv4.iptable_filter = 69 net->ipv4.iptable_filter =
70 ipt_register_table(net, &packet_filter, repl); 70 ipt_register_table(net, &packet_filter, repl);
71 kfree(repl); 71 kfree(repl);
72 if (IS_ERR(net->ipv4.iptable_filter)) 72 return PTR_RET(net->ipv4.iptable_filter);
73 return PTR_ERR(net->ipv4.iptable_filter);
74 return 0;
75} 73}
76 74
77static void __net_exit iptable_filter_net_exit(struct net *net) 75static void __net_exit iptable_filter_net_exit(struct net *net)
@@ -96,14 +94,10 @@ static int __init iptable_filter_init(void)
96 filter_ops = xt_hook_link(&packet_filter, iptable_filter_hook); 94 filter_ops = xt_hook_link(&packet_filter, iptable_filter_hook);
97 if (IS_ERR(filter_ops)) { 95 if (IS_ERR(filter_ops)) {
98 ret = PTR_ERR(filter_ops); 96 ret = PTR_ERR(filter_ops);
99 goto cleanup_table; 97 unregister_pernet_subsys(&iptable_filter_net_ops);
100 } 98 }
101 99
102 return ret; 100 return ret;
103
104 cleanup_table:
105 unregister_pernet_subsys(&iptable_filter_net_ops);
106 return ret;
107} 101}
108 102
109static void __exit iptable_filter_fini(void) 103static void __exit iptable_filter_fini(void)
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index aef5d1fbe77d..85d88f206447 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -104,9 +104,7 @@ static int __net_init iptable_mangle_net_init(struct net *net)
104 net->ipv4.iptable_mangle = 104 net->ipv4.iptable_mangle =
105 ipt_register_table(net, &packet_mangler, repl); 105 ipt_register_table(net, &packet_mangler, repl);
106 kfree(repl); 106 kfree(repl);
107 if (IS_ERR(net->ipv4.iptable_mangle)) 107 return PTR_RET(net->ipv4.iptable_mangle);
108 return PTR_ERR(net->ipv4.iptable_mangle);
109 return 0;
110} 108}
111 109
112static void __net_exit iptable_mangle_net_exit(struct net *net) 110static void __net_exit iptable_mangle_net_exit(struct net *net)
@@ -131,14 +129,10 @@ static int __init iptable_mangle_init(void)
131 mangle_ops = xt_hook_link(&packet_mangler, iptable_mangle_hook); 129 mangle_ops = xt_hook_link(&packet_mangler, iptable_mangle_hook);
132 if (IS_ERR(mangle_ops)) { 130 if (IS_ERR(mangle_ops)) {
133 ret = PTR_ERR(mangle_ops); 131 ret = PTR_ERR(mangle_ops);
134 goto cleanup_table; 132 unregister_pernet_subsys(&iptable_mangle_net_ops);
135 } 133 }
136 134
137 return ret; 135 return ret;
138
139 cleanup_table:
140 unregister_pernet_subsys(&iptable_mangle_net_ops);
141 return ret;
142} 136}
143 137
144static void __exit iptable_mangle_fini(void) 138static void __exit iptable_mangle_fini(void)
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index 07fb710cd722..03d9696d3c6e 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -48,9 +48,7 @@ static int __net_init iptable_raw_net_init(struct net *net)
48 net->ipv4.iptable_raw = 48 net->ipv4.iptable_raw =
49 ipt_register_table(net, &packet_raw, repl); 49 ipt_register_table(net, &packet_raw, repl);
50 kfree(repl); 50 kfree(repl);
51 if (IS_ERR(net->ipv4.iptable_raw)) 51 return PTR_RET(net->ipv4.iptable_raw);
52 return PTR_ERR(net->ipv4.iptable_raw);
53 return 0;
54} 52}
55 53
56static void __net_exit iptable_raw_net_exit(struct net *net) 54static void __net_exit iptable_raw_net_exit(struct net *net)
@@ -75,14 +73,10 @@ static int __init iptable_raw_init(void)
75 rawtable_ops = xt_hook_link(&packet_raw, iptable_raw_hook); 73 rawtable_ops = xt_hook_link(&packet_raw, iptable_raw_hook);
76 if (IS_ERR(rawtable_ops)) { 74 if (IS_ERR(rawtable_ops)) {
77 ret = PTR_ERR(rawtable_ops); 75 ret = PTR_ERR(rawtable_ops);
78 goto cleanup_table; 76 unregister_pernet_subsys(&iptable_raw_net_ops);
79 } 77 }
80 78
81 return ret; 79 return ret;
82
83 cleanup_table:
84 unregister_pernet_subsys(&iptable_raw_net_ops);
85 return ret;
86} 80}
87 81
88static void __exit iptable_raw_fini(void) 82static void __exit iptable_raw_fini(void)
diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c
index be45bdc4c602..b283d8e2601a 100644
--- a/net/ipv4/netfilter/iptable_security.c
+++ b/net/ipv4/netfilter/iptable_security.c
@@ -66,10 +66,7 @@ static int __net_init iptable_security_net_init(struct net *net)
66 net->ipv4.iptable_security = 66 net->ipv4.iptable_security =
67 ipt_register_table(net, &security_table, repl); 67 ipt_register_table(net, &security_table, repl);
68 kfree(repl); 68 kfree(repl);
69 if (IS_ERR(net->ipv4.iptable_security)) 69 return PTR_RET(net->ipv4.iptable_security);
70 return PTR_ERR(net->ipv4.iptable_security);
71
72 return 0;
73} 70}
74 71
75static void __net_exit iptable_security_net_exit(struct net *net) 72static void __net_exit iptable_security_net_exit(struct net *net)
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 325e59a0224f..beb5777d2043 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -61,9 +61,7 @@ static int __net_init ip6table_filter_net_init(struct net *net)
61 net->ipv6.ip6table_filter = 61 net->ipv6.ip6table_filter =
62 ip6t_register_table(net, &packet_filter, repl); 62 ip6t_register_table(net, &packet_filter, repl);
63 kfree(repl); 63 kfree(repl);
64 if (IS_ERR(net->ipv6.ip6table_filter)) 64 return PTR_RET(net->ipv6.ip6table_filter);
65 return PTR_ERR(net->ipv6.ip6table_filter);
66 return 0;
67} 65}
68 66
69static void __net_exit ip6table_filter_net_exit(struct net *net) 67static void __net_exit ip6table_filter_net_exit(struct net *net)
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index 4d782405f125..7431121b87de 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -97,9 +97,7 @@ static int __net_init ip6table_mangle_net_init(struct net *net)
97 net->ipv6.ip6table_mangle = 97 net->ipv6.ip6table_mangle =
98 ip6t_register_table(net, &packet_mangler, repl); 98 ip6t_register_table(net, &packet_mangler, repl);
99 kfree(repl); 99 kfree(repl);
100 if (IS_ERR(net->ipv6.ip6table_mangle)) 100 return PTR_RET(net->ipv6.ip6table_mangle);
101 return PTR_ERR(net->ipv6.ip6table_mangle);
102 return 0;
103} 101}
104 102
105static void __net_exit ip6table_mangle_net_exit(struct net *net) 103static void __net_exit ip6table_mangle_net_exit(struct net *net)
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index 5b9926a011bd..60d1bddff7a0 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -40,9 +40,7 @@ static int __net_init ip6table_raw_net_init(struct net *net)
40 net->ipv6.ip6table_raw = 40 net->ipv6.ip6table_raw =
41 ip6t_register_table(net, &packet_raw, repl); 41 ip6t_register_table(net, &packet_raw, repl);
42 kfree(repl); 42 kfree(repl);
43 if (IS_ERR(net->ipv6.ip6table_raw)) 43 return PTR_RET(net->ipv6.ip6table_raw);
44 return PTR_ERR(net->ipv6.ip6table_raw);
45 return 0;
46} 44}
47 45
48static void __net_exit ip6table_raw_net_exit(struct net *net) 46static void __net_exit ip6table_raw_net_exit(struct net *net)
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
index 91aa2b4d83c9..db155351339c 100644
--- a/net/ipv6/netfilter/ip6table_security.c
+++ b/net/ipv6/netfilter/ip6table_security.c
@@ -58,10 +58,7 @@ static int __net_init ip6table_security_net_init(struct net *net)
58 net->ipv6.ip6table_security = 58 net->ipv6.ip6table_security =
59 ip6t_register_table(net, &security_table, repl); 59 ip6t_register_table(net, &security_table, repl);
60 kfree(repl); 60 kfree(repl);
61 if (IS_ERR(net->ipv6.ip6table_security)) 61 return PTR_RET(net->ipv6.ip6table_security);
62 return PTR_ERR(net->ipv6.ip6table_security);
63
64 return 0;
65} 62}
66 63
67static void __net_exit ip6table_security_net_exit(struct net *net) 64static void __net_exit ip6table_security_net_exit(struct net *net)
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 0bc6b60db4df..8f4b0b2b6f80 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -131,14 +131,13 @@ unsigned int nf_iterate(struct list_head *head,
131 int hook_thresh) 131 int hook_thresh)
132{ 132{
133 unsigned int verdict; 133 unsigned int verdict;
134 struct nf_hook_ops *elem = list_entry_rcu(*i, struct nf_hook_ops, list);
134 135
135 /* 136 /*
136 * The caller must not block between calls to this 137 * The caller must not block between calls to this
137 * function because of risk of continuing from deleted element. 138 * function because of risk of continuing from deleted element.
138 */ 139 */
139 list_for_each_continue_rcu(*i, head) { 140 list_for_each_entry_continue_rcu(elem, head, list) {
140 struct nf_hook_ops *elem = (struct nf_hook_ops *)*i;
141
142 if (hook_thresh > elem->priority) 141 if (hook_thresh > elem->priority)
143 continue; 142 continue;
144 143
@@ -155,11 +154,14 @@ repeat:
155 continue; 154 continue;
156 } 155 }
157#endif 156#endif
158 if (verdict != NF_REPEAT) 157 if (verdict != NF_REPEAT) {
158 *i = &elem->list;
159 return verdict; 159 return verdict;
160 }
160 goto repeat; 161 goto repeat;
161 } 162 }
162 } 163 }
164 *i = &elem->list;
163 return NF_ACCEPT; 165 return NF_ACCEPT;
164} 166}
165 167
diff --git a/net/netfilter/ipvs/Kconfig b/net/netfilter/ipvs/Kconfig
index f9871385a65e..8b2cffdfdd99 100644
--- a/net/netfilter/ipvs/Kconfig
+++ b/net/netfilter/ipvs/Kconfig
@@ -250,7 +250,8 @@ comment 'IPVS application helper'
250 250
251config IP_VS_FTP 251config IP_VS_FTP
252 tristate "FTP protocol helper" 252 tristate "FTP protocol helper"
253 depends on IP_VS_PROTO_TCP && NF_CONNTRACK && NF_NAT 253 depends on IP_VS_PROTO_TCP && NF_CONNTRACK && NF_NAT && \
254 NF_CONNTRACK_FTP
254 select IP_VS_NFCT 255 select IP_VS_NFCT
255 ---help--- 256 ---help---
256 FTP is a protocol that transfers IP address and/or port number in 257 FTP is a protocol that transfers IP address and/or port number in
diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c
index 64f9e8f13207..9713e6e86d47 100644
--- a/net/netfilter/ipvs/ip_vs_app.c
+++ b/net/netfilter/ipvs/ip_vs_app.c
@@ -180,22 +180,38 @@ register_ip_vs_app_inc(struct net *net, struct ip_vs_app *app, __u16 proto,
180} 180}
181 181
182 182
183/* 183/* Register application for netns */
184 * ip_vs_app registration routine 184struct ip_vs_app *register_ip_vs_app(struct net *net, struct ip_vs_app *app)
185 */
186int register_ip_vs_app(struct net *net, struct ip_vs_app *app)
187{ 185{
188 struct netns_ipvs *ipvs = net_ipvs(net); 186 struct netns_ipvs *ipvs = net_ipvs(net);
189 /* increase the module use count */ 187 struct ip_vs_app *a;
190 ip_vs_use_count_inc(); 188 int err = 0;
189
190 if (!ipvs)
191 return ERR_PTR(-ENOENT);
191 192
192 mutex_lock(&__ip_vs_app_mutex); 193 mutex_lock(&__ip_vs_app_mutex);
193 194
194 list_add(&app->a_list, &ipvs->app_list); 195 list_for_each_entry(a, &ipvs->app_list, a_list) {
196 if (!strcmp(app->name, a->name)) {
197 err = -EEXIST;
198 goto out_unlock;
199 }
200 }
201 a = kmemdup(app, sizeof(*app), GFP_KERNEL);
202 if (!a) {
203 err = -ENOMEM;
204 goto out_unlock;
205 }
206 INIT_LIST_HEAD(&a->incs_list);
207 list_add(&a->a_list, &ipvs->app_list);
208 /* increase the module use count */
209 ip_vs_use_count_inc();
195 210
211out_unlock:
196 mutex_unlock(&__ip_vs_app_mutex); 212 mutex_unlock(&__ip_vs_app_mutex);
197 213
198 return 0; 214 return err ? ERR_PTR(err) : a;
199} 215}
200 216
201 217
@@ -205,20 +221,29 @@ int register_ip_vs_app(struct net *net, struct ip_vs_app *app)
205 */ 221 */
206void unregister_ip_vs_app(struct net *net, struct ip_vs_app *app) 222void unregister_ip_vs_app(struct net *net, struct ip_vs_app *app)
207{ 223{
208 struct ip_vs_app *inc, *nxt; 224 struct netns_ipvs *ipvs = net_ipvs(net);
225 struct ip_vs_app *a, *anxt, *inc, *nxt;
226
227 if (!ipvs)
228 return;
209 229
210 mutex_lock(&__ip_vs_app_mutex); 230 mutex_lock(&__ip_vs_app_mutex);
211 231
212 list_for_each_entry_safe(inc, nxt, &app->incs_list, a_list) { 232 list_for_each_entry_safe(a, anxt, &ipvs->app_list, a_list) {
213 ip_vs_app_inc_release(net, inc); 233 if (app && strcmp(app->name, a->name))
214 } 234 continue;
235 list_for_each_entry_safe(inc, nxt, &a->incs_list, a_list) {
236 ip_vs_app_inc_release(net, inc);
237 }
215 238
216 list_del(&app->a_list); 239 list_del(&a->a_list);
240 kfree(a);
217 241
218 mutex_unlock(&__ip_vs_app_mutex); 242 /* decrease the module use count */
243 ip_vs_use_count_dec();
244 }
219 245
220 /* decrease the module use count */ 246 mutex_unlock(&__ip_vs_app_mutex);
221 ip_vs_use_count_dec();
222} 247}
223 248
224 249
@@ -586,5 +611,6 @@ int __net_init ip_vs_app_net_init(struct net *net)
586 611
587void __net_exit ip_vs_app_net_cleanup(struct net *net) 612void __net_exit ip_vs_app_net_cleanup(struct net *net)
588{ 613{
614 unregister_ip_vs_app(net, NULL /* all */);
589 proc_net_remove(net, "ip_vs_app"); 615 proc_net_remove(net, "ip_vs_app");
590} 616}
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index b54eccef40b5..58918e20f9d5 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -1303,7 +1303,8 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
1303 struct ip_vs_conn *cp; 1303 struct ip_vs_conn *cp;
1304 struct ip_vs_protocol *pp; 1304 struct ip_vs_protocol *pp;
1305 struct ip_vs_proto_data *pd; 1305 struct ip_vs_proto_data *pd;
1306 unsigned int offset, ihl, verdict; 1306 unsigned int offset, offset2, ihl, verdict;
1307 bool ipip;
1307 1308
1308 *related = 1; 1309 *related = 1;
1309 1310
@@ -1345,6 +1346,21 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
1345 1346
1346 net = skb_net(skb); 1347 net = skb_net(skb);
1347 1348
1349 /* Special case for errors for IPIP packets */
1350 ipip = false;
1351 if (cih->protocol == IPPROTO_IPIP) {
1352 if (unlikely(cih->frag_off & htons(IP_OFFSET)))
1353 return NF_ACCEPT;
1354 /* Error for our IPIP must arrive at LOCAL_IN */
1355 if (!(skb_rtable(skb)->rt_flags & RTCF_LOCAL))
1356 return NF_ACCEPT;
1357 offset += cih->ihl * 4;
1358 cih = skb_header_pointer(skb, offset, sizeof(_ciph), &_ciph);
1359 if (cih == NULL)
1360 return NF_ACCEPT; /* The packet looks wrong, ignore */
1361 ipip = true;
1362 }
1363
1348 pd = ip_vs_proto_data_get(net, cih->protocol); 1364 pd = ip_vs_proto_data_get(net, cih->protocol);
1349 if (!pd) 1365 if (!pd)
1350 return NF_ACCEPT; 1366 return NF_ACCEPT;
@@ -1358,11 +1374,14 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
1358 IP_VS_DBG_PKT(11, AF_INET, pp, skb, offset, 1374 IP_VS_DBG_PKT(11, AF_INET, pp, skb, offset,
1359 "Checking incoming ICMP for"); 1375 "Checking incoming ICMP for");
1360 1376
1377 offset2 = offset;
1361 offset += cih->ihl * 4; 1378 offset += cih->ihl * 4;
1362 1379
1363 ip_vs_fill_iphdr(AF_INET, cih, &ciph); 1380 ip_vs_fill_iphdr(AF_INET, cih, &ciph);
1364 /* The embedded headers contain source and dest in reverse order */ 1381 /* The embedded headers contain source and dest in reverse order.
1365 cp = pp->conn_in_get(AF_INET, skb, &ciph, offset, 1); 1382 * For IPIP this is error for request, not for reply.
1383 */
1384 cp = pp->conn_in_get(AF_INET, skb, &ciph, offset, ipip ? 0 : 1);
1366 if (!cp) 1385 if (!cp)
1367 return NF_ACCEPT; 1386 return NF_ACCEPT;
1368 1387
@@ -1376,6 +1395,57 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
1376 goto out; 1395 goto out;
1377 } 1396 }
1378 1397
1398 if (ipip) {
1399 __be32 info = ic->un.gateway;
1400
1401 /* Update the MTU */
1402 if (ic->type == ICMP_DEST_UNREACH &&
1403 ic->code == ICMP_FRAG_NEEDED) {
1404 struct ip_vs_dest *dest = cp->dest;
1405 u32 mtu = ntohs(ic->un.frag.mtu);
1406
1407 /* Strip outer IP and ICMP, go to IPIP header */
1408 __skb_pull(skb, ihl + sizeof(_icmph));
1409 offset2 -= ihl + sizeof(_icmph);
1410 skb_reset_network_header(skb);
1411 IP_VS_DBG(12, "ICMP for IPIP %pI4->%pI4: mtu=%u\n",
1412 &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, mtu);
1413 rcu_read_lock();
1414 ipv4_update_pmtu(skb, dev_net(skb->dev),
1415 mtu, 0, 0, 0, 0);
1416 rcu_read_unlock();
1417 /* Client uses PMTUD? */
1418 if (!(cih->frag_off & htons(IP_DF)))
1419 goto ignore_ipip;
1420 /* Prefer the resulting PMTU */
1421 if (dest) {
1422 spin_lock(&dest->dst_lock);
1423 if (dest->dst_cache)
1424 mtu = dst_mtu(dest->dst_cache);
1425 spin_unlock(&dest->dst_lock);
1426 }
1427 if (mtu > 68 + sizeof(struct iphdr))
1428 mtu -= sizeof(struct iphdr);
1429 info = htonl(mtu);
1430 }
1431 /* Strip outer IP, ICMP and IPIP, go to IP header of
1432 * original request.
1433 */
1434 __skb_pull(skb, offset2);
1435 skb_reset_network_header(skb);
1436 IP_VS_DBG(12, "Sending ICMP for %pI4->%pI4: t=%u, c=%u, i=%u\n",
1437 &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr,
1438 ic->type, ic->code, ntohl(info));
1439 icmp_send(skb, ic->type, ic->code, info);
1440 /* ICMP can be shorter but anyways, account it */
1441 ip_vs_out_stats(cp, skb);
1442
1443ignore_ipip:
1444 consume_skb(skb);
1445 verdict = NF_STOLEN;
1446 goto out;
1447 }
1448
1379 /* do the statistics and put it back */ 1449 /* do the statistics and put it back */
1380 ip_vs_in_stats(cp, skb); 1450 ip_vs_in_stats(cp, skb);
1381 if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol) 1451 if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol)
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 72bf32a84874..3c601378d27e 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -1801,6 +1801,12 @@ static struct ctl_table vs_vars[] = {
1801 .mode = 0644, 1801 .mode = 0644,
1802 .proc_handler = proc_dointvec, 1802 .proc_handler = proc_dointvec,
1803 }, 1803 },
1804 {
1805 .procname = "pmtu_disc",
1806 .maxlen = sizeof(int),
1807 .mode = 0644,
1808 .proc_handler = proc_dointvec,
1809 },
1804#ifdef CONFIG_IP_VS_DEBUG 1810#ifdef CONFIG_IP_VS_DEBUG
1805 { 1811 {
1806 .procname = "debug_level", 1812 .procname = "debug_level",
@@ -3676,7 +3682,7 @@ static void ip_vs_genl_unregister(void)
3676 * per netns intit/exit func. 3682 * per netns intit/exit func.
3677 */ 3683 */
3678#ifdef CONFIG_SYSCTL 3684#ifdef CONFIG_SYSCTL
3679int __net_init ip_vs_control_net_init_sysctl(struct net *net) 3685static int __net_init ip_vs_control_net_init_sysctl(struct net *net)
3680{ 3686{
3681 int idx; 3687 int idx;
3682 struct netns_ipvs *ipvs = net_ipvs(net); 3688 struct netns_ipvs *ipvs = net_ipvs(net);
@@ -3727,6 +3733,8 @@ int __net_init ip_vs_control_net_init_sysctl(struct net *net)
3727 ipvs->sysctl_sync_retries = clamp_t(int, DEFAULT_SYNC_RETRIES, 0, 3); 3733 ipvs->sysctl_sync_retries = clamp_t(int, DEFAULT_SYNC_RETRIES, 0, 3);
3728 tbl[idx++].data = &ipvs->sysctl_sync_retries; 3734 tbl[idx++].data = &ipvs->sysctl_sync_retries;
3729 tbl[idx++].data = &ipvs->sysctl_nat_icmp_send; 3735 tbl[idx++].data = &ipvs->sysctl_nat_icmp_send;
3736 ipvs->sysctl_pmtu_disc = 1;
3737 tbl[idx++].data = &ipvs->sysctl_pmtu_disc;
3730 3738
3731 3739
3732 ipvs->sysctl_hdr = register_net_sysctl(net, "net/ipv4/vs", tbl); 3740 ipvs->sysctl_hdr = register_net_sysctl(net, "net/ipv4/vs", tbl);
@@ -3744,7 +3752,7 @@ int __net_init ip_vs_control_net_init_sysctl(struct net *net)
3744 return 0; 3752 return 0;
3745} 3753}
3746 3754
3747void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net) 3755static void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net)
3748{ 3756{
3749 struct netns_ipvs *ipvs = net_ipvs(net); 3757 struct netns_ipvs *ipvs = net_ipvs(net);
3750 3758
@@ -3755,8 +3763,8 @@ void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net)
3755 3763
3756#else 3764#else
3757 3765
3758int __net_init ip_vs_control_net_init_sysctl(struct net *net) { return 0; } 3766static int __net_init ip_vs_control_net_init_sysctl(struct net *net) { return 0; }
3759void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net) { } 3767static void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net) { }
3760 3768
3761#endif 3769#endif
3762 3770
diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c
index b20b29c903ef..ad70b7e4ac4a 100644
--- a/net/netfilter/ipvs/ip_vs_ftp.c
+++ b/net/netfilter/ipvs/ip_vs_ftp.c
@@ -441,16 +441,10 @@ static int __net_init __ip_vs_ftp_init(struct net *net)
441 441
442 if (!ipvs) 442 if (!ipvs)
443 return -ENOENT; 443 return -ENOENT;
444 app = kmemdup(&ip_vs_ftp, sizeof(struct ip_vs_app), GFP_KERNEL);
445 if (!app)
446 return -ENOMEM;
447 INIT_LIST_HEAD(&app->a_list);
448 INIT_LIST_HEAD(&app->incs_list);
449 ipvs->ftp_app = app;
450 444
451 ret = register_ip_vs_app(net, app); 445 app = register_ip_vs_app(net, &ip_vs_ftp);
452 if (ret) 446 if (IS_ERR(app))
453 goto err_exit; 447 return PTR_ERR(app);
454 448
455 for (i = 0; i < ports_count; i++) { 449 for (i = 0; i < ports_count; i++) {
456 if (!ports[i]) 450 if (!ports[i])
@@ -464,9 +458,7 @@ static int __net_init __ip_vs_ftp_init(struct net *net)
464 return 0; 458 return 0;
465 459
466err_unreg: 460err_unreg:
467 unregister_ip_vs_app(net, app); 461 unregister_ip_vs_app(net, &ip_vs_ftp);
468err_exit:
469 kfree(ipvs->ftp_app);
470 return ret; 462 return ret;
471} 463}
472/* 464/*
@@ -474,10 +466,7 @@ err_exit:
474 */ 466 */
475static void __ip_vs_ftp_exit(struct net *net) 467static void __ip_vs_ftp_exit(struct net *net)
476{ 468{
477 struct netns_ipvs *ipvs = net_ipvs(net); 469 unregister_ip_vs_app(net, &ip_vs_ftp);
478
479 unregister_ip_vs_app(net, ipvs->ftp_app);
480 kfree(ipvs->ftp_app);
481} 470}
482 471
483static struct pernet_operations ip_vs_ftp_ops = { 472static struct pernet_operations ip_vs_ftp_ops = {
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 65b616ae1716..543a554008af 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -49,6 +49,7 @@ enum {
49 IP_VS_RT_MODE_RDR = 4, /* Allow redirect from remote daddr to 49 IP_VS_RT_MODE_RDR = 4, /* Allow redirect from remote daddr to
50 * local 50 * local
51 */ 51 */
52 IP_VS_RT_MODE_CONNECT = 8, /* Always bind route to saddr */
52}; 53};
53 54
54/* 55/*
@@ -84,6 +85,42 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos)
84 return dst; 85 return dst;
85} 86}
86 87
88/* Get route to daddr, update *saddr, optionally bind route to saddr */
89static struct rtable *do_output_route4(struct net *net, __be32 daddr,
90 u32 rtos, int rt_mode, __be32 *saddr)
91{
92 struct flowi4 fl4;
93 struct rtable *rt;
94 int loop = 0;
95
96 memset(&fl4, 0, sizeof(fl4));
97 fl4.daddr = daddr;
98 fl4.saddr = (rt_mode & IP_VS_RT_MODE_CONNECT) ? *saddr : 0;
99 fl4.flowi4_tos = rtos;
100
101retry:
102 rt = ip_route_output_key(net, &fl4);
103 if (IS_ERR(rt)) {
104 /* Invalid saddr ? */
105 if (PTR_ERR(rt) == -EINVAL && *saddr &&
106 rt_mode & IP_VS_RT_MODE_CONNECT && !loop) {
107 *saddr = 0;
108 flowi4_update_output(&fl4, 0, rtos, daddr, 0);
109 goto retry;
110 }
111 IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n", &daddr);
112 return NULL;
113 } else if (!*saddr && rt_mode & IP_VS_RT_MODE_CONNECT && fl4.saddr) {
114 ip_rt_put(rt);
115 *saddr = fl4.saddr;
116 flowi4_update_output(&fl4, 0, rtos, daddr, fl4.saddr);
117 loop++;
118 goto retry;
119 }
120 *saddr = fl4.saddr;
121 return rt;
122}
123
87/* Get route to destination or remote server */ 124/* Get route to destination or remote server */
88static struct rtable * 125static struct rtable *
89__ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest, 126__ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
@@ -98,20 +135,13 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
98 spin_lock(&dest->dst_lock); 135 spin_lock(&dest->dst_lock);
99 if (!(rt = (struct rtable *) 136 if (!(rt = (struct rtable *)
100 __ip_vs_dst_check(dest, rtos))) { 137 __ip_vs_dst_check(dest, rtos))) {
101 struct flowi4 fl4; 138 rt = do_output_route4(net, dest->addr.ip, rtos,
102 139 rt_mode, &dest->dst_saddr.ip);
103 memset(&fl4, 0, sizeof(fl4)); 140 if (!rt) {
104 fl4.daddr = dest->addr.ip;
105 fl4.flowi4_tos = rtos;
106 rt = ip_route_output_key(net, &fl4);
107 if (IS_ERR(rt)) {
108 spin_unlock(&dest->dst_lock); 141 spin_unlock(&dest->dst_lock);
109 IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n",
110 &dest->addr.ip);
111 return NULL; 142 return NULL;
112 } 143 }
113 __ip_vs_dst_set(dest, rtos, dst_clone(&rt->dst), 0); 144 __ip_vs_dst_set(dest, rtos, dst_clone(&rt->dst), 0);
114 dest->dst_saddr.ip = fl4.saddr;
115 IP_VS_DBG(10, "new dst %pI4, src %pI4, refcnt=%d, " 145 IP_VS_DBG(10, "new dst %pI4, src %pI4, refcnt=%d, "
116 "rtos=%X\n", 146 "rtos=%X\n",
117 &dest->addr.ip, &dest->dst_saddr.ip, 147 &dest->addr.ip, &dest->dst_saddr.ip,
@@ -122,19 +152,17 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
122 *ret_saddr = dest->dst_saddr.ip; 152 *ret_saddr = dest->dst_saddr.ip;
123 spin_unlock(&dest->dst_lock); 153 spin_unlock(&dest->dst_lock);
124 } else { 154 } else {
125 struct flowi4 fl4; 155 __be32 saddr = htonl(INADDR_ANY);
126 156
127 memset(&fl4, 0, sizeof(fl4)); 157 /* For such unconfigured boxes avoid many route lookups
128 fl4.daddr = daddr; 158 * for performance reasons because we do not remember saddr
129 fl4.flowi4_tos = rtos; 159 */
130 rt = ip_route_output_key(net, &fl4); 160 rt_mode &= ~IP_VS_RT_MODE_CONNECT;
131 if (IS_ERR(rt)) { 161 rt = do_output_route4(net, daddr, rtos, rt_mode, &saddr);
132 IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n", 162 if (!rt)
133 &daddr);
134 return NULL; 163 return NULL;
135 }
136 if (ret_saddr) 164 if (ret_saddr)
137 *ret_saddr = fl4.saddr; 165 *ret_saddr = saddr;
138 } 166 }
139 167
140 local = rt->rt_flags & RTCF_LOCAL; 168 local = rt->rt_flags & RTCF_LOCAL;
@@ -331,6 +359,7 @@ ip_vs_dst_reset(struct ip_vs_dest *dest)
331 old_dst = dest->dst_cache; 359 old_dst = dest->dst_cache;
332 dest->dst_cache = NULL; 360 dest->dst_cache = NULL;
333 dst_release(old_dst); 361 dst_release(old_dst);
362 dest->dst_saddr.ip = 0;
334} 363}
335 364
336#define IP_VS_XMIT_TUNNEL(skb, cp) \ 365#define IP_VS_XMIT_TUNNEL(skb, cp) \
@@ -766,12 +795,13 @@ int
766ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, 795ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
767 struct ip_vs_protocol *pp) 796 struct ip_vs_protocol *pp)
768{ 797{
798 struct netns_ipvs *ipvs = net_ipvs(skb_net(skb));
769 struct rtable *rt; /* Route to the other host */ 799 struct rtable *rt; /* Route to the other host */
770 __be32 saddr; /* Source for tunnel */ 800 __be32 saddr; /* Source for tunnel */
771 struct net_device *tdev; /* Device to other host */ 801 struct net_device *tdev; /* Device to other host */
772 struct iphdr *old_iph = ip_hdr(skb); 802 struct iphdr *old_iph = ip_hdr(skb);
773 u8 tos = old_iph->tos; 803 u8 tos = old_iph->tos;
774 __be16 df = old_iph->frag_off; 804 __be16 df;
775 struct iphdr *iph; /* Our new IP header */ 805 struct iphdr *iph; /* Our new IP header */
776 unsigned int max_headroom; /* The extra header space needed */ 806 unsigned int max_headroom; /* The extra header space needed */
777 int mtu; 807 int mtu;
@@ -781,7 +811,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
781 811
782 if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip, 812 if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
783 RT_TOS(tos), IP_VS_RT_MODE_LOCAL | 813 RT_TOS(tos), IP_VS_RT_MODE_LOCAL |
784 IP_VS_RT_MODE_NON_LOCAL, 814 IP_VS_RT_MODE_NON_LOCAL |
815 IP_VS_RT_MODE_CONNECT,
785 &saddr))) 816 &saddr)))
786 goto tx_error_icmp; 817 goto tx_error_icmp;
787 if (rt->rt_flags & RTCF_LOCAL) { 818 if (rt->rt_flags & RTCF_LOCAL) {
@@ -796,13 +827,13 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
796 IP_VS_DBG_RL("%s(): mtu less than 68\n", __func__); 827 IP_VS_DBG_RL("%s(): mtu less than 68\n", __func__);
797 goto tx_error_put; 828 goto tx_error_put;
798 } 829 }
799 if (skb_dst(skb)) 830 if (rt_is_output_route(skb_rtable(skb)))
800 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); 831 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
801 832
802 df |= (old_iph->frag_off & htons(IP_DF)); 833 /* Copy DF, reset fragment offset and MF */
834 df = sysctl_pmtu_disc(ipvs) ? old_iph->frag_off & htons(IP_DF) : 0;
803 835
804 if ((old_iph->frag_off & htons(IP_DF) && 836 if (df && mtu < ntohs(old_iph->tot_len) && !skb_is_gso(skb)) {
805 mtu < ntohs(old_iph->tot_len) && !skb_is_gso(skb))) {
806 icmp_send(skb, ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED, htonl(mtu)); 837 icmp_send(skb, ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED, htonl(mtu));
807 IP_VS_DBG_RL("%s(): frag needed\n", __func__); 838 IP_VS_DBG_RL("%s(): frag needed\n", __func__);
808 goto tx_error_put; 839 goto tx_error_put;
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 0dc63854390f..51e928db48c8 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -21,7 +21,6 @@
21#include <linux/notifier.h> 21#include <linux/notifier.h>
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/netdevice.h> 23#include <linux/netdevice.h>
24#include <linux/rtnetlink.h>
25 24
26#include <net/netfilter/nf_conntrack.h> 25#include <net/netfilter/nf_conntrack.h>
27#include <net/netfilter/nf_conntrack_l3proto.h> 26#include <net/netfilter/nf_conntrack_l3proto.h>
@@ -294,9 +293,7 @@ void nf_conntrack_l3proto_unregister(struct net *net,
294 nf_ct_l3proto_unregister_sysctl(net, proto); 293 nf_ct_l3proto_unregister_sysctl(net, proto);
295 294
296 /* Remove all contrack entries for this protocol */ 295 /* Remove all contrack entries for this protocol */
297 rtnl_lock();
298 nf_ct_iterate_cleanup(net, kill_l3proto, proto); 296 nf_ct_iterate_cleanup(net, kill_l3proto, proto);
299 rtnl_unlock();
300} 297}
301EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister); 298EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister);
302 299
@@ -502,9 +499,7 @@ void nf_conntrack_l4proto_unregister(struct net *net,
502 nf_ct_l4proto_unregister_sysctl(net, pn, l4proto); 499 nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
503 500
504 /* Remove all contrack entries for this protocol */ 501 /* Remove all contrack entries for this protocol */
505 rtnl_lock();
506 nf_ct_iterate_cleanup(net, kill_l4proto, l4proto); 502 nf_ct_iterate_cleanup(net, kill_l4proto, l4proto);
507 rtnl_unlock();
508} 503}
509EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister); 504EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister);
510 505
diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c
index b2e7310ca0b8..d7ec92879071 100644
--- a/net/netfilter/nfnetlink_acct.c
+++ b/net/netfilter/nfnetlink_acct.c
@@ -79,11 +79,11 @@ nfnl_acct_new(struct sock *nfnl, struct sk_buff *skb,
79 79
80 if (tb[NFACCT_BYTES]) { 80 if (tb[NFACCT_BYTES]) {
81 atomic64_set(&nfacct->bytes, 81 atomic64_set(&nfacct->bytes,
82 be64_to_cpu(nla_get_u64(tb[NFACCT_BYTES]))); 82 be64_to_cpu(nla_get_be64(tb[NFACCT_BYTES])));
83 } 83 }
84 if (tb[NFACCT_PKTS]) { 84 if (tb[NFACCT_PKTS]) {
85 atomic64_set(&nfacct->pkts, 85 atomic64_set(&nfacct->pkts,
86 be64_to_cpu(nla_get_u64(tb[NFACCT_PKTS]))); 86 be64_to_cpu(nla_get_be64(tb[NFACCT_PKTS])));
87 } 87 }
88 atomic_set(&nfacct->refcnt, 1); 88 atomic_set(&nfacct->refcnt, 1);
89 list_add_tail_rcu(&nfacct->head, &nfnl_acct_list); 89 list_add_tail_rcu(&nfacct->head, &nfnl_acct_list);
diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c
index d6836193d479..32a1ba3f3e27 100644
--- a/net/netfilter/nfnetlink_cthelper.c
+++ b/net/netfilter/nfnetlink_cthelper.c
@@ -74,7 +74,7 @@ nfnl_cthelper_parse_tuple(struct nf_conntrack_tuple *tuple,
74 if (!tb[NFCTH_TUPLE_L3PROTONUM] || !tb[NFCTH_TUPLE_L4PROTONUM]) 74 if (!tb[NFCTH_TUPLE_L3PROTONUM] || !tb[NFCTH_TUPLE_L4PROTONUM])
75 return -EINVAL; 75 return -EINVAL;
76 76
77 tuple->src.l3num = ntohs(nla_get_u16(tb[NFCTH_TUPLE_L3PROTONUM])); 77 tuple->src.l3num = ntohs(nla_get_be16(tb[NFCTH_TUPLE_L3PROTONUM]));
78 tuple->dst.protonum = nla_get_u8(tb[NFCTH_TUPLE_L4PROTONUM]); 78 tuple->dst.protonum = nla_get_u8(tb[NFCTH_TUPLE_L4PROTONUM]);
79 79
80 return 0; 80 return 0;
diff --git a/net/netfilter/xt_NFQUEUE.c b/net/netfilter/xt_NFQUEUE.c
index 7babe7d68716..817f9e9f2b16 100644
--- a/net/netfilter/xt_NFQUEUE.c
+++ b/net/netfilter/xt_NFQUEUE.c
@@ -43,7 +43,7 @@ static u32 hash_v4(const struct sk_buff *skb)
43 const struct iphdr *iph = ip_hdr(skb); 43 const struct iphdr *iph = ip_hdr(skb);
44 44
45 /* packets in either direction go into same queue */ 45 /* packets in either direction go into same queue */
46 if (iph->saddr < iph->daddr) 46 if ((__force u32)iph->saddr < (__force u32)iph->daddr)
47 return jhash_3words((__force u32)iph->saddr, 47 return jhash_3words((__force u32)iph->saddr,
48 (__force u32)iph->daddr, iph->protocol, jhash_initval); 48 (__force u32)iph->daddr, iph->protocol, jhash_initval);
49 49
@@ -57,7 +57,8 @@ static u32 hash_v6(const struct sk_buff *skb)
57 const struct ipv6hdr *ip6h = ipv6_hdr(skb); 57 const struct ipv6hdr *ip6h = ipv6_hdr(skb);
58 u32 a, b, c; 58 u32 a, b, c;
59 59
60 if (ip6h->saddr.s6_addr32[3] < ip6h->daddr.s6_addr32[3]) { 60 if ((__force u32)ip6h->saddr.s6_addr32[3] <
61 (__force u32)ip6h->daddr.s6_addr32[3]) {
61 a = (__force u32) ip6h->saddr.s6_addr32[3]; 62 a = (__force u32) ip6h->saddr.s6_addr32[3];
62 b = (__force u32) ip6h->daddr.s6_addr32[3]; 63 b = (__force u32) ip6h->daddr.s6_addr32[3];
63 } else { 64 } else {
@@ -65,7 +66,8 @@ static u32 hash_v6(const struct sk_buff *skb)
65 a = (__force u32) ip6h->daddr.s6_addr32[3]; 66 a = (__force u32) ip6h->daddr.s6_addr32[3];
66 } 67 }
67 68
68 if (ip6h->saddr.s6_addr32[1] < ip6h->daddr.s6_addr32[1]) 69 if ((__force u32)ip6h->saddr.s6_addr32[1] <
70 (__force u32)ip6h->daddr.s6_addr32[1])
69 c = (__force u32) ip6h->saddr.s6_addr32[1]; 71 c = (__force u32) ip6h->saddr.s6_addr32[1];
70 else 72 else
71 c = (__force u32) ip6h->daddr.s6_addr32[1]; 73 c = (__force u32) ip6h->daddr.s6_addr32[1];
diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c
index 846f895cb656..a5e673d32bda 100644
--- a/net/netfilter/xt_osf.c
+++ b/net/netfilter/xt_osf.c
@@ -269,7 +269,7 @@ xt_osf_match_packet(const struct sk_buff *skb, struct xt_action_param *p)
269 mss <<= 8; 269 mss <<= 8;
270 mss |= optp[2]; 270 mss |= optp[2];
271 271
272 mss = ntohs(mss); 272 mss = ntohs((__force __be16)mss);
273 break; 273 break;
274 case OSFOPT_TS: 274 case OSFOPT_TS:
275 loop_cont = 1; 275 loop_cont = 1;