diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2016-01-07 18:51:13 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2016-01-07 18:51:13 -0500 |
commit | abaee091a18c19ccd86feb1c8374585d82e96777 (patch) | |
tree | 01602bae73e1278c3d98dafe1c269049927c58ce /net | |
parent | a2746fb16e41b7c8f02aa4d2605ecce97abbebbd (diff) | |
parent | 3f8d6f2a0797e8c650a47e5c1b5c2601a46f4293 (diff) |
Merge branch 'jejb-scsi' into misc
Diffstat (limited to 'net')
72 files changed, 605 insertions, 298 deletions
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index a3bffd1ec2b4..70306cc9d814 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -271,11 +271,11 @@ static long bt_sock_data_wait(struct sock *sk, long timeo) | |||
271 | if (signal_pending(current) || !timeo) | 271 | if (signal_pending(current) || !timeo) |
272 | break; | 272 | break; |
273 | 273 | ||
274 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 274 | sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
275 | release_sock(sk); | 275 | release_sock(sk); |
276 | timeo = schedule_timeout(timeo); | 276 | timeo = schedule_timeout(timeo); |
277 | lock_sock(sk); | 277 | lock_sock(sk); |
278 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 278 | sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
279 | } | 279 | } |
280 | 280 | ||
281 | __set_current_state(TASK_RUNNING); | 281 | __set_current_state(TASK_RUNNING); |
@@ -441,7 +441,7 @@ unsigned int bt_sock_poll(struct file *file, struct socket *sock, | |||
441 | if (!test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags) && sock_writeable(sk)) | 441 | if (!test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags) && sock_writeable(sk)) |
442 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; | 442 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; |
443 | else | 443 | else |
444 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 444 | sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
445 | 445 | ||
446 | return mask; | 446 | return mask; |
447 | } | 447 | } |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index c91353841e40..ffed8a1d4f27 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -3027,8 +3027,13 @@ static void smp_ready_cb(struct l2cap_chan *chan) | |||
3027 | 3027 | ||
3028 | BT_DBG("chan %p", chan); | 3028 | BT_DBG("chan %p", chan); |
3029 | 3029 | ||
3030 | /* No need to call l2cap_chan_hold() here since we already own | ||
3031 | * the reference taken in smp_new_conn_cb(). This is just the | ||
3032 | * first time that we tie it to a specific pointer. The code in | ||
3033 | * l2cap_core.c ensures that there's no risk this function wont | ||
3034 | * get called if smp_new_conn_cb was previously called. | ||
3035 | */ | ||
3030 | conn->smp = chan; | 3036 | conn->smp = chan; |
3031 | l2cap_chan_hold(chan); | ||
3032 | 3037 | ||
3033 | if (hcon->type == ACL_LINK && test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) | 3038 | if (hcon->type == ACL_LINK && test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) |
3034 | bredr_pairing(chan); | 3039 | bredr_pairing(chan); |
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index cc858919108e..aa209b1066c9 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c | |||
@@ -323,7 +323,7 @@ static long caif_stream_data_wait(struct sock *sk, long timeo) | |||
323 | !timeo) | 323 | !timeo) |
324 | break; | 324 | break; |
325 | 325 | ||
326 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 326 | sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
327 | release_sock(sk); | 327 | release_sock(sk); |
328 | timeo = schedule_timeout(timeo); | 328 | timeo = schedule_timeout(timeo); |
329 | lock_sock(sk); | 329 | lock_sock(sk); |
@@ -331,7 +331,7 @@ static long caif_stream_data_wait(struct sock *sk, long timeo) | |||
331 | if (sock_flag(sk, SOCK_DEAD)) | 331 | if (sock_flag(sk, SOCK_DEAD)) |
332 | break; | 332 | break; |
333 | 333 | ||
334 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 334 | sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
335 | } | 335 | } |
336 | 336 | ||
337 | finish_wait(sk_sleep(sk), &wait); | 337 | finish_wait(sk_sleep(sk), &wait); |
diff --git a/net/core/datagram.c b/net/core/datagram.c index 617088aee21d..d62af69ad844 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -785,7 +785,7 @@ unsigned int datagram_poll(struct file *file, struct socket *sock, | |||
785 | if (sock_writeable(sk)) | 785 | if (sock_writeable(sk)) |
786 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; | 786 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; |
787 | else | 787 | else |
788 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 788 | sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
789 | 789 | ||
790 | return mask; | 790 | return mask; |
791 | } | 791 | } |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index e6af42da28d9..f18ae91b652e 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -2215,7 +2215,7 @@ static int pneigh_fill_info(struct sk_buff *skb, struct pneigh_entry *pn, | |||
2215 | ndm->ndm_pad2 = 0; | 2215 | ndm->ndm_pad2 = 0; |
2216 | ndm->ndm_flags = pn->flags | NTF_PROXY; | 2216 | ndm->ndm_flags = pn->flags | NTF_PROXY; |
2217 | ndm->ndm_type = RTN_UNICAST; | 2217 | ndm->ndm_type = RTN_UNICAST; |
2218 | ndm->ndm_ifindex = pn->dev->ifindex; | 2218 | ndm->ndm_ifindex = pn->dev ? pn->dev->ifindex : 0; |
2219 | ndm->ndm_state = NUD_NONE; | 2219 | ndm->ndm_state = NUD_NONE; |
2220 | 2220 | ||
2221 | if (nla_put(skb, NDA_DST, tbl->key_len, pn->key)) | 2221 | if (nla_put(skb, NDA_DST, tbl->key_len, pn->key)) |
@@ -2333,7 +2333,7 @@ static int pneigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, | |||
2333 | if (h > s_h) | 2333 | if (h > s_h) |
2334 | s_idx = 0; | 2334 | s_idx = 0; |
2335 | for (n = tbl->phash_buckets[h], idx = 0; n; n = n->next) { | 2335 | for (n = tbl->phash_buckets[h], idx = 0; n; n = n->next) { |
2336 | if (dev_net(n->dev) != net) | 2336 | if (pneigh_net(n) != net) |
2337 | continue; | 2337 | continue; |
2338 | if (idx < s_idx) | 2338 | if (idx < s_idx) |
2339 | goto next; | 2339 | goto next; |
diff --git a/net/core/netclassid_cgroup.c b/net/core/netclassid_cgroup.c index 6441f47b1a8f..2e4df84c34a1 100644 --- a/net/core/netclassid_cgroup.c +++ b/net/core/netclassid_cgroup.c | |||
@@ -56,7 +56,7 @@ static void cgrp_css_free(struct cgroup_subsys_state *css) | |||
56 | kfree(css_cls_state(css)); | 56 | kfree(css_cls_state(css)); |
57 | } | 57 | } |
58 | 58 | ||
59 | static int update_classid(const void *v, struct file *file, unsigned n) | 59 | static int update_classid_sock(const void *v, struct file *file, unsigned n) |
60 | { | 60 | { |
61 | int err; | 61 | int err; |
62 | struct socket *sock = sock_from_file(file, &err); | 62 | struct socket *sock = sock_from_file(file, &err); |
@@ -67,18 +67,25 @@ static int update_classid(const void *v, struct file *file, unsigned n) | |||
67 | return 0; | 67 | return 0; |
68 | } | 68 | } |
69 | 69 | ||
70 | static void cgrp_attach(struct cgroup_subsys_state *css, | 70 | static void update_classid(struct cgroup_subsys_state *css, void *v) |
71 | struct cgroup_taskset *tset) | ||
72 | { | 71 | { |
73 | struct cgroup_cls_state *cs = css_cls_state(css); | 72 | struct css_task_iter it; |
74 | void *v = (void *)(unsigned long)cs->classid; | ||
75 | struct task_struct *p; | 73 | struct task_struct *p; |
76 | 74 | ||
77 | cgroup_taskset_for_each(p, tset) { | 75 | css_task_iter_start(css, &it); |
76 | while ((p = css_task_iter_next(&it))) { | ||
78 | task_lock(p); | 77 | task_lock(p); |
79 | iterate_fd(p->files, 0, update_classid, v); | 78 | iterate_fd(p->files, 0, update_classid_sock, v); |
80 | task_unlock(p); | 79 | task_unlock(p); |
81 | } | 80 | } |
81 | css_task_iter_end(&it); | ||
82 | } | ||
83 | |||
84 | static void cgrp_attach(struct cgroup_subsys_state *css, | ||
85 | struct cgroup_taskset *tset) | ||
86 | { | ||
87 | update_classid(css, | ||
88 | (void *)(unsigned long)css_cls_state(css)->classid); | ||
82 | } | 89 | } |
83 | 90 | ||
84 | static u64 read_classid(struct cgroup_subsys_state *css, struct cftype *cft) | 91 | static u64 read_classid(struct cgroup_subsys_state *css, struct cftype *cft) |
@@ -89,8 +96,11 @@ static u64 read_classid(struct cgroup_subsys_state *css, struct cftype *cft) | |||
89 | static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft, | 96 | static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft, |
90 | u64 value) | 97 | u64 value) |
91 | { | 98 | { |
92 | css_cls_state(css)->classid = (u32) value; | 99 | struct cgroup_cls_state *cs = css_cls_state(css); |
100 | |||
101 | cs->classid = (u32)value; | ||
93 | 102 | ||
103 | update_classid(css, (void *)(unsigned long)cs->classid); | ||
94 | return 0; | 104 | return 0; |
95 | } | 105 | } |
96 | 106 | ||
diff --git a/net/core/scm.c b/net/core/scm.c index 3b6899b7d810..8a1741b14302 100644 --- a/net/core/scm.c +++ b/net/core/scm.c | |||
@@ -305,6 +305,8 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) | |||
305 | err = put_user(cmlen, &cm->cmsg_len); | 305 | err = put_user(cmlen, &cm->cmsg_len); |
306 | if (!err) { | 306 | if (!err) { |
307 | cmlen = CMSG_SPACE(i*sizeof(int)); | 307 | cmlen = CMSG_SPACE(i*sizeof(int)); |
308 | if (msg->msg_controllen < cmlen) | ||
309 | cmlen = msg->msg_controllen; | ||
308 | msg->msg_control += cmlen; | 310 | msg->msg_control += cmlen; |
309 | msg->msg_controllen -= cmlen; | 311 | msg->msg_controllen -= cmlen; |
310 | } | 312 | } |
diff --git a/net/core/sock.c b/net/core/sock.c index 1e4dd54bfb5a..e31dfcee1729 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -1530,7 +1530,6 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) | |||
1530 | skb_queue_head_init(&newsk->sk_receive_queue); | 1530 | skb_queue_head_init(&newsk->sk_receive_queue); |
1531 | skb_queue_head_init(&newsk->sk_write_queue); | 1531 | skb_queue_head_init(&newsk->sk_write_queue); |
1532 | 1532 | ||
1533 | spin_lock_init(&newsk->sk_dst_lock); | ||
1534 | rwlock_init(&newsk->sk_callback_lock); | 1533 | rwlock_init(&newsk->sk_callback_lock); |
1535 | lockdep_set_class_and_name(&newsk->sk_callback_lock, | 1534 | lockdep_set_class_and_name(&newsk->sk_callback_lock, |
1536 | af_callback_keys + newsk->sk_family, | 1535 | af_callback_keys + newsk->sk_family, |
@@ -1607,7 +1606,7 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst) | |||
1607 | { | 1606 | { |
1608 | u32 max_segs = 1; | 1607 | u32 max_segs = 1; |
1609 | 1608 | ||
1610 | __sk_dst_set(sk, dst); | 1609 | sk_dst_set(sk, dst); |
1611 | sk->sk_route_caps = dst->dev->features; | 1610 | sk->sk_route_caps = dst->dev->features; |
1612 | if (sk->sk_route_caps & NETIF_F_GSO) | 1611 | if (sk->sk_route_caps & NETIF_F_GSO) |
1613 | sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE; | 1612 | sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE; |
@@ -1815,7 +1814,7 @@ static long sock_wait_for_wmem(struct sock *sk, long timeo) | |||
1815 | { | 1814 | { |
1816 | DEFINE_WAIT(wait); | 1815 | DEFINE_WAIT(wait); |
1817 | 1816 | ||
1818 | clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 1817 | sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
1819 | for (;;) { | 1818 | for (;;) { |
1820 | if (!timeo) | 1819 | if (!timeo) |
1821 | break; | 1820 | break; |
@@ -1861,7 +1860,7 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len, | |||
1861 | if (sk_wmem_alloc_get(sk) < sk->sk_sndbuf) | 1860 | if (sk_wmem_alloc_get(sk) < sk->sk_sndbuf) |
1862 | break; | 1861 | break; |
1863 | 1862 | ||
1864 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 1863 | sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
1865 | set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); | 1864 | set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); |
1866 | err = -EAGAIN; | 1865 | err = -EAGAIN; |
1867 | if (!timeo) | 1866 | if (!timeo) |
@@ -2048,9 +2047,9 @@ int sk_wait_data(struct sock *sk, long *timeo, const struct sk_buff *skb) | |||
2048 | DEFINE_WAIT(wait); | 2047 | DEFINE_WAIT(wait); |
2049 | 2048 | ||
2050 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 2049 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
2051 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 2050 | sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
2052 | rc = sk_wait_event(sk, timeo, skb_peek_tail(&sk->sk_receive_queue) != skb); | 2051 | rc = sk_wait_event(sk, timeo, skb_peek_tail(&sk->sk_receive_queue) != skb); |
2053 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 2052 | sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
2054 | finish_wait(sk_sleep(sk), &wait); | 2053 | finish_wait(sk_sleep(sk), &wait); |
2055 | return rc; | 2054 | return rc; |
2056 | } | 2055 | } |
@@ -2388,7 +2387,6 @@ void sock_init_data(struct socket *sock, struct sock *sk) | |||
2388 | } else | 2387 | } else |
2389 | sk->sk_wq = NULL; | 2388 | sk->sk_wq = NULL; |
2390 | 2389 | ||
2391 | spin_lock_init(&sk->sk_dst_lock); | ||
2392 | rwlock_init(&sk->sk_callback_lock); | 2390 | rwlock_init(&sk->sk_callback_lock); |
2393 | lockdep_set_class_and_name(&sk->sk_callback_lock, | 2391 | lockdep_set_class_and_name(&sk->sk_callback_lock, |
2394 | af_callback_keys + sk->sk_family, | 2392 | af_callback_keys + sk->sk_family, |
diff --git a/net/core/stream.c b/net/core/stream.c index d70f77a0c889..b96f7a79e544 100644 --- a/net/core/stream.c +++ b/net/core/stream.c | |||
@@ -39,7 +39,7 @@ void sk_stream_write_space(struct sock *sk) | |||
39 | wake_up_interruptible_poll(&wq->wait, POLLOUT | | 39 | wake_up_interruptible_poll(&wq->wait, POLLOUT | |
40 | POLLWRNORM | POLLWRBAND); | 40 | POLLWRNORM | POLLWRBAND); |
41 | if (wq && wq->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN)) | 41 | if (wq && wq->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN)) |
42 | sock_wake_async(sock, SOCK_WAKE_SPACE, POLL_OUT); | 42 | sock_wake_async(wq, SOCK_WAKE_SPACE, POLL_OUT); |
43 | rcu_read_unlock(); | 43 | rcu_read_unlock(); |
44 | } | 44 | } |
45 | } | 45 | } |
@@ -126,7 +126,7 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p) | |||
126 | current_timeo = vm_wait = (prandom_u32() % (HZ / 5)) + 2; | 126 | current_timeo = vm_wait = (prandom_u32() % (HZ / 5)) + 2; |
127 | 127 | ||
128 | while (1) { | 128 | while (1) { |
129 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 129 | sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
130 | 130 | ||
131 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 131 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
132 | 132 | ||
@@ -139,7 +139,7 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p) | |||
139 | } | 139 | } |
140 | if (signal_pending(current)) | 140 | if (signal_pending(current)) |
141 | goto do_interrupted; | 141 | goto do_interrupted; |
142 | clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 142 | sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
143 | if (sk_stream_memory_free(sk) && !vm_wait) | 143 | if (sk_stream_memory_free(sk) && !vm_wait) |
144 | break; | 144 | break; |
145 | 145 | ||
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index db5fc2440a23..9c6d0508e63a 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -202,7 +202,9 @@ static int dccp_v6_send_response(const struct sock *sk, struct request_sock *req | |||
202 | security_req_classify_flow(req, flowi6_to_flowi(&fl6)); | 202 | security_req_classify_flow(req, flowi6_to_flowi(&fl6)); |
203 | 203 | ||
204 | 204 | ||
205 | final_p = fl6_update_dst(&fl6, np->opt, &final); | 205 | rcu_read_lock(); |
206 | final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final); | ||
207 | rcu_read_unlock(); | ||
206 | 208 | ||
207 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p); | 209 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p); |
208 | if (IS_ERR(dst)) { | 210 | if (IS_ERR(dst)) { |
@@ -219,7 +221,10 @@ static int dccp_v6_send_response(const struct sock *sk, struct request_sock *req | |||
219 | &ireq->ir_v6_loc_addr, | 221 | &ireq->ir_v6_loc_addr, |
220 | &ireq->ir_v6_rmt_addr); | 222 | &ireq->ir_v6_rmt_addr); |
221 | fl6.daddr = ireq->ir_v6_rmt_addr; | 223 | fl6.daddr = ireq->ir_v6_rmt_addr; |
222 | err = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); | 224 | rcu_read_lock(); |
225 | err = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt), | ||
226 | np->tclass); | ||
227 | rcu_read_unlock(); | ||
223 | err = net_xmit_eval(err); | 228 | err = net_xmit_eval(err); |
224 | } | 229 | } |
225 | 230 | ||
@@ -387,6 +392,7 @@ static struct sock *dccp_v6_request_recv_sock(const struct sock *sk, | |||
387 | struct inet_request_sock *ireq = inet_rsk(req); | 392 | struct inet_request_sock *ireq = inet_rsk(req); |
388 | struct ipv6_pinfo *newnp; | 393 | struct ipv6_pinfo *newnp; |
389 | const struct ipv6_pinfo *np = inet6_sk(sk); | 394 | const struct ipv6_pinfo *np = inet6_sk(sk); |
395 | struct ipv6_txoptions *opt; | ||
390 | struct inet_sock *newinet; | 396 | struct inet_sock *newinet; |
391 | struct dccp6_sock *newdp6; | 397 | struct dccp6_sock *newdp6; |
392 | struct sock *newsk; | 398 | struct sock *newsk; |
@@ -453,7 +459,7 @@ static struct sock *dccp_v6_request_recv_sock(const struct sock *sk, | |||
453 | * comment in that function for the gory details. -acme | 459 | * comment in that function for the gory details. -acme |
454 | */ | 460 | */ |
455 | 461 | ||
456 | __ip6_dst_store(newsk, dst, NULL, NULL); | 462 | ip6_dst_store(newsk, dst, NULL, NULL); |
457 | newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM | | 463 | newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM | |
458 | NETIF_F_TSO); | 464 | NETIF_F_TSO); |
459 | newdp6 = (struct dccp6_sock *)newsk; | 465 | newdp6 = (struct dccp6_sock *)newsk; |
@@ -488,13 +494,15 @@ static struct sock *dccp_v6_request_recv_sock(const struct sock *sk, | |||
488 | * Yes, keeping reference count would be much more clever, but we make | 494 | * Yes, keeping reference count would be much more clever, but we make |
489 | * one more one thing there: reattach optmem to newsk. | 495 | * one more one thing there: reattach optmem to newsk. |
490 | */ | 496 | */ |
491 | if (np->opt != NULL) | 497 | opt = rcu_dereference(np->opt); |
492 | newnp->opt = ipv6_dup_options(newsk, np->opt); | 498 | if (opt) { |
493 | 499 | opt = ipv6_dup_options(newsk, opt); | |
500 | RCU_INIT_POINTER(newnp->opt, opt); | ||
501 | } | ||
494 | inet_csk(newsk)->icsk_ext_hdr_len = 0; | 502 | inet_csk(newsk)->icsk_ext_hdr_len = 0; |
495 | if (newnp->opt != NULL) | 503 | if (opt) |
496 | inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + | 504 | inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen + |
497 | newnp->opt->opt_flen); | 505 | opt->opt_flen; |
498 | 506 | ||
499 | dccp_sync_mss(newsk, dst_mtu(dst)); | 507 | dccp_sync_mss(newsk, dst_mtu(dst)); |
500 | 508 | ||
@@ -757,6 +765,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
757 | struct ipv6_pinfo *np = inet6_sk(sk); | 765 | struct ipv6_pinfo *np = inet6_sk(sk); |
758 | struct dccp_sock *dp = dccp_sk(sk); | 766 | struct dccp_sock *dp = dccp_sk(sk); |
759 | struct in6_addr *saddr = NULL, *final_p, final; | 767 | struct in6_addr *saddr = NULL, *final_p, final; |
768 | struct ipv6_txoptions *opt; | ||
760 | struct flowi6 fl6; | 769 | struct flowi6 fl6; |
761 | struct dst_entry *dst; | 770 | struct dst_entry *dst; |
762 | int addr_type; | 771 | int addr_type; |
@@ -856,7 +865,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
856 | fl6.fl6_sport = inet->inet_sport; | 865 | fl6.fl6_sport = inet->inet_sport; |
857 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); | 866 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); |
858 | 867 | ||
859 | final_p = fl6_update_dst(&fl6, np->opt, &final); | 868 | opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); |
869 | final_p = fl6_update_dst(&fl6, opt, &final); | ||
860 | 870 | ||
861 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p); | 871 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p); |
862 | if (IS_ERR(dst)) { | 872 | if (IS_ERR(dst)) { |
@@ -873,12 +883,11 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
873 | np->saddr = *saddr; | 883 | np->saddr = *saddr; |
874 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; | 884 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; |
875 | 885 | ||
876 | __ip6_dst_store(sk, dst, NULL, NULL); | 886 | ip6_dst_store(sk, dst, NULL, NULL); |
877 | 887 | ||
878 | icsk->icsk_ext_hdr_len = 0; | 888 | icsk->icsk_ext_hdr_len = 0; |
879 | if (np->opt != NULL) | 889 | if (opt) |
880 | icsk->icsk_ext_hdr_len = (np->opt->opt_flen + | 890 | icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen; |
881 | np->opt->opt_nflen); | ||
882 | 891 | ||
883 | inet->inet_dport = usin->sin6_port; | 892 | inet->inet_dport = usin->sin6_port; |
884 | 893 | ||
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index b5cf13a28009..41e65804ddf5 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -339,8 +339,7 @@ unsigned int dccp_poll(struct file *file, struct socket *sock, | |||
339 | if (sk_stream_is_writeable(sk)) { | 339 | if (sk_stream_is_writeable(sk)) { |
340 | mask |= POLLOUT | POLLWRNORM; | 340 | mask |= POLLOUT | POLLWRNORM; |
341 | } else { /* send SIGIO later */ | 341 | } else { /* send SIGIO later */ |
342 | set_bit(SOCK_ASYNC_NOSPACE, | 342 | sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
343 | &sk->sk_socket->flags); | ||
344 | set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); | 343 | set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); |
345 | 344 | ||
346 | /* Race breaker. If space is freed after | 345 | /* Race breaker. If space is freed after |
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 675cf94e04f8..eebf5ac8ce18 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
@@ -1747,9 +1747,9 @@ static int dn_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, | |||
1747 | } | 1747 | } |
1748 | 1748 | ||
1749 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 1749 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
1750 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 1750 | sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
1751 | sk_wait_event(sk, &timeo, dn_data_ready(sk, queue, flags, target)); | 1751 | sk_wait_event(sk, &timeo, dn_data_ready(sk, queue, flags, target)); |
1752 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 1752 | sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
1753 | finish_wait(sk_sleep(sk), &wait); | 1753 | finish_wait(sk_sleep(sk), &wait); |
1754 | } | 1754 | } |
1755 | 1755 | ||
@@ -2004,10 +2004,10 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) | |||
2004 | } | 2004 | } |
2005 | 2005 | ||
2006 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 2006 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
2007 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 2007 | sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
2008 | sk_wait_event(sk, &timeo, | 2008 | sk_wait_event(sk, &timeo, |
2009 | !dn_queue_too_long(scp, queue, flags)); | 2009 | !dn_queue_too_long(scp, queue, flags)); |
2010 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 2010 | sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
2011 | finish_wait(sk_sleep(sk), &wait); | 2011 | finish_wait(sk_sleep(sk), &wait); |
2012 | continue; | 2012 | continue; |
2013 | } | 2013 | } |
diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c index 4677b6fa6dda..ecc28cff08ab 100644 --- a/net/dns_resolver/dns_query.c +++ b/net/dns_resolver/dns_query.c | |||
@@ -67,7 +67,7 @@ | |||
67 | * Returns the size of the result on success, -ve error code otherwise. | 67 | * Returns the size of the result on success, -ve error code otherwise. |
68 | */ | 68 | */ |
69 | int dns_query(const char *type, const char *name, size_t namelen, | 69 | int dns_query(const char *type, const char *name, size_t namelen, |
70 | const char *options, char **_result, time_t *_expiry) | 70 | const char *options, char **_result, time64_t *_expiry) |
71 | { | 71 | { |
72 | struct key *rkey; | 72 | struct key *rkey; |
73 | const struct user_key_payload *upayload; | 73 | const struct user_key_payload *upayload; |
diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index 35a9788bb3ae..c7d1adca30d8 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c | |||
@@ -312,7 +312,7 @@ static void send_hsr_supervision_frame(struct hsr_port *master, u8 type) | |||
312 | return; | 312 | return; |
313 | 313 | ||
314 | out: | 314 | out: |
315 | WARN_ON_ONCE("HSR: Could not send supervision frame\n"); | 315 | WARN_ONCE(1, "HSR: Could not send supervision frame\n"); |
316 | kfree_skb(skb); | 316 | kfree_skb(skb); |
317 | } | 317 | } |
318 | 318 | ||
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 6baf36e11808..05e4cba14162 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -2126,7 +2126,7 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) | |||
2126 | ASSERT_RTNL(); | 2126 | ASSERT_RTNL(); |
2127 | 2127 | ||
2128 | in_dev = ip_mc_find_dev(net, imr); | 2128 | in_dev = ip_mc_find_dev(net, imr); |
2129 | if (!in_dev) { | 2129 | if (!imr->imr_ifindex && !imr->imr_address.s_addr && !in_dev) { |
2130 | ret = -ENODEV; | 2130 | ret = -ENODEV; |
2131 | goto out; | 2131 | goto out; |
2132 | } | 2132 | } |
@@ -2147,7 +2147,8 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) | |||
2147 | 2147 | ||
2148 | *imlp = iml->next_rcu; | 2148 | *imlp = iml->next_rcu; |
2149 | 2149 | ||
2150 | ip_mc_dec_group(in_dev, group); | 2150 | if (in_dev) |
2151 | ip_mc_dec_group(in_dev, group); | ||
2151 | 2152 | ||
2152 | /* decrease mem now to avoid the memleak warning */ | 2153 | /* decrease mem now to avoid the memleak warning */ |
2153 | atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); | 2154 | atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 92dd4b74d513..c3a38353f5dc 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -134,7 +134,7 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, | |||
134 | struct mfc_cache *c, struct rtmsg *rtm); | 134 | struct mfc_cache *c, struct rtmsg *rtm); |
135 | static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc, | 135 | static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc, |
136 | int cmd); | 136 | int cmd); |
137 | static void mroute_clean_tables(struct mr_table *mrt); | 137 | static void mroute_clean_tables(struct mr_table *mrt, bool all); |
138 | static void ipmr_expire_process(unsigned long arg); | 138 | static void ipmr_expire_process(unsigned long arg); |
139 | 139 | ||
140 | #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES | 140 | #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES |
@@ -350,7 +350,7 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id) | |||
350 | static void ipmr_free_table(struct mr_table *mrt) | 350 | static void ipmr_free_table(struct mr_table *mrt) |
351 | { | 351 | { |
352 | del_timer_sync(&mrt->ipmr_expire_timer); | 352 | del_timer_sync(&mrt->ipmr_expire_timer); |
353 | mroute_clean_tables(mrt); | 353 | mroute_clean_tables(mrt, true); |
354 | kfree(mrt); | 354 | kfree(mrt); |
355 | } | 355 | } |
356 | 356 | ||
@@ -441,10 +441,6 @@ struct net_device *ipmr_new_tunnel(struct net *net, struct vifctl *v) | |||
441 | return dev; | 441 | return dev; |
442 | 442 | ||
443 | failure: | 443 | failure: |
444 | /* allow the register to be completed before unregistering. */ | ||
445 | rtnl_unlock(); | ||
446 | rtnl_lock(); | ||
447 | |||
448 | unregister_netdevice(dev); | 444 | unregister_netdevice(dev); |
449 | return NULL; | 445 | return NULL; |
450 | } | 446 | } |
@@ -540,10 +536,6 @@ static struct net_device *ipmr_reg_vif(struct net *net, struct mr_table *mrt) | |||
540 | return dev; | 536 | return dev; |
541 | 537 | ||
542 | failure: | 538 | failure: |
543 | /* allow the register to be completed before unregistering. */ | ||
544 | rtnl_unlock(); | ||
545 | rtnl_lock(); | ||
546 | |||
547 | unregister_netdevice(dev); | 539 | unregister_netdevice(dev); |
548 | return NULL; | 540 | return NULL; |
549 | } | 541 | } |
@@ -1208,7 +1200,7 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt, | |||
1208 | * Close the multicast socket, and clear the vif tables etc | 1200 | * Close the multicast socket, and clear the vif tables etc |
1209 | */ | 1201 | */ |
1210 | 1202 | ||
1211 | static void mroute_clean_tables(struct mr_table *mrt) | 1203 | static void mroute_clean_tables(struct mr_table *mrt, bool all) |
1212 | { | 1204 | { |
1213 | int i; | 1205 | int i; |
1214 | LIST_HEAD(list); | 1206 | LIST_HEAD(list); |
@@ -1217,8 +1209,9 @@ static void mroute_clean_tables(struct mr_table *mrt) | |||
1217 | /* Shut down all active vif entries */ | 1209 | /* Shut down all active vif entries */ |
1218 | 1210 | ||
1219 | for (i = 0; i < mrt->maxvif; i++) { | 1211 | for (i = 0; i < mrt->maxvif; i++) { |
1220 | if (!(mrt->vif_table[i].flags & VIFF_STATIC)) | 1212 | if (!all && (mrt->vif_table[i].flags & VIFF_STATIC)) |
1221 | vif_delete(mrt, i, 0, &list); | 1213 | continue; |
1214 | vif_delete(mrt, i, 0, &list); | ||
1222 | } | 1215 | } |
1223 | unregister_netdevice_many(&list); | 1216 | unregister_netdevice_many(&list); |
1224 | 1217 | ||
@@ -1226,7 +1219,7 @@ static void mroute_clean_tables(struct mr_table *mrt) | |||
1226 | 1219 | ||
1227 | for (i = 0; i < MFC_LINES; i++) { | 1220 | for (i = 0; i < MFC_LINES; i++) { |
1228 | list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[i], list) { | 1221 | list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[i], list) { |
1229 | if (c->mfc_flags & MFC_STATIC) | 1222 | if (!all && (c->mfc_flags & MFC_STATIC)) |
1230 | continue; | 1223 | continue; |
1231 | list_del_rcu(&c->list); | 1224 | list_del_rcu(&c->list); |
1232 | mroute_netlink_event(mrt, c, RTM_DELROUTE); | 1225 | mroute_netlink_event(mrt, c, RTM_DELROUTE); |
@@ -1261,7 +1254,7 @@ static void mrtsock_destruct(struct sock *sk) | |||
1261 | NETCONFA_IFINDEX_ALL, | 1254 | NETCONFA_IFINDEX_ALL, |
1262 | net->ipv4.devconf_all); | 1255 | net->ipv4.devconf_all); |
1263 | RCU_INIT_POINTER(mrt->mroute_sk, NULL); | 1256 | RCU_INIT_POINTER(mrt->mroute_sk, NULL); |
1264 | mroute_clean_tables(mrt); | 1257 | mroute_clean_tables(mrt, false); |
1265 | } | 1258 | } |
1266 | } | 1259 | } |
1267 | rtnl_unlock(); | 1260 | rtnl_unlock(); |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index c1728771cf89..c82cca18c90f 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -517,8 +517,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
517 | if (sk_stream_is_writeable(sk)) { | 517 | if (sk_stream_is_writeable(sk)) { |
518 | mask |= POLLOUT | POLLWRNORM; | 518 | mask |= POLLOUT | POLLWRNORM; |
519 | } else { /* send SIGIO later */ | 519 | } else { /* send SIGIO later */ |
520 | set_bit(SOCK_ASYNC_NOSPACE, | 520 | sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
521 | &sk->sk_socket->flags); | ||
522 | set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); | 521 | set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); |
523 | 522 | ||
524 | /* Race breaker. If space is freed after | 523 | /* Race breaker. If space is freed after |
@@ -906,7 +905,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset, | |||
906 | goto out_err; | 905 | goto out_err; |
907 | } | 906 | } |
908 | 907 | ||
909 | clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 908 | sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
910 | 909 | ||
911 | mss_now = tcp_send_mss(sk, &size_goal, flags); | 910 | mss_now = tcp_send_mss(sk, &size_goal, flags); |
912 | copied = 0; | 911 | copied = 0; |
@@ -1134,7 +1133,7 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) | |||
1134 | } | 1133 | } |
1135 | 1134 | ||
1136 | /* This should be in poll */ | 1135 | /* This should be in poll */ |
1137 | clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 1136 | sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
1138 | 1137 | ||
1139 | mss_now = tcp_send_mss(sk, &size_goal, flags); | 1138 | mss_now = tcp_send_mss(sk, &size_goal, flags); |
1140 | 1139 | ||
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index fdd88c3803a6..2d656eef7f8e 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -4481,19 +4481,34 @@ static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int | |||
4481 | int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) | 4481 | int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) |
4482 | { | 4482 | { |
4483 | struct sk_buff *skb; | 4483 | struct sk_buff *skb; |
4484 | int err = -ENOMEM; | ||
4485 | int data_len = 0; | ||
4484 | bool fragstolen; | 4486 | bool fragstolen; |
4485 | 4487 | ||
4486 | if (size == 0) | 4488 | if (size == 0) |
4487 | return 0; | 4489 | return 0; |
4488 | 4490 | ||
4489 | skb = alloc_skb(size, sk->sk_allocation); | 4491 | if (size > PAGE_SIZE) { |
4492 | int npages = min_t(size_t, size >> PAGE_SHIFT, MAX_SKB_FRAGS); | ||
4493 | |||
4494 | data_len = npages << PAGE_SHIFT; | ||
4495 | size = data_len + (size & ~PAGE_MASK); | ||
4496 | } | ||
4497 | skb = alloc_skb_with_frags(size - data_len, data_len, | ||
4498 | PAGE_ALLOC_COSTLY_ORDER, | ||
4499 | &err, sk->sk_allocation); | ||
4490 | if (!skb) | 4500 | if (!skb) |
4491 | goto err; | 4501 | goto err; |
4492 | 4502 | ||
4503 | skb_put(skb, size - data_len); | ||
4504 | skb->data_len = data_len; | ||
4505 | skb->len = size; | ||
4506 | |||
4493 | if (tcp_try_rmem_schedule(sk, skb, skb->truesize)) | 4507 | if (tcp_try_rmem_schedule(sk, skb, skb->truesize)) |
4494 | goto err_free; | 4508 | goto err_free; |
4495 | 4509 | ||
4496 | if (memcpy_from_msg(skb_put(skb, size), msg, size)) | 4510 | err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size); |
4511 | if (err) | ||
4497 | goto err_free; | 4512 | goto err_free; |
4498 | 4513 | ||
4499 | TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt; | 4514 | TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt; |
@@ -4509,7 +4524,8 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) | |||
4509 | err_free: | 4524 | err_free: |
4510 | kfree_skb(skb); | 4525 | kfree_skb(skb); |
4511 | err: | 4526 | err: |
4512 | return -ENOMEM; | 4527 | return err; |
4528 | |||
4513 | } | 4529 | } |
4514 | 4530 | ||
4515 | static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) | 4531 | static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) |
@@ -5667,6 +5683,7 @@ discard: | |||
5667 | } | 5683 | } |
5668 | 5684 | ||
5669 | tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; | 5685 | tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; |
5686 | tp->copied_seq = tp->rcv_nxt; | ||
5670 | tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1; | 5687 | tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1; |
5671 | 5688 | ||
5672 | /* RFC1323: The window in SYN & SYN/ACK segments is | 5689 | /* RFC1323: The window in SYN & SYN/ACK segments is |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index ba09016d1bfd..db003438aaf5 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -921,7 +921,8 @@ int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr, | |||
921 | } | 921 | } |
922 | 922 | ||
923 | md5sig = rcu_dereference_protected(tp->md5sig_info, | 923 | md5sig = rcu_dereference_protected(tp->md5sig_info, |
924 | sock_owned_by_user(sk)); | 924 | sock_owned_by_user(sk) || |
925 | lockdep_is_held(&sk->sk_lock.slock)); | ||
925 | if (!md5sig) { | 926 | if (!md5sig) { |
926 | md5sig = kmalloc(sizeof(*md5sig), gfp); | 927 | md5sig = kmalloc(sizeof(*md5sig), gfp); |
927 | if (!md5sig) | 928 | if (!md5sig) |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index c9c716a483e4..193ba1fa8a9a 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -168,7 +168,7 @@ static int tcp_write_timeout(struct sock *sk) | |||
168 | dst_negative_advice(sk); | 168 | dst_negative_advice(sk); |
169 | if (tp->syn_fastopen || tp->syn_data) | 169 | if (tp->syn_fastopen || tp->syn_data) |
170 | tcp_fastopen_cache_set(sk, 0, NULL, true, 0); | 170 | tcp_fastopen_cache_set(sk, 0, NULL, true, 0); |
171 | if (tp->syn_data) | 171 | if (tp->syn_data && icsk->icsk_retransmits == 1) |
172 | NET_INC_STATS_BH(sock_net(sk), | 172 | NET_INC_STATS_BH(sock_net(sk), |
173 | LINUX_MIB_TCPFASTOPENACTIVEFAIL); | 173 | LINUX_MIB_TCPFASTOPENACTIVEFAIL); |
174 | } | 174 | } |
@@ -176,6 +176,18 @@ static int tcp_write_timeout(struct sock *sk) | |||
176 | syn_set = true; | 176 | syn_set = true; |
177 | } else { | 177 | } else { |
178 | if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0, 0)) { | 178 | if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0, 0)) { |
179 | /* Some middle-boxes may black-hole Fast Open _after_ | ||
180 | * the handshake. Therefore we conservatively disable | ||
181 | * Fast Open on this path on recurring timeouts with | ||
182 | * few or zero bytes acked after Fast Open. | ||
183 | */ | ||
184 | if (tp->syn_data_acked && | ||
185 | tp->bytes_acked <= tp->rx_opt.mss_clamp) { | ||
186 | tcp_fastopen_cache_set(sk, 0, NULL, true, 0); | ||
187 | if (icsk->icsk_retransmits == sysctl_tcp_retries1) | ||
188 | NET_INC_STATS_BH(sock_net(sk), | ||
189 | LINUX_MIB_TCPFASTOPENACTIVEFAIL); | ||
190 | } | ||
179 | /* Black hole detection */ | 191 | /* Black hole detection */ |
180 | tcp_mtu_probing(icsk, sk); | 192 | tcp_mtu_probing(icsk, sk); |
181 | 193 | ||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 24ec14f9825c..0c7b0e61b917 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -100,7 +100,6 @@ | |||
100 | #include <linux/slab.h> | 100 | #include <linux/slab.h> |
101 | #include <net/tcp_states.h> | 101 | #include <net/tcp_states.h> |
102 | #include <linux/skbuff.h> | 102 | #include <linux/skbuff.h> |
103 | #include <linux/netdevice.h> | ||
104 | #include <linux/proc_fs.h> | 103 | #include <linux/proc_fs.h> |
105 | #include <linux/seq_file.h> | 104 | #include <linux/seq_file.h> |
106 | #include <net/net_namespace.h> | 105 | #include <net/net_namespace.h> |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d84742f003a9..61f26851655c 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -3642,7 +3642,7 @@ static void addrconf_dad_work(struct work_struct *w) | |||
3642 | 3642 | ||
3643 | /* send a neighbour solicitation for our addr */ | 3643 | /* send a neighbour solicitation for our addr */ |
3644 | addrconf_addr_solict_mult(&ifp->addr, &mcaddr); | 3644 | addrconf_addr_solict_mult(&ifp->addr, &mcaddr); |
3645 | ndisc_send_ns(ifp->idev->dev, &ifp->addr, &mcaddr, &in6addr_any, NULL); | 3645 | ndisc_send_ns(ifp->idev->dev, &ifp->addr, &mcaddr, &in6addr_any); |
3646 | out: | 3646 | out: |
3647 | in6_ifa_put(ifp); | 3647 | in6_ifa_put(ifp); |
3648 | rtnl_unlock(); | 3648 | rtnl_unlock(); |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 44bb66bde0e2..8ec0df75f1c4 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -428,9 +428,11 @@ void inet6_destroy_sock(struct sock *sk) | |||
428 | 428 | ||
429 | /* Free tx options */ | 429 | /* Free tx options */ |
430 | 430 | ||
431 | opt = xchg(&np->opt, NULL); | 431 | opt = xchg((__force struct ipv6_txoptions **)&np->opt, NULL); |
432 | if (opt) | 432 | if (opt) { |
433 | sock_kfree_s(sk, opt, opt->tot_len); | 433 | atomic_sub(opt->tot_len, &sk->sk_omem_alloc); |
434 | txopt_put(opt); | ||
435 | } | ||
434 | } | 436 | } |
435 | EXPORT_SYMBOL_GPL(inet6_destroy_sock); | 437 | EXPORT_SYMBOL_GPL(inet6_destroy_sock); |
436 | 438 | ||
@@ -659,7 +661,10 @@ int inet6_sk_rebuild_header(struct sock *sk) | |||
659 | fl6.fl6_sport = inet->inet_sport; | 661 | fl6.fl6_sport = inet->inet_sport; |
660 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); | 662 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); |
661 | 663 | ||
662 | final_p = fl6_update_dst(&fl6, np->opt, &final); | 664 | rcu_read_lock(); |
665 | final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), | ||
666 | &final); | ||
667 | rcu_read_unlock(); | ||
663 | 668 | ||
664 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p); | 669 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p); |
665 | if (IS_ERR(dst)) { | 670 | if (IS_ERR(dst)) { |
@@ -668,7 +673,7 @@ int inet6_sk_rebuild_header(struct sock *sk) | |||
668 | return PTR_ERR(dst); | 673 | return PTR_ERR(dst); |
669 | } | 674 | } |
670 | 675 | ||
671 | __ip6_dst_store(sk, dst, NULL, NULL); | 676 | ip6_dst_store(sk, dst, NULL, NULL); |
672 | } | 677 | } |
673 | 678 | ||
674 | return 0; | 679 | return 0; |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index d70b0238f468..517c55b01ba8 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -167,8 +167,10 @@ ipv4_connected: | |||
167 | 167 | ||
168 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); | 168 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); |
169 | 169 | ||
170 | opt = flowlabel ? flowlabel->opt : np->opt; | 170 | rcu_read_lock(); |
171 | opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt); | ||
171 | final_p = fl6_update_dst(&fl6, opt, &final); | 172 | final_p = fl6_update_dst(&fl6, opt, &final); |
173 | rcu_read_unlock(); | ||
172 | 174 | ||
173 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p); | 175 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p); |
174 | err = 0; | 176 | err = 0; |
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index ce203b0402be..ea7c4d64a00a 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -727,6 +727,7 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt) | |||
727 | *((char **)&opt2->dst1opt) += dif; | 727 | *((char **)&opt2->dst1opt) += dif; |
728 | if (opt2->srcrt) | 728 | if (opt2->srcrt) |
729 | *((char **)&opt2->srcrt) += dif; | 729 | *((char **)&opt2->srcrt) += dif; |
730 | atomic_set(&opt2->refcnt, 1); | ||
730 | } | 731 | } |
731 | return opt2; | 732 | return opt2; |
732 | } | 733 | } |
@@ -790,7 +791,7 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, | |||
790 | return ERR_PTR(-ENOBUFS); | 791 | return ERR_PTR(-ENOBUFS); |
791 | 792 | ||
792 | memset(opt2, 0, tot_len); | 793 | memset(opt2, 0, tot_len); |
793 | 794 | atomic_set(&opt2->refcnt, 1); | |
794 | opt2->tot_len = tot_len; | 795 | opt2->tot_len = tot_len; |
795 | p = (char *)(opt2 + 1); | 796 | p = (char *)(opt2 + 1); |
796 | 797 | ||
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 36c5a98b0472..0a37ddc7af51 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -834,11 +834,6 @@ void icmpv6_flow_init(struct sock *sk, struct flowi6 *fl6, | |||
834 | security_sk_classify_flow(sk, flowi6_to_flowi(fl6)); | 834 | security_sk_classify_flow(sk, flowi6_to_flowi(fl6)); |
835 | } | 835 | } |
836 | 836 | ||
837 | /* | ||
838 | * Special lock-class for __icmpv6_sk: | ||
839 | */ | ||
840 | static struct lock_class_key icmpv6_socket_sk_dst_lock_key; | ||
841 | |||
842 | static int __net_init icmpv6_sk_init(struct net *net) | 837 | static int __net_init icmpv6_sk_init(struct net *net) |
843 | { | 838 | { |
844 | struct sock *sk; | 839 | struct sock *sk; |
@@ -860,15 +855,6 @@ static int __net_init icmpv6_sk_init(struct net *net) | |||
860 | 855 | ||
861 | net->ipv6.icmp_sk[i] = sk; | 856 | net->ipv6.icmp_sk[i] = sk; |
862 | 857 | ||
863 | /* | ||
864 | * Split off their lock-class, because sk->sk_dst_lock | ||
865 | * gets used from softirqs, which is safe for | ||
866 | * __icmpv6_sk (because those never get directly used | ||
867 | * via userspace syscalls), but unsafe for normal sockets. | ||
868 | */ | ||
869 | lockdep_set_class(&sk->sk_dst_lock, | ||
870 | &icmpv6_socket_sk_dst_lock_key); | ||
871 | |||
872 | /* Enough space for 2 64K ICMP packets, including | 858 | /* Enough space for 2 64K ICMP packets, including |
873 | * sk_buff struct overhead. | 859 | * sk_buff struct overhead. |
874 | */ | 860 | */ |
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 5d1c7cee2cb2..a7ca2cde2ecb 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
@@ -78,7 +78,9 @@ struct dst_entry *inet6_csk_route_req(const struct sock *sk, | |||
78 | memset(fl6, 0, sizeof(*fl6)); | 78 | memset(fl6, 0, sizeof(*fl6)); |
79 | fl6->flowi6_proto = proto; | 79 | fl6->flowi6_proto = proto; |
80 | fl6->daddr = ireq->ir_v6_rmt_addr; | 80 | fl6->daddr = ireq->ir_v6_rmt_addr; |
81 | final_p = fl6_update_dst(fl6, np->opt, &final); | 81 | rcu_read_lock(); |
82 | final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); | ||
83 | rcu_read_unlock(); | ||
82 | fl6->saddr = ireq->ir_v6_loc_addr; | 84 | fl6->saddr = ireq->ir_v6_loc_addr; |
83 | fl6->flowi6_oif = ireq->ir_iif; | 85 | fl6->flowi6_oif = ireq->ir_iif; |
84 | fl6->flowi6_mark = ireq->ir_mark; | 86 | fl6->flowi6_mark = ireq->ir_mark; |
@@ -109,14 +111,6 @@ void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr) | |||
109 | EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr); | 111 | EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr); |
110 | 112 | ||
111 | static inline | 113 | static inline |
112 | void __inet6_csk_dst_store(struct sock *sk, struct dst_entry *dst, | ||
113 | const struct in6_addr *daddr, | ||
114 | const struct in6_addr *saddr) | ||
115 | { | ||
116 | __ip6_dst_store(sk, dst, daddr, saddr); | ||
117 | } | ||
118 | |||
119 | static inline | ||
120 | struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie) | 114 | struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie) |
121 | { | 115 | { |
122 | return __sk_dst_check(sk, cookie); | 116 | return __sk_dst_check(sk, cookie); |
@@ -142,14 +136,16 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk, | |||
142 | fl6->fl6_dport = inet->inet_dport; | 136 | fl6->fl6_dport = inet->inet_dport; |
143 | security_sk_classify_flow(sk, flowi6_to_flowi(fl6)); | 137 | security_sk_classify_flow(sk, flowi6_to_flowi(fl6)); |
144 | 138 | ||
145 | final_p = fl6_update_dst(fl6, np->opt, &final); | 139 | rcu_read_lock(); |
140 | final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); | ||
141 | rcu_read_unlock(); | ||
146 | 142 | ||
147 | dst = __inet6_csk_dst_check(sk, np->dst_cookie); | 143 | dst = __inet6_csk_dst_check(sk, np->dst_cookie); |
148 | if (!dst) { | 144 | if (!dst) { |
149 | dst = ip6_dst_lookup_flow(sk, fl6, final_p); | 145 | dst = ip6_dst_lookup_flow(sk, fl6, final_p); |
150 | 146 | ||
151 | if (!IS_ERR(dst)) | 147 | if (!IS_ERR(dst)) |
152 | __inet6_csk_dst_store(sk, dst, NULL, NULL); | 148 | ip6_dst_store(sk, dst, NULL, NULL); |
153 | } | 149 | } |
154 | return dst; | 150 | return dst; |
155 | } | 151 | } |
@@ -175,7 +171,8 @@ int inet6_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl_unused | |||
175 | /* Restore final destination back after routing done */ | 171 | /* Restore final destination back after routing done */ |
176 | fl6.daddr = sk->sk_v6_daddr; | 172 | fl6.daddr = sk->sk_v6_daddr; |
177 | 173 | ||
178 | res = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); | 174 | res = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt), |
175 | np->tclass); | ||
179 | rcu_read_unlock(); | 176 | rcu_read_unlock(); |
180 | return res; | 177 | return res; |
181 | } | 178 | } |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index eabffbb89795..137fca42aaa6 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -177,7 +177,7 @@ void ip6_tnl_dst_reset(struct ip6_tnl *t) | |||
177 | int i; | 177 | int i; |
178 | 178 | ||
179 | for_each_possible_cpu(i) | 179 | for_each_possible_cpu(i) |
180 | ip6_tnl_per_cpu_dst_set(raw_cpu_ptr(t->dst_cache), NULL); | 180 | ip6_tnl_per_cpu_dst_set(per_cpu_ptr(t->dst_cache, i), NULL); |
181 | } | 181 | } |
182 | EXPORT_SYMBOL_GPL(ip6_tnl_dst_reset); | 182 | EXPORT_SYMBOL_GPL(ip6_tnl_dst_reset); |
183 | 183 | ||
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index ad19136086dd..a10e77103c88 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -118,7 +118,7 @@ static void mr6_netlink_event(struct mr6_table *mrt, struct mfc6_cache *mfc, | |||
118 | int cmd); | 118 | int cmd); |
119 | static int ip6mr_rtm_dumproute(struct sk_buff *skb, | 119 | static int ip6mr_rtm_dumproute(struct sk_buff *skb, |
120 | struct netlink_callback *cb); | 120 | struct netlink_callback *cb); |
121 | static void mroute_clean_tables(struct mr6_table *mrt); | 121 | static void mroute_clean_tables(struct mr6_table *mrt, bool all); |
122 | static void ipmr_expire_process(unsigned long arg); | 122 | static void ipmr_expire_process(unsigned long arg); |
123 | 123 | ||
124 | #ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES | 124 | #ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES |
@@ -334,7 +334,7 @@ static struct mr6_table *ip6mr_new_table(struct net *net, u32 id) | |||
334 | static void ip6mr_free_table(struct mr6_table *mrt) | 334 | static void ip6mr_free_table(struct mr6_table *mrt) |
335 | { | 335 | { |
336 | del_timer_sync(&mrt->ipmr_expire_timer); | 336 | del_timer_sync(&mrt->ipmr_expire_timer); |
337 | mroute_clean_tables(mrt); | 337 | mroute_clean_tables(mrt, true); |
338 | kfree(mrt); | 338 | kfree(mrt); |
339 | } | 339 | } |
340 | 340 | ||
@@ -765,10 +765,6 @@ static struct net_device *ip6mr_reg_vif(struct net *net, struct mr6_table *mrt) | |||
765 | return dev; | 765 | return dev; |
766 | 766 | ||
767 | failure: | 767 | failure: |
768 | /* allow the register to be completed before unregistering. */ | ||
769 | rtnl_unlock(); | ||
770 | rtnl_lock(); | ||
771 | |||
772 | unregister_netdevice(dev); | 768 | unregister_netdevice(dev); |
773 | return NULL; | 769 | return NULL; |
774 | } | 770 | } |
@@ -1542,7 +1538,7 @@ static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt, | |||
1542 | * Close the multicast socket, and clear the vif tables etc | 1538 | * Close the multicast socket, and clear the vif tables etc |
1543 | */ | 1539 | */ |
1544 | 1540 | ||
1545 | static void mroute_clean_tables(struct mr6_table *mrt) | 1541 | static void mroute_clean_tables(struct mr6_table *mrt, bool all) |
1546 | { | 1542 | { |
1547 | int i; | 1543 | int i; |
1548 | LIST_HEAD(list); | 1544 | LIST_HEAD(list); |
@@ -1552,8 +1548,9 @@ static void mroute_clean_tables(struct mr6_table *mrt) | |||
1552 | * Shut down all active vif entries | 1548 | * Shut down all active vif entries |
1553 | */ | 1549 | */ |
1554 | for (i = 0; i < mrt->maxvif; i++) { | 1550 | for (i = 0; i < mrt->maxvif; i++) { |
1555 | if (!(mrt->vif6_table[i].flags & VIFF_STATIC)) | 1551 | if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC)) |
1556 | mif6_delete(mrt, i, &list); | 1552 | continue; |
1553 | mif6_delete(mrt, i, &list); | ||
1557 | } | 1554 | } |
1558 | unregister_netdevice_many(&list); | 1555 | unregister_netdevice_many(&list); |
1559 | 1556 | ||
@@ -1562,7 +1559,7 @@ static void mroute_clean_tables(struct mr6_table *mrt) | |||
1562 | */ | 1559 | */ |
1563 | for (i = 0; i < MFC6_LINES; i++) { | 1560 | for (i = 0; i < MFC6_LINES; i++) { |
1564 | list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[i], list) { | 1561 | list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[i], list) { |
1565 | if (c->mfc_flags & MFC_STATIC) | 1562 | if (!all && (c->mfc_flags & MFC_STATIC)) |
1566 | continue; | 1563 | continue; |
1567 | write_lock_bh(&mrt_lock); | 1564 | write_lock_bh(&mrt_lock); |
1568 | list_del(&c->list); | 1565 | list_del(&c->list); |
@@ -1625,7 +1622,7 @@ int ip6mr_sk_done(struct sock *sk) | |||
1625 | net->ipv6.devconf_all); | 1622 | net->ipv6.devconf_all); |
1626 | write_unlock_bh(&mrt_lock); | 1623 | write_unlock_bh(&mrt_lock); |
1627 | 1624 | ||
1628 | mroute_clean_tables(mrt); | 1625 | mroute_clean_tables(mrt, false); |
1629 | err = 0; | 1626 | err = 0; |
1630 | break; | 1627 | break; |
1631 | } | 1628 | } |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 63e6956917c9..4449ad1f8114 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -111,7 +111,8 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk, | |||
111 | icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie); | 111 | icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie); |
112 | } | 112 | } |
113 | } | 113 | } |
114 | opt = xchg(&inet6_sk(sk)->opt, opt); | 114 | opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt, |
115 | opt); | ||
115 | sk_dst_reset(sk); | 116 | sk_dst_reset(sk); |
116 | 117 | ||
117 | return opt; | 118 | return opt; |
@@ -231,9 +232,12 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
231 | sk->sk_socket->ops = &inet_dgram_ops; | 232 | sk->sk_socket->ops = &inet_dgram_ops; |
232 | sk->sk_family = PF_INET; | 233 | sk->sk_family = PF_INET; |
233 | } | 234 | } |
234 | opt = xchg(&np->opt, NULL); | 235 | opt = xchg((__force struct ipv6_txoptions **)&np->opt, |
235 | if (opt) | 236 | NULL); |
236 | sock_kfree_s(sk, opt, opt->tot_len); | 237 | if (opt) { |
238 | atomic_sub(opt->tot_len, &sk->sk_omem_alloc); | ||
239 | txopt_put(opt); | ||
240 | } | ||
237 | pktopt = xchg(&np->pktoptions, NULL); | 241 | pktopt = xchg(&np->pktoptions, NULL); |
238 | kfree_skb(pktopt); | 242 | kfree_skb(pktopt); |
239 | 243 | ||
@@ -403,7 +407,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
403 | if (optname != IPV6_RTHDR && !ns_capable(net->user_ns, CAP_NET_RAW)) | 407 | if (optname != IPV6_RTHDR && !ns_capable(net->user_ns, CAP_NET_RAW)) |
404 | break; | 408 | break; |
405 | 409 | ||
406 | opt = ipv6_renew_options(sk, np->opt, optname, | 410 | opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); |
411 | opt = ipv6_renew_options(sk, opt, optname, | ||
407 | (struct ipv6_opt_hdr __user *)optval, | 412 | (struct ipv6_opt_hdr __user *)optval, |
408 | optlen); | 413 | optlen); |
409 | if (IS_ERR(opt)) { | 414 | if (IS_ERR(opt)) { |
@@ -432,8 +437,10 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
432 | retv = 0; | 437 | retv = 0; |
433 | opt = ipv6_update_options(sk, opt); | 438 | opt = ipv6_update_options(sk, opt); |
434 | sticky_done: | 439 | sticky_done: |
435 | if (opt) | 440 | if (opt) { |
436 | sock_kfree_s(sk, opt, opt->tot_len); | 441 | atomic_sub(opt->tot_len, &sk->sk_omem_alloc); |
442 | txopt_put(opt); | ||
443 | } | ||
437 | break; | 444 | break; |
438 | } | 445 | } |
439 | 446 | ||
@@ -486,6 +493,7 @@ sticky_done: | |||
486 | break; | 493 | break; |
487 | 494 | ||
488 | memset(opt, 0, sizeof(*opt)); | 495 | memset(opt, 0, sizeof(*opt)); |
496 | atomic_set(&opt->refcnt, 1); | ||
489 | opt->tot_len = sizeof(*opt) + optlen; | 497 | opt->tot_len = sizeof(*opt) + optlen; |
490 | retv = -EFAULT; | 498 | retv = -EFAULT; |
491 | if (copy_from_user(opt+1, optval, optlen)) | 499 | if (copy_from_user(opt+1, optval, optlen)) |
@@ -502,8 +510,10 @@ update: | |||
502 | retv = 0; | 510 | retv = 0; |
503 | opt = ipv6_update_options(sk, opt); | 511 | opt = ipv6_update_options(sk, opt); |
504 | done: | 512 | done: |
505 | if (opt) | 513 | if (opt) { |
506 | sock_kfree_s(sk, opt, opt->tot_len); | 514 | atomic_sub(opt->tot_len, &sk->sk_omem_alloc); |
515 | txopt_put(opt); | ||
516 | } | ||
507 | break; | 517 | break; |
508 | } | 518 | } |
509 | case IPV6_UNICAST_HOPS: | 519 | case IPV6_UNICAST_HOPS: |
@@ -1110,10 +1120,11 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
1110 | case IPV6_RTHDR: | 1120 | case IPV6_RTHDR: |
1111 | case IPV6_DSTOPTS: | 1121 | case IPV6_DSTOPTS: |
1112 | { | 1122 | { |
1123 | struct ipv6_txoptions *opt; | ||
1113 | 1124 | ||
1114 | lock_sock(sk); | 1125 | lock_sock(sk); |
1115 | len = ipv6_getsockopt_sticky(sk, np->opt, | 1126 | opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); |
1116 | optname, optval, len); | 1127 | len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len); |
1117 | release_sock(sk); | 1128 | release_sock(sk); |
1118 | /* check if ipv6_getsockopt_sticky() returns err code */ | 1129 | /* check if ipv6_getsockopt_sticky() returns err code */ |
1119 | if (len < 0) | 1130 | if (len < 0) |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 3e0f855e1bea..d6161e1c48c8 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -556,8 +556,7 @@ static void ndisc_send_unsol_na(struct net_device *dev) | |||
556 | } | 556 | } |
557 | 557 | ||
558 | void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit, | 558 | void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit, |
559 | const struct in6_addr *daddr, const struct in6_addr *saddr, | 559 | const struct in6_addr *daddr, const struct in6_addr *saddr) |
560 | struct sk_buff *oskb) | ||
561 | { | 560 | { |
562 | struct sk_buff *skb; | 561 | struct sk_buff *skb; |
563 | struct in6_addr addr_buf; | 562 | struct in6_addr addr_buf; |
@@ -593,9 +592,6 @@ void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit, | |||
593 | ndisc_fill_addr_option(skb, ND_OPT_SOURCE_LL_ADDR, | 592 | ndisc_fill_addr_option(skb, ND_OPT_SOURCE_LL_ADDR, |
594 | dev->dev_addr); | 593 | dev->dev_addr); |
595 | 594 | ||
596 | if (!(dev->priv_flags & IFF_XMIT_DST_RELEASE) && oskb) | ||
597 | skb_dst_copy(skb, oskb); | ||
598 | |||
599 | ndisc_send_skb(skb, daddr, saddr); | 595 | ndisc_send_skb(skb, daddr, saddr); |
600 | } | 596 | } |
601 | 597 | ||
@@ -682,12 +678,12 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb) | |||
682 | "%s: trying to ucast probe in NUD_INVALID: %pI6\n", | 678 | "%s: trying to ucast probe in NUD_INVALID: %pI6\n", |
683 | __func__, target); | 679 | __func__, target); |
684 | } | 680 | } |
685 | ndisc_send_ns(dev, target, target, saddr, skb); | 681 | ndisc_send_ns(dev, target, target, saddr); |
686 | } else if ((probes -= NEIGH_VAR(neigh->parms, APP_PROBES)) < 0) { | 682 | } else if ((probes -= NEIGH_VAR(neigh->parms, APP_PROBES)) < 0) { |
687 | neigh_app_ns(neigh); | 683 | neigh_app_ns(neigh); |
688 | } else { | 684 | } else { |
689 | addrconf_addr_solict_mult(target, &mcaddr); | 685 | addrconf_addr_solict_mult(target, &mcaddr); |
690 | ndisc_send_ns(dev, target, &mcaddr, saddr, skb); | 686 | ndisc_send_ns(dev, target, &mcaddr, saddr); |
691 | } | 687 | } |
692 | } | 688 | } |
693 | 689 | ||
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index d5efeb87350e..bab4441ed4e4 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
@@ -190,7 +190,7 @@ static void nf_ct_frag6_expire(unsigned long data) | |||
190 | /* Creation primitives. */ | 190 | /* Creation primitives. */ |
191 | static inline struct frag_queue *fq_find(struct net *net, __be32 id, | 191 | static inline struct frag_queue *fq_find(struct net *net, __be32 id, |
192 | u32 user, struct in6_addr *src, | 192 | u32 user, struct in6_addr *src, |
193 | struct in6_addr *dst, u8 ecn) | 193 | struct in6_addr *dst, int iif, u8 ecn) |
194 | { | 194 | { |
195 | struct inet_frag_queue *q; | 195 | struct inet_frag_queue *q; |
196 | struct ip6_create_arg arg; | 196 | struct ip6_create_arg arg; |
@@ -200,6 +200,7 @@ static inline struct frag_queue *fq_find(struct net *net, __be32 id, | |||
200 | arg.user = user; | 200 | arg.user = user; |
201 | arg.src = src; | 201 | arg.src = src; |
202 | arg.dst = dst; | 202 | arg.dst = dst; |
203 | arg.iif = iif; | ||
203 | arg.ecn = ecn; | 204 | arg.ecn = ecn; |
204 | 205 | ||
205 | local_bh_disable(); | 206 | local_bh_disable(); |
@@ -601,7 +602,7 @@ struct sk_buff *nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 use | |||
601 | fhdr = (struct frag_hdr *)skb_transport_header(clone); | 602 | fhdr = (struct frag_hdr *)skb_transport_header(clone); |
602 | 603 | ||
603 | fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr, | 604 | fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr, |
604 | ip6_frag_ecn(hdr)); | 605 | skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr)); |
605 | if (fq == NULL) { | 606 | if (fq == NULL) { |
606 | pr_debug("Can't find and can't create new queue\n"); | 607 | pr_debug("Can't find and can't create new queue\n"); |
607 | goto ret_orig; | 608 | goto ret_orig; |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index dc65ec198f7c..99140986e887 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -733,6 +733,7 @@ static int raw6_getfrag(void *from, char *to, int offset, int len, int odd, | |||
733 | 733 | ||
734 | static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | 734 | static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) |
735 | { | 735 | { |
736 | struct ipv6_txoptions *opt_to_free = NULL; | ||
736 | struct ipv6_txoptions opt_space; | 737 | struct ipv6_txoptions opt_space; |
737 | DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); | 738 | DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); |
738 | struct in6_addr *daddr, *final_p, final; | 739 | struct in6_addr *daddr, *final_p, final; |
@@ -839,8 +840,10 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
839 | if (!(opt->opt_nflen|opt->opt_flen)) | 840 | if (!(opt->opt_nflen|opt->opt_flen)) |
840 | opt = NULL; | 841 | opt = NULL; |
841 | } | 842 | } |
842 | if (!opt) | 843 | if (!opt) { |
843 | opt = np->opt; | 844 | opt = txopt_get(np); |
845 | opt_to_free = opt; | ||
846 | } | ||
844 | if (flowlabel) | 847 | if (flowlabel) |
845 | opt = fl6_merge_options(&opt_space, flowlabel, opt); | 848 | opt = fl6_merge_options(&opt_space, flowlabel, opt); |
846 | opt = ipv6_fixup_options(&opt_space, opt); | 849 | opt = ipv6_fixup_options(&opt_space, opt); |
@@ -906,6 +909,7 @@ done: | |||
906 | dst_release(dst); | 909 | dst_release(dst); |
907 | out: | 910 | out: |
908 | fl6_sock_release(flowlabel); | 911 | fl6_sock_release(flowlabel); |
912 | txopt_put(opt_to_free); | ||
909 | return err < 0 ? err : len; | 913 | return err < 0 ? err : len; |
910 | do_confirm: | 914 | do_confirm: |
911 | dst_confirm(dst); | 915 | dst_confirm(dst); |
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 44e21a03cfc3..45f5ae51de65 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
@@ -108,7 +108,10 @@ bool ip6_frag_match(const struct inet_frag_queue *q, const void *a) | |||
108 | return fq->id == arg->id && | 108 | return fq->id == arg->id && |
109 | fq->user == arg->user && | 109 | fq->user == arg->user && |
110 | ipv6_addr_equal(&fq->saddr, arg->src) && | 110 | ipv6_addr_equal(&fq->saddr, arg->src) && |
111 | ipv6_addr_equal(&fq->daddr, arg->dst); | 111 | ipv6_addr_equal(&fq->daddr, arg->dst) && |
112 | (arg->iif == fq->iif || | ||
113 | !(ipv6_addr_type(arg->dst) & (IPV6_ADDR_MULTICAST | | ||
114 | IPV6_ADDR_LINKLOCAL))); | ||
112 | } | 115 | } |
113 | EXPORT_SYMBOL(ip6_frag_match); | 116 | EXPORT_SYMBOL(ip6_frag_match); |
114 | 117 | ||
@@ -180,7 +183,7 @@ static void ip6_frag_expire(unsigned long data) | |||
180 | 183 | ||
181 | static struct frag_queue * | 184 | static struct frag_queue * |
182 | fq_find(struct net *net, __be32 id, const struct in6_addr *src, | 185 | fq_find(struct net *net, __be32 id, const struct in6_addr *src, |
183 | const struct in6_addr *dst, u8 ecn) | 186 | const struct in6_addr *dst, int iif, u8 ecn) |
184 | { | 187 | { |
185 | struct inet_frag_queue *q; | 188 | struct inet_frag_queue *q; |
186 | struct ip6_create_arg arg; | 189 | struct ip6_create_arg arg; |
@@ -190,6 +193,7 @@ fq_find(struct net *net, __be32 id, const struct in6_addr *src, | |||
190 | arg.user = IP6_DEFRAG_LOCAL_DELIVER; | 193 | arg.user = IP6_DEFRAG_LOCAL_DELIVER; |
191 | arg.src = src; | 194 | arg.src = src; |
192 | arg.dst = dst; | 195 | arg.dst = dst; |
196 | arg.iif = iif; | ||
193 | arg.ecn = ecn; | 197 | arg.ecn = ecn; |
194 | 198 | ||
195 | hash = inet6_hash_frag(id, src, dst); | 199 | hash = inet6_hash_frag(id, src, dst); |
@@ -551,7 +555,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb) | |||
551 | } | 555 | } |
552 | 556 | ||
553 | fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr, | 557 | fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr, |
554 | ip6_frag_ecn(hdr)); | 558 | skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr)); |
555 | if (fq) { | 559 | if (fq) { |
556 | int ret; | 560 | int ret; |
557 | 561 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 6f01fe122abd..826e6aa44f8d 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -523,7 +523,7 @@ static void rt6_probe_deferred(struct work_struct *w) | |||
523 | container_of(w, struct __rt6_probe_work, work); | 523 | container_of(w, struct __rt6_probe_work, work); |
524 | 524 | ||
525 | addrconf_addr_solict_mult(&work->target, &mcaddr); | 525 | addrconf_addr_solict_mult(&work->target, &mcaddr); |
526 | ndisc_send_ns(work->dev, &work->target, &mcaddr, NULL, NULL); | 526 | ndisc_send_ns(work->dev, &work->target, &mcaddr, NULL); |
527 | dev_put(work->dev); | 527 | dev_put(work->dev); |
528 | kfree(work); | 528 | kfree(work); |
529 | } | 529 | } |
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index bb8f2fa1c7fb..eaf7ac496d50 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c | |||
@@ -222,7 +222,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
222 | memset(&fl6, 0, sizeof(fl6)); | 222 | memset(&fl6, 0, sizeof(fl6)); |
223 | fl6.flowi6_proto = IPPROTO_TCP; | 223 | fl6.flowi6_proto = IPPROTO_TCP; |
224 | fl6.daddr = ireq->ir_v6_rmt_addr; | 224 | fl6.daddr = ireq->ir_v6_rmt_addr; |
225 | final_p = fl6_update_dst(&fl6, np->opt, &final); | 225 | final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final); |
226 | fl6.saddr = ireq->ir_v6_loc_addr; | 226 | fl6.saddr = ireq->ir_v6_loc_addr; |
227 | fl6.flowi6_oif = sk->sk_bound_dev_if; | 227 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
228 | fl6.flowi6_mark = ireq->ir_mark; | 228 | fl6.flowi6_mark = ireq->ir_mark; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index c5429a636f1a..e7aab561b7b4 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -120,6 +120,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
120 | struct ipv6_pinfo *np = inet6_sk(sk); | 120 | struct ipv6_pinfo *np = inet6_sk(sk); |
121 | struct tcp_sock *tp = tcp_sk(sk); | 121 | struct tcp_sock *tp = tcp_sk(sk); |
122 | struct in6_addr *saddr = NULL, *final_p, final; | 122 | struct in6_addr *saddr = NULL, *final_p, final; |
123 | struct ipv6_txoptions *opt; | ||
123 | struct flowi6 fl6; | 124 | struct flowi6 fl6; |
124 | struct dst_entry *dst; | 125 | struct dst_entry *dst; |
125 | int addr_type; | 126 | int addr_type; |
@@ -235,7 +236,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
235 | fl6.fl6_dport = usin->sin6_port; | 236 | fl6.fl6_dport = usin->sin6_port; |
236 | fl6.fl6_sport = inet->inet_sport; | 237 | fl6.fl6_sport = inet->inet_sport; |
237 | 238 | ||
238 | final_p = fl6_update_dst(&fl6, np->opt, &final); | 239 | opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); |
240 | final_p = fl6_update_dst(&fl6, opt, &final); | ||
239 | 241 | ||
240 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); | 242 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); |
241 | 243 | ||
@@ -255,7 +257,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
255 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; | 257 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; |
256 | 258 | ||
257 | sk->sk_gso_type = SKB_GSO_TCPV6; | 259 | sk->sk_gso_type = SKB_GSO_TCPV6; |
258 | __ip6_dst_store(sk, dst, NULL, NULL); | 260 | ip6_dst_store(sk, dst, NULL, NULL); |
259 | 261 | ||
260 | if (tcp_death_row.sysctl_tw_recycle && | 262 | if (tcp_death_row.sysctl_tw_recycle && |
261 | !tp->rx_opt.ts_recent_stamp && | 263 | !tp->rx_opt.ts_recent_stamp && |
@@ -263,9 +265,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
263 | tcp_fetch_timewait_stamp(sk, dst); | 265 | tcp_fetch_timewait_stamp(sk, dst); |
264 | 266 | ||
265 | icsk->icsk_ext_hdr_len = 0; | 267 | icsk->icsk_ext_hdr_len = 0; |
266 | if (np->opt) | 268 | if (opt) |
267 | icsk->icsk_ext_hdr_len = (np->opt->opt_flen + | 269 | icsk->icsk_ext_hdr_len = opt->opt_flen + |
268 | np->opt->opt_nflen); | 270 | opt->opt_nflen; |
269 | 271 | ||
270 | tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); | 272 | tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); |
271 | 273 | ||
@@ -461,7 +463,8 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst, | |||
461 | if (np->repflow && ireq->pktopts) | 463 | if (np->repflow && ireq->pktopts) |
462 | fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts)); | 464 | fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts)); |
463 | 465 | ||
464 | err = ip6_xmit(sk, skb, fl6, np->opt, np->tclass); | 466 | err = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt), |
467 | np->tclass); | ||
465 | err = net_xmit_eval(err); | 468 | err = net_xmit_eval(err); |
466 | } | 469 | } |
467 | 470 | ||
@@ -972,6 +975,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff * | |||
972 | struct inet_request_sock *ireq; | 975 | struct inet_request_sock *ireq; |
973 | struct ipv6_pinfo *newnp; | 976 | struct ipv6_pinfo *newnp; |
974 | const struct ipv6_pinfo *np = inet6_sk(sk); | 977 | const struct ipv6_pinfo *np = inet6_sk(sk); |
978 | struct ipv6_txoptions *opt; | ||
975 | struct tcp6_sock *newtcp6sk; | 979 | struct tcp6_sock *newtcp6sk; |
976 | struct inet_sock *newinet; | 980 | struct inet_sock *newinet; |
977 | struct tcp_sock *newtp; | 981 | struct tcp_sock *newtp; |
@@ -1056,7 +1060,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff * | |||
1056 | */ | 1060 | */ |
1057 | 1061 | ||
1058 | newsk->sk_gso_type = SKB_GSO_TCPV6; | 1062 | newsk->sk_gso_type = SKB_GSO_TCPV6; |
1059 | __ip6_dst_store(newsk, dst, NULL, NULL); | 1063 | ip6_dst_store(newsk, dst, NULL, NULL); |
1060 | inet6_sk_rx_dst_set(newsk, skb); | 1064 | inet6_sk_rx_dst_set(newsk, skb); |
1061 | 1065 | ||
1062 | newtcp6sk = (struct tcp6_sock *)newsk; | 1066 | newtcp6sk = (struct tcp6_sock *)newsk; |
@@ -1098,13 +1102,15 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff * | |||
1098 | but we make one more one thing there: reattach optmem | 1102 | but we make one more one thing there: reattach optmem |
1099 | to newsk. | 1103 | to newsk. |
1100 | */ | 1104 | */ |
1101 | if (np->opt) | 1105 | opt = rcu_dereference(np->opt); |
1102 | newnp->opt = ipv6_dup_options(newsk, np->opt); | 1106 | if (opt) { |
1103 | 1107 | opt = ipv6_dup_options(newsk, opt); | |
1108 | RCU_INIT_POINTER(newnp->opt, opt); | ||
1109 | } | ||
1104 | inet_csk(newsk)->icsk_ext_hdr_len = 0; | 1110 | inet_csk(newsk)->icsk_ext_hdr_len = 0; |
1105 | if (newnp->opt) | 1111 | if (opt) |
1106 | inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + | 1112 | inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen + |
1107 | newnp->opt->opt_flen); | 1113 | opt->opt_flen; |
1108 | 1114 | ||
1109 | tcp_ca_openreq_child(newsk, dst); | 1115 | tcp_ca_openreq_child(newsk, dst); |
1110 | 1116 | ||
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 01bcb49619ee..9da3287a3923 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -1110,6 +1110,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
1110 | DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); | 1110 | DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); |
1111 | struct in6_addr *daddr, *final_p, final; | 1111 | struct in6_addr *daddr, *final_p, final; |
1112 | struct ipv6_txoptions *opt = NULL; | 1112 | struct ipv6_txoptions *opt = NULL; |
1113 | struct ipv6_txoptions *opt_to_free = NULL; | ||
1113 | struct ip6_flowlabel *flowlabel = NULL; | 1114 | struct ip6_flowlabel *flowlabel = NULL; |
1114 | struct flowi6 fl6; | 1115 | struct flowi6 fl6; |
1115 | struct dst_entry *dst; | 1116 | struct dst_entry *dst; |
@@ -1263,8 +1264,10 @@ do_udp_sendmsg: | |||
1263 | opt = NULL; | 1264 | opt = NULL; |
1264 | connected = 0; | 1265 | connected = 0; |
1265 | } | 1266 | } |
1266 | if (!opt) | 1267 | if (!opt) { |
1267 | opt = np->opt; | 1268 | opt = txopt_get(np); |
1269 | opt_to_free = opt; | ||
1270 | } | ||
1268 | if (flowlabel) | 1271 | if (flowlabel) |
1269 | opt = fl6_merge_options(&opt_space, flowlabel, opt); | 1272 | opt = fl6_merge_options(&opt_space, flowlabel, opt); |
1270 | opt = ipv6_fixup_options(&opt_space, opt); | 1273 | opt = ipv6_fixup_options(&opt_space, opt); |
@@ -1373,6 +1376,7 @@ release_dst: | |||
1373 | out: | 1376 | out: |
1374 | dst_release(dst); | 1377 | dst_release(dst); |
1375 | fl6_sock_release(flowlabel); | 1378 | fl6_sock_release(flowlabel); |
1379 | txopt_put(opt_to_free); | ||
1376 | if (!err) | 1380 | if (!err) |
1377 | return len; | 1381 | return len; |
1378 | /* | 1382 | /* |
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index fcb2752419c6..435608c4306d 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
@@ -1483,7 +1483,7 @@ unsigned int iucv_sock_poll(struct file *file, struct socket *sock, | |||
1483 | if (sock_writeable(sk) && iucv_below_msglim(sk)) | 1483 | if (sock_writeable(sk) && iucv_below_msglim(sk)) |
1484 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; | 1484 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; |
1485 | else | 1485 | else |
1486 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 1486 | sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
1487 | 1487 | ||
1488 | return mask; | 1488 | return mask; |
1489 | } | 1489 | } |
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index aca38d8aed8e..a2c8747d2936 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c | |||
@@ -486,6 +486,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
486 | DECLARE_SOCKADDR(struct sockaddr_l2tpip6 *, lsa, msg->msg_name); | 486 | DECLARE_SOCKADDR(struct sockaddr_l2tpip6 *, lsa, msg->msg_name); |
487 | struct in6_addr *daddr, *final_p, final; | 487 | struct in6_addr *daddr, *final_p, final; |
488 | struct ipv6_pinfo *np = inet6_sk(sk); | 488 | struct ipv6_pinfo *np = inet6_sk(sk); |
489 | struct ipv6_txoptions *opt_to_free = NULL; | ||
489 | struct ipv6_txoptions *opt = NULL; | 490 | struct ipv6_txoptions *opt = NULL; |
490 | struct ip6_flowlabel *flowlabel = NULL; | 491 | struct ip6_flowlabel *flowlabel = NULL; |
491 | struct dst_entry *dst = NULL; | 492 | struct dst_entry *dst = NULL; |
@@ -575,8 +576,10 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
575 | opt = NULL; | 576 | opt = NULL; |
576 | } | 577 | } |
577 | 578 | ||
578 | if (opt == NULL) | 579 | if (!opt) { |
579 | opt = np->opt; | 580 | opt = txopt_get(np); |
581 | opt_to_free = opt; | ||
582 | } | ||
580 | if (flowlabel) | 583 | if (flowlabel) |
581 | opt = fl6_merge_options(&opt_space, flowlabel, opt); | 584 | opt = fl6_merge_options(&opt_space, flowlabel, opt); |
582 | opt = ipv6_fixup_options(&opt_space, opt); | 585 | opt = ipv6_fixup_options(&opt_space, opt); |
@@ -631,6 +634,7 @@ done: | |||
631 | dst_release(dst); | 634 | dst_release(dst); |
632 | out: | 635 | out: |
633 | fl6_sock_release(flowlabel); | 636 | fl6_sock_release(flowlabel); |
637 | txopt_put(opt_to_free); | ||
634 | 638 | ||
635 | return err < 0 ? err : len; | 639 | return err < 0 ? err : len; |
636 | 640 | ||
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index a758eb84e8f0..ff757181b0a8 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -500,7 +500,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) | |||
500 | /* send AddBA request */ | 500 | /* send AddBA request */ |
501 | ieee80211_send_addba_request(sdata, sta->sta.addr, tid, | 501 | ieee80211_send_addba_request(sdata, sta->sta.addr, tid, |
502 | tid_tx->dialog_token, start_seq_num, | 502 | tid_tx->dialog_token, start_seq_num, |
503 | local->hw.max_tx_aggregation_subframes, | 503 | IEEE80211_MAX_AMPDU_BUF, |
504 | tid_tx->timeout); | 504 | tid_tx->timeout); |
505 | } | 505 | } |
506 | 506 | ||
@@ -926,6 +926,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
926 | amsdu = capab & IEEE80211_ADDBA_PARAM_AMSDU_MASK; | 926 | amsdu = capab & IEEE80211_ADDBA_PARAM_AMSDU_MASK; |
927 | tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; | 927 | tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; |
928 | buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6; | 928 | buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6; |
929 | buf_size = min(buf_size, local->hw.max_tx_aggregation_subframes); | ||
929 | 930 | ||
930 | mutex_lock(&sta->ampdu_mlme.mtx); | 931 | mutex_lock(&sta->ampdu_mlme.mtx); |
931 | 932 | ||
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index c2bd1b6a6922..da471eef07bb 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -3454,8 +3454,12 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | |||
3454 | goto out_unlock; | 3454 | goto out_unlock; |
3455 | } | 3455 | } |
3456 | } else { | 3456 | } else { |
3457 | /* for cookie below */ | 3457 | /* Assign a dummy non-zero cookie, it's not sent to |
3458 | ack_skb = skb; | 3458 | * userspace in this case but we rely on its value |
3459 | * internally in the need_offchan case to distinguish | ||
3460 | * mgmt-tx from remain-on-channel. | ||
3461 | */ | ||
3462 | *cookie = 0xffffffff; | ||
3459 | } | 3463 | } |
3460 | 3464 | ||
3461 | if (!need_offchan) { | 3465 | if (!need_offchan) { |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index d0dc1bfaeec2..c9e325d2e120 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -76,7 +76,8 @@ bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) | |||
76 | void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata, | 76 | void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata, |
77 | bool update_bss) | 77 | bool update_bss) |
78 | { | 78 | { |
79 | if (__ieee80211_recalc_txpower(sdata) || update_bss) | 79 | if (__ieee80211_recalc_txpower(sdata) || |
80 | (update_bss && ieee80211_sdata_running(sdata))) | ||
80 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); | 81 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); |
81 | } | 82 | } |
82 | 83 | ||
@@ -1861,6 +1862,7 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata) | |||
1861 | unregister_netdevice(sdata->dev); | 1862 | unregister_netdevice(sdata->dev); |
1862 | } else { | 1863 | } else { |
1863 | cfg80211_unregister_wdev(&sdata->wdev); | 1864 | cfg80211_unregister_wdev(&sdata->wdev); |
1865 | ieee80211_teardown_sdata(sdata); | ||
1864 | kfree(sdata); | 1866 | kfree(sdata); |
1865 | } | 1867 | } |
1866 | } | 1868 | } |
@@ -1870,7 +1872,6 @@ void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata) | |||
1870 | if (WARN_ON_ONCE(!test_bit(SDATA_STATE_RUNNING, &sdata->state))) | 1872 | if (WARN_ON_ONCE(!test_bit(SDATA_STATE_RUNNING, &sdata->state))) |
1871 | return; | 1873 | return; |
1872 | ieee80211_do_stop(sdata, true); | 1874 | ieee80211_do_stop(sdata, true); |
1873 | ieee80211_teardown_sdata(sdata); | ||
1874 | } | 1875 | } |
1875 | 1876 | ||
1876 | void ieee80211_remove_interfaces(struct ieee80211_local *local) | 1877 | void ieee80211_remove_interfaces(struct ieee80211_local *local) |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 858f6b1cb149..175ffcf7fb06 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -541,8 +541,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, | |||
541 | NL80211_FEATURE_HT_IBSS | | 541 | NL80211_FEATURE_HT_IBSS | |
542 | NL80211_FEATURE_VIF_TXPOWER | | 542 | NL80211_FEATURE_VIF_TXPOWER | |
543 | NL80211_FEATURE_MAC_ON_CREATE | | 543 | NL80211_FEATURE_MAC_ON_CREATE | |
544 | NL80211_FEATURE_USERSPACE_MPM | | 544 | NL80211_FEATURE_USERSPACE_MPM; |
545 | NL80211_FEATURE_FULL_AP_CLIENT_STATE; | ||
546 | 545 | ||
547 | if (!ops->hw_scan) | 546 | if (!ops->hw_scan) |
548 | wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN | | 547 | wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN | |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index b890e225a8f1..b3b44a5dd375 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -779,10 +779,8 @@ void mesh_plink_broken(struct sta_info *sta) | |||
779 | static void mesh_path_node_reclaim(struct rcu_head *rp) | 779 | static void mesh_path_node_reclaim(struct rcu_head *rp) |
780 | { | 780 | { |
781 | struct mpath_node *node = container_of(rp, struct mpath_node, rcu); | 781 | struct mpath_node *node = container_of(rp, struct mpath_node, rcu); |
782 | struct ieee80211_sub_if_data *sdata = node->mpath->sdata; | ||
783 | 782 | ||
784 | del_timer_sync(&node->mpath->timer); | 783 | del_timer_sync(&node->mpath->timer); |
785 | atomic_dec(&sdata->u.mesh.mpaths); | ||
786 | kfree(node->mpath); | 784 | kfree(node->mpath); |
787 | kfree(node); | 785 | kfree(node); |
788 | } | 786 | } |
@@ -790,8 +788,9 @@ static void mesh_path_node_reclaim(struct rcu_head *rp) | |||
790 | /* needs to be called with the corresponding hashwlock taken */ | 788 | /* needs to be called with the corresponding hashwlock taken */ |
791 | static void __mesh_path_del(struct mesh_table *tbl, struct mpath_node *node) | 789 | static void __mesh_path_del(struct mesh_table *tbl, struct mpath_node *node) |
792 | { | 790 | { |
793 | struct mesh_path *mpath; | 791 | struct mesh_path *mpath = node->mpath; |
794 | mpath = node->mpath; | 792 | struct ieee80211_sub_if_data *sdata = node->mpath->sdata; |
793 | |||
795 | spin_lock(&mpath->state_lock); | 794 | spin_lock(&mpath->state_lock); |
796 | mpath->flags |= MESH_PATH_RESOLVING; | 795 | mpath->flags |= MESH_PATH_RESOLVING; |
797 | if (mpath->is_gate) | 796 | if (mpath->is_gate) |
@@ -799,6 +798,7 @@ static void __mesh_path_del(struct mesh_table *tbl, struct mpath_node *node) | |||
799 | hlist_del_rcu(&node->list); | 798 | hlist_del_rcu(&node->list); |
800 | call_rcu(&node->rcu, mesh_path_node_reclaim); | 799 | call_rcu(&node->rcu, mesh_path_node_reclaim); |
801 | spin_unlock(&mpath->state_lock); | 800 | spin_unlock(&mpath->state_lock); |
801 | atomic_dec(&sdata->u.mesh.mpaths); | ||
802 | atomic_dec(&tbl->entries); | 802 | atomic_dec(&tbl->entries); |
803 | } | 803 | } |
804 | 804 | ||
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 4aeca4b0c3cb..a413e52f7691 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -597,8 +597,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
597 | /* We need to ensure power level is at max for scanning. */ | 597 | /* We need to ensure power level is at max for scanning. */ |
598 | ieee80211_hw_config(local, 0); | 598 | ieee80211_hw_config(local, 0); |
599 | 599 | ||
600 | if ((req->channels[0]->flags & | 600 | if ((req->channels[0]->flags & (IEEE80211_CHAN_NO_IR | |
601 | IEEE80211_CHAN_NO_IR) || | 601 | IEEE80211_CHAN_RADAR)) || |
602 | !req->n_ssids) { | 602 | !req->n_ssids) { |
603 | next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; | 603 | next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; |
604 | } else { | 604 | } else { |
@@ -645,7 +645,7 @@ ieee80211_scan_get_channel_time(struct ieee80211_channel *chan) | |||
645 | * TODO: channel switching also consumes quite some time, | 645 | * TODO: channel switching also consumes quite some time, |
646 | * add that delay as well to get a better estimation | 646 | * add that delay as well to get a better estimation |
647 | */ | 647 | */ |
648 | if (chan->flags & IEEE80211_CHAN_NO_IR) | 648 | if (chan->flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR)) |
649 | return IEEE80211_PASSIVE_CHANNEL_TIME; | 649 | return IEEE80211_PASSIVE_CHANNEL_TIME; |
650 | return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME; | 650 | return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME; |
651 | } | 651 | } |
@@ -777,7 +777,8 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local, | |||
777 | * | 777 | * |
778 | * In any case, it is not necessary for a passive scan. | 778 | * In any case, it is not necessary for a passive scan. |
779 | */ | 779 | */ |
780 | if (chan->flags & IEEE80211_CHAN_NO_IR || !scan_req->n_ssids) { | 780 | if ((chan->flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR)) || |
781 | !scan_req->n_ssids) { | ||
781 | *next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; | 782 | *next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; |
782 | local->next_scan_state = SCAN_DECISION; | 783 | local->next_scan_state = SCAN_DECISION; |
783 | return; | 784 | return; |
diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c index b7de0da46acd..ecf0a0196f18 100644 --- a/net/nfc/llcp_sock.c +++ b/net/nfc/llcp_sock.c | |||
@@ -572,7 +572,7 @@ static unsigned int llcp_sock_poll(struct file *file, struct socket *sock, | |||
572 | if (sock_writeable(sk) && sk->sk_state == LLCP_CONNECTED) | 572 | if (sock_writeable(sk) && sk->sk_state == LLCP_CONNECTED) |
573 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; | 573 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; |
574 | else | 574 | else |
575 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 575 | sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
576 | 576 | ||
577 | pr_debug("mask 0x%x\n", mask); | 577 | pr_debug("mask 0x%x\n", mask); |
578 | 578 | ||
diff --git a/net/openvswitch/dp_notify.c b/net/openvswitch/dp_notify.c index a7a80a6b77b0..653d073bae45 100644 --- a/net/openvswitch/dp_notify.c +++ b/net/openvswitch/dp_notify.c | |||
@@ -58,7 +58,7 @@ void ovs_dp_notify_wq(struct work_struct *work) | |||
58 | struct hlist_node *n; | 58 | struct hlist_node *n; |
59 | 59 | ||
60 | hlist_for_each_entry_safe(vport, n, &dp->ports[i], dp_hash_node) { | 60 | hlist_for_each_entry_safe(vport, n, &dp->ports[i], dp_hash_node) { |
61 | if (vport->ops->type != OVS_VPORT_TYPE_NETDEV) | 61 | if (vport->ops->type == OVS_VPORT_TYPE_INTERNAL) |
62 | continue; | 62 | continue; |
63 | 63 | ||
64 | if (!(vport->dev->priv_flags & IFF_OVS_DATAPATH)) | 64 | if (!(vport->dev->priv_flags & IFF_OVS_DATAPATH)) |
diff --git a/net/openvswitch/vport-geneve.c b/net/openvswitch/vport-geneve.c index efb736bb6855..e41cd12d9b2d 100644 --- a/net/openvswitch/vport-geneve.c +++ b/net/openvswitch/vport-geneve.c | |||
@@ -117,7 +117,6 @@ static struct vport_ops ovs_geneve_vport_ops = { | |||
117 | .destroy = ovs_netdev_tunnel_destroy, | 117 | .destroy = ovs_netdev_tunnel_destroy, |
118 | .get_options = geneve_get_options, | 118 | .get_options = geneve_get_options, |
119 | .send = dev_queue_xmit, | 119 | .send = dev_queue_xmit, |
120 | .owner = THIS_MODULE, | ||
121 | }; | 120 | }; |
122 | 121 | ||
123 | static int __init ovs_geneve_tnl_init(void) | 122 | static int __init ovs_geneve_tnl_init(void) |
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c index c3257d78d3d2..7f8897f33a67 100644 --- a/net/openvswitch/vport-gre.c +++ b/net/openvswitch/vport-gre.c | |||
@@ -89,7 +89,6 @@ static struct vport_ops ovs_gre_vport_ops = { | |||
89 | .create = gre_create, | 89 | .create = gre_create, |
90 | .send = dev_queue_xmit, | 90 | .send = dev_queue_xmit, |
91 | .destroy = ovs_netdev_tunnel_destroy, | 91 | .destroy = ovs_netdev_tunnel_destroy, |
92 | .owner = THIS_MODULE, | ||
93 | }; | 92 | }; |
94 | 93 | ||
95 | static int __init ovs_gre_tnl_init(void) | 94 | static int __init ovs_gre_tnl_init(void) |
diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c index b327368a3848..6b0190b987ec 100644 --- a/net/openvswitch/vport-netdev.c +++ b/net/openvswitch/vport-netdev.c | |||
@@ -180,9 +180,13 @@ void ovs_netdev_tunnel_destroy(struct vport *vport) | |||
180 | if (vport->dev->priv_flags & IFF_OVS_DATAPATH) | 180 | if (vport->dev->priv_flags & IFF_OVS_DATAPATH) |
181 | ovs_netdev_detach_dev(vport); | 181 | ovs_netdev_detach_dev(vport); |
182 | 182 | ||
183 | /* Early release so we can unregister the device */ | 183 | /* We can be invoked by both explicit vport deletion and |
184 | * underlying netdev deregistration; delete the link only | ||
185 | * if it's not already shutting down. | ||
186 | */ | ||
187 | if (vport->dev->reg_state == NETREG_REGISTERED) | ||
188 | rtnl_delete_link(vport->dev); | ||
184 | dev_put(vport->dev); | 189 | dev_put(vport->dev); |
185 | rtnl_delete_link(vport->dev); | ||
186 | vport->dev = NULL; | 190 | vport->dev = NULL; |
187 | rtnl_unlock(); | 191 | rtnl_unlock(); |
188 | 192 | ||
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index 0ac0fd004d7e..31cbc8c5c7db 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c | |||
@@ -71,7 +71,7 @@ static struct hlist_head *hash_bucket(const struct net *net, const char *name) | |||
71 | return &dev_table[hash & (VPORT_HASH_BUCKETS - 1)]; | 71 | return &dev_table[hash & (VPORT_HASH_BUCKETS - 1)]; |
72 | } | 72 | } |
73 | 73 | ||
74 | int ovs_vport_ops_register(struct vport_ops *ops) | 74 | int __ovs_vport_ops_register(struct vport_ops *ops) |
75 | { | 75 | { |
76 | int err = -EEXIST; | 76 | int err = -EEXIST; |
77 | struct vport_ops *o; | 77 | struct vport_ops *o; |
@@ -87,7 +87,7 @@ errout: | |||
87 | ovs_unlock(); | 87 | ovs_unlock(); |
88 | return err; | 88 | return err; |
89 | } | 89 | } |
90 | EXPORT_SYMBOL_GPL(ovs_vport_ops_register); | 90 | EXPORT_SYMBOL_GPL(__ovs_vport_ops_register); |
91 | 91 | ||
92 | void ovs_vport_ops_unregister(struct vport_ops *ops) | 92 | void ovs_vport_ops_unregister(struct vport_ops *ops) |
93 | { | 93 | { |
@@ -256,8 +256,8 @@ int ovs_vport_set_options(struct vport *vport, struct nlattr *options) | |||
256 | * | 256 | * |
257 | * @vport: vport to delete. | 257 | * @vport: vport to delete. |
258 | * | 258 | * |
259 | * Detaches @vport from its datapath and destroys it. It is possible to fail | 259 | * Detaches @vport from its datapath and destroys it. ovs_mutex must |
260 | * for reasons such as lack of memory. ovs_mutex must be held. | 260 | * be held. |
261 | */ | 261 | */ |
262 | void ovs_vport_del(struct vport *vport) | 262 | void ovs_vport_del(struct vport *vport) |
263 | { | 263 | { |
diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h index bdfd82a7c064..8ea3a96980ac 100644 --- a/net/openvswitch/vport.h +++ b/net/openvswitch/vport.h | |||
@@ -196,7 +196,13 @@ static inline const char *ovs_vport_name(struct vport *vport) | |||
196 | return vport->dev->name; | 196 | return vport->dev->name; |
197 | } | 197 | } |
198 | 198 | ||
199 | int ovs_vport_ops_register(struct vport_ops *ops); | 199 | int __ovs_vport_ops_register(struct vport_ops *ops); |
200 | #define ovs_vport_ops_register(ops) \ | ||
201 | ({ \ | ||
202 | (ops)->owner = THIS_MODULE; \ | ||
203 | __ovs_vport_ops_register(ops); \ | ||
204 | }) | ||
205 | |||
200 | void ovs_vport_ops_unregister(struct vport_ops *ops); | 206 | void ovs_vport_ops_unregister(struct vport_ops *ops); |
201 | 207 | ||
202 | static inline struct rtable *ovs_tunnel_route_lookup(struct net *net, | 208 | static inline struct rtable *ovs_tunnel_route_lookup(struct net *net, |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 1cf928fb573e..992396aa635c 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -2329,8 +2329,8 @@ static void tpacket_destruct_skb(struct sk_buff *skb) | |||
2329 | static bool ll_header_truncated(const struct net_device *dev, int len) | 2329 | static bool ll_header_truncated(const struct net_device *dev, int len) |
2330 | { | 2330 | { |
2331 | /* net device doesn't like empty head */ | 2331 | /* net device doesn't like empty head */ |
2332 | if (unlikely(len <= dev->hard_header_len)) { | 2332 | if (unlikely(len < dev->hard_header_len)) { |
2333 | net_warn_ratelimited("%s: packet size is too short (%d <= %d)\n", | 2333 | net_warn_ratelimited("%s: packet size is too short (%d < %d)\n", |
2334 | current->comm, len, dev->hard_header_len); | 2334 | current->comm, len, dev->hard_header_len); |
2335 | return true; | 2335 | return true; |
2336 | } | 2336 | } |
diff --git a/net/rds/connection.c b/net/rds/connection.c index d4564036a339..e3b118cae81d 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c | |||
@@ -186,12 +186,6 @@ static struct rds_connection *__rds_conn_create(struct net *net, | |||
186 | } | 186 | } |
187 | } | 187 | } |
188 | 188 | ||
189 | if (trans == NULL) { | ||
190 | kmem_cache_free(rds_conn_slab, conn); | ||
191 | conn = ERR_PTR(-ENODEV); | ||
192 | goto out; | ||
193 | } | ||
194 | |||
195 | conn->c_trans = trans; | 189 | conn->c_trans = trans; |
196 | 190 | ||
197 | ret = trans->conn_alloc(conn, gfp); | 191 | ret = trans->conn_alloc(conn, gfp); |
diff --git a/net/rds/send.c b/net/rds/send.c index 827155c2ead1..c9cdb358ea88 100644 --- a/net/rds/send.c +++ b/net/rds/send.c | |||
@@ -1013,11 +1013,13 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len) | |||
1013 | release_sock(sk); | 1013 | release_sock(sk); |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | /* racing with another thread binding seems ok here */ | 1016 | lock_sock(sk); |
1017 | if (daddr == 0 || rs->rs_bound_addr == 0) { | 1017 | if (daddr == 0 || rs->rs_bound_addr == 0) { |
1018 | release_sock(sk); | ||
1018 | ret = -ENOTCONN; /* XXX not a great errno */ | 1019 | ret = -ENOTCONN; /* XXX not a great errno */ |
1019 | goto out; | 1020 | goto out; |
1020 | } | 1021 | } |
1022 | release_sock(sk); | ||
1021 | 1023 | ||
1022 | if (payload_len > rds_sk_sndbuf(rs)) { | 1024 | if (payload_len > rds_sk_sndbuf(rs)) { |
1023 | ret = -EMSGSIZE; | 1025 | ret = -EMSGSIZE; |
diff --git a/net/rxrpc/ar-ack.c b/net/rxrpc/ar-ack.c index e0547f521f20..adc555e0323d 100644 --- a/net/rxrpc/ar-ack.c +++ b/net/rxrpc/ar-ack.c | |||
@@ -723,8 +723,10 @@ process_further: | |||
723 | 723 | ||
724 | if ((call->state == RXRPC_CALL_CLIENT_AWAIT_REPLY || | 724 | if ((call->state == RXRPC_CALL_CLIENT_AWAIT_REPLY || |
725 | call->state == RXRPC_CALL_SERVER_AWAIT_ACK) && | 725 | call->state == RXRPC_CALL_SERVER_AWAIT_ACK) && |
726 | hard > tx) | 726 | hard > tx) { |
727 | call->acks_hard = tx; | ||
727 | goto all_acked; | 728 | goto all_acked; |
729 | } | ||
728 | 730 | ||
729 | smp_rmb(); | 731 | smp_rmb(); |
730 | rxrpc_rotate_tx_window(call, hard - 1); | 732 | rxrpc_rotate_tx_window(call, hard - 1); |
diff --git a/net/rxrpc/ar-output.c b/net/rxrpc/ar-output.c index a40d3afe93b7..14c4e12c47b0 100644 --- a/net/rxrpc/ar-output.c +++ b/net/rxrpc/ar-output.c | |||
@@ -531,7 +531,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx, | |||
531 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); | 531 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); |
532 | 532 | ||
533 | /* this should be in poll */ | 533 | /* this should be in poll */ |
534 | clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 534 | sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
535 | 535 | ||
536 | if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) | 536 | if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) |
537 | return -EPIPE; | 537 | return -EPIPE; |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index f43c8f33f09e..7ec667dd4ce1 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -253,7 +253,8 @@ int qdisc_set_default(const char *name) | |||
253 | } | 253 | } |
254 | 254 | ||
255 | /* We know handle. Find qdisc among all qdisc's attached to device | 255 | /* We know handle. Find qdisc among all qdisc's attached to device |
256 | (root qdisc, all its children, children of children etc.) | 256 | * (root qdisc, all its children, children of children etc.) |
257 | * Note: caller either uses rtnl or rcu_read_lock() | ||
257 | */ | 258 | */ |
258 | 259 | ||
259 | static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle) | 260 | static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle) |
@@ -264,7 +265,7 @@ static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle) | |||
264 | root->handle == handle) | 265 | root->handle == handle) |
265 | return root; | 266 | return root; |
266 | 267 | ||
267 | list_for_each_entry(q, &root->list, list) { | 268 | list_for_each_entry_rcu(q, &root->list, list) { |
268 | if (q->handle == handle) | 269 | if (q->handle == handle) |
269 | return q; | 270 | return q; |
270 | } | 271 | } |
@@ -277,15 +278,18 @@ void qdisc_list_add(struct Qdisc *q) | |||
277 | struct Qdisc *root = qdisc_dev(q)->qdisc; | 278 | struct Qdisc *root = qdisc_dev(q)->qdisc; |
278 | 279 | ||
279 | WARN_ON_ONCE(root == &noop_qdisc); | 280 | WARN_ON_ONCE(root == &noop_qdisc); |
280 | list_add_tail(&q->list, &root->list); | 281 | ASSERT_RTNL(); |
282 | list_add_tail_rcu(&q->list, &root->list); | ||
281 | } | 283 | } |
282 | } | 284 | } |
283 | EXPORT_SYMBOL(qdisc_list_add); | 285 | EXPORT_SYMBOL(qdisc_list_add); |
284 | 286 | ||
285 | void qdisc_list_del(struct Qdisc *q) | 287 | void qdisc_list_del(struct Qdisc *q) |
286 | { | 288 | { |
287 | if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) | 289 | if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) { |
288 | list_del(&q->list); | 290 | ASSERT_RTNL(); |
291 | list_del_rcu(&q->list); | ||
292 | } | ||
289 | } | 293 | } |
290 | EXPORT_SYMBOL(qdisc_list_del); | 294 | EXPORT_SYMBOL(qdisc_list_del); |
291 | 295 | ||
@@ -750,14 +754,18 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n) | |||
750 | if (n == 0) | 754 | if (n == 0) |
751 | return; | 755 | return; |
752 | drops = max_t(int, n, 0); | 756 | drops = max_t(int, n, 0); |
757 | rcu_read_lock(); | ||
753 | while ((parentid = sch->parent)) { | 758 | while ((parentid = sch->parent)) { |
754 | if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS)) | 759 | if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS)) |
755 | return; | 760 | break; |
756 | 761 | ||
762 | if (sch->flags & TCQ_F_NOPARENT) | ||
763 | break; | ||
764 | /* TODO: perform the search on a per txq basis */ | ||
757 | sch = qdisc_lookup(qdisc_dev(sch), TC_H_MAJ(parentid)); | 765 | sch = qdisc_lookup(qdisc_dev(sch), TC_H_MAJ(parentid)); |
758 | if (sch == NULL) { | 766 | if (sch == NULL) { |
759 | WARN_ON(parentid != TC_H_ROOT); | 767 | WARN_ON_ONCE(parentid != TC_H_ROOT); |
760 | return; | 768 | break; |
761 | } | 769 | } |
762 | cops = sch->ops->cl_ops; | 770 | cops = sch->ops->cl_ops; |
763 | if (cops->qlen_notify) { | 771 | if (cops->qlen_notify) { |
@@ -768,6 +776,7 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n) | |||
768 | sch->q.qlen -= n; | 776 | sch->q.qlen -= n; |
769 | __qdisc_qstats_drop(sch, drops); | 777 | __qdisc_qstats_drop(sch, drops); |
770 | } | 778 | } |
779 | rcu_read_unlock(); | ||
771 | } | 780 | } |
772 | EXPORT_SYMBOL(qdisc_tree_decrease_qlen); | 781 | EXPORT_SYMBOL(qdisc_tree_decrease_qlen); |
773 | 782 | ||
@@ -941,7 +950,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue, | |||
941 | } | 950 | } |
942 | lockdep_set_class(qdisc_lock(sch), &qdisc_tx_lock); | 951 | lockdep_set_class(qdisc_lock(sch), &qdisc_tx_lock); |
943 | if (!netif_is_multiqueue(dev)) | 952 | if (!netif_is_multiqueue(dev)) |
944 | sch->flags |= TCQ_F_ONETXQUEUE; | 953 | sch->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; |
945 | } | 954 | } |
946 | 955 | ||
947 | sch->handle = handle; | 956 | sch->handle = handle; |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index cb5d4ad32946..e82a1ad80aa5 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -737,7 +737,7 @@ static void attach_one_default_qdisc(struct net_device *dev, | |||
737 | return; | 737 | return; |
738 | } | 738 | } |
739 | if (!netif_is_multiqueue(dev)) | 739 | if (!netif_is_multiqueue(dev)) |
740 | qdisc->flags |= TCQ_F_ONETXQUEUE; | 740 | qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; |
741 | dev_queue->qdisc_sleeping = qdisc; | 741 | dev_queue->qdisc_sleeping = qdisc; |
742 | } | 742 | } |
743 | 743 | ||
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c index f3cbaecd283a..3e82f047caaf 100644 --- a/net/sched/sch_mq.c +++ b/net/sched/sch_mq.c | |||
@@ -63,7 +63,7 @@ static int mq_init(struct Qdisc *sch, struct nlattr *opt) | |||
63 | if (qdisc == NULL) | 63 | if (qdisc == NULL) |
64 | goto err; | 64 | goto err; |
65 | priv->qdiscs[ntx] = qdisc; | 65 | priv->qdiscs[ntx] = qdisc; |
66 | qdisc->flags |= TCQ_F_ONETXQUEUE; | 66 | qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; |
67 | } | 67 | } |
68 | 68 | ||
69 | sch->flags |= TCQ_F_MQROOT; | 69 | sch->flags |= TCQ_F_MQROOT; |
@@ -156,7 +156,7 @@ static int mq_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new, | |||
156 | 156 | ||
157 | *old = dev_graft_qdisc(dev_queue, new); | 157 | *old = dev_graft_qdisc(dev_queue, new); |
158 | if (new) | 158 | if (new) |
159 | new->flags |= TCQ_F_ONETXQUEUE; | 159 | new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; |
160 | if (dev->flags & IFF_UP) | 160 | if (dev->flags & IFF_UP) |
161 | dev_activate(dev); | 161 | dev_activate(dev); |
162 | return 0; | 162 | return 0; |
diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c index 3811a745452c..ad70ecf57ce7 100644 --- a/net/sched/sch_mqprio.c +++ b/net/sched/sch_mqprio.c | |||
@@ -132,7 +132,7 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt) | |||
132 | goto err; | 132 | goto err; |
133 | } | 133 | } |
134 | priv->qdiscs[i] = qdisc; | 134 | priv->qdiscs[i] = qdisc; |
135 | qdisc->flags |= TCQ_F_ONETXQUEUE; | 135 | qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; |
136 | } | 136 | } |
137 | 137 | ||
138 | /* If the mqprio options indicate that hardware should own | 138 | /* If the mqprio options indicate that hardware should own |
@@ -209,7 +209,7 @@ static int mqprio_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new, | |||
209 | *old = dev_graft_qdisc(dev_queue, new); | 209 | *old = dev_graft_qdisc(dev_queue, new); |
210 | 210 | ||
211 | if (new) | 211 | if (new) |
212 | new->flags |= TCQ_F_ONETXQUEUE; | 212 | new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; |
213 | 213 | ||
214 | if (dev->flags & IFF_UP) | 214 | if (dev->flags & IFF_UP) |
215 | dev_activate(dev); | 215 | dev_activate(dev); |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index e917d27328ea..acb45b8c2a9d 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -209,6 +209,7 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport) | |||
209 | struct sock *sk = skb->sk; | 209 | struct sock *sk = skb->sk; |
210 | struct ipv6_pinfo *np = inet6_sk(sk); | 210 | struct ipv6_pinfo *np = inet6_sk(sk); |
211 | struct flowi6 *fl6 = &transport->fl.u.ip6; | 211 | struct flowi6 *fl6 = &transport->fl.u.ip6; |
212 | int res; | ||
212 | 213 | ||
213 | pr_debug("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", __func__, skb, | 214 | pr_debug("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", __func__, skb, |
214 | skb->len, &fl6->saddr, &fl6->daddr); | 215 | skb->len, &fl6->saddr, &fl6->daddr); |
@@ -220,7 +221,10 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport) | |||
220 | 221 | ||
221 | SCTP_INC_STATS(sock_net(sk), SCTP_MIB_OUTSCTPPACKS); | 222 | SCTP_INC_STATS(sock_net(sk), SCTP_MIB_OUTSCTPPACKS); |
222 | 223 | ||
223 | return ip6_xmit(sk, skb, fl6, np->opt, np->tclass); | 224 | rcu_read_lock(); |
225 | res = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt), np->tclass); | ||
226 | rcu_read_unlock(); | ||
227 | return res; | ||
224 | } | 228 | } |
225 | 229 | ||
226 | /* Returns the dst cache entry for the given source and destination ip | 230 | /* Returns the dst cache entry for the given source and destination ip |
@@ -262,7 +266,10 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, | |||
262 | pr_debug("src=%pI6 - ", &fl6->saddr); | 266 | pr_debug("src=%pI6 - ", &fl6->saddr); |
263 | } | 267 | } |
264 | 268 | ||
265 | final_p = fl6_update_dst(fl6, np->opt, &final); | 269 | rcu_read_lock(); |
270 | final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); | ||
271 | rcu_read_unlock(); | ||
272 | |||
266 | dst = ip6_dst_lookup_flow(sk, fl6, final_p); | 273 | dst = ip6_dst_lookup_flow(sk, fl6, final_p); |
267 | if (!asoc || saddr) | 274 | if (!asoc || saddr) |
268 | goto out; | 275 | goto out; |
@@ -321,7 +328,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, | |||
321 | if (baddr) { | 328 | if (baddr) { |
322 | fl6->saddr = baddr->v6.sin6_addr; | 329 | fl6->saddr = baddr->v6.sin6_addr; |
323 | fl6->fl6_sport = baddr->v6.sin6_port; | 330 | fl6->fl6_sport = baddr->v6.sin6_port; |
324 | final_p = fl6_update_dst(fl6, np->opt, &final); | 331 | final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); |
325 | dst = ip6_dst_lookup_flow(sk, fl6, final_p); | 332 | dst = ip6_dst_lookup_flow(sk, fl6, final_p); |
326 | } | 333 | } |
327 | 334 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 897c01c029ca..03c8256063ec 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -972,7 +972,7 @@ static int sctp_setsockopt_bindx(struct sock *sk, | |||
972 | return -EFAULT; | 972 | return -EFAULT; |
973 | 973 | ||
974 | /* Alloc space for the address array in kernel memory. */ | 974 | /* Alloc space for the address array in kernel memory. */ |
975 | kaddrs = kmalloc(addrs_size, GFP_KERNEL); | 975 | kaddrs = kmalloc(addrs_size, GFP_USER | __GFP_NOWARN); |
976 | if (unlikely(!kaddrs)) | 976 | if (unlikely(!kaddrs)) |
977 | return -ENOMEM; | 977 | return -ENOMEM; |
978 | 978 | ||
@@ -4928,7 +4928,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
4928 | to = optval + offsetof(struct sctp_getaddrs, addrs); | 4928 | to = optval + offsetof(struct sctp_getaddrs, addrs); |
4929 | space_left = len - offsetof(struct sctp_getaddrs, addrs); | 4929 | space_left = len - offsetof(struct sctp_getaddrs, addrs); |
4930 | 4930 | ||
4931 | addrs = kmalloc(space_left, GFP_KERNEL); | 4931 | addrs = kmalloc(space_left, GFP_USER | __GFP_NOWARN); |
4932 | if (!addrs) | 4932 | if (!addrs) |
4933 | return -ENOMEM; | 4933 | return -ENOMEM; |
4934 | 4934 | ||
@@ -6458,7 +6458,7 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
6458 | if (sctp_writeable(sk)) { | 6458 | if (sctp_writeable(sk)) { |
6459 | mask |= POLLOUT | POLLWRNORM; | 6459 | mask |= POLLOUT | POLLWRNORM; |
6460 | } else { | 6460 | } else { |
6461 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 6461 | sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
6462 | /* | 6462 | /* |
6463 | * Since the socket is not locked, the buffer | 6463 | * Since the socket is not locked, the buffer |
6464 | * might be made available after the writeable check and | 6464 | * might be made available after the writeable check and |
@@ -6801,26 +6801,30 @@ no_packet: | |||
6801 | static void __sctp_write_space(struct sctp_association *asoc) | 6801 | static void __sctp_write_space(struct sctp_association *asoc) |
6802 | { | 6802 | { |
6803 | struct sock *sk = asoc->base.sk; | 6803 | struct sock *sk = asoc->base.sk; |
6804 | struct socket *sock = sk->sk_socket; | ||
6805 | 6804 | ||
6806 | if ((sctp_wspace(asoc) > 0) && sock) { | 6805 | if (sctp_wspace(asoc) <= 0) |
6807 | if (waitqueue_active(&asoc->wait)) | 6806 | return; |
6808 | wake_up_interruptible(&asoc->wait); | 6807 | |
6808 | if (waitqueue_active(&asoc->wait)) | ||
6809 | wake_up_interruptible(&asoc->wait); | ||
6809 | 6810 | ||
6810 | if (sctp_writeable(sk)) { | 6811 | if (sctp_writeable(sk)) { |
6811 | wait_queue_head_t *wq = sk_sleep(sk); | 6812 | struct socket_wq *wq; |
6812 | 6813 | ||
6813 | if (wq && waitqueue_active(wq)) | 6814 | rcu_read_lock(); |
6814 | wake_up_interruptible(wq); | 6815 | wq = rcu_dereference(sk->sk_wq); |
6816 | if (wq) { | ||
6817 | if (waitqueue_active(&wq->wait)) | ||
6818 | wake_up_interruptible(&wq->wait); | ||
6815 | 6819 | ||
6816 | /* Note that we try to include the Async I/O support | 6820 | /* Note that we try to include the Async I/O support |
6817 | * here by modeling from the current TCP/UDP code. | 6821 | * here by modeling from the current TCP/UDP code. |
6818 | * We have not tested with it yet. | 6822 | * We have not tested with it yet. |
6819 | */ | 6823 | */ |
6820 | if (!(sk->sk_shutdown & SEND_SHUTDOWN)) | 6824 | if (!(sk->sk_shutdown & SEND_SHUTDOWN)) |
6821 | sock_wake_async(sock, | 6825 | sock_wake_async(wq, SOCK_WAKE_SPACE, POLL_OUT); |
6822 | SOCK_WAKE_SPACE, POLL_OUT); | ||
6823 | } | 6826 | } |
6827 | rcu_read_unlock(); | ||
6824 | } | 6828 | } |
6825 | } | 6829 | } |
6826 | 6830 | ||
@@ -7375,6 +7379,13 @@ struct proto sctp_prot = { | |||
7375 | 7379 | ||
7376 | #if IS_ENABLED(CONFIG_IPV6) | 7380 | #if IS_ENABLED(CONFIG_IPV6) |
7377 | 7381 | ||
7382 | #include <net/transp_v6.h> | ||
7383 | static void sctp_v6_destroy_sock(struct sock *sk) | ||
7384 | { | ||
7385 | sctp_destroy_sock(sk); | ||
7386 | inet6_destroy_sock(sk); | ||
7387 | } | ||
7388 | |||
7378 | struct proto sctpv6_prot = { | 7389 | struct proto sctpv6_prot = { |
7379 | .name = "SCTPv6", | 7390 | .name = "SCTPv6", |
7380 | .owner = THIS_MODULE, | 7391 | .owner = THIS_MODULE, |
@@ -7384,7 +7395,7 @@ struct proto sctpv6_prot = { | |||
7384 | .accept = sctp_accept, | 7395 | .accept = sctp_accept, |
7385 | .ioctl = sctp_ioctl, | 7396 | .ioctl = sctp_ioctl, |
7386 | .init = sctp_init_sock, | 7397 | .init = sctp_init_sock, |
7387 | .destroy = sctp_destroy_sock, | 7398 | .destroy = sctp_v6_destroy_sock, |
7388 | .shutdown = sctp_shutdown, | 7399 | .shutdown = sctp_shutdown, |
7389 | .setsockopt = sctp_setsockopt, | 7400 | .setsockopt = sctp_setsockopt, |
7390 | .getsockopt = sctp_getsockopt, | 7401 | .getsockopt = sctp_getsockopt, |
diff --git a/net/socket.c b/net/socket.c index dd2c247c99e3..456fadb3d819 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -1056,27 +1056,20 @@ static int sock_fasync(int fd, struct file *filp, int on) | |||
1056 | return 0; | 1056 | return 0; |
1057 | } | 1057 | } |
1058 | 1058 | ||
1059 | /* This function may be called only under socket lock or callback_lock or rcu_lock */ | 1059 | /* This function may be called only under rcu_lock */ |
1060 | 1060 | ||
1061 | int sock_wake_async(struct socket *sock, int how, int band) | 1061 | int sock_wake_async(struct socket_wq *wq, int how, int band) |
1062 | { | 1062 | { |
1063 | struct socket_wq *wq; | 1063 | if (!wq || !wq->fasync_list) |
1064 | |||
1065 | if (!sock) | ||
1066 | return -1; | ||
1067 | rcu_read_lock(); | ||
1068 | wq = rcu_dereference(sock->wq); | ||
1069 | if (!wq || !wq->fasync_list) { | ||
1070 | rcu_read_unlock(); | ||
1071 | return -1; | 1064 | return -1; |
1072 | } | 1065 | |
1073 | switch (how) { | 1066 | switch (how) { |
1074 | case SOCK_WAKE_WAITD: | 1067 | case SOCK_WAKE_WAITD: |
1075 | if (test_bit(SOCK_ASYNC_WAITDATA, &sock->flags)) | 1068 | if (test_bit(SOCKWQ_ASYNC_WAITDATA, &wq->flags)) |
1076 | break; | 1069 | break; |
1077 | goto call_kill; | 1070 | goto call_kill; |
1078 | case SOCK_WAKE_SPACE: | 1071 | case SOCK_WAKE_SPACE: |
1079 | if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags)) | 1072 | if (!test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags)) |
1080 | break; | 1073 | break; |
1081 | /* fall through */ | 1074 | /* fall through */ |
1082 | case SOCK_WAKE_IO: | 1075 | case SOCK_WAKE_IO: |
@@ -1086,7 +1079,7 @@ call_kill: | |||
1086 | case SOCK_WAKE_URG: | 1079 | case SOCK_WAKE_URG: |
1087 | kill_fasync(&wq->fasync_list, SIGURG, band); | 1080 | kill_fasync(&wq->fasync_list, SIGURG, band); |
1088 | } | 1081 | } |
1089 | rcu_read_unlock(); | 1082 | |
1090 | return 0; | 1083 | return 0; |
1091 | } | 1084 | } |
1092 | EXPORT_SYMBOL(sock_wake_async); | 1085 | EXPORT_SYMBOL(sock_wake_async); |
diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c index 229956bf8457..95f82d8d4888 100644 --- a/net/sunrpc/backchannel_rqst.c +++ b/net/sunrpc/backchannel_rqst.c | |||
@@ -353,12 +353,20 @@ void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied) | |||
353 | { | 353 | { |
354 | struct rpc_xprt *xprt = req->rq_xprt; | 354 | struct rpc_xprt *xprt = req->rq_xprt; |
355 | struct svc_serv *bc_serv = xprt->bc_serv; | 355 | struct svc_serv *bc_serv = xprt->bc_serv; |
356 | struct xdr_buf *rq_rcv_buf = &req->rq_rcv_buf; | ||
356 | 357 | ||
357 | spin_lock(&xprt->bc_pa_lock); | 358 | spin_lock(&xprt->bc_pa_lock); |
358 | list_del(&req->rq_bc_pa_list); | 359 | list_del(&req->rq_bc_pa_list); |
359 | xprt_dec_alloc_count(xprt, 1); | 360 | xprt_dec_alloc_count(xprt, 1); |
360 | spin_unlock(&xprt->bc_pa_lock); | 361 | spin_unlock(&xprt->bc_pa_lock); |
361 | 362 | ||
363 | if (copied <= rq_rcv_buf->head[0].iov_len) { | ||
364 | rq_rcv_buf->head[0].iov_len = copied; | ||
365 | rq_rcv_buf->page_len = 0; | ||
366 | } else { | ||
367 | rq_rcv_buf->page_len = copied - rq_rcv_buf->head[0].iov_len; | ||
368 | } | ||
369 | |||
362 | req->rq_private_buf.len = copied; | 370 | req->rq_private_buf.len = copied; |
363 | set_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state); | 371 | set_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state); |
364 | 372 | ||
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index bc5b7b5032ca..7fccf9675df8 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -1363,6 +1363,7 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req, | |||
1363 | memcpy(&rqstp->rq_addr, &req->rq_xprt->addr, rqstp->rq_addrlen); | 1363 | memcpy(&rqstp->rq_addr, &req->rq_xprt->addr, rqstp->rq_addrlen); |
1364 | memcpy(&rqstp->rq_arg, &req->rq_rcv_buf, sizeof(rqstp->rq_arg)); | 1364 | memcpy(&rqstp->rq_arg, &req->rq_rcv_buf, sizeof(rqstp->rq_arg)); |
1365 | memcpy(&rqstp->rq_res, &req->rq_snd_buf, sizeof(rqstp->rq_res)); | 1365 | memcpy(&rqstp->rq_res, &req->rq_snd_buf, sizeof(rqstp->rq_res)); |
1366 | rqstp->rq_arg.len = req->rq_private_buf.len; | ||
1366 | 1367 | ||
1367 | /* reset result send buffer "put" position */ | 1368 | /* reset result send buffer "put" position */ |
1368 | resv->iov_len = 0; | 1369 | resv->iov_len = 0; |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 1d1a70498910..2ffaf6a79499 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -398,7 +398,7 @@ static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, | |||
398 | if (unlikely(!sock)) | 398 | if (unlikely(!sock)) |
399 | return -ENOTSOCK; | 399 | return -ENOTSOCK; |
400 | 400 | ||
401 | clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags); | 401 | clear_bit(SOCKWQ_ASYNC_NOSPACE, &sock->flags); |
402 | if (base != 0) { | 402 | if (base != 0) { |
403 | addr = NULL; | 403 | addr = NULL; |
404 | addrlen = 0; | 404 | addrlen = 0; |
@@ -442,7 +442,7 @@ static void xs_nospace_callback(struct rpc_task *task) | |||
442 | struct sock_xprt *transport = container_of(task->tk_rqstp->rq_xprt, struct sock_xprt, xprt); | 442 | struct sock_xprt *transport = container_of(task->tk_rqstp->rq_xprt, struct sock_xprt, xprt); |
443 | 443 | ||
444 | transport->inet->sk_write_pending--; | 444 | transport->inet->sk_write_pending--; |
445 | clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); | 445 | clear_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags); |
446 | } | 446 | } |
447 | 447 | ||
448 | /** | 448 | /** |
@@ -467,7 +467,7 @@ static int xs_nospace(struct rpc_task *task) | |||
467 | 467 | ||
468 | /* Don't race with disconnect */ | 468 | /* Don't race with disconnect */ |
469 | if (xprt_connected(xprt)) { | 469 | if (xprt_connected(xprt)) { |
470 | if (test_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags)) { | 470 | if (test_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags)) { |
471 | /* | 471 | /* |
472 | * Notify TCP that we're limited by the application | 472 | * Notify TCP that we're limited by the application |
473 | * window size | 473 | * window size |
@@ -478,7 +478,7 @@ static int xs_nospace(struct rpc_task *task) | |||
478 | xprt_wait_for_buffer_space(task, xs_nospace_callback); | 478 | xprt_wait_for_buffer_space(task, xs_nospace_callback); |
479 | } | 479 | } |
480 | } else { | 480 | } else { |
481 | clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); | 481 | clear_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags); |
482 | ret = -ENOTCONN; | 482 | ret = -ENOTCONN; |
483 | } | 483 | } |
484 | 484 | ||
@@ -626,7 +626,7 @@ process_status: | |||
626 | case -EPERM: | 626 | case -EPERM: |
627 | /* When the server has died, an ICMP port unreachable message | 627 | /* When the server has died, an ICMP port unreachable message |
628 | * prompts ECONNREFUSED. */ | 628 | * prompts ECONNREFUSED. */ |
629 | clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); | 629 | clear_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags); |
630 | } | 630 | } |
631 | 631 | ||
632 | return status; | 632 | return status; |
@@ -715,7 +715,7 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
715 | case -EADDRINUSE: | 715 | case -EADDRINUSE: |
716 | case -ENOBUFS: | 716 | case -ENOBUFS: |
717 | case -EPIPE: | 717 | case -EPIPE: |
718 | clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); | 718 | clear_bit(SOCKWQ_ASYNC_NOSPACE, &transport->sock->flags); |
719 | } | 719 | } |
720 | 720 | ||
721 | return status; | 721 | return status; |
@@ -1618,7 +1618,7 @@ static void xs_write_space(struct sock *sk) | |||
1618 | 1618 | ||
1619 | if (unlikely(!(xprt = xprt_from_sock(sk)))) | 1619 | if (unlikely(!(xprt = xprt_from_sock(sk)))) |
1620 | return; | 1620 | return; |
1621 | if (test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags) == 0) | 1621 | if (test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &sock->flags) == 0) |
1622 | return; | 1622 | return; |
1623 | 1623 | ||
1624 | xprt_write_space(xprt); | 1624 | xprt_write_space(xprt); |
diff --git a/net/tipc/link.c b/net/tipc/link.c index 9efbdbde2b08..91aea071ab27 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -191,6 +191,7 @@ void tipc_link_add_bc_peer(struct tipc_link *snd_l, | |||
191 | 191 | ||
192 | snd_l->ackers++; | 192 | snd_l->ackers++; |
193 | rcv_l->acked = snd_l->snd_nxt - 1; | 193 | rcv_l->acked = snd_l->snd_nxt - 1; |
194 | snd_l->state = LINK_ESTABLISHED; | ||
194 | tipc_link_build_bc_init_msg(uc_l, xmitq); | 195 | tipc_link_build_bc_init_msg(uc_l, xmitq); |
195 | } | 196 | } |
196 | 197 | ||
@@ -206,6 +207,7 @@ void tipc_link_remove_bc_peer(struct tipc_link *snd_l, | |||
206 | rcv_l->state = LINK_RESET; | 207 | rcv_l->state = LINK_RESET; |
207 | if (!snd_l->ackers) { | 208 | if (!snd_l->ackers) { |
208 | tipc_link_reset(snd_l); | 209 | tipc_link_reset(snd_l); |
210 | snd_l->state = LINK_RESET; | ||
209 | __skb_queue_purge(xmitq); | 211 | __skb_queue_purge(xmitq); |
210 | } | 212 | } |
211 | } | 213 | } |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 552dbaba9cf3..b53246fb0412 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -105,6 +105,7 @@ struct tipc_sock { | |||
105 | static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb); | 105 | static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb); |
106 | static void tipc_data_ready(struct sock *sk); | 106 | static void tipc_data_ready(struct sock *sk); |
107 | static void tipc_write_space(struct sock *sk); | 107 | static void tipc_write_space(struct sock *sk); |
108 | static void tipc_sock_destruct(struct sock *sk); | ||
108 | static int tipc_release(struct socket *sock); | 109 | static int tipc_release(struct socket *sock); |
109 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags); | 110 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags); |
110 | static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p); | 111 | static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p); |
@@ -381,6 +382,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock, | |||
381 | sk->sk_rcvbuf = sysctl_tipc_rmem[1]; | 382 | sk->sk_rcvbuf = sysctl_tipc_rmem[1]; |
382 | sk->sk_data_ready = tipc_data_ready; | 383 | sk->sk_data_ready = tipc_data_ready; |
383 | sk->sk_write_space = tipc_write_space; | 384 | sk->sk_write_space = tipc_write_space; |
385 | sk->sk_destruct = tipc_sock_destruct; | ||
384 | tsk->conn_timeout = CONN_TIMEOUT_DEFAULT; | 386 | tsk->conn_timeout = CONN_TIMEOUT_DEFAULT; |
385 | tsk->sent_unacked = 0; | 387 | tsk->sent_unacked = 0; |
386 | atomic_set(&tsk->dupl_rcvcnt, 0); | 388 | atomic_set(&tsk->dupl_rcvcnt, 0); |
@@ -470,9 +472,6 @@ static int tipc_release(struct socket *sock) | |||
470 | tipc_node_remove_conn(net, dnode, tsk->portid); | 472 | tipc_node_remove_conn(net, dnode, tsk->portid); |
471 | } | 473 | } |
472 | 474 | ||
473 | /* Discard any remaining (connection-based) messages in receive queue */ | ||
474 | __skb_queue_purge(&sk->sk_receive_queue); | ||
475 | |||
476 | /* Reject any messages that accumulated in backlog queue */ | 475 | /* Reject any messages that accumulated in backlog queue */ |
477 | sock->state = SS_DISCONNECTING; | 476 | sock->state = SS_DISCONNECTING; |
478 | release_sock(sk); | 477 | release_sock(sk); |
@@ -1515,6 +1514,11 @@ static void tipc_data_ready(struct sock *sk) | |||
1515 | rcu_read_unlock(); | 1514 | rcu_read_unlock(); |
1516 | } | 1515 | } |
1517 | 1516 | ||
1517 | static void tipc_sock_destruct(struct sock *sk) | ||
1518 | { | ||
1519 | __skb_queue_purge(&sk->sk_receive_queue); | ||
1520 | } | ||
1521 | |||
1518 | /** | 1522 | /** |
1519 | * filter_connect - Handle all incoming messages for a connection-based socket | 1523 | * filter_connect - Handle all incoming messages for a connection-based socket |
1520 | * @tsk: TIPC socket | 1524 | * @tsk: TIPC socket |
diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c index ad2719ad4c1b..70c03271b798 100644 --- a/net/tipc/udp_media.c +++ b/net/tipc/udp_media.c | |||
@@ -158,8 +158,11 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb, | |||
158 | struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value; | 158 | struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value; |
159 | struct rtable *rt; | 159 | struct rtable *rt; |
160 | 160 | ||
161 | if (skb_headroom(skb) < UDP_MIN_HEADROOM) | 161 | if (skb_headroom(skb) < UDP_MIN_HEADROOM) { |
162 | pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC); | 162 | err = pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC); |
163 | if (err) | ||
164 | goto tx_error; | ||
165 | } | ||
163 | 166 | ||
164 | skb_set_inner_protocol(skb, htons(ETH_P_TIPC)); | 167 | skb_set_inner_protocol(skb, htons(ETH_P_TIPC)); |
165 | ub = rcu_dereference_rtnl(b->media_ptr); | 168 | ub = rcu_dereference_rtnl(b->media_ptr); |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 955ec152cb71..45aebd966978 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -326,6 +326,118 @@ found: | |||
326 | return s; | 326 | return s; |
327 | } | 327 | } |
328 | 328 | ||
329 | /* Support code for asymmetrically connected dgram sockets | ||
330 | * | ||
331 | * If a datagram socket is connected to a socket not itself connected | ||
332 | * to the first socket (eg, /dev/log), clients may only enqueue more | ||
333 | * messages if the present receive queue of the server socket is not | ||
334 | * "too large". This means there's a second writeability condition | ||
335 | * poll and sendmsg need to test. The dgram recv code will do a wake | ||
336 | * up on the peer_wait wait queue of a socket upon reception of a | ||
337 | * datagram which needs to be propagated to sleeping would-be writers | ||
338 | * since these might not have sent anything so far. This can't be | ||
339 | * accomplished via poll_wait because the lifetime of the server | ||
340 | * socket might be less than that of its clients if these break their | ||
341 | * association with it or if the server socket is closed while clients | ||
342 | * are still connected to it and there's no way to inform "a polling | ||
343 | * implementation" that it should let go of a certain wait queue | ||
344 | * | ||
345 | * In order to propagate a wake up, a wait_queue_t of the client | ||
346 | * socket is enqueued on the peer_wait queue of the server socket | ||
347 | * whose wake function does a wake_up on the ordinary client socket | ||
348 | * wait queue. This connection is established whenever a write (or | ||
349 | * poll for write) hit the flow control condition and broken when the | ||
350 | * association to the server socket is dissolved or after a wake up | ||
351 | * was relayed. | ||
352 | */ | ||
353 | |||
354 | static int unix_dgram_peer_wake_relay(wait_queue_t *q, unsigned mode, int flags, | ||
355 | void *key) | ||
356 | { | ||
357 | struct unix_sock *u; | ||
358 | wait_queue_head_t *u_sleep; | ||
359 | |||
360 | u = container_of(q, struct unix_sock, peer_wake); | ||
361 | |||
362 | __remove_wait_queue(&unix_sk(u->peer_wake.private)->peer_wait, | ||
363 | q); | ||
364 | u->peer_wake.private = NULL; | ||
365 | |||
366 | /* relaying can only happen while the wq still exists */ | ||
367 | u_sleep = sk_sleep(&u->sk); | ||
368 | if (u_sleep) | ||
369 | wake_up_interruptible_poll(u_sleep, key); | ||
370 | |||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other) | ||
375 | { | ||
376 | struct unix_sock *u, *u_other; | ||
377 | int rc; | ||
378 | |||
379 | u = unix_sk(sk); | ||
380 | u_other = unix_sk(other); | ||
381 | rc = 0; | ||
382 | spin_lock(&u_other->peer_wait.lock); | ||
383 | |||
384 | if (!u->peer_wake.private) { | ||
385 | u->peer_wake.private = other; | ||
386 | __add_wait_queue(&u_other->peer_wait, &u->peer_wake); | ||
387 | |||
388 | rc = 1; | ||
389 | } | ||
390 | |||
391 | spin_unlock(&u_other->peer_wait.lock); | ||
392 | return rc; | ||
393 | } | ||
394 | |||
395 | static void unix_dgram_peer_wake_disconnect(struct sock *sk, | ||
396 | struct sock *other) | ||
397 | { | ||
398 | struct unix_sock *u, *u_other; | ||
399 | |||
400 | u = unix_sk(sk); | ||
401 | u_other = unix_sk(other); | ||
402 | spin_lock(&u_other->peer_wait.lock); | ||
403 | |||
404 | if (u->peer_wake.private == other) { | ||
405 | __remove_wait_queue(&u_other->peer_wait, &u->peer_wake); | ||
406 | u->peer_wake.private = NULL; | ||
407 | } | ||
408 | |||
409 | spin_unlock(&u_other->peer_wait.lock); | ||
410 | } | ||
411 | |||
412 | static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk, | ||
413 | struct sock *other) | ||
414 | { | ||
415 | unix_dgram_peer_wake_disconnect(sk, other); | ||
416 | wake_up_interruptible_poll(sk_sleep(sk), | ||
417 | POLLOUT | | ||
418 | POLLWRNORM | | ||
419 | POLLWRBAND); | ||
420 | } | ||
421 | |||
422 | /* preconditions: | ||
423 | * - unix_peer(sk) == other | ||
424 | * - association is stable | ||
425 | */ | ||
426 | static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other) | ||
427 | { | ||
428 | int connected; | ||
429 | |||
430 | connected = unix_dgram_peer_wake_connect(sk, other); | ||
431 | |||
432 | if (unix_recvq_full(other)) | ||
433 | return 1; | ||
434 | |||
435 | if (connected) | ||
436 | unix_dgram_peer_wake_disconnect(sk, other); | ||
437 | |||
438 | return 0; | ||
439 | } | ||
440 | |||
329 | static int unix_writable(const struct sock *sk) | 441 | static int unix_writable(const struct sock *sk) |
330 | { | 442 | { |
331 | return sk->sk_state != TCP_LISTEN && | 443 | return sk->sk_state != TCP_LISTEN && |
@@ -431,6 +543,8 @@ static void unix_release_sock(struct sock *sk, int embrion) | |||
431 | skpair->sk_state_change(skpair); | 543 | skpair->sk_state_change(skpair); |
432 | sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP); | 544 | sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP); |
433 | } | 545 | } |
546 | |||
547 | unix_dgram_peer_wake_disconnect(sk, skpair); | ||
434 | sock_put(skpair); /* It may now die */ | 548 | sock_put(skpair); /* It may now die */ |
435 | unix_peer(sk) = NULL; | 549 | unix_peer(sk) = NULL; |
436 | } | 550 | } |
@@ -666,6 +780,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern) | |||
666 | INIT_LIST_HEAD(&u->link); | 780 | INIT_LIST_HEAD(&u->link); |
667 | mutex_init(&u->readlock); /* single task reading lock */ | 781 | mutex_init(&u->readlock); /* single task reading lock */ |
668 | init_waitqueue_head(&u->peer_wait); | 782 | init_waitqueue_head(&u->peer_wait); |
783 | init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay); | ||
669 | unix_insert_socket(unix_sockets_unbound(sk), sk); | 784 | unix_insert_socket(unix_sockets_unbound(sk), sk); |
670 | out: | 785 | out: |
671 | if (sk == NULL) | 786 | if (sk == NULL) |
@@ -1033,6 +1148,8 @@ restart: | |||
1033 | if (unix_peer(sk)) { | 1148 | if (unix_peer(sk)) { |
1034 | struct sock *old_peer = unix_peer(sk); | 1149 | struct sock *old_peer = unix_peer(sk); |
1035 | unix_peer(sk) = other; | 1150 | unix_peer(sk) = other; |
1151 | unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer); | ||
1152 | |||
1036 | unix_state_double_unlock(sk, other); | 1153 | unix_state_double_unlock(sk, other); |
1037 | 1154 | ||
1038 | if (other != old_peer) | 1155 | if (other != old_peer) |
@@ -1434,6 +1551,14 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen | |||
1434 | return err; | 1551 | return err; |
1435 | } | 1552 | } |
1436 | 1553 | ||
1554 | static bool unix_passcred_enabled(const struct socket *sock, | ||
1555 | const struct sock *other) | ||
1556 | { | ||
1557 | return test_bit(SOCK_PASSCRED, &sock->flags) || | ||
1558 | !other->sk_socket || | ||
1559 | test_bit(SOCK_PASSCRED, &other->sk_socket->flags); | ||
1560 | } | ||
1561 | |||
1437 | /* | 1562 | /* |
1438 | * Some apps rely on write() giving SCM_CREDENTIALS | 1563 | * Some apps rely on write() giving SCM_CREDENTIALS |
1439 | * We include credentials if source or destination socket | 1564 | * We include credentials if source or destination socket |
@@ -1444,14 +1569,41 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock, | |||
1444 | { | 1569 | { |
1445 | if (UNIXCB(skb).pid) | 1570 | if (UNIXCB(skb).pid) |
1446 | return; | 1571 | return; |
1447 | if (test_bit(SOCK_PASSCRED, &sock->flags) || | 1572 | if (unix_passcred_enabled(sock, other)) { |
1448 | !other->sk_socket || | ||
1449 | test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) { | ||
1450 | UNIXCB(skb).pid = get_pid(task_tgid(current)); | 1573 | UNIXCB(skb).pid = get_pid(task_tgid(current)); |
1451 | current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid); | 1574 | current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid); |
1452 | } | 1575 | } |
1453 | } | 1576 | } |
1454 | 1577 | ||
1578 | static int maybe_init_creds(struct scm_cookie *scm, | ||
1579 | struct socket *socket, | ||
1580 | const struct sock *other) | ||
1581 | { | ||
1582 | int err; | ||
1583 | struct msghdr msg = { .msg_controllen = 0 }; | ||
1584 | |||
1585 | err = scm_send(socket, &msg, scm, false); | ||
1586 | if (err) | ||
1587 | return err; | ||
1588 | |||
1589 | if (unix_passcred_enabled(socket, other)) { | ||
1590 | scm->pid = get_pid(task_tgid(current)); | ||
1591 | current_uid_gid(&scm->creds.uid, &scm->creds.gid); | ||
1592 | } | ||
1593 | return err; | ||
1594 | } | ||
1595 | |||
1596 | static bool unix_skb_scm_eq(struct sk_buff *skb, | ||
1597 | struct scm_cookie *scm) | ||
1598 | { | ||
1599 | const struct unix_skb_parms *u = &UNIXCB(skb); | ||
1600 | |||
1601 | return u->pid == scm->pid && | ||
1602 | uid_eq(u->uid, scm->creds.uid) && | ||
1603 | gid_eq(u->gid, scm->creds.gid) && | ||
1604 | unix_secdata_eq(scm, skb); | ||
1605 | } | ||
1606 | |||
1455 | /* | 1607 | /* |
1456 | * Send AF_UNIX data. | 1608 | * Send AF_UNIX data. |
1457 | */ | 1609 | */ |
@@ -1472,6 +1624,7 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1472 | struct scm_cookie scm; | 1624 | struct scm_cookie scm; |
1473 | int max_level; | 1625 | int max_level; |
1474 | int data_len = 0; | 1626 | int data_len = 0; |
1627 | int sk_locked; | ||
1475 | 1628 | ||
1476 | wait_for_unix_gc(); | 1629 | wait_for_unix_gc(); |
1477 | err = scm_send(sock, msg, &scm, false); | 1630 | err = scm_send(sock, msg, &scm, false); |
@@ -1550,12 +1703,14 @@ restart: | |||
1550 | goto out_free; | 1703 | goto out_free; |
1551 | } | 1704 | } |
1552 | 1705 | ||
1706 | sk_locked = 0; | ||
1553 | unix_state_lock(other); | 1707 | unix_state_lock(other); |
1708 | restart_locked: | ||
1554 | err = -EPERM; | 1709 | err = -EPERM; |
1555 | if (!unix_may_send(sk, other)) | 1710 | if (!unix_may_send(sk, other)) |
1556 | goto out_unlock; | 1711 | goto out_unlock; |
1557 | 1712 | ||
1558 | if (sock_flag(other, SOCK_DEAD)) { | 1713 | if (unlikely(sock_flag(other, SOCK_DEAD))) { |
1559 | /* | 1714 | /* |
1560 | * Check with 1003.1g - what should | 1715 | * Check with 1003.1g - what should |
1561 | * datagram error | 1716 | * datagram error |
@@ -1563,10 +1718,14 @@ restart: | |||
1563 | unix_state_unlock(other); | 1718 | unix_state_unlock(other); |
1564 | sock_put(other); | 1719 | sock_put(other); |
1565 | 1720 | ||
1721 | if (!sk_locked) | ||
1722 | unix_state_lock(sk); | ||
1723 | |||
1566 | err = 0; | 1724 | err = 0; |
1567 | unix_state_lock(sk); | ||
1568 | if (unix_peer(sk) == other) { | 1725 | if (unix_peer(sk) == other) { |
1569 | unix_peer(sk) = NULL; | 1726 | unix_peer(sk) = NULL; |
1727 | unix_dgram_peer_wake_disconnect_wakeup(sk, other); | ||
1728 | |||
1570 | unix_state_unlock(sk); | 1729 | unix_state_unlock(sk); |
1571 | 1730 | ||
1572 | unix_dgram_disconnected(sk, other); | 1731 | unix_dgram_disconnected(sk, other); |
@@ -1592,21 +1751,38 @@ restart: | |||
1592 | goto out_unlock; | 1751 | goto out_unlock; |
1593 | } | 1752 | } |
1594 | 1753 | ||
1595 | if (unix_peer(other) != sk && unix_recvq_full(other)) { | 1754 | if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) { |
1596 | if (!timeo) { | 1755 | if (timeo) { |
1597 | err = -EAGAIN; | 1756 | timeo = unix_wait_for_peer(other, timeo); |
1598 | goto out_unlock; | 1757 | |
1758 | err = sock_intr_errno(timeo); | ||
1759 | if (signal_pending(current)) | ||
1760 | goto out_free; | ||
1761 | |||
1762 | goto restart; | ||
1599 | } | 1763 | } |
1600 | 1764 | ||
1601 | timeo = unix_wait_for_peer(other, timeo); | 1765 | if (!sk_locked) { |
1766 | unix_state_unlock(other); | ||
1767 | unix_state_double_lock(sk, other); | ||
1768 | } | ||
1602 | 1769 | ||
1603 | err = sock_intr_errno(timeo); | 1770 | if (unix_peer(sk) != other || |
1604 | if (signal_pending(current)) | 1771 | unix_dgram_peer_wake_me(sk, other)) { |
1605 | goto out_free; | 1772 | err = -EAGAIN; |
1773 | sk_locked = 1; | ||
1774 | goto out_unlock; | ||
1775 | } | ||
1606 | 1776 | ||
1607 | goto restart; | 1777 | if (!sk_locked) { |
1778 | sk_locked = 1; | ||
1779 | goto restart_locked; | ||
1780 | } | ||
1608 | } | 1781 | } |
1609 | 1782 | ||
1783 | if (unlikely(sk_locked)) | ||
1784 | unix_state_unlock(sk); | ||
1785 | |||
1610 | if (sock_flag(other, SOCK_RCVTSTAMP)) | 1786 | if (sock_flag(other, SOCK_RCVTSTAMP)) |
1611 | __net_timestamp(skb); | 1787 | __net_timestamp(skb); |
1612 | maybe_add_creds(skb, sock, other); | 1788 | maybe_add_creds(skb, sock, other); |
@@ -1620,6 +1796,8 @@ restart: | |||
1620 | return len; | 1796 | return len; |
1621 | 1797 | ||
1622 | out_unlock: | 1798 | out_unlock: |
1799 | if (sk_locked) | ||
1800 | unix_state_unlock(sk); | ||
1623 | unix_state_unlock(other); | 1801 | unix_state_unlock(other); |
1624 | out_free: | 1802 | out_free: |
1625 | kfree_skb(skb); | 1803 | kfree_skb(skb); |
@@ -1741,8 +1919,10 @@ out_err: | |||
1741 | static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page, | 1919 | static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page, |
1742 | int offset, size_t size, int flags) | 1920 | int offset, size_t size, int flags) |
1743 | { | 1921 | { |
1744 | int err = 0; | 1922 | int err; |
1745 | bool send_sigpipe = true; | 1923 | bool send_sigpipe = false; |
1924 | bool init_scm = true; | ||
1925 | struct scm_cookie scm; | ||
1746 | struct sock *other, *sk = socket->sk; | 1926 | struct sock *other, *sk = socket->sk; |
1747 | struct sk_buff *skb, *newskb = NULL, *tail = NULL; | 1927 | struct sk_buff *skb, *newskb = NULL, *tail = NULL; |
1748 | 1928 | ||
@@ -1760,7 +1940,7 @@ alloc_skb: | |||
1760 | newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT, | 1940 | newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT, |
1761 | &err, 0); | 1941 | &err, 0); |
1762 | if (!newskb) | 1942 | if (!newskb) |
1763 | return err; | 1943 | goto err; |
1764 | } | 1944 | } |
1765 | 1945 | ||
1766 | /* we must acquire readlock as we modify already present | 1946 | /* we must acquire readlock as we modify already present |
@@ -1769,12 +1949,12 @@ alloc_skb: | |||
1769 | err = mutex_lock_interruptible(&unix_sk(other)->readlock); | 1949 | err = mutex_lock_interruptible(&unix_sk(other)->readlock); |
1770 | if (err) { | 1950 | if (err) { |
1771 | err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS; | 1951 | err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS; |
1772 | send_sigpipe = false; | ||
1773 | goto err; | 1952 | goto err; |
1774 | } | 1953 | } |
1775 | 1954 | ||
1776 | if (sk->sk_shutdown & SEND_SHUTDOWN) { | 1955 | if (sk->sk_shutdown & SEND_SHUTDOWN) { |
1777 | err = -EPIPE; | 1956 | err = -EPIPE; |
1957 | send_sigpipe = true; | ||
1778 | goto err_unlock; | 1958 | goto err_unlock; |
1779 | } | 1959 | } |
1780 | 1960 | ||
@@ -1783,17 +1963,27 @@ alloc_skb: | |||
1783 | if (sock_flag(other, SOCK_DEAD) || | 1963 | if (sock_flag(other, SOCK_DEAD) || |
1784 | other->sk_shutdown & RCV_SHUTDOWN) { | 1964 | other->sk_shutdown & RCV_SHUTDOWN) { |
1785 | err = -EPIPE; | 1965 | err = -EPIPE; |
1966 | send_sigpipe = true; | ||
1786 | goto err_state_unlock; | 1967 | goto err_state_unlock; |
1787 | } | 1968 | } |
1788 | 1969 | ||
1970 | if (init_scm) { | ||
1971 | err = maybe_init_creds(&scm, socket, other); | ||
1972 | if (err) | ||
1973 | goto err_state_unlock; | ||
1974 | init_scm = false; | ||
1975 | } | ||
1976 | |||
1789 | skb = skb_peek_tail(&other->sk_receive_queue); | 1977 | skb = skb_peek_tail(&other->sk_receive_queue); |
1790 | if (tail && tail == skb) { | 1978 | if (tail && tail == skb) { |
1791 | skb = newskb; | 1979 | skb = newskb; |
1792 | } else if (!skb) { | 1980 | } else if (!skb || !unix_skb_scm_eq(skb, &scm)) { |
1793 | if (newskb) | 1981 | if (newskb) { |
1794 | skb = newskb; | 1982 | skb = newskb; |
1795 | else | 1983 | } else { |
1984 | tail = skb; | ||
1796 | goto alloc_skb; | 1985 | goto alloc_skb; |
1986 | } | ||
1797 | } else if (newskb) { | 1987 | } else if (newskb) { |
1798 | /* this is fast path, we don't necessarily need to | 1988 | /* this is fast path, we don't necessarily need to |
1799 | * call to kfree_skb even though with newskb == NULL | 1989 | * call to kfree_skb even though with newskb == NULL |
@@ -1814,6 +2004,9 @@ alloc_skb: | |||
1814 | atomic_add(size, &sk->sk_wmem_alloc); | 2004 | atomic_add(size, &sk->sk_wmem_alloc); |
1815 | 2005 | ||
1816 | if (newskb) { | 2006 | if (newskb) { |
2007 | err = unix_scm_to_skb(&scm, skb, false); | ||
2008 | if (err) | ||
2009 | goto err_state_unlock; | ||
1817 | spin_lock(&other->sk_receive_queue.lock); | 2010 | spin_lock(&other->sk_receive_queue.lock); |
1818 | __skb_queue_tail(&other->sk_receive_queue, newskb); | 2011 | __skb_queue_tail(&other->sk_receive_queue, newskb); |
1819 | spin_unlock(&other->sk_receive_queue.lock); | 2012 | spin_unlock(&other->sk_receive_queue.lock); |
@@ -1823,7 +2016,7 @@ alloc_skb: | |||
1823 | mutex_unlock(&unix_sk(other)->readlock); | 2016 | mutex_unlock(&unix_sk(other)->readlock); |
1824 | 2017 | ||
1825 | other->sk_data_ready(other); | 2018 | other->sk_data_ready(other); |
1826 | 2019 | scm_destroy(&scm); | |
1827 | return size; | 2020 | return size; |
1828 | 2021 | ||
1829 | err_state_unlock: | 2022 | err_state_unlock: |
@@ -1834,6 +2027,8 @@ err: | |||
1834 | kfree_skb(newskb); | 2027 | kfree_skb(newskb); |
1835 | if (send_sigpipe && !(flags & MSG_NOSIGNAL)) | 2028 | if (send_sigpipe && !(flags & MSG_NOSIGNAL)) |
1836 | send_sig(SIGPIPE, current, 0); | 2029 | send_sig(SIGPIPE, current, 0); |
2030 | if (!init_scm) | ||
2031 | scm_destroy(&scm); | ||
1837 | return err; | 2032 | return err; |
1838 | } | 2033 | } |
1839 | 2034 | ||
@@ -1996,7 +2191,7 @@ static long unix_stream_data_wait(struct sock *sk, long timeo, | |||
1996 | !timeo) | 2191 | !timeo) |
1997 | break; | 2192 | break; |
1998 | 2193 | ||
1999 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 2194 | sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
2000 | unix_state_unlock(sk); | 2195 | unix_state_unlock(sk); |
2001 | timeo = freezable_schedule_timeout(timeo); | 2196 | timeo = freezable_schedule_timeout(timeo); |
2002 | unix_state_lock(sk); | 2197 | unix_state_lock(sk); |
@@ -2004,7 +2199,7 @@ static long unix_stream_data_wait(struct sock *sk, long timeo, | |||
2004 | if (sock_flag(sk, SOCK_DEAD)) | 2199 | if (sock_flag(sk, SOCK_DEAD)) |
2005 | break; | 2200 | break; |
2006 | 2201 | ||
2007 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 2202 | sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
2008 | } | 2203 | } |
2009 | 2204 | ||
2010 | finish_wait(sk_sleep(sk), &wait); | 2205 | finish_wait(sk_sleep(sk), &wait); |
@@ -2137,10 +2332,7 @@ unlock: | |||
2137 | 2332 | ||
2138 | if (check_creds) { | 2333 | if (check_creds) { |
2139 | /* Never glue messages from different writers */ | 2334 | /* Never glue messages from different writers */ |
2140 | if ((UNIXCB(skb).pid != scm.pid) || | 2335 | if (!unix_skb_scm_eq(skb, &scm)) |
2141 | !uid_eq(UNIXCB(skb).uid, scm.creds.uid) || | ||
2142 | !gid_eq(UNIXCB(skb).gid, scm.creds.gid) || | ||
2143 | !unix_secdata_eq(&scm, skb)) | ||
2144 | break; | 2336 | break; |
2145 | } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { | 2337 | } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { |
2146 | /* Copy credentials */ | 2338 | /* Copy credentials */ |
@@ -2476,20 +2668,22 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, | |||
2476 | return mask; | 2668 | return mask; |
2477 | 2669 | ||
2478 | writable = unix_writable(sk); | 2670 | writable = unix_writable(sk); |
2479 | other = unix_peer_get(sk); | 2671 | if (writable) { |
2480 | if (other) { | 2672 | unix_state_lock(sk); |
2481 | if (unix_peer(other) != sk) { | 2673 | |
2482 | sock_poll_wait(file, &unix_sk(other)->peer_wait, wait); | 2674 | other = unix_peer(sk); |
2483 | if (unix_recvq_full(other)) | 2675 | if (other && unix_peer(other) != sk && |
2484 | writable = 0; | 2676 | unix_recvq_full(other) && |
2485 | } | 2677 | unix_dgram_peer_wake_me(sk, other)) |
2486 | sock_put(other); | 2678 | writable = 0; |
2679 | |||
2680 | unix_state_unlock(sk); | ||
2487 | } | 2681 | } |
2488 | 2682 | ||
2489 | if (writable) | 2683 | if (writable) |
2490 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; | 2684 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; |
2491 | else | 2685 | else |
2492 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 2686 | sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
2493 | 2687 | ||
2494 | return mask; | 2688 | return mask; |
2495 | } | 2689 | } |