Annotation of /trunk/kernel-alx/patches-3.10/0169-3.10.70-all-fixes.patch
Parent Directory | Revision Log
Revision 2657 -
(hide 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 | niro | 2657 | 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 |