1 |
commit: 92d71a68a84f1c78e69d17af7292951a881c1972 |
2 |
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Fri Feb 27 13:26:19 2015 +0000 |
4 |
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
5 |
CommitDate: Fri Feb 27 13:26:19 2015 +0000 |
6 |
URL: http://sources.gentoo.org/gitweb/?p=proj/linux-patches.git;a=commit;h=92d71a68 |
7 |
|
8 |
Linux patch 3.18.8 |
9 |
|
10 |
--- |
11 |
0000_README | 4 + |
12 |
1007_linux-3.18.8.patch | 668 ++++++++++++++++++++++++++++++++++++++++++++++++ |
13 |
2 files changed, 672 insertions(+) |
14 |
|
15 |
diff --git a/0000_README b/0000_README |
16 |
index bfdd162..7c4ea05 100644 |
17 |
--- a/0000_README |
18 |
+++ b/0000_README |
19 |
@@ -71,6 +71,10 @@ Patch: 1006_linux-3.18.7.patch |
20 |
From: http://www.kernel.org |
21 |
Desc: Linux 3.18.7 |
22 |
|
23 |
+Patch: 1007_linux-3.18.8.patch |
24 |
+From: http://www.kernel.org |
25 |
+Desc: Linux 3.18.8 |
26 |
+ |
27 |
Patch: 1500_XATTR_USER_PREFIX.patch |
28 |
From: https://bugs.gentoo.org/show_bug.cgi?id=470644 |
29 |
Desc: Support for namespace user.pax.* on tmpfs. |
30 |
|
31 |
diff --git a/1007_linux-3.18.8.patch b/1007_linux-3.18.8.patch |
32 |
new file mode 100644 |
33 |
index 0000000..7cc436c |
34 |
--- /dev/null |
35 |
+++ b/1007_linux-3.18.8.patch |
36 |
@@ -0,0 +1,668 @@ |
37 |
+diff --git a/Makefile b/Makefile |
38 |
+index 0efae2279fbe..0b3f8a1b3715 100644 |
39 |
+--- a/Makefile |
40 |
++++ b/Makefile |
41 |
+@@ -1,6 +1,6 @@ |
42 |
+ VERSION = 3 |
43 |
+ PATCHLEVEL = 18 |
44 |
+-SUBLEVEL = 7 |
45 |
++SUBLEVEL = 8 |
46 |
+ EXTRAVERSION = |
47 |
+ NAME = Diseased Newt |
48 |
+ |
49 |
+diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c |
50 |
+index ed2c8a1ed8ca..98893a8332c7 100644 |
51 |
+--- a/drivers/media/rc/ir-lirc-codec.c |
52 |
++++ b/drivers/media/rc/ir-lirc-codec.c |
53 |
+@@ -42,11 +42,17 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev) |
54 |
+ return -EINVAL; |
55 |
+ |
56 |
+ /* Packet start */ |
57 |
+- if (ev.reset) |
58 |
+- return 0; |
59 |
++ if (ev.reset) { |
60 |
++ /* Userspace expects a long space event before the start of |
61 |
++ * the signal to use as a sync. This may be done with repeat |
62 |
++ * packets and normal samples. But if a reset has been sent |
63 |
++ * then we assume that a long time has passed, so we send a |
64 |
++ * space with the maximum time value. */ |
65 |
++ sample = LIRC_SPACE(LIRC_VALUE_MASK); |
66 |
++ IR_dprintk(2, "delivering reset sync space to lirc_dev\n"); |
67 |
+ |
68 |
+ /* Carrier reports */ |
69 |
+- if (ev.carrier_report) { |
70 |
++ } else if (ev.carrier_report) { |
71 |
+ sample = LIRC_FREQUENCY(ev.carrier); |
72 |
+ IR_dprintk(2, "carrier report (freq: %d)\n", sample); |
73 |
+ |
74 |
+diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c |
75 |
+index 40beef5bca88..ec4cebabff49 100644 |
76 |
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c |
77 |
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c |
78 |
+@@ -3175,7 +3175,7 @@ static int bnx2x_poll(struct napi_struct *napi, int budget) |
79 |
+ } |
80 |
+ #endif |
81 |
+ if (!bnx2x_fp_lock_napi(fp)) |
82 |
+- return work_done; |
83 |
++ return budget; |
84 |
+ |
85 |
+ for_each_cos_in_tx_queue(fp, cos) |
86 |
+ if (bnx2x_tx_queue_has_work(fp->txdata_ptr[cos])) |
87 |
+diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c |
88 |
+index 613037584d08..c531c8ae1be4 100644 |
89 |
+--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c |
90 |
++++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c |
91 |
+@@ -2388,7 +2388,10 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) |
92 |
+ |
93 |
+ work_done = netxen_process_rcv_ring(sds_ring, budget); |
94 |
+ |
95 |
+- if ((work_done < budget) && tx_complete) { |
96 |
++ if (!tx_complete) |
97 |
++ work_done = budget; |
98 |
++ |
99 |
++ if (work_done < budget) { |
100 |
+ napi_complete(&sds_ring->napi); |
101 |
+ if (test_bit(__NX_DEV_UP, &adapter->state)) |
102 |
+ netxen_nic_enable_int(sds_ring); |
103 |
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c |
104 |
+index 7d76c9523395..63d7a642733d 100644 |
105 |
+--- a/drivers/net/hyperv/netvsc.c |
106 |
++++ b/drivers/net/hyperv/netvsc.c |
107 |
+@@ -716,7 +716,7 @@ int netvsc_send(struct hv_device *device, |
108 |
+ u64 req_id; |
109 |
+ unsigned int section_index = NETVSC_INVALID_INDEX; |
110 |
+ u32 msg_size = 0; |
111 |
+- struct sk_buff *skb; |
112 |
++ struct sk_buff *skb = NULL; |
113 |
+ u16 q_idx = packet->q_idx; |
114 |
+ |
115 |
+ |
116 |
+@@ -743,8 +743,6 @@ int netvsc_send(struct hv_device *device, |
117 |
+ packet); |
118 |
+ skb = (struct sk_buff *) |
119 |
+ (unsigned long)packet->send_completion_tid; |
120 |
+- if (skb) |
121 |
+- dev_kfree_skb_any(skb); |
122 |
+ packet->page_buf_cnt = 0; |
123 |
+ } |
124 |
+ } |
125 |
+@@ -807,6 +805,13 @@ int netvsc_send(struct hv_device *device, |
126 |
+ packet, ret); |
127 |
+ } |
128 |
+ |
129 |
++ if (ret != 0) { |
130 |
++ if (section_index != NETVSC_INVALID_INDEX) |
131 |
++ netvsc_free_send_slot(net_device, section_index); |
132 |
++ } else if (skb) { |
133 |
++ dev_kfree_skb_any(skb); |
134 |
++ } |
135 |
++ |
136 |
+ return ret; |
137 |
+ } |
138 |
+ |
139 |
+diff --git a/drivers/net/ppp/ppp_deflate.c b/drivers/net/ppp/ppp_deflate.c |
140 |
+index 602c625d95d5..b5edc7f96a39 100644 |
141 |
+--- a/drivers/net/ppp/ppp_deflate.c |
142 |
++++ b/drivers/net/ppp/ppp_deflate.c |
143 |
+@@ -246,7 +246,7 @@ static int z_compress(void *arg, unsigned char *rptr, unsigned char *obuf, |
144 |
+ /* |
145 |
+ * See if we managed to reduce the size of the packet. |
146 |
+ */ |
147 |
+- if (olen < isize) { |
148 |
++ if (olen < isize && olen <= osize) { |
149 |
+ state->stats.comp_bytes += olen; |
150 |
+ state->stats.comp_packets++; |
151 |
+ } else { |
152 |
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c |
153 |
+index 2c9e6864abd9..fc7391e14c2a 100644 |
154 |
+--- a/fs/ext4/super.c |
155 |
++++ b/fs/ext4/super.c |
156 |
+@@ -4849,9 +4849,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) |
157 |
+ if ((old_opts.s_mount_opt & EXT4_MOUNT_JOURNAL_CHECKSUM) ^ |
158 |
+ test_opt(sb, JOURNAL_CHECKSUM)) { |
159 |
+ ext4_msg(sb, KERN_ERR, "changing journal_checksum " |
160 |
+- "during remount not supported"); |
161 |
+- err = -EINVAL; |
162 |
+- goto restore_opts; |
163 |
++ "during remount not supported; ignoring"); |
164 |
++ sbi->s_mount_opt ^= EXT4_MOUNT_JOURNAL_CHECKSUM; |
165 |
+ } |
166 |
+ |
167 |
+ if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { |
168 |
+diff --git a/include/net/ip.h b/include/net/ip.h |
169 |
+index 0bb620702929..09cf5aebb283 100644 |
170 |
+--- a/include/net/ip.h |
171 |
++++ b/include/net/ip.h |
172 |
+@@ -39,11 +39,12 @@ struct inet_skb_parm { |
173 |
+ struct ip_options opt; /* Compiled IP options */ |
174 |
+ unsigned char flags; |
175 |
+ |
176 |
+-#define IPSKB_FORWARDED 1 |
177 |
+-#define IPSKB_XFRM_TUNNEL_SIZE 2 |
178 |
+-#define IPSKB_XFRM_TRANSFORMED 4 |
179 |
+-#define IPSKB_FRAG_COMPLETE 8 |
180 |
+-#define IPSKB_REROUTED 16 |
181 |
++#define IPSKB_FORWARDED BIT(0) |
182 |
++#define IPSKB_XFRM_TUNNEL_SIZE BIT(1) |
183 |
++#define IPSKB_XFRM_TRANSFORMED BIT(2) |
184 |
++#define IPSKB_FRAG_COMPLETE BIT(3) |
185 |
++#define IPSKB_REROUTED BIT(4) |
186 |
++#define IPSKB_DOREDIRECT BIT(5) |
187 |
+ |
188 |
+ u16 frag_max_size; |
189 |
+ }; |
190 |
+@@ -180,7 +181,7 @@ static inline __u8 ip_reply_arg_flowi_flags(const struct ip_reply_arg *arg) |
191 |
+ return (arg->flags & IP_REPLY_ARG_NOSRCCHECK) ? FLOWI_FLAG_ANYSRC : 0; |
192 |
+ } |
193 |
+ |
194 |
+-void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, |
195 |
++void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb, |
196 |
+ const struct ip_options *sopt, |
197 |
+ __be32 daddr, __be32 saddr, |
198 |
+ const struct ip_reply_arg *arg, |
199 |
+diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h |
200 |
+index 24945cefc4fd..0ffef1a38efc 100644 |
201 |
+--- a/include/net/netns/ipv4.h |
202 |
++++ b/include/net/netns/ipv4.h |
203 |
+@@ -52,6 +52,7 @@ struct netns_ipv4 { |
204 |
+ struct inet_peer_base *peers; |
205 |
+ struct tcpm_hash_bucket *tcp_metrics_hash; |
206 |
+ unsigned int tcp_metrics_hash_log; |
207 |
++ struct sock * __percpu *tcp_sk; |
208 |
+ struct netns_frags frags; |
209 |
+ #ifdef CONFIG_NETFILTER |
210 |
+ struct xt_table *iptable_filter; |
211 |
+diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h |
212 |
+index d17ed6fb2f70..5ccfe161f359 100644 |
213 |
+--- a/include/net/sch_generic.h |
214 |
++++ b/include/net/sch_generic.h |
215 |
+@@ -79,6 +79,9 @@ struct Qdisc { |
216 |
+ struct netdev_queue *dev_queue; |
217 |
+ |
218 |
+ struct gnet_stats_rate_est64 rate_est; |
219 |
++ struct gnet_stats_basic_cpu __percpu *cpu_bstats; |
220 |
++ struct gnet_stats_queue __percpu *cpu_qstats; |
221 |
++ |
222 |
+ struct Qdisc *next_sched; |
223 |
+ struct sk_buff *gso_skb; |
224 |
+ /* |
225 |
+@@ -86,15 +89,9 @@ struct Qdisc { |
226 |
+ */ |
227 |
+ unsigned long state; |
228 |
+ struct sk_buff_head q; |
229 |
+- union { |
230 |
+- struct gnet_stats_basic_packed bstats; |
231 |
+- struct gnet_stats_basic_cpu __percpu *cpu_bstats; |
232 |
+- } __packed; |
233 |
++ struct gnet_stats_basic_packed bstats; |
234 |
+ unsigned int __state; |
235 |
+- union { |
236 |
+- struct gnet_stats_queue qstats; |
237 |
+- struct gnet_stats_queue __percpu *cpu_qstats; |
238 |
+- } __packed; |
239 |
++ struct gnet_stats_queue qstats; |
240 |
+ struct rcu_head rcu_head; |
241 |
+ int padded; |
242 |
+ atomic_t refcnt; |
243 |
+diff --git a/net/core/dev.c b/net/core/dev.c |
244 |
+index 84409688ff39..9704a5c1103e 100644 |
245 |
+--- a/net/core/dev.c |
246 |
++++ b/net/core/dev.c |
247 |
+@@ -6990,10 +6990,20 @@ static int dev_cpu_callback(struct notifier_block *nfb, |
248 |
+ oldsd->output_queue = NULL; |
249 |
+ oldsd->output_queue_tailp = &oldsd->output_queue; |
250 |
+ } |
251 |
+- /* Append NAPI poll list from offline CPU. */ |
252 |
+- if (!list_empty(&oldsd->poll_list)) { |
253 |
+- list_splice_init(&oldsd->poll_list, &sd->poll_list); |
254 |
+- raise_softirq_irqoff(NET_RX_SOFTIRQ); |
255 |
++ /* Append NAPI poll list from offline CPU, with one exception : |
256 |
++ * process_backlog() must be called by cpu owning percpu backlog. |
257 |
++ * We properly handle process_queue & input_pkt_queue later. |
258 |
++ */ |
259 |
++ while (!list_empty(&oldsd->poll_list)) { |
260 |
++ struct napi_struct *napi = list_first_entry(&oldsd->poll_list, |
261 |
++ struct napi_struct, |
262 |
++ poll_list); |
263 |
++ |
264 |
++ list_del_init(&napi->poll_list); |
265 |
++ if (napi->poll == process_backlog) |
266 |
++ napi->state = 0; |
267 |
++ else |
268 |
++ ____napi_schedule(sd, napi); |
269 |
+ } |
270 |
+ |
271 |
+ raise_softirq_irqoff(NET_TX_SOFTIRQ); |
272 |
+@@ -7004,7 +7014,7 @@ static int dev_cpu_callback(struct notifier_block *nfb, |
273 |
+ netif_rx_internal(skb); |
274 |
+ input_queue_head_incr(oldsd); |
275 |
+ } |
276 |
+- while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) { |
277 |
++ while ((skb = skb_dequeue(&oldsd->input_pkt_queue))) { |
278 |
+ netif_rx_internal(skb); |
279 |
+ input_queue_head_incr(oldsd); |
280 |
+ } |
281 |
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c |
282 |
+index 76321ea442c3..ca82629de0b2 100644 |
283 |
+--- a/net/core/rtnetlink.c |
284 |
++++ b/net/core/rtnetlink.c |
285 |
+@@ -2770,12 +2770,16 @@ static int rtnl_bridge_notify(struct net_device *dev, u16 flags) |
286 |
+ goto errout; |
287 |
+ } |
288 |
+ |
289 |
++ if (!skb->len) |
290 |
++ goto errout; |
291 |
++ |
292 |
+ rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); |
293 |
+ return 0; |
294 |
+ errout: |
295 |
+ WARN_ON(err == -EMSGSIZE); |
296 |
+ kfree_skb(skb); |
297 |
+- rtnl_set_sk_err(net, RTNLGRP_LINK, err); |
298 |
++ if (err) |
299 |
++ rtnl_set_sk_err(net, RTNLGRP_LINK, err); |
300 |
+ return err; |
301 |
+ } |
302 |
+ |
303 |
+diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c |
304 |
+index 3a83ce5efa80..787b3c294ce6 100644 |
305 |
+--- a/net/ipv4/ip_forward.c |
306 |
++++ b/net/ipv4/ip_forward.c |
307 |
+@@ -129,7 +129,8 @@ int ip_forward(struct sk_buff *skb) |
308 |
+ * We now generate an ICMP HOST REDIRECT giving the route |
309 |
+ * we calculated. |
310 |
+ */ |
311 |
+- if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr && !skb_sec_path(skb)) |
312 |
++ if (IPCB(skb)->flags & IPSKB_DOREDIRECT && !opt->srr && |
313 |
++ !skb_sec_path(skb)) |
314 |
+ ip_rt_send_redirect(skb); |
315 |
+ |
316 |
+ skb->priority = rt_tos2priority(iph->tos); |
317 |
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c |
318 |
+index bc6471d4abcd..4a2a074bfb4a 100644 |
319 |
+--- a/net/ipv4/ip_output.c |
320 |
++++ b/net/ipv4/ip_output.c |
321 |
+@@ -1506,23 +1506,8 @@ static int ip_reply_glue_bits(void *dptr, char *to, int offset, |
322 |
+ /* |
323 |
+ * Generic function to send a packet as reply to another packet. |
324 |
+ * Used to send some TCP resets/acks so far. |
325 |
+- * |
326 |
+- * Use a fake percpu inet socket to avoid false sharing and contention. |
327 |
+ */ |
328 |
+-static DEFINE_PER_CPU(struct inet_sock, unicast_sock) = { |
329 |
+- .sk = { |
330 |
+- .__sk_common = { |
331 |
+- .skc_refcnt = ATOMIC_INIT(1), |
332 |
+- }, |
333 |
+- .sk_wmem_alloc = ATOMIC_INIT(1), |
334 |
+- .sk_allocation = GFP_ATOMIC, |
335 |
+- .sk_flags = (1UL << SOCK_USE_WRITE_QUEUE), |
336 |
+- }, |
337 |
+- .pmtudisc = IP_PMTUDISC_WANT, |
338 |
+- .uc_ttl = -1, |
339 |
+-}; |
340 |
+- |
341 |
+-void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, |
342 |
++void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb, |
343 |
+ const struct ip_options *sopt, |
344 |
+ __be32 daddr, __be32 saddr, |
345 |
+ const struct ip_reply_arg *arg, |
346 |
+@@ -1532,9 +1517,8 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, |
347 |
+ struct ipcm_cookie ipc; |
348 |
+ struct flowi4 fl4; |
349 |
+ struct rtable *rt = skb_rtable(skb); |
350 |
++ struct net *net = sock_net(sk); |
351 |
+ struct sk_buff *nskb; |
352 |
+- struct sock *sk; |
353 |
+- struct inet_sock *inet; |
354 |
+ int err; |
355 |
+ |
356 |
+ if (__ip_options_echo(&replyopts.opt.opt, skb, sopt)) |
357 |
+@@ -1565,15 +1549,11 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, |
358 |
+ if (IS_ERR(rt)) |
359 |
+ return; |
360 |
+ |
361 |
+- inet = &get_cpu_var(unicast_sock); |
362 |
++ inet_sk(sk)->tos = arg->tos; |
363 |
+ |
364 |
+- inet->tos = arg->tos; |
365 |
+- sk = &inet->sk; |
366 |
+ sk->sk_priority = skb->priority; |
367 |
+ sk->sk_protocol = ip_hdr(skb)->protocol; |
368 |
+ sk->sk_bound_dev_if = arg->bound_dev_if; |
369 |
+- sock_net_set(sk, net); |
370 |
+- __skb_queue_head_init(&sk->sk_write_queue); |
371 |
+ sk->sk_sndbuf = sysctl_wmem_default; |
372 |
+ err = ip_append_data(sk, &fl4, ip_reply_glue_bits, arg->iov->iov_base, |
373 |
+ len, 0, &ipc, &rt, MSG_DONTWAIT); |
374 |
+@@ -1589,13 +1569,10 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, |
375 |
+ arg->csumoffset) = csum_fold(csum_add(nskb->csum, |
376 |
+ arg->csum)); |
377 |
+ nskb->ip_summed = CHECKSUM_NONE; |
378 |
+- skb_orphan(nskb); |
379 |
+ skb_set_queue_mapping(nskb, skb_get_queue_mapping(skb)); |
380 |
+ ip_push_pending_frames(sk, &fl4); |
381 |
+ } |
382 |
+ out: |
383 |
+- put_cpu_var(unicast_sock); |
384 |
+- |
385 |
+ ip_rt_put(rt); |
386 |
+ } |
387 |
+ |
388 |
+diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c |
389 |
+index 9daf2177dc00..046fce012da5 100644 |
390 |
+--- a/net/ipv4/ip_sockglue.c |
391 |
++++ b/net/ipv4/ip_sockglue.c |
392 |
+@@ -443,15 +443,11 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) |
393 |
+ |
394 |
+ memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); |
395 |
+ sin = &errhdr.offender; |
396 |
+- sin->sin_family = AF_UNSPEC; |
397 |
++ memset(sin, 0, sizeof(*sin)); |
398 |
+ if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP) { |
399 |
+- struct inet_sock *inet = inet_sk(sk); |
400 |
+- |
401 |
+ sin->sin_family = AF_INET; |
402 |
+ sin->sin_addr.s_addr = ip_hdr(skb)->saddr; |
403 |
+- sin->sin_port = 0; |
404 |
+- memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); |
405 |
+- if (inet->cmsg_flags) |
406 |
++ if (inet_sk(sk)->cmsg_flags) |
407 |
+ ip_cmsg_recv(msg, skb); |
408 |
+ } |
409 |
+ |
410 |
+diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c |
411 |
+index 5d740cccf69e..5638b179b355 100644 |
412 |
+--- a/net/ipv4/ping.c |
413 |
++++ b/net/ipv4/ping.c |
414 |
+@@ -965,8 +965,11 @@ void ping_rcv(struct sk_buff *skb) |
415 |
+ |
416 |
+ sk = ping_lookup(net, skb, ntohs(icmph->un.echo.id)); |
417 |
+ if (sk != NULL) { |
418 |
++ struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); |
419 |
++ |
420 |
+ pr_debug("rcv on socket %p\n", sk); |
421 |
+- ping_queue_rcv_skb(sk, skb_get(skb)); |
422 |
++ if (skb2) |
423 |
++ ping_queue_rcv_skb(sk, skb2); |
424 |
+ sock_put(sk); |
425 |
+ return; |
426 |
+ } |
427 |
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c |
428 |
+index 6a2155b02602..d58dd0ec3e53 100644 |
429 |
+--- a/net/ipv4/route.c |
430 |
++++ b/net/ipv4/route.c |
431 |
+@@ -1554,11 +1554,10 @@ static int __mkroute_input(struct sk_buff *skb, |
432 |
+ |
433 |
+ do_cache = res->fi && !itag; |
434 |
+ if (out_dev == in_dev && err && IN_DEV_TX_REDIRECTS(out_dev) && |
435 |
++ skb->protocol == htons(ETH_P_IP) && |
436 |
+ (IN_DEV_SHARED_MEDIA(out_dev) || |
437 |
+- inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) { |
438 |
+- flags |= RTCF_DOREDIRECT; |
439 |
+- do_cache = false; |
440 |
+- } |
441 |
++ inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) |
442 |
++ IPCB(skb)->flags |= IPSKB_DOREDIRECT; |
443 |
+ |
444 |
+ if (skb->protocol != htons(ETH_P_IP)) { |
445 |
+ /* Not IP (i.e. ARP). Do not create route, if it is |
446 |
+@@ -2303,6 +2302,8 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, |
447 |
+ r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED; |
448 |
+ if (rt->rt_flags & RTCF_NOTIFY) |
449 |
+ r->rtm_flags |= RTM_F_NOTIFY; |
450 |
++ if (IPCB(skb)->flags & IPSKB_DOREDIRECT) |
451 |
++ r->rtm_flags |= RTCF_DOREDIRECT; |
452 |
+ |
453 |
+ if (nla_put_be32(skb, RTA_DST, dst)) |
454 |
+ goto nla_put_failure; |
455 |
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c |
456 |
+index ef7089ca86e2..944ce5edbfb7 100644 |
457 |
+--- a/net/ipv4/tcp_ipv4.c |
458 |
++++ b/net/ipv4/tcp_ipv4.c |
459 |
+@@ -683,7 +683,8 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) |
460 |
+ arg.bound_dev_if = sk->sk_bound_dev_if; |
461 |
+ |
462 |
+ arg.tos = ip_hdr(skb)->tos; |
463 |
+- ip_send_unicast_reply(net, skb, &TCP_SKB_CB(skb)->header.h4.opt, |
464 |
++ ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), |
465 |
++ skb, &TCP_SKB_CB(skb)->header.h4.opt, |
466 |
+ ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, |
467 |
+ &arg, arg.iov[0].iov_len); |
468 |
+ |
469 |
+@@ -767,7 +768,8 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, |
470 |
+ if (oif) |
471 |
+ arg.bound_dev_if = oif; |
472 |
+ arg.tos = tos; |
473 |
+- ip_send_unicast_reply(net, skb, &TCP_SKB_CB(skb)->header.h4.opt, |
474 |
++ ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), |
475 |
++ skb, &TCP_SKB_CB(skb)->header.h4.opt, |
476 |
+ ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, |
477 |
+ &arg, arg.iov[0].iov_len); |
478 |
+ |
479 |
+@@ -2426,14 +2428,39 @@ struct proto tcp_prot = { |
480 |
+ }; |
481 |
+ EXPORT_SYMBOL(tcp_prot); |
482 |
+ |
483 |
++static void __net_exit tcp_sk_exit(struct net *net) |
484 |
++{ |
485 |
++ int cpu; |
486 |
++ |
487 |
++ for_each_possible_cpu(cpu) |
488 |
++ inet_ctl_sock_destroy(*per_cpu_ptr(net->ipv4.tcp_sk, cpu)); |
489 |
++ free_percpu(net->ipv4.tcp_sk); |
490 |
++} |
491 |
++ |
492 |
+ static int __net_init tcp_sk_init(struct net *net) |
493 |
+ { |
494 |
++ int res, cpu; |
495 |
++ |
496 |
++ net->ipv4.tcp_sk = alloc_percpu(struct sock *); |
497 |
++ if (!net->ipv4.tcp_sk) |
498 |
++ return -ENOMEM; |
499 |
++ |
500 |
++ for_each_possible_cpu(cpu) { |
501 |
++ struct sock *sk; |
502 |
++ |
503 |
++ res = inet_ctl_sock_create(&sk, PF_INET, SOCK_RAW, |
504 |
++ IPPROTO_TCP, net); |
505 |
++ if (res) |
506 |
++ goto fail; |
507 |
++ *per_cpu_ptr(net->ipv4.tcp_sk, cpu) = sk; |
508 |
++ } |
509 |
+ net->ipv4.sysctl_tcp_ecn = 2; |
510 |
+ return 0; |
511 |
+-} |
512 |
+ |
513 |
+-static void __net_exit tcp_sk_exit(struct net *net) |
514 |
+-{ |
515 |
++fail: |
516 |
++ tcp_sk_exit(net); |
517 |
++ |
518 |
++ return res; |
519 |
+ } |
520 |
+ |
521 |
+ static void __net_exit tcp_sk_exit_batch(struct list_head *net_exit_list) |
522 |
+diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c |
523 |
+index 7927db0a9279..4a000f1dd757 100644 |
524 |
+--- a/net/ipv4/udp_diag.c |
525 |
++++ b/net/ipv4/udp_diag.c |
526 |
+@@ -99,11 +99,13 @@ static void udp_dump(struct udp_table *table, struct sk_buff *skb, struct netlin |
527 |
+ s_slot = cb->args[0]; |
528 |
+ num = s_num = cb->args[1]; |
529 |
+ |
530 |
+- for (slot = s_slot; slot <= table->mask; num = s_num = 0, slot++) { |
531 |
++ for (slot = s_slot; slot <= table->mask; s_num = 0, slot++) { |
532 |
+ struct sock *sk; |
533 |
+ struct hlist_nulls_node *node; |
534 |
+ struct udp_hslot *hslot = &table->hash[slot]; |
535 |
+ |
536 |
++ num = 0; |
537 |
++ |
538 |
+ if (hlist_nulls_empty(&hslot->head)) |
539 |
+ continue; |
540 |
+ |
541 |
+diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c |
542 |
+index 2cdc38338be3..11e3945eeac7 100644 |
543 |
+--- a/net/ipv6/datagram.c |
544 |
++++ b/net/ipv6/datagram.c |
545 |
+@@ -383,11 +383,10 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) |
546 |
+ |
547 |
+ memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); |
548 |
+ sin = &errhdr.offender; |
549 |
+- sin->sin6_family = AF_UNSPEC; |
550 |
++ memset(sin, 0, sizeof(*sin)); |
551 |
++ |
552 |
+ if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) { |
553 |
+ sin->sin6_family = AF_INET6; |
554 |
+- sin->sin6_flowinfo = 0; |
555 |
+- sin->sin6_port = 0; |
556 |
+ if (np->rxopt.all) |
557 |
+ ip6_datagram_recv_common_ctl(sk, msg, skb); |
558 |
+ if (skb->protocol == htons(ETH_P_IPV6)) { |
559 |
+@@ -398,12 +397,9 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) |
560 |
+ ipv6_iface_scope_id(&sin->sin6_addr, |
561 |
+ IP6CB(skb)->iif); |
562 |
+ } else { |
563 |
+- struct inet_sock *inet = inet_sk(sk); |
564 |
+- |
565 |
+ ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, |
566 |
+ &sin->sin6_addr); |
567 |
+- sin->sin6_scope_id = 0; |
568 |
+- if (inet->cmsg_flags) |
569 |
++ if (inet_sk(sk)->cmsg_flags) |
570 |
+ ip_cmsg_recv(msg, skb); |
571 |
+ } |
572 |
+ } |
573 |
+diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c |
574 |
+index b2d1838897c9..f1c6d5e98322 100644 |
575 |
+--- a/net/ipv6/ip6_fib.c |
576 |
++++ b/net/ipv6/ip6_fib.c |
577 |
+@@ -659,6 +659,29 @@ static int fib6_commit_metrics(struct dst_entry *dst, |
578 |
+ return 0; |
579 |
+ } |
580 |
+ |
581 |
++static void fib6_purge_rt(struct rt6_info *rt, struct fib6_node *fn, |
582 |
++ struct net *net) |
583 |
++{ |
584 |
++ if (atomic_read(&rt->rt6i_ref) != 1) { |
585 |
++ /* This route is used as dummy address holder in some split |
586 |
++ * nodes. It is not leaked, but it still holds other resources, |
587 |
++ * which must be released in time. So, scan ascendant nodes |
588 |
++ * and replace dummy references to this route with references |
589 |
++ * to still alive ones. |
590 |
++ */ |
591 |
++ while (fn) { |
592 |
++ if (!(fn->fn_flags & RTN_RTINFO) && fn->leaf == rt) { |
593 |
++ fn->leaf = fib6_find_prefix(net, fn); |
594 |
++ atomic_inc(&fn->leaf->rt6i_ref); |
595 |
++ rt6_release(rt); |
596 |
++ } |
597 |
++ fn = fn->parent; |
598 |
++ } |
599 |
++ /* No more references are possible at this point. */ |
600 |
++ BUG_ON(atomic_read(&rt->rt6i_ref) != 1); |
601 |
++ } |
602 |
++} |
603 |
++ |
604 |
+ /* |
605 |
+ * Insert routing information in a node. |
606 |
+ */ |
607 |
+@@ -807,11 +830,12 @@ add: |
608 |
+ rt->dst.rt6_next = iter->dst.rt6_next; |
609 |
+ atomic_inc(&rt->rt6i_ref); |
610 |
+ inet6_rt_notify(RTM_NEWROUTE, rt, info); |
611 |
+- rt6_release(iter); |
612 |
+ if (!(fn->fn_flags & RTN_RTINFO)) { |
613 |
+ info->nl_net->ipv6.rt6_stats->fib_route_nodes++; |
614 |
+ fn->fn_flags |= RTN_RTINFO; |
615 |
+ } |
616 |
++ fib6_purge_rt(iter, fn, info->nl_net); |
617 |
++ rt6_release(iter); |
618 |
+ } |
619 |
+ |
620 |
+ return 0; |
621 |
+@@ -1322,24 +1346,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, |
622 |
+ fn = fib6_repair_tree(net, fn); |
623 |
+ } |
624 |
+ |
625 |
+- if (atomic_read(&rt->rt6i_ref) != 1) { |
626 |
+- /* This route is used as dummy address holder in some split |
627 |
+- * nodes. It is not leaked, but it still holds other resources, |
628 |
+- * which must be released in time. So, scan ascendant nodes |
629 |
+- * and replace dummy references to this route with references |
630 |
+- * to still alive ones. |
631 |
+- */ |
632 |
+- while (fn) { |
633 |
+- if (!(fn->fn_flags & RTN_RTINFO) && fn->leaf == rt) { |
634 |
+- fn->leaf = fib6_find_prefix(net, fn); |
635 |
+- atomic_inc(&fn->leaf->rt6i_ref); |
636 |
+- rt6_release(rt); |
637 |
+- } |
638 |
+- fn = fn->parent; |
639 |
+- } |
640 |
+- /* No more references are possible at this point. */ |
641 |
+- BUG_ON(atomic_read(&rt->rt6i_ref) != 1); |
642 |
+- } |
643 |
++ fib6_purge_rt(rt, fn, net); |
644 |
+ |
645 |
+ inet6_rt_notify(RTM_DELROUTE, rt, info); |
646 |
+ rt6_release(rt); |
647 |
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c |
648 |
+index a318dd89b6d9..d02ee019382e 100644 |
649 |
+--- a/net/ipv6/route.c |
650 |
++++ b/net/ipv6/route.c |
651 |
+@@ -1150,12 +1150,9 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, |
652 |
+ struct net *net = dev_net(dst->dev); |
653 |
+ |
654 |
+ rt6->rt6i_flags |= RTF_MODIFIED; |
655 |
+- if (mtu < IPV6_MIN_MTU) { |
656 |
+- u32 features = dst_metric(dst, RTAX_FEATURES); |
657 |
++ if (mtu < IPV6_MIN_MTU) |
658 |
+ mtu = IPV6_MIN_MTU; |
659 |
+- features |= RTAX_FEATURE_ALLFRAG; |
660 |
+- dst_metric_set(dst, RTAX_FEATURES, features); |
661 |
+- } |
662 |
++ |
663 |
+ dst_metric_set(dst, RTAX_MTU, mtu); |
664 |
+ rt6_update_expires(rt6, net->ipv6.sysctl.ip6_rt_mtu_expires); |
665 |
+ } |
666 |
+diff --git a/net/sctp/associola.c b/net/sctp/associola.c |
667 |
+index f791edd64d6c..26d06dbcc1c8 100644 |
668 |
+--- a/net/sctp/associola.c |
669 |
++++ b/net/sctp/associola.c |
670 |
+@@ -1182,7 +1182,6 @@ void sctp_assoc_update(struct sctp_association *asoc, |
671 |
+ asoc->peer.peer_hmacs = new->peer.peer_hmacs; |
672 |
+ new->peer.peer_hmacs = NULL; |
673 |
+ |
674 |
+- sctp_auth_key_put(asoc->asoc_shared_key); |
675 |
+ sctp_auth_asoc_init_active_key(asoc, GFP_ATOMIC); |
676 |
+ } |
677 |
+ |
678 |
+diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c |
679 |
+index 9f32741abb1c..371a152d9759 100644 |
680 |
+--- a/net/sctp/sm_make_chunk.c |
681 |
++++ b/net/sctp/sm_make_chunk.c |
682 |
+@@ -2608,7 +2608,7 @@ do_addr_param: |
683 |
+ |
684 |
+ addr_param = param.v + sizeof(sctp_addip_param_t); |
685 |
+ |
686 |
+- af = sctp_get_af_specific(param_type2af(param.p->type)); |
687 |
++ af = sctp_get_af_specific(param_type2af(addr_param->p.type)); |
688 |
+ if (af == NULL) |
689 |
+ break; |
690 |
+ |
691 |
+diff --git a/net/socket.c b/net/socket.c |
692 |
+index fe20c319a0bb..cf9ebf10c841 100644 |
693 |
+--- a/net/socket.c |
694 |
++++ b/net/socket.c |
695 |
+@@ -892,9 +892,6 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos, |
696 |
+ static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb, |
697 |
+ struct sock_iocb *siocb) |
698 |
+ { |
699 |
+- if (!is_sync_kiocb(iocb)) |
700 |
+- BUG(); |
701 |
+- |
702 |
+ siocb->kiocb = iocb; |
703 |
+ iocb->private = siocb; |
704 |
+ return siocb; |