Contents of /trunk/kernel-alx/patches-3.10/0169-3.10.70-all-fixes.patch
Parent Directory | Revision Log
Revision 2657 -
(show annotations)
(download)
Tue Jul 21 16:20:22 2015 UTC (9 years, 2 months ago) by niro
File size: 18737 byte(s)
Tue Jul 21 16:20:22 2015 UTC (9 years, 2 months ago) by niro
File size: 18737 byte(s)
-linux-3.10.70
1 | diff --git a/Makefile b/Makefile |
2 | index 81ede20061cf..402cbb7c27f1 100644 |
3 | --- a/Makefile |
4 | +++ b/Makefile |
5 | @@ -1,6 +1,6 @@ |
6 | VERSION = 3 |
7 | PATCHLEVEL = 10 |
8 | -SUBLEVEL = 69 |
9 | +SUBLEVEL = 70 |
10 | EXTRAVERSION = |
11 | NAME = TOSSUG Baby Fish |
12 | |
13 | diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c |
14 | index 9951e66b8502..7e3f45105f11 100644 |
15 | --- a/drivers/block/rbd.c |
16 | +++ b/drivers/block/rbd.c |
17 | @@ -2149,7 +2149,6 @@ static void rbd_img_obj_callback(struct rbd_obj_request *obj_request) |
18 | rbd_assert(img_request->obj_request_count > 0); |
19 | rbd_assert(which != BAD_WHICH); |
20 | rbd_assert(which < img_request->obj_request_count); |
21 | - rbd_assert(which >= img_request->next_completion); |
22 | |
23 | spin_lock_irq(&img_request->completion_lock); |
24 | if (which != img_request->next_completion) |
25 | diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c |
26 | index e4561264e124..a895ed02da86 100644 |
27 | --- a/drivers/media/rc/ir-lirc-codec.c |
28 | +++ b/drivers/media/rc/ir-lirc-codec.c |
29 | @@ -42,11 +42,17 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev) |
30 | return -EINVAL; |
31 | |
32 | /* Packet start */ |
33 | - if (ev.reset) |
34 | - return 0; |
35 | + if (ev.reset) { |
36 | + /* Userspace expects a long space event before the start of |
37 | + * the signal to use as a sync. This may be done with repeat |
38 | + * packets and normal samples. But if a reset has been sent |
39 | + * then we assume that a long time has passed, so we send a |
40 | + * space with the maximum time value. */ |
41 | + sample = LIRC_SPACE(LIRC_VALUE_MASK); |
42 | + IR_dprintk(2, "delivering reset sync space to lirc_dev\n"); |
43 | |
44 | /* Carrier reports */ |
45 | - if (ev.carrier_report) { |
46 | + } else if (ev.carrier_report) { |
47 | sample = LIRC_FREQUENCY(ev.carrier); |
48 | IR_dprintk(2, "carrier report (freq: %d)\n", sample); |
49 | |
50 | diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c |
51 | index af951f343ff6..50104a7e963f 100644 |
52 | --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c |
53 | +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c |
54 | @@ -2315,7 +2315,10 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) |
55 | |
56 | work_done = netxen_process_rcv_ring(sds_ring, budget); |
57 | |
58 | - if ((work_done < budget) && tx_complete) { |
59 | + if (!tx_complete) |
60 | + work_done = budget; |
61 | + |
62 | + if (work_done < budget) { |
63 | napi_complete(&sds_ring->napi); |
64 | if (test_bit(__NX_DEV_UP, &adapter->state)) |
65 | netxen_nic_enable_int(sds_ring); |
66 | diff --git a/drivers/net/ppp/ppp_deflate.c b/drivers/net/ppp/ppp_deflate.c |
67 | index 602c625d95d5..b5edc7f96a39 100644 |
68 | --- a/drivers/net/ppp/ppp_deflate.c |
69 | +++ b/drivers/net/ppp/ppp_deflate.c |
70 | @@ -246,7 +246,7 @@ static int z_compress(void *arg, unsigned char *rptr, unsigned char *obuf, |
71 | /* |
72 | * See if we managed to reduce the size of the packet. |
73 | */ |
74 | - if (olen < isize) { |
75 | + if (olen < isize && olen <= osize) { |
76 | state->stats.comp_bytes += olen; |
77 | state->stats.comp_packets++; |
78 | } else { |
79 | diff --git a/include/net/ip.h b/include/net/ip.h |
80 | index 8695359982d1..0a62365149e2 100644 |
81 | --- a/include/net/ip.h |
82 | +++ b/include/net/ip.h |
83 | @@ -37,11 +37,12 @@ struct inet_skb_parm { |
84 | struct ip_options opt; /* Compiled IP options */ |
85 | unsigned char flags; |
86 | |
87 | -#define IPSKB_FORWARDED 1 |
88 | -#define IPSKB_XFRM_TUNNEL_SIZE 2 |
89 | -#define IPSKB_XFRM_TRANSFORMED 4 |
90 | -#define IPSKB_FRAG_COMPLETE 8 |
91 | -#define IPSKB_REROUTED 16 |
92 | +#define IPSKB_FORWARDED BIT(0) |
93 | +#define IPSKB_XFRM_TUNNEL_SIZE BIT(1) |
94 | +#define IPSKB_XFRM_TRANSFORMED BIT(2) |
95 | +#define IPSKB_FRAG_COMPLETE BIT(3) |
96 | +#define IPSKB_REROUTED BIT(4) |
97 | +#define IPSKB_DOREDIRECT BIT(5) |
98 | |
99 | u16 frag_max_size; |
100 | }; |
101 | @@ -162,7 +163,7 @@ static inline __u8 ip_reply_arg_flowi_flags(const struct ip_reply_arg *arg) |
102 | return (arg->flags & IP_REPLY_ARG_NOSRCCHECK) ? FLOWI_FLAG_ANYSRC : 0; |
103 | } |
104 | |
105 | -void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr, |
106 | +void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr, |
107 | __be32 saddr, const struct ip_reply_arg *arg, |
108 | unsigned int len); |
109 | |
110 | diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h |
111 | index 2ba9de89e8ec..03e6378d5353 100644 |
112 | --- a/include/net/netns/ipv4.h |
113 | +++ b/include/net/netns/ipv4.h |
114 | @@ -43,6 +43,7 @@ struct netns_ipv4 { |
115 | struct inet_peer_base *peers; |
116 | struct tcpm_hash_bucket *tcp_metrics_hash; |
117 | unsigned int tcp_metrics_hash_log; |
118 | + struct sock * __percpu *tcp_sk; |
119 | struct netns_frags frags; |
120 | #ifdef CONFIG_NETFILTER |
121 | struct xt_table *iptable_filter; |
122 | diff --git a/net/core/dev.c b/net/core/dev.c |
123 | index cca7ae0ba915..c310440309bb 100644 |
124 | --- a/net/core/dev.c |
125 | +++ b/net/core/dev.c |
126 | @@ -6015,10 +6015,20 @@ static int dev_cpu_callback(struct notifier_block *nfb, |
127 | oldsd->output_queue = NULL; |
128 | oldsd->output_queue_tailp = &oldsd->output_queue; |
129 | } |
130 | - /* Append NAPI poll list from offline CPU. */ |
131 | - if (!list_empty(&oldsd->poll_list)) { |
132 | - list_splice_init(&oldsd->poll_list, &sd->poll_list); |
133 | - raise_softirq_irqoff(NET_RX_SOFTIRQ); |
134 | + /* Append NAPI poll list from offline CPU, with one exception : |
135 | + * process_backlog() must be called by cpu owning percpu backlog. |
136 | + * We properly handle process_queue & input_pkt_queue later. |
137 | + */ |
138 | + while (!list_empty(&oldsd->poll_list)) { |
139 | + struct napi_struct *napi = list_first_entry(&oldsd->poll_list, |
140 | + struct napi_struct, |
141 | + poll_list); |
142 | + |
143 | + list_del_init(&napi->poll_list); |
144 | + if (napi->poll == process_backlog) |
145 | + napi->state = 0; |
146 | + else |
147 | + ____napi_schedule(sd, napi); |
148 | } |
149 | |
150 | raise_softirq_irqoff(NET_TX_SOFTIRQ); |
151 | @@ -6029,7 +6039,7 @@ static int dev_cpu_callback(struct notifier_block *nfb, |
152 | netif_rx(skb); |
153 | input_queue_head_incr(oldsd); |
154 | } |
155 | - while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) { |
156 | + while ((skb = skb_dequeue(&oldsd->input_pkt_queue))) { |
157 | netif_rx(skb); |
158 | input_queue_head_incr(oldsd); |
159 | } |
160 | diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c |
161 | index 25c4dd563a79..279b5dcf09ae 100644 |
162 | --- a/net/core/rtnetlink.c |
163 | +++ b/net/core/rtnetlink.c |
164 | @@ -2477,12 +2477,16 @@ static int rtnl_bridge_notify(struct net_device *dev, u16 flags) |
165 | goto errout; |
166 | } |
167 | |
168 | + if (!skb->len) |
169 | + goto errout; |
170 | + |
171 | rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); |
172 | return 0; |
173 | errout: |
174 | WARN_ON(err == -EMSGSIZE); |
175 | kfree_skb(skb); |
176 | - rtnl_set_sk_err(net, RTNLGRP_LINK, err); |
177 | + if (err) |
178 | + rtnl_set_sk_err(net, RTNLGRP_LINK, err); |
179 | return err; |
180 | } |
181 | |
182 | diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c |
183 | index bd1c5baf69be..31ee5c6033df 100644 |
184 | --- a/net/ipv4/ip_forward.c |
185 | +++ b/net/ipv4/ip_forward.c |
186 | @@ -175,7 +175,8 @@ int ip_forward(struct sk_buff *skb) |
187 | * We now generate an ICMP HOST REDIRECT giving the route |
188 | * we calculated. |
189 | */ |
190 | - if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr && !skb_sec_path(skb)) |
191 | + if (IPCB(skb)->flags & IPSKB_DOREDIRECT && !opt->srr && |
192 | + !skb_sec_path(skb)) |
193 | ip_rt_send_redirect(skb); |
194 | |
195 | skb->priority = rt_tos2priority(iph->tos); |
196 | diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c |
197 | index 22fa05e041ea..def18547748e 100644 |
198 | --- a/net/ipv4/ip_output.c |
199 | +++ b/net/ipv4/ip_output.c |
200 | @@ -1454,23 +1454,8 @@ static int ip_reply_glue_bits(void *dptr, char *to, int offset, |
201 | /* |
202 | * Generic function to send a packet as reply to another packet. |
203 | * Used to send some TCP resets/acks so far. |
204 | - * |
205 | - * Use a fake percpu inet socket to avoid false sharing and contention. |
206 | */ |
207 | -static DEFINE_PER_CPU(struct inet_sock, unicast_sock) = { |
208 | - .sk = { |
209 | - .__sk_common = { |
210 | - .skc_refcnt = ATOMIC_INIT(1), |
211 | - }, |
212 | - .sk_wmem_alloc = ATOMIC_INIT(1), |
213 | - .sk_allocation = GFP_ATOMIC, |
214 | - .sk_flags = (1UL << SOCK_USE_WRITE_QUEUE), |
215 | - }, |
216 | - .pmtudisc = IP_PMTUDISC_WANT, |
217 | - .uc_ttl = -1, |
218 | -}; |
219 | - |
220 | -void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr, |
221 | +void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr, |
222 | __be32 saddr, const struct ip_reply_arg *arg, |
223 | unsigned int len) |
224 | { |
225 | @@ -1478,9 +1463,8 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr, |
226 | struct ipcm_cookie ipc; |
227 | struct flowi4 fl4; |
228 | struct rtable *rt = skb_rtable(skb); |
229 | + struct net *net = sock_net(sk); |
230 | struct sk_buff *nskb; |
231 | - struct sock *sk; |
232 | - struct inet_sock *inet; |
233 | int err; |
234 | |
235 | if (ip_options_echo(&replyopts.opt.opt, skb)) |
236 | @@ -1508,15 +1492,11 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr, |
237 | if (IS_ERR(rt)) |
238 | return; |
239 | |
240 | - inet = &get_cpu_var(unicast_sock); |
241 | + inet_sk(sk)->tos = arg->tos; |
242 | |
243 | - inet->tos = arg->tos; |
244 | - sk = &inet->sk; |
245 | sk->sk_priority = skb->priority; |
246 | sk->sk_protocol = ip_hdr(skb)->protocol; |
247 | sk->sk_bound_dev_if = arg->bound_dev_if; |
248 | - sock_net_set(sk, net); |
249 | - __skb_queue_head_init(&sk->sk_write_queue); |
250 | sk->sk_sndbuf = sysctl_wmem_default; |
251 | err = ip_append_data(sk, &fl4, ip_reply_glue_bits, arg->iov->iov_base, |
252 | len, 0, &ipc, &rt, MSG_DONTWAIT); |
253 | @@ -1532,13 +1512,10 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr, |
254 | arg->csumoffset) = csum_fold(csum_add(nskb->csum, |
255 | arg->csum)); |
256 | nskb->ip_summed = CHECKSUM_NONE; |
257 | - skb_orphan(nskb); |
258 | skb_set_queue_mapping(nskb, skb_get_queue_mapping(skb)); |
259 | ip_push_pending_frames(sk, &fl4); |
260 | } |
261 | out: |
262 | - put_cpu_var(unicast_sock); |
263 | - |
264 | ip_rt_put(rt); |
265 | } |
266 | |
267 | diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c |
268 | index 23e6ab0a2dc0..f6603142cb33 100644 |
269 | --- a/net/ipv4/ip_sockglue.c |
270 | +++ b/net/ipv4/ip_sockglue.c |
271 | @@ -410,15 +410,11 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) |
272 | |
273 | memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); |
274 | sin = &errhdr.offender; |
275 | - sin->sin_family = AF_UNSPEC; |
276 | + memset(sin, 0, sizeof(*sin)); |
277 | if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP) { |
278 | - struct inet_sock *inet = inet_sk(sk); |
279 | - |
280 | sin->sin_family = AF_INET; |
281 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; |
282 | - sin->sin_port = 0; |
283 | - memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); |
284 | - if (inet->cmsg_flags) |
285 | + if (inet_sk(sk)->cmsg_flags) |
286 | ip_cmsg_recv(msg, skb); |
287 | } |
288 | |
289 | diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c |
290 | index aa857a4a06a8..698f3a2ac5ae 100644 |
291 | --- a/net/ipv4/ping.c |
292 | +++ b/net/ipv4/ping.c |
293 | @@ -720,8 +720,11 @@ void ping_rcv(struct sk_buff *skb) |
294 | sk = ping_v4_lookup(net, saddr, daddr, ntohs(icmph->un.echo.id), |
295 | skb->dev->ifindex); |
296 | if (sk != NULL) { |
297 | + struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); |
298 | + |
299 | pr_debug("rcv on socket %p\n", sk); |
300 | - ping_queue_rcv_skb(sk, skb_get(skb)); |
301 | + if (skb2) |
302 | + ping_queue_rcv_skb(sk, skb2); |
303 | sock_put(sk); |
304 | return; |
305 | } |
306 | diff --git a/net/ipv4/route.c b/net/ipv4/route.c |
307 | index d4d162eac4df..e23c5f64286b 100644 |
308 | --- a/net/ipv4/route.c |
309 | +++ b/net/ipv4/route.c |
310 | @@ -1514,11 +1514,10 @@ static int __mkroute_input(struct sk_buff *skb, |
311 | |
312 | do_cache = res->fi && !itag; |
313 | if (out_dev == in_dev && err && IN_DEV_TX_REDIRECTS(out_dev) && |
314 | + skb->protocol == htons(ETH_P_IP) && |
315 | (IN_DEV_SHARED_MEDIA(out_dev) || |
316 | - inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) { |
317 | - flags |= RTCF_DOREDIRECT; |
318 | - do_cache = false; |
319 | - } |
320 | + inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) |
321 | + IPCB(skb)->flags |= IPSKB_DOREDIRECT; |
322 | |
323 | if (skb->protocol != htons(ETH_P_IP)) { |
324 | /* Not IP (i.e. ARP). Do not create route, if it is |
325 | @@ -2255,6 +2254,8 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, |
326 | r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED; |
327 | if (rt->rt_flags & RTCF_NOTIFY) |
328 | r->rtm_flags |= RTM_F_NOTIFY; |
329 | + if (IPCB(skb)->flags & IPSKB_DOREDIRECT) |
330 | + r->rtm_flags |= RTCF_DOREDIRECT; |
331 | |
332 | if (nla_put_be32(skb, RTA_DST, dst)) |
333 | goto nla_put_failure; |
334 | diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c |
335 | index e025c1c788a1..cce35e5a7ee6 100644 |
336 | --- a/net/ipv4/tcp_ipv4.c |
337 | +++ b/net/ipv4/tcp_ipv4.c |
338 | @@ -707,7 +707,8 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) |
339 | |
340 | net = dev_net(skb_dst(skb)->dev); |
341 | arg.tos = ip_hdr(skb)->tos; |
342 | - ip_send_unicast_reply(net, skb, ip_hdr(skb)->saddr, |
343 | + ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), |
344 | + skb, ip_hdr(skb)->saddr, |
345 | ip_hdr(skb)->daddr, &arg, arg.iov[0].iov_len); |
346 | |
347 | TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); |
348 | @@ -790,7 +791,8 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, |
349 | if (oif) |
350 | arg.bound_dev_if = oif; |
351 | arg.tos = tos; |
352 | - ip_send_unicast_reply(net, skb, ip_hdr(skb)->saddr, |
353 | + ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), |
354 | + skb, ip_hdr(skb)->saddr, |
355 | ip_hdr(skb)->daddr, &arg, arg.iov[0].iov_len); |
356 | |
357 | TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); |
358 | @@ -2898,14 +2900,39 @@ struct proto tcp_prot = { |
359 | }; |
360 | EXPORT_SYMBOL(tcp_prot); |
361 | |
362 | +static void __net_exit tcp_sk_exit(struct net *net) |
363 | +{ |
364 | + int cpu; |
365 | + |
366 | + for_each_possible_cpu(cpu) |
367 | + inet_ctl_sock_destroy(*per_cpu_ptr(net->ipv4.tcp_sk, cpu)); |
368 | + free_percpu(net->ipv4.tcp_sk); |
369 | +} |
370 | + |
371 | static int __net_init tcp_sk_init(struct net *net) |
372 | { |
373 | + int res, cpu; |
374 | + |
375 | + net->ipv4.tcp_sk = alloc_percpu(struct sock *); |
376 | + if (!net->ipv4.tcp_sk) |
377 | + return -ENOMEM; |
378 | + |
379 | + for_each_possible_cpu(cpu) { |
380 | + struct sock *sk; |
381 | + |
382 | + res = inet_ctl_sock_create(&sk, PF_INET, SOCK_RAW, |
383 | + IPPROTO_TCP, net); |
384 | + if (res) |
385 | + goto fail; |
386 | + *per_cpu_ptr(net->ipv4.tcp_sk, cpu) = sk; |
387 | + } |
388 | net->ipv4.sysctl_tcp_ecn = 2; |
389 | return 0; |
390 | -} |
391 | |
392 | -static void __net_exit tcp_sk_exit(struct net *net) |
393 | -{ |
394 | +fail: |
395 | + tcp_sk_exit(net); |
396 | + |
397 | + return res; |
398 | } |
399 | |
400 | static void __net_exit tcp_sk_exit_batch(struct list_head *net_exit_list) |
401 | diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c |
402 | index 7927db0a9279..4a000f1dd757 100644 |
403 | --- a/net/ipv4/udp_diag.c |
404 | +++ b/net/ipv4/udp_diag.c |
405 | @@ -99,11 +99,13 @@ static void udp_dump(struct udp_table *table, struct sk_buff *skb, struct netlin |
406 | s_slot = cb->args[0]; |
407 | num = s_num = cb->args[1]; |
408 | |
409 | - for (slot = s_slot; slot <= table->mask; num = s_num = 0, slot++) { |
410 | + for (slot = s_slot; slot <= table->mask; s_num = 0, slot++) { |
411 | struct sock *sk; |
412 | struct hlist_nulls_node *node; |
413 | struct udp_hslot *hslot = &table->hash[slot]; |
414 | |
415 | + num = 0; |
416 | + |
417 | if (hlist_nulls_empty(&hslot->head)) |
418 | continue; |
419 | |
420 | diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c |
421 | index 8997340e3742..ce17d3da9b2b 100644 |
422 | --- a/net/ipv6/datagram.c |
423 | +++ b/net/ipv6/datagram.c |
424 | @@ -374,11 +374,10 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) |
425 | |
426 | memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); |
427 | sin = &errhdr.offender; |
428 | - sin->sin6_family = AF_UNSPEC; |
429 | + memset(sin, 0, sizeof(*sin)); |
430 | + |
431 | if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) { |
432 | sin->sin6_family = AF_INET6; |
433 | - sin->sin6_flowinfo = 0; |
434 | - sin->sin6_port = 0; |
435 | if (skb->protocol == htons(ETH_P_IPV6)) { |
436 | sin->sin6_addr = ipv6_hdr(skb)->saddr; |
437 | if (np->rxopt.all) |
438 | @@ -387,12 +386,9 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) |
439 | ipv6_iface_scope_id(&sin->sin6_addr, |
440 | IP6CB(skb)->iif); |
441 | } else { |
442 | - struct inet_sock *inet = inet_sk(sk); |
443 | - |
444 | ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, |
445 | &sin->sin6_addr); |
446 | - sin->sin6_scope_id = 0; |
447 | - if (inet->cmsg_flags) |
448 | + if (inet_sk(sk)->cmsg_flags) |
449 | ip_cmsg_recv(msg, skb); |
450 | } |
451 | } |
452 | diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c |
453 | index 009c9620f442..ceeb9458bb60 100644 |
454 | --- a/net/ipv6/ip6_fib.c |
455 | +++ b/net/ipv6/ip6_fib.c |
456 | @@ -638,6 +638,29 @@ static inline bool rt6_qualify_for_ecmp(struct rt6_info *rt) |
457 | RTF_GATEWAY; |
458 | } |
459 | |
460 | +static void fib6_purge_rt(struct rt6_info *rt, struct fib6_node *fn, |
461 | + struct net *net) |
462 | +{ |
463 | + if (atomic_read(&rt->rt6i_ref) != 1) { |
464 | + /* This route is used as dummy address holder in some split |
465 | + * nodes. It is not leaked, but it still holds other resources, |
466 | + * which must be released in time. So, scan ascendant nodes |
467 | + * and replace dummy references to this route with references |
468 | + * to still alive ones. |
469 | + */ |
470 | + while (fn) { |
471 | + if (!(fn->fn_flags & RTN_RTINFO) && fn->leaf == rt) { |
472 | + fn->leaf = fib6_find_prefix(net, fn); |
473 | + atomic_inc(&fn->leaf->rt6i_ref); |
474 | + rt6_release(rt); |
475 | + } |
476 | + fn = fn->parent; |
477 | + } |
478 | + /* No more references are possible at this point. */ |
479 | + BUG_ON(atomic_read(&rt->rt6i_ref) != 1); |
480 | + } |
481 | +} |
482 | + |
483 | /* |
484 | * Insert routing information in a node. |
485 | */ |
486 | @@ -775,11 +798,12 @@ add: |
487 | rt->dst.rt6_next = iter->dst.rt6_next; |
488 | atomic_inc(&rt->rt6i_ref); |
489 | inet6_rt_notify(RTM_NEWROUTE, rt, info); |
490 | - rt6_release(iter); |
491 | if (!(fn->fn_flags & RTN_RTINFO)) { |
492 | info->nl_net->ipv6.rt6_stats->fib_route_nodes++; |
493 | fn->fn_flags |= RTN_RTINFO; |
494 | } |
495 | + fib6_purge_rt(iter, fn, info->nl_net); |
496 | + rt6_release(iter); |
497 | } |
498 | |
499 | return 0; |
500 | @@ -1284,24 +1308,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, |
501 | fn = fib6_repair_tree(net, fn); |
502 | } |
503 | |
504 | - if (atomic_read(&rt->rt6i_ref) != 1) { |
505 | - /* This route is used as dummy address holder in some split |
506 | - * nodes. It is not leaked, but it still holds other resources, |
507 | - * which must be released in time. So, scan ascendant nodes |
508 | - * and replace dummy references to this route with references |
509 | - * to still alive ones. |
510 | - */ |
511 | - while (fn) { |
512 | - if (!(fn->fn_flags & RTN_RTINFO) && fn->leaf == rt) { |
513 | - fn->leaf = fib6_find_prefix(net, fn); |
514 | - atomic_inc(&fn->leaf->rt6i_ref); |
515 | - rt6_release(rt); |
516 | - } |
517 | - fn = fn->parent; |
518 | - } |
519 | - /* No more references are possible at this point. */ |
520 | - BUG_ON(atomic_read(&rt->rt6i_ref) != 1); |
521 | - } |
522 | + fib6_purge_rt(rt, fn, net); |
523 | |
524 | inet6_rt_notify(RTM_DELROUTE, rt, info); |
525 | rt6_release(rt); |
526 | diff --git a/net/ipv6/route.c b/net/ipv6/route.c |
527 | index b2614b22622b..92274796eb71 100644 |
528 | --- a/net/ipv6/route.c |
529 | +++ b/net/ipv6/route.c |
530 | @@ -1141,12 +1141,9 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, |
531 | struct net *net = dev_net(dst->dev); |
532 | |
533 | rt6->rt6i_flags |= RTF_MODIFIED; |
534 | - if (mtu < IPV6_MIN_MTU) { |
535 | - u32 features = dst_metric(dst, RTAX_FEATURES); |
536 | + if (mtu < IPV6_MIN_MTU) |
537 | mtu = IPV6_MIN_MTU; |
538 | - features |= RTAX_FEATURE_ALLFRAG; |
539 | - dst_metric_set(dst, RTAX_FEATURES, features); |
540 | - } |
541 | + |
542 | dst_metric_set(dst, RTAX_MTU, mtu); |
543 | rt6_update_expires(rt6, net->ipv6.sysctl.ip6_rt_mtu_expires); |
544 | } |
545 | diff --git a/net/sctp/associola.c b/net/sctp/associola.c |
546 | index ca4a1a1b8e69..6360a14edeab 100644 |
547 | --- a/net/sctp/associola.c |
548 | +++ b/net/sctp/associola.c |
549 | @@ -1297,7 +1297,6 @@ void sctp_assoc_update(struct sctp_association *asoc, |
550 | asoc->peer.peer_hmacs = new->peer.peer_hmacs; |
551 | new->peer.peer_hmacs = NULL; |
552 | |
553 | - sctp_auth_key_put(asoc->asoc_shared_key); |
554 | sctp_auth_asoc_init_active_key(asoc, GFP_ATOMIC); |
555 | } |
556 | |
557 | diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c |
558 | index 29fc16f3633f..beedadf62f6c 100644 |
559 | --- a/net/sctp/sm_make_chunk.c |
560 | +++ b/net/sctp/sm_make_chunk.c |
561 | @@ -2595,7 +2595,7 @@ do_addr_param: |
562 | |
563 | addr_param = param.v + sizeof(sctp_addip_param_t); |
564 | |
565 | - af = sctp_get_af_specific(param_type2af(param.p->type)); |
566 | + af = sctp_get_af_specific(param_type2af(addr_param->p.type)); |
567 | if (af == NULL) |
568 | break; |
569 |