diff options
author | Patrick McHardy <kaber@trash.net> | 2010-05-10 12:39:28 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-05-10 12:39:28 -0400 |
commit | 1e4b1057121bc756b91758a434b504d2010f6088 (patch) | |
tree | b016cf2c728289c7e36d9e4e488f30ab0bd0ae6e /net | |
parent | 3b254c54ec46eb022cb26ee6ab37fae23f5f7d6a (diff) | |
parent | 3ee943728fff536edaf8f59faa58aaa1aa7366e3 (diff) |
Merge branch 'master' of /repos/git/net-next-2.6
Conflicts:
net/bridge/br_device.c
net/bridge/br_forward.c
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net')
139 files changed, 3662 insertions, 2480 deletions
diff --git a/net/atm/common.c b/net/atm/common.c index 97ed94aa0cbc..b43feb1a3995 100644 --- a/net/atm/common.c +++ b/net/atm/common.c | |||
@@ -90,10 +90,13 @@ static void vcc_sock_destruct(struct sock *sk) | |||
90 | 90 | ||
91 | static void vcc_def_wakeup(struct sock *sk) | 91 | static void vcc_def_wakeup(struct sock *sk) |
92 | { | 92 | { |
93 | read_lock(&sk->sk_callback_lock); | 93 | struct socket_wq *wq; |
94 | if (sk_has_sleeper(sk)) | 94 | |
95 | wake_up(sk->sk_sleep); | 95 | rcu_read_lock(); |
96 | read_unlock(&sk->sk_callback_lock); | 96 | wq = rcu_dereference(sk->sk_wq); |
97 | if (wq_has_sleeper(wq)) | ||
98 | wake_up(&wq->wait); | ||
99 | rcu_read_unlock(); | ||
97 | } | 100 | } |
98 | 101 | ||
99 | static inline int vcc_writable(struct sock *sk) | 102 | static inline int vcc_writable(struct sock *sk) |
@@ -106,16 +109,19 @@ static inline int vcc_writable(struct sock *sk) | |||
106 | 109 | ||
107 | static void vcc_write_space(struct sock *sk) | 110 | static void vcc_write_space(struct sock *sk) |
108 | { | 111 | { |
109 | read_lock(&sk->sk_callback_lock); | 112 | struct socket_wq *wq; |
113 | |||
114 | rcu_read_lock(); | ||
110 | 115 | ||
111 | if (vcc_writable(sk)) { | 116 | if (vcc_writable(sk)) { |
112 | if (sk_has_sleeper(sk)) | 117 | wq = rcu_dereference(sk->sk_wq); |
113 | wake_up_interruptible(sk->sk_sleep); | 118 | if (wq_has_sleeper(wq)) |
119 | wake_up_interruptible(&wq->wait); | ||
114 | 120 | ||
115 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); | 121 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); |
116 | } | 122 | } |
117 | 123 | ||
118 | read_unlock(&sk->sk_callback_lock); | 124 | rcu_read_unlock(); |
119 | } | 125 | } |
120 | 126 | ||
121 | static struct proto vcc_proto = { | 127 | static struct proto vcc_proto = { |
@@ -549,7 +555,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, | |||
549 | } | 555 | } |
550 | 556 | ||
551 | eff = (size+3) & ~3; /* align to word boundary */ | 557 | eff = (size+3) & ~3; /* align to word boundary */ |
552 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 558 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
553 | error = 0; | 559 | error = 0; |
554 | while (!(skb = alloc_tx(vcc, eff))) { | 560 | while (!(skb = alloc_tx(vcc, eff))) { |
555 | if (m->msg_flags & MSG_DONTWAIT) { | 561 | if (m->msg_flags & MSG_DONTWAIT) { |
@@ -568,9 +574,9 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, | |||
568 | send_sig(SIGPIPE, current, 0); | 574 | send_sig(SIGPIPE, current, 0); |
569 | break; | 575 | break; |
570 | } | 576 | } |
571 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 577 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
572 | } | 578 | } |
573 | finish_wait(sk->sk_sleep, &wait); | 579 | finish_wait(sk_sleep(sk), &wait); |
574 | if (error) | 580 | if (error) |
575 | goto out; | 581 | goto out; |
576 | skb->dev = NULL; /* for paths shared with net_device interfaces */ | 582 | skb->dev = NULL; /* for paths shared with net_device interfaces */ |
@@ -595,7 +601,7 @@ unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
595 | struct atm_vcc *vcc; | 601 | struct atm_vcc *vcc; |
596 | unsigned int mask; | 602 | unsigned int mask; |
597 | 603 | ||
598 | sock_poll_wait(file, sk->sk_sleep, wait); | 604 | sock_poll_wait(file, sk_sleep(sk), wait); |
599 | mask = 0; | 605 | mask = 0; |
600 | 606 | ||
601 | vcc = ATM_SD(sock); | 607 | vcc = ATM_SD(sock); |
diff --git a/net/atm/signaling.c b/net/atm/signaling.c index 6ba6e466ee54..509c8ac02b63 100644 --- a/net/atm/signaling.c +++ b/net/atm/signaling.c | |||
@@ -131,7 +131,7 @@ static int sigd_send(struct atm_vcc *vcc, struct sk_buff *skb) | |||
131 | } | 131 | } |
132 | sk->sk_ack_backlog++; | 132 | sk->sk_ack_backlog++; |
133 | skb_queue_tail(&sk->sk_receive_queue, skb); | 133 | skb_queue_tail(&sk->sk_receive_queue, skb); |
134 | pr_debug("waking sk->sk_sleep 0x%p\n", sk->sk_sleep); | 134 | pr_debug("waking sk_sleep(sk) 0x%p\n", sk_sleep(sk)); |
135 | sk->sk_state_change(sk); | 135 | sk->sk_state_change(sk); |
136 | as_indicate_complete: | 136 | as_indicate_complete: |
137 | release_sock(sk); | 137 | release_sock(sk); |
diff --git a/net/atm/svc.c b/net/atm/svc.c index 3ba9a45a51ac..754ee4791d96 100644 --- a/net/atm/svc.c +++ b/net/atm/svc.c | |||
@@ -49,14 +49,14 @@ static void svc_disconnect(struct atm_vcc *vcc) | |||
49 | 49 | ||
50 | pr_debug("%p\n", vcc); | 50 | pr_debug("%p\n", vcc); |
51 | if (test_bit(ATM_VF_REGIS, &vcc->flags)) { | 51 | if (test_bit(ATM_VF_REGIS, &vcc->flags)) { |
52 | prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); | 52 | prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); |
53 | sigd_enq(vcc, as_close, NULL, NULL, NULL); | 53 | sigd_enq(vcc, as_close, NULL, NULL, NULL); |
54 | while (!test_bit(ATM_VF_RELEASED, &vcc->flags) && sigd) { | 54 | while (!test_bit(ATM_VF_RELEASED, &vcc->flags) && sigd) { |
55 | schedule(); | 55 | schedule(); |
56 | prepare_to_wait(sk->sk_sleep, &wait, | 56 | prepare_to_wait(sk_sleep(sk), &wait, |
57 | TASK_UNINTERRUPTIBLE); | 57 | TASK_UNINTERRUPTIBLE); |
58 | } | 58 | } |
59 | finish_wait(sk->sk_sleep, &wait); | 59 | finish_wait(sk_sleep(sk), &wait); |
60 | } | 60 | } |
61 | /* beware - socket is still in use by atmsigd until the last | 61 | /* beware - socket is still in use by atmsigd until the last |
62 | as_indicate has been answered */ | 62 | as_indicate has been answered */ |
@@ -125,13 +125,13 @@ static int svc_bind(struct socket *sock, struct sockaddr *sockaddr, | |||
125 | } | 125 | } |
126 | vcc->local = *addr; | 126 | vcc->local = *addr; |
127 | set_bit(ATM_VF_WAITING, &vcc->flags); | 127 | set_bit(ATM_VF_WAITING, &vcc->flags); |
128 | prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); | 128 | prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); |
129 | sigd_enq(vcc, as_bind, NULL, NULL, &vcc->local); | 129 | sigd_enq(vcc, as_bind, NULL, NULL, &vcc->local); |
130 | while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { | 130 | while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { |
131 | schedule(); | 131 | schedule(); |
132 | prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); | 132 | prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); |
133 | } | 133 | } |
134 | finish_wait(sk->sk_sleep, &wait); | 134 | finish_wait(sk_sleep(sk), &wait); |
135 | clear_bit(ATM_VF_REGIS, &vcc->flags); /* doesn't count */ | 135 | clear_bit(ATM_VF_REGIS, &vcc->flags); /* doesn't count */ |
136 | if (!sigd) { | 136 | if (!sigd) { |
137 | error = -EUNATCH; | 137 | error = -EUNATCH; |
@@ -201,10 +201,10 @@ static int svc_connect(struct socket *sock, struct sockaddr *sockaddr, | |||
201 | } | 201 | } |
202 | vcc->remote = *addr; | 202 | vcc->remote = *addr; |
203 | set_bit(ATM_VF_WAITING, &vcc->flags); | 203 | set_bit(ATM_VF_WAITING, &vcc->flags); |
204 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 204 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
205 | sigd_enq(vcc, as_connect, NULL, NULL, &vcc->remote); | 205 | sigd_enq(vcc, as_connect, NULL, NULL, &vcc->remote); |
206 | if (flags & O_NONBLOCK) { | 206 | if (flags & O_NONBLOCK) { |
207 | finish_wait(sk->sk_sleep, &wait); | 207 | finish_wait(sk_sleep(sk), &wait); |
208 | sock->state = SS_CONNECTING; | 208 | sock->state = SS_CONNECTING; |
209 | error = -EINPROGRESS; | 209 | error = -EINPROGRESS; |
210 | goto out; | 210 | goto out; |
@@ -213,7 +213,7 @@ static int svc_connect(struct socket *sock, struct sockaddr *sockaddr, | |||
213 | while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { | 213 | while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { |
214 | schedule(); | 214 | schedule(); |
215 | if (!signal_pending(current)) { | 215 | if (!signal_pending(current)) { |
216 | prepare_to_wait(sk->sk_sleep, &wait, | 216 | prepare_to_wait(sk_sleep(sk), &wait, |
217 | TASK_INTERRUPTIBLE); | 217 | TASK_INTERRUPTIBLE); |
218 | continue; | 218 | continue; |
219 | } | 219 | } |
@@ -232,14 +232,14 @@ static int svc_connect(struct socket *sock, struct sockaddr *sockaddr, | |||
232 | */ | 232 | */ |
233 | sigd_enq(vcc, as_close, NULL, NULL, NULL); | 233 | sigd_enq(vcc, as_close, NULL, NULL, NULL); |
234 | while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { | 234 | while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { |
235 | prepare_to_wait(sk->sk_sleep, &wait, | 235 | prepare_to_wait(sk_sleep(sk), &wait, |
236 | TASK_INTERRUPTIBLE); | 236 | TASK_INTERRUPTIBLE); |
237 | schedule(); | 237 | schedule(); |
238 | } | 238 | } |
239 | if (!sk->sk_err) | 239 | if (!sk->sk_err) |
240 | while (!test_bit(ATM_VF_RELEASED, &vcc->flags) && | 240 | while (!test_bit(ATM_VF_RELEASED, &vcc->flags) && |
241 | sigd) { | 241 | sigd) { |
242 | prepare_to_wait(sk->sk_sleep, &wait, | 242 | prepare_to_wait(sk_sleep(sk), &wait, |
243 | TASK_INTERRUPTIBLE); | 243 | TASK_INTERRUPTIBLE); |
244 | schedule(); | 244 | schedule(); |
245 | } | 245 | } |
@@ -250,7 +250,7 @@ static int svc_connect(struct socket *sock, struct sockaddr *sockaddr, | |||
250 | error = -EINTR; | 250 | error = -EINTR; |
251 | break; | 251 | break; |
252 | } | 252 | } |
253 | finish_wait(sk->sk_sleep, &wait); | 253 | finish_wait(sk_sleep(sk), &wait); |
254 | if (error) | 254 | if (error) |
255 | goto out; | 255 | goto out; |
256 | if (!sigd) { | 256 | if (!sigd) { |
@@ -302,13 +302,13 @@ static int svc_listen(struct socket *sock, int backlog) | |||
302 | goto out; | 302 | goto out; |
303 | } | 303 | } |
304 | set_bit(ATM_VF_WAITING, &vcc->flags); | 304 | set_bit(ATM_VF_WAITING, &vcc->flags); |
305 | prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); | 305 | prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); |
306 | sigd_enq(vcc, as_listen, NULL, NULL, &vcc->local); | 306 | sigd_enq(vcc, as_listen, NULL, NULL, &vcc->local); |
307 | while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { | 307 | while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { |
308 | schedule(); | 308 | schedule(); |
309 | prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); | 309 | prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); |
310 | } | 310 | } |
311 | finish_wait(sk->sk_sleep, &wait); | 311 | finish_wait(sk_sleep(sk), &wait); |
312 | if (!sigd) { | 312 | if (!sigd) { |
313 | error = -EUNATCH; | 313 | error = -EUNATCH; |
314 | goto out; | 314 | goto out; |
@@ -343,7 +343,7 @@ static int svc_accept(struct socket *sock, struct socket *newsock, int flags) | |||
343 | while (1) { | 343 | while (1) { |
344 | DEFINE_WAIT(wait); | 344 | DEFINE_WAIT(wait); |
345 | 345 | ||
346 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 346 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
347 | while (!(skb = skb_dequeue(&sk->sk_receive_queue)) && | 347 | while (!(skb = skb_dequeue(&sk->sk_receive_queue)) && |
348 | sigd) { | 348 | sigd) { |
349 | if (test_bit(ATM_VF_RELEASED, &old_vcc->flags)) | 349 | if (test_bit(ATM_VF_RELEASED, &old_vcc->flags)) |
@@ -363,10 +363,10 @@ static int svc_accept(struct socket *sock, struct socket *newsock, int flags) | |||
363 | error = -ERESTARTSYS; | 363 | error = -ERESTARTSYS; |
364 | break; | 364 | break; |
365 | } | 365 | } |
366 | prepare_to_wait(sk->sk_sleep, &wait, | 366 | prepare_to_wait(sk_sleep(sk), &wait, |
367 | TASK_INTERRUPTIBLE); | 367 | TASK_INTERRUPTIBLE); |
368 | } | 368 | } |
369 | finish_wait(sk->sk_sleep, &wait); | 369 | finish_wait(sk_sleep(sk), &wait); |
370 | if (error) | 370 | if (error) |
371 | goto out; | 371 | goto out; |
372 | if (!skb) { | 372 | if (!skb) { |
@@ -392,17 +392,17 @@ static int svc_accept(struct socket *sock, struct socket *newsock, int flags) | |||
392 | } | 392 | } |
393 | /* wait should be short, so we ignore the non-blocking flag */ | 393 | /* wait should be short, so we ignore the non-blocking flag */ |
394 | set_bit(ATM_VF_WAITING, &new_vcc->flags); | 394 | set_bit(ATM_VF_WAITING, &new_vcc->flags); |
395 | prepare_to_wait(sk_atm(new_vcc)->sk_sleep, &wait, | 395 | prepare_to_wait(sk_sleep(sk_atm(new_vcc)), &wait, |
396 | TASK_UNINTERRUPTIBLE); | 396 | TASK_UNINTERRUPTIBLE); |
397 | sigd_enq(new_vcc, as_accept, old_vcc, NULL, NULL); | 397 | sigd_enq(new_vcc, as_accept, old_vcc, NULL, NULL); |
398 | while (test_bit(ATM_VF_WAITING, &new_vcc->flags) && sigd) { | 398 | while (test_bit(ATM_VF_WAITING, &new_vcc->flags) && sigd) { |
399 | release_sock(sk); | 399 | release_sock(sk); |
400 | schedule(); | 400 | schedule(); |
401 | lock_sock(sk); | 401 | lock_sock(sk); |
402 | prepare_to_wait(sk_atm(new_vcc)->sk_sleep, &wait, | 402 | prepare_to_wait(sk_sleep(sk_atm(new_vcc)), &wait, |
403 | TASK_UNINTERRUPTIBLE); | 403 | TASK_UNINTERRUPTIBLE); |
404 | } | 404 | } |
405 | finish_wait(sk_atm(new_vcc)->sk_sleep, &wait); | 405 | finish_wait(sk_sleep(sk_atm(new_vcc)), &wait); |
406 | if (!sigd) { | 406 | if (!sigd) { |
407 | error = -EUNATCH; | 407 | error = -EUNATCH; |
408 | goto out; | 408 | goto out; |
@@ -438,14 +438,14 @@ int svc_change_qos(struct atm_vcc *vcc, struct atm_qos *qos) | |||
438 | DEFINE_WAIT(wait); | 438 | DEFINE_WAIT(wait); |
439 | 439 | ||
440 | set_bit(ATM_VF_WAITING, &vcc->flags); | 440 | set_bit(ATM_VF_WAITING, &vcc->flags); |
441 | prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); | 441 | prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); |
442 | sigd_enq2(vcc, as_modify, NULL, NULL, &vcc->local, qos, 0); | 442 | sigd_enq2(vcc, as_modify, NULL, NULL, &vcc->local, qos, 0); |
443 | while (test_bit(ATM_VF_WAITING, &vcc->flags) && | 443 | while (test_bit(ATM_VF_WAITING, &vcc->flags) && |
444 | !test_bit(ATM_VF_RELEASED, &vcc->flags) && sigd) { | 444 | !test_bit(ATM_VF_RELEASED, &vcc->flags) && sigd) { |
445 | schedule(); | 445 | schedule(); |
446 | prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); | 446 | prepare_to_wait(sk_sleep(sk), &wait, TASK_UNINTERRUPTIBLE); |
447 | } | 447 | } |
448 | finish_wait(sk->sk_sleep, &wait); | 448 | finish_wait(sk_sleep(sk), &wait); |
449 | if (!sigd) | 449 | if (!sigd) |
450 | return -EUNATCH; | 450 | return -EUNATCH; |
451 | return -sk->sk_err; | 451 | return -sk->sk_err; |
@@ -534,20 +534,20 @@ static int svc_addparty(struct socket *sock, struct sockaddr *sockaddr, | |||
534 | 534 | ||
535 | lock_sock(sk); | 535 | lock_sock(sk); |
536 | set_bit(ATM_VF_WAITING, &vcc->flags); | 536 | set_bit(ATM_VF_WAITING, &vcc->flags); |
537 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 537 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
538 | sigd_enq(vcc, as_addparty, NULL, NULL, | 538 | sigd_enq(vcc, as_addparty, NULL, NULL, |
539 | (struct sockaddr_atmsvc *) sockaddr); | 539 | (struct sockaddr_atmsvc *) sockaddr); |
540 | if (flags & O_NONBLOCK) { | 540 | if (flags & O_NONBLOCK) { |
541 | finish_wait(sk->sk_sleep, &wait); | 541 | finish_wait(sk_sleep(sk), &wait); |
542 | error = -EINPROGRESS; | 542 | error = -EINPROGRESS; |
543 | goto out; | 543 | goto out; |
544 | } | 544 | } |
545 | pr_debug("added wait queue\n"); | 545 | pr_debug("added wait queue\n"); |
546 | while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { | 546 | while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { |
547 | schedule(); | 547 | schedule(); |
548 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 548 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
549 | } | 549 | } |
550 | finish_wait(sk->sk_sleep, &wait); | 550 | finish_wait(sk_sleep(sk), &wait); |
551 | error = xchg(&sk->sk_err_soft, 0); | 551 | error = xchg(&sk->sk_err_soft, 0); |
552 | out: | 552 | out: |
553 | release_sock(sk); | 553 | release_sock(sk); |
@@ -563,13 +563,13 @@ static int svc_dropparty(struct socket *sock, int ep_ref) | |||
563 | 563 | ||
564 | lock_sock(sk); | 564 | lock_sock(sk); |
565 | set_bit(ATM_VF_WAITING, &vcc->flags); | 565 | set_bit(ATM_VF_WAITING, &vcc->flags); |
566 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 566 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
567 | sigd_enq2(vcc, as_dropparty, NULL, NULL, NULL, NULL, ep_ref); | 567 | sigd_enq2(vcc, as_dropparty, NULL, NULL, NULL, NULL, ep_ref); |
568 | while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { | 568 | while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { |
569 | schedule(); | 569 | schedule(); |
570 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 570 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
571 | } | 571 | } |
572 | finish_wait(sk->sk_sleep, &wait); | 572 | finish_wait(sk_sleep(sk), &wait); |
573 | if (!sigd) { | 573 | if (!sigd) { |
574 | error = -EUNATCH; | 574 | error = -EUNATCH; |
575 | goto out; | 575 | goto out; |
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 65c5801261f9..cfdfd7e2a172 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
@@ -1281,7 +1281,7 @@ static int __must_check ax25_connect(struct socket *sock, | |||
1281 | DEFINE_WAIT(wait); | 1281 | DEFINE_WAIT(wait); |
1282 | 1282 | ||
1283 | for (;;) { | 1283 | for (;;) { |
1284 | prepare_to_wait(sk->sk_sleep, &wait, | 1284 | prepare_to_wait(sk_sleep(sk), &wait, |
1285 | TASK_INTERRUPTIBLE); | 1285 | TASK_INTERRUPTIBLE); |
1286 | if (sk->sk_state != TCP_SYN_SENT) | 1286 | if (sk->sk_state != TCP_SYN_SENT) |
1287 | break; | 1287 | break; |
@@ -1294,7 +1294,7 @@ static int __must_check ax25_connect(struct socket *sock, | |||
1294 | err = -ERESTARTSYS; | 1294 | err = -ERESTARTSYS; |
1295 | break; | 1295 | break; |
1296 | } | 1296 | } |
1297 | finish_wait(sk->sk_sleep, &wait); | 1297 | finish_wait(sk_sleep(sk), &wait); |
1298 | 1298 | ||
1299 | if (err) | 1299 | if (err) |
1300 | goto out_release; | 1300 | goto out_release; |
@@ -1346,7 +1346,7 @@ static int ax25_accept(struct socket *sock, struct socket *newsock, int flags) | |||
1346 | * hooked into the SABM we saved | 1346 | * hooked into the SABM we saved |
1347 | */ | 1347 | */ |
1348 | for (;;) { | 1348 | for (;;) { |
1349 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 1349 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
1350 | skb = skb_dequeue(&sk->sk_receive_queue); | 1350 | skb = skb_dequeue(&sk->sk_receive_queue); |
1351 | if (skb) | 1351 | if (skb) |
1352 | break; | 1352 | break; |
@@ -1364,7 +1364,7 @@ static int ax25_accept(struct socket *sock, struct socket *newsock, int flags) | |||
1364 | err = -ERESTARTSYS; | 1364 | err = -ERESTARTSYS; |
1365 | break; | 1365 | break; |
1366 | } | 1366 | } |
1367 | finish_wait(sk->sk_sleep, &wait); | 1367 | finish_wait(sk_sleep(sk), &wait); |
1368 | 1368 | ||
1369 | if (err) | 1369 | if (err) |
1370 | goto out; | 1370 | goto out; |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 404a8500fd03..421c45bd1b95 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -288,7 +288,7 @@ unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *w | |||
288 | 288 | ||
289 | BT_DBG("sock %p, sk %p", sock, sk); | 289 | BT_DBG("sock %p, sk %p", sock, sk); |
290 | 290 | ||
291 | poll_wait(file, sk->sk_sleep, wait); | 291 | poll_wait(file, sk_sleep(sk), wait); |
292 | 292 | ||
293 | if (sk->sk_state == BT_LISTEN) | 293 | if (sk->sk_state == BT_LISTEN) |
294 | return bt_accept_poll(sk); | 294 | return bt_accept_poll(sk); |
@@ -378,7 +378,7 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) | |||
378 | 378 | ||
379 | BT_DBG("sk %p", sk); | 379 | BT_DBG("sk %p", sk); |
380 | 380 | ||
381 | add_wait_queue(sk->sk_sleep, &wait); | 381 | add_wait_queue(sk_sleep(sk), &wait); |
382 | while (sk->sk_state != state) { | 382 | while (sk->sk_state != state) { |
383 | set_current_state(TASK_INTERRUPTIBLE); | 383 | set_current_state(TASK_INTERRUPTIBLE); |
384 | 384 | ||
@@ -401,7 +401,7 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) | |||
401 | break; | 401 | break; |
402 | } | 402 | } |
403 | set_current_state(TASK_RUNNING); | 403 | set_current_state(TASK_RUNNING); |
404 | remove_wait_queue(sk->sk_sleep, &wait); | 404 | remove_wait_queue(sk_sleep(sk), &wait); |
405 | return err; | 405 | return err; |
406 | } | 406 | } |
407 | EXPORT_SYMBOL(bt_sock_wait_state); | 407 | EXPORT_SYMBOL(bt_sock_wait_state); |
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 8062dad6d10d..f10b41fb05a0 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c | |||
@@ -474,7 +474,7 @@ static int bnep_session(void *arg) | |||
474 | set_user_nice(current, -15); | 474 | set_user_nice(current, -15); |
475 | 475 | ||
476 | init_waitqueue_entry(&wait, current); | 476 | init_waitqueue_entry(&wait, current); |
477 | add_wait_queue(sk->sk_sleep, &wait); | 477 | add_wait_queue(sk_sleep(sk), &wait); |
478 | while (!atomic_read(&s->killed)) { | 478 | while (!atomic_read(&s->killed)) { |
479 | set_current_state(TASK_INTERRUPTIBLE); | 479 | set_current_state(TASK_INTERRUPTIBLE); |
480 | 480 | ||
@@ -496,7 +496,7 @@ static int bnep_session(void *arg) | |||
496 | schedule(); | 496 | schedule(); |
497 | } | 497 | } |
498 | set_current_state(TASK_RUNNING); | 498 | set_current_state(TASK_RUNNING); |
499 | remove_wait_queue(sk->sk_sleep, &wait); | 499 | remove_wait_queue(sk_sleep(sk), &wait); |
500 | 500 | ||
501 | /* Cleanup session */ | 501 | /* Cleanup session */ |
502 | down_write(&bnep_session_sem); | 502 | down_write(&bnep_session_sem); |
@@ -507,7 +507,7 @@ static int bnep_session(void *arg) | |||
507 | /* Wakeup user-space polling for socket errors */ | 507 | /* Wakeup user-space polling for socket errors */ |
508 | s->sock->sk->sk_err = EUNATCH; | 508 | s->sock->sk->sk_err = EUNATCH; |
509 | 509 | ||
510 | wake_up_interruptible(s->sock->sk->sk_sleep); | 510 | wake_up_interruptible(sk_sleep(s->sock->sk)); |
511 | 511 | ||
512 | /* Release the socket */ | 512 | /* Release the socket */ |
513 | fput(s->sock->file); | 513 | fput(s->sock->file); |
@@ -638,7 +638,7 @@ int bnep_del_connection(struct bnep_conndel_req *req) | |||
638 | 638 | ||
639 | /* Kill session thread */ | 639 | /* Kill session thread */ |
640 | atomic_inc(&s->killed); | 640 | atomic_inc(&s->killed); |
641 | wake_up_interruptible(s->sock->sk->sk_sleep); | 641 | wake_up_interruptible(sk_sleep(s->sock->sk)); |
642 | } else | 642 | } else |
643 | err = -ENOENT; | 643 | err = -ENOENT; |
644 | 644 | ||
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c index d48b33f4d4ba..0faad5ce6dc4 100644 --- a/net/bluetooth/bnep/netdev.c +++ b/net/bluetooth/bnep/netdev.c | |||
@@ -109,7 +109,7 @@ static void bnep_net_set_mc_list(struct net_device *dev) | |||
109 | } | 109 | } |
110 | 110 | ||
111 | skb_queue_tail(&sk->sk_write_queue, skb); | 111 | skb_queue_tail(&sk->sk_write_queue, skb); |
112 | wake_up_interruptible(sk->sk_sleep); | 112 | wake_up_interruptible(sk_sleep(sk)); |
113 | #endif | 113 | #endif |
114 | } | 114 | } |
115 | 115 | ||
@@ -193,11 +193,11 @@ static netdev_tx_t bnep_net_xmit(struct sk_buff *skb, | |||
193 | /* | 193 | /* |
194 | * We cannot send L2CAP packets from here as we are potentially in a bh. | 194 | * We cannot send L2CAP packets from here as we are potentially in a bh. |
195 | * So we have to queue them and wake up session thread which is sleeping | 195 | * So we have to queue them and wake up session thread which is sleeping |
196 | * on the sk->sk_sleep. | 196 | * on the sk_sleep(sk). |
197 | */ | 197 | */ |
198 | dev->trans_start = jiffies; | 198 | dev->trans_start = jiffies; |
199 | skb_queue_tail(&sk->sk_write_queue, skb); | 199 | skb_queue_tail(&sk->sk_write_queue, skb); |
200 | wake_up_interruptible(sk->sk_sleep); | 200 | wake_up_interruptible(sk_sleep(sk)); |
201 | 201 | ||
202 | if (skb_queue_len(&sk->sk_write_queue) >= BNEP_TX_QUEUE_LEN) { | 202 | if (skb_queue_len(&sk->sk_write_queue) >= BNEP_TX_QUEUE_LEN) { |
203 | BT_DBG("tx queue is full"); | 203 | BT_DBG("tx queue is full"); |
diff --git a/net/bluetooth/cmtp/cmtp.h b/net/bluetooth/cmtp/cmtp.h index e4663aa14d26..785e79e953c5 100644 --- a/net/bluetooth/cmtp/cmtp.h +++ b/net/bluetooth/cmtp/cmtp.h | |||
@@ -125,7 +125,7 @@ static inline void cmtp_schedule(struct cmtp_session *session) | |||
125 | { | 125 | { |
126 | struct sock *sk = session->sock->sk; | 126 | struct sock *sk = session->sock->sk; |
127 | 127 | ||
128 | wake_up_interruptible(sk->sk_sleep); | 128 | wake_up_interruptible(sk_sleep(sk)); |
129 | } | 129 | } |
130 | 130 | ||
131 | /* CMTP init defines */ | 131 | /* CMTP init defines */ |
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 0073ec8495da..d4c6af082d48 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c | |||
@@ -284,7 +284,7 @@ static int cmtp_session(void *arg) | |||
284 | set_user_nice(current, -15); | 284 | set_user_nice(current, -15); |
285 | 285 | ||
286 | init_waitqueue_entry(&wait, current); | 286 | init_waitqueue_entry(&wait, current); |
287 | add_wait_queue(sk->sk_sleep, &wait); | 287 | add_wait_queue(sk_sleep(sk), &wait); |
288 | while (!atomic_read(&session->terminate)) { | 288 | while (!atomic_read(&session->terminate)) { |
289 | set_current_state(TASK_INTERRUPTIBLE); | 289 | set_current_state(TASK_INTERRUPTIBLE); |
290 | 290 | ||
@@ -301,7 +301,7 @@ static int cmtp_session(void *arg) | |||
301 | schedule(); | 301 | schedule(); |
302 | } | 302 | } |
303 | set_current_state(TASK_RUNNING); | 303 | set_current_state(TASK_RUNNING); |
304 | remove_wait_queue(sk->sk_sleep, &wait); | 304 | remove_wait_queue(sk_sleep(sk), &wait); |
305 | 305 | ||
306 | down_write(&cmtp_session_sem); | 306 | down_write(&cmtp_session_sem); |
307 | 307 | ||
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 280529ad9274..bfe641b7dfaf 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -561,8 +561,8 @@ static int hidp_session(void *arg) | |||
561 | 561 | ||
562 | init_waitqueue_entry(&ctrl_wait, current); | 562 | init_waitqueue_entry(&ctrl_wait, current); |
563 | init_waitqueue_entry(&intr_wait, current); | 563 | init_waitqueue_entry(&intr_wait, current); |
564 | add_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait); | 564 | add_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait); |
565 | add_wait_queue(intr_sk->sk_sleep, &intr_wait); | 565 | add_wait_queue(sk_sleep(intr_sk), &intr_wait); |
566 | while (!atomic_read(&session->terminate)) { | 566 | while (!atomic_read(&session->terminate)) { |
567 | set_current_state(TASK_INTERRUPTIBLE); | 567 | set_current_state(TASK_INTERRUPTIBLE); |
568 | 568 | ||
@@ -584,8 +584,8 @@ static int hidp_session(void *arg) | |||
584 | schedule(); | 584 | schedule(); |
585 | } | 585 | } |
586 | set_current_state(TASK_RUNNING); | 586 | set_current_state(TASK_RUNNING); |
587 | remove_wait_queue(intr_sk->sk_sleep, &intr_wait); | 587 | remove_wait_queue(sk_sleep(intr_sk), &intr_wait); |
588 | remove_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait); | 588 | remove_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait); |
589 | 589 | ||
590 | down_write(&hidp_session_sem); | 590 | down_write(&hidp_session_sem); |
591 | 591 | ||
@@ -609,7 +609,7 @@ static int hidp_session(void *arg) | |||
609 | 609 | ||
610 | fput(session->intr_sock->file); | 610 | fput(session->intr_sock->file); |
611 | 611 | ||
612 | wait_event_timeout(*(ctrl_sk->sk_sleep), | 612 | wait_event_timeout(*(sk_sleep(ctrl_sk)), |
613 | (ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500)); | 613 | (ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500)); |
614 | 614 | ||
615 | fput(session->ctrl_sock->file); | 615 | fput(session->ctrl_sock->file); |
diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h index a4e215d50c10..8d934a19da0a 100644 --- a/net/bluetooth/hidp/hidp.h +++ b/net/bluetooth/hidp/hidp.h | |||
@@ -164,8 +164,8 @@ static inline void hidp_schedule(struct hidp_session *session) | |||
164 | struct sock *ctrl_sk = session->ctrl_sock->sk; | 164 | struct sock *ctrl_sk = session->ctrl_sock->sk; |
165 | struct sock *intr_sk = session->intr_sock->sk; | 165 | struct sock *intr_sk = session->intr_sock->sk; |
166 | 166 | ||
167 | wake_up_interruptible(ctrl_sk->sk_sleep); | 167 | wake_up_interruptible(sk_sleep(ctrl_sk)); |
168 | wake_up_interruptible(intr_sk->sk_sleep); | 168 | wake_up_interruptible(sk_sleep(intr_sk)); |
169 | } | 169 | } |
170 | 170 | ||
171 | /* HIDP init defines */ | 171 | /* HIDP init defines */ |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 99d68c34e4f1..864c76f4a678 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -1147,7 +1147,7 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl | |||
1147 | BT_DBG("sk %p timeo %ld", sk, timeo); | 1147 | BT_DBG("sk %p timeo %ld", sk, timeo); |
1148 | 1148 | ||
1149 | /* Wait for an incoming connection. (wake-one). */ | 1149 | /* Wait for an incoming connection. (wake-one). */ |
1150 | add_wait_queue_exclusive(sk->sk_sleep, &wait); | 1150 | add_wait_queue_exclusive(sk_sleep(sk), &wait); |
1151 | while (!(nsk = bt_accept_dequeue(sk, newsock))) { | 1151 | while (!(nsk = bt_accept_dequeue(sk, newsock))) { |
1152 | set_current_state(TASK_INTERRUPTIBLE); | 1152 | set_current_state(TASK_INTERRUPTIBLE); |
1153 | if (!timeo) { | 1153 | if (!timeo) { |
@@ -1170,7 +1170,7 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl | |||
1170 | } | 1170 | } |
1171 | } | 1171 | } |
1172 | set_current_state(TASK_RUNNING); | 1172 | set_current_state(TASK_RUNNING); |
1173 | remove_wait_queue(sk->sk_sleep, &wait); | 1173 | remove_wait_queue(sk_sleep(sk), &wait); |
1174 | 1174 | ||
1175 | if (err) | 1175 | if (err) |
1176 | goto done; | 1176 | goto done; |
@@ -1626,7 +1626,10 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
1626 | /* Connectionless channel */ | 1626 | /* Connectionless channel */ |
1627 | if (sk->sk_type == SOCK_DGRAM) { | 1627 | if (sk->sk_type == SOCK_DGRAM) { |
1628 | skb = l2cap_create_connless_pdu(sk, msg, len); | 1628 | skb = l2cap_create_connless_pdu(sk, msg, len); |
1629 | err = l2cap_do_send(sk, skb); | 1629 | if (IS_ERR(skb)) |
1630 | err = PTR_ERR(skb); | ||
1631 | else | ||
1632 | err = l2cap_do_send(sk, skb); | ||
1630 | goto done; | 1633 | goto done; |
1631 | } | 1634 | } |
1632 | 1635 | ||
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 8ed3c37684fa..43fbf6b4b4bf 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -503,7 +503,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | |||
503 | BT_DBG("sk %p timeo %ld", sk, timeo); | 503 | BT_DBG("sk %p timeo %ld", sk, timeo); |
504 | 504 | ||
505 | /* Wait for an incoming connection. (wake-one). */ | 505 | /* Wait for an incoming connection. (wake-one). */ |
506 | add_wait_queue_exclusive(sk->sk_sleep, &wait); | 506 | add_wait_queue_exclusive(sk_sleep(sk), &wait); |
507 | while (!(nsk = bt_accept_dequeue(sk, newsock))) { | 507 | while (!(nsk = bt_accept_dequeue(sk, newsock))) { |
508 | set_current_state(TASK_INTERRUPTIBLE); | 508 | set_current_state(TASK_INTERRUPTIBLE); |
509 | if (!timeo) { | 509 | if (!timeo) { |
@@ -526,7 +526,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | |||
526 | } | 526 | } |
527 | } | 527 | } |
528 | set_current_state(TASK_RUNNING); | 528 | set_current_state(TASK_RUNNING); |
529 | remove_wait_queue(sk->sk_sleep, &wait); | 529 | remove_wait_queue(sk_sleep(sk), &wait); |
530 | 530 | ||
531 | if (err) | 531 | if (err) |
532 | goto done; | 532 | goto done; |
@@ -621,7 +621,7 @@ static long rfcomm_sock_data_wait(struct sock *sk, long timeo) | |||
621 | { | 621 | { |
622 | DECLARE_WAITQUEUE(wait, current); | 622 | DECLARE_WAITQUEUE(wait, current); |
623 | 623 | ||
624 | add_wait_queue(sk->sk_sleep, &wait); | 624 | add_wait_queue(sk_sleep(sk), &wait); |
625 | for (;;) { | 625 | for (;;) { |
626 | set_current_state(TASK_INTERRUPTIBLE); | 626 | set_current_state(TASK_INTERRUPTIBLE); |
627 | 627 | ||
@@ -640,7 +640,7 @@ static long rfcomm_sock_data_wait(struct sock *sk, long timeo) | |||
640 | } | 640 | } |
641 | 641 | ||
642 | __set_current_state(TASK_RUNNING); | 642 | __set_current_state(TASK_RUNNING); |
643 | remove_wait_queue(sk->sk_sleep, &wait); | 643 | remove_wait_queue(sk_sleep(sk), &wait); |
644 | return timeo; | 644 | return timeo; |
645 | } | 645 | } |
646 | 646 | ||
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index ca6b2ad1c3fc..b406d3eff53a 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -567,7 +567,7 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag | |||
567 | BT_DBG("sk %p timeo %ld", sk, timeo); | 567 | BT_DBG("sk %p timeo %ld", sk, timeo); |
568 | 568 | ||
569 | /* Wait for an incoming connection. (wake-one). */ | 569 | /* Wait for an incoming connection. (wake-one). */ |
570 | add_wait_queue_exclusive(sk->sk_sleep, &wait); | 570 | add_wait_queue_exclusive(sk_sleep(sk), &wait); |
571 | while (!(ch = bt_accept_dequeue(sk, newsock))) { | 571 | while (!(ch = bt_accept_dequeue(sk, newsock))) { |
572 | set_current_state(TASK_INTERRUPTIBLE); | 572 | set_current_state(TASK_INTERRUPTIBLE); |
573 | if (!timeo) { | 573 | if (!timeo) { |
@@ -590,7 +590,7 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag | |||
590 | } | 590 | } |
591 | } | 591 | } |
592 | set_current_state(TASK_RUNNING); | 592 | set_current_state(TASK_RUNNING); |
593 | remove_wait_queue(sk->sk_sleep, &wait); | 593 | remove_wait_queue(sk_sleep(sk), &wait); |
594 | 594 | ||
595 | if (err) | 595 | if (err) |
596 | goto done; | 596 | goto done; |
diff --git a/net/bridge/Kconfig b/net/bridge/Kconfig index d115d5cea5b6..9190ae462cb4 100644 --- a/net/bridge/Kconfig +++ b/net/bridge/Kconfig | |||
@@ -33,14 +33,14 @@ config BRIDGE | |||
33 | If unsure, say N. | 33 | If unsure, say N. |
34 | 34 | ||
35 | config BRIDGE_IGMP_SNOOPING | 35 | config BRIDGE_IGMP_SNOOPING |
36 | bool "IGMP snooping" | 36 | bool "IGMP/MLD snooping" |
37 | depends on BRIDGE | 37 | depends on BRIDGE |
38 | depends on INET | 38 | depends on INET |
39 | default y | 39 | default y |
40 | ---help--- | 40 | ---help--- |
41 | If you say Y here, then the Ethernet bridge will be able selectively | 41 | If you say Y here, then the Ethernet bridge will be able selectively |
42 | forward multicast traffic based on IGMP traffic received from each | 42 | forward multicast traffic based on IGMP/MLD traffic received from |
43 | port. | 43 | each port. |
44 | 44 | ||
45 | Say N to exclude this support and reduce the binary size. | 45 | Say N to exclude this support and reduce the binary size. |
46 | 46 | ||
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 007bde87415d..f15f9c4a0dd2 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
@@ -13,9 +13,12 @@ | |||
13 | 13 | ||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/netdevice.h> | 15 | #include <linux/netdevice.h> |
16 | #include <linux/netpoll.h> | ||
16 | #include <linux/etherdevice.h> | 17 | #include <linux/etherdevice.h> |
17 | #include <linux/ethtool.h> | 18 | #include <linux/ethtool.h> |
19 | #include <linux/list.h> | ||
18 | #include <linux/netfilter_bridge.h> | 20 | #include <linux/netfilter_bridge.h> |
21 | |||
19 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
20 | #include "br_private.h" | 23 | #include "br_private.h" |
21 | 24 | ||
@@ -43,7 +46,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) | |||
43 | skb_reset_mac_header(skb); | 46 | skb_reset_mac_header(skb); |
44 | skb_pull(skb, ETH_HLEN); | 47 | skb_pull(skb, ETH_HLEN); |
45 | 48 | ||
46 | if (dest[0] & 1) { | 49 | if (is_multicast_ether_addr(dest)) { |
47 | if (br_multicast_rcv(br, NULL, skb)) | 50 | if (br_multicast_rcv(br, NULL, skb)) |
48 | goto out; | 51 | goto out; |
49 | 52 | ||
@@ -195,6 +198,59 @@ static int br_set_tx_csum(struct net_device *dev, u32 data) | |||
195 | return 0; | 198 | return 0; |
196 | } | 199 | } |
197 | 200 | ||
201 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
202 | bool br_devices_support_netpoll(struct net_bridge *br) | ||
203 | { | ||
204 | struct net_bridge_port *p; | ||
205 | bool ret = true; | ||
206 | int count = 0; | ||
207 | unsigned long flags; | ||
208 | |||
209 | spin_lock_irqsave(&br->lock, flags); | ||
210 | list_for_each_entry(p, &br->port_list, list) { | ||
211 | count++; | ||
212 | if ((p->dev->priv_flags & IFF_DISABLE_NETPOLL) || | ||
213 | !p->dev->netdev_ops->ndo_poll_controller) | ||
214 | ret = false; | ||
215 | } | ||
216 | spin_unlock_irqrestore(&br->lock, flags); | ||
217 | return count != 0 && ret; | ||
218 | } | ||
219 | |||
220 | static void br_poll_controller(struct net_device *br_dev) | ||
221 | { | ||
222 | struct netpoll *np = br_dev->npinfo->netpoll; | ||
223 | |||
224 | if (np->real_dev != br_dev) | ||
225 | netpoll_poll_dev(np->real_dev); | ||
226 | } | ||
227 | |||
228 | void br_netpoll_cleanup(struct net_device *br_dev) | ||
229 | { | ||
230 | struct net_bridge *br = netdev_priv(br_dev); | ||
231 | struct net_bridge_port *p, *n; | ||
232 | const struct net_device_ops *ops; | ||
233 | |||
234 | br->dev->npinfo = NULL; | ||
235 | list_for_each_entry_safe(p, n, &br->port_list, list) { | ||
236 | if (p->dev) { | ||
237 | ops = p->dev->netdev_ops; | ||
238 | if (ops->ndo_netpoll_cleanup) | ||
239 | ops->ndo_netpoll_cleanup(p->dev); | ||
240 | else | ||
241 | p->dev->npinfo = NULL; | ||
242 | } | ||
243 | } | ||
244 | } | ||
245 | |||
246 | #else | ||
247 | |||
248 | void br_netpoll_cleanup(struct net_device *br_dev) | ||
249 | { | ||
250 | } | ||
251 | |||
252 | #endif | ||
253 | |||
198 | static const struct ethtool_ops br_ethtool_ops = { | 254 | static const struct ethtool_ops br_ethtool_ops = { |
199 | .get_drvinfo = br_getinfo, | 255 | .get_drvinfo = br_getinfo, |
200 | .get_link = ethtool_op_get_link, | 256 | .get_link = ethtool_op_get_link, |
@@ -218,6 +274,10 @@ static const struct net_device_ops br_netdev_ops = { | |||
218 | .ndo_set_multicast_list = br_dev_set_multicast_list, | 274 | .ndo_set_multicast_list = br_dev_set_multicast_list, |
219 | .ndo_change_mtu = br_change_mtu, | 275 | .ndo_change_mtu = br_change_mtu, |
220 | .ndo_do_ioctl = br_dev_ioctl, | 276 | .ndo_do_ioctl = br_dev_ioctl, |
277 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
278 | .ndo_netpoll_cleanup = br_netpoll_cleanup, | ||
279 | .ndo_poll_controller = br_poll_controller, | ||
280 | #endif | ||
221 | }; | 281 | }; |
222 | 282 | ||
223 | static void br_dev_free(struct net_device *dev) | 283 | static void br_dev_free(struct net_device *dev) |
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 92fb3293a215..a98ef1393097 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/netdevice.h> | 17 | #include <linux/netdevice.h> |
18 | #include <linux/netpoll.h> | ||
18 | #include <linux/skbuff.h> | 19 | #include <linux/skbuff.h> |
19 | #include <linux/if_vlan.h> | 20 | #include <linux/if_vlan.h> |
20 | #include <linux/netfilter_bridge.h> | 21 | #include <linux/netfilter_bridge.h> |
@@ -50,7 +51,13 @@ int br_dev_queue_push_xmit(struct sk_buff *skb) | |||
50 | else { | 51 | else { |
51 | skb_push(skb, ETH_HLEN); | 52 | skb_push(skb, ETH_HLEN); |
52 | 53 | ||
53 | dev_queue_xmit(skb); | 54 | #ifdef CONFIG_NET_POLL_CONTROLLER |
55 | if (unlikely(skb->dev->priv_flags & IFF_IN_NETPOLL)) { | ||
56 | netpoll_send_skb(skb->dev->npinfo->netpoll, skb); | ||
57 | skb->dev->priv_flags &= ~IFF_IN_NETPOLL; | ||
58 | } else | ||
59 | #endif | ||
60 | dev_queue_xmit(skb); | ||
54 | } | 61 | } |
55 | } | 62 | } |
56 | 63 | ||
@@ -66,9 +73,23 @@ int br_forward_finish(struct sk_buff *skb) | |||
66 | 73 | ||
67 | static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb) | 74 | static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb) |
68 | { | 75 | { |
76 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
77 | struct net_bridge *br = to->br; | ||
78 | if (unlikely(br->dev->priv_flags & IFF_IN_NETPOLL)) { | ||
79 | struct netpoll *np; | ||
80 | to->dev->npinfo = skb->dev->npinfo; | ||
81 | np = skb->dev->npinfo->netpoll; | ||
82 | np->real_dev = np->dev = to->dev; | ||
83 | to->dev->priv_flags |= IFF_IN_NETPOLL; | ||
84 | } | ||
85 | #endif | ||
69 | skb->dev = to->dev; | 86 | skb->dev = to->dev; |
70 | NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, | 87 | NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, |
71 | br_forward_finish); | 88 | br_forward_finish); |
89 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
90 | if (skb->dev->npinfo) | ||
91 | skb->dev->npinfo->netpoll->dev = br->dev; | ||
92 | #endif | ||
72 | } | 93 | } |
73 | 94 | ||
74 | static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb) | 95 | static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb) |
@@ -208,17 +229,15 @@ static void br_multicast_flood(struct net_bridge_mdb_entry *mdst, | |||
208 | { | 229 | { |
209 | struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev; | 230 | struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev; |
210 | struct net_bridge *br = netdev_priv(dev); | 231 | struct net_bridge *br = netdev_priv(dev); |
211 | struct net_bridge_port *port; | 232 | struct net_bridge_port *prev = NULL; |
212 | struct net_bridge_port *lport, *rport; | ||
213 | struct net_bridge_port *prev; | ||
214 | struct net_bridge_port_group *p; | 233 | struct net_bridge_port_group *p; |
215 | struct hlist_node *rp; | 234 | struct hlist_node *rp; |
216 | 235 | ||
217 | prev = NULL; | 236 | rp = rcu_dereference(br->router_list.first); |
218 | 237 | p = mdst ? rcu_dereference(mdst->ports) : NULL; | |
219 | rp = br->router_list.first; | ||
220 | p = mdst ? mdst->ports : NULL; | ||
221 | while (p || rp) { | 238 | while (p || rp) { |
239 | struct net_bridge_port *port, *lport, *rport; | ||
240 | |||
222 | lport = p ? p->port : NULL; | 241 | lport = p ? p->port : NULL; |
223 | rport = rp ? hlist_entry(rp, struct net_bridge_port, rlist) : | 242 | rport = rp ? hlist_entry(rp, struct net_bridge_port, rlist) : |
224 | NULL; | 243 | NULL; |
@@ -231,9 +250,9 @@ static void br_multicast_flood(struct net_bridge_mdb_entry *mdst, | |||
231 | goto out; | 250 | goto out; |
232 | 251 | ||
233 | if ((unsigned long)lport >= (unsigned long)port) | 252 | if ((unsigned long)lport >= (unsigned long)port) |
234 | p = p->next; | 253 | p = rcu_dereference(p->next); |
235 | if ((unsigned long)rport >= (unsigned long)port) | 254 | if ((unsigned long)rport >= (unsigned long)port) |
236 | rp = rp->next; | 255 | rp = rcu_dereference(rp->next); |
237 | } | 256 | } |
238 | 257 | ||
239 | if (!prev) | 258 | if (!prev) |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 521439333316..537bdd60d9b9 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/netdevice.h> | 15 | #include <linux/netdevice.h> |
16 | #include <linux/netpoll.h> | ||
16 | #include <linux/ethtool.h> | 17 | #include <linux/ethtool.h> |
17 | #include <linux/if_arp.h> | 18 | #include <linux/if_arp.h> |
18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
@@ -153,6 +154,14 @@ static void del_nbp(struct net_bridge_port *p) | |||
153 | kobject_uevent(&p->kobj, KOBJ_REMOVE); | 154 | kobject_uevent(&p->kobj, KOBJ_REMOVE); |
154 | kobject_del(&p->kobj); | 155 | kobject_del(&p->kobj); |
155 | 156 | ||
157 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
158 | if (br_devices_support_netpoll(br)) | ||
159 | br->dev->priv_flags &= ~IFF_DISABLE_NETPOLL; | ||
160 | if (dev->netdev_ops->ndo_netpoll_cleanup) | ||
161 | dev->netdev_ops->ndo_netpoll_cleanup(dev); | ||
162 | else | ||
163 | dev->npinfo = NULL; | ||
164 | #endif | ||
156 | call_rcu(&p->rcu, destroy_nbp_rcu); | 165 | call_rcu(&p->rcu, destroy_nbp_rcu); |
157 | } | 166 | } |
158 | 167 | ||
@@ -165,6 +174,8 @@ static void del_br(struct net_bridge *br, struct list_head *head) | |||
165 | del_nbp(p); | 174 | del_nbp(p); |
166 | } | 175 | } |
167 | 176 | ||
177 | br_netpoll_cleanup(br->dev); | ||
178 | |||
168 | del_timer_sync(&br->gc_timer); | 179 | del_timer_sync(&br->gc_timer); |
169 | 180 | ||
170 | br_sysfs_delbr(br->dev); | 181 | br_sysfs_delbr(br->dev); |
@@ -444,6 +455,20 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
444 | 455 | ||
445 | kobject_uevent(&p->kobj, KOBJ_ADD); | 456 | kobject_uevent(&p->kobj, KOBJ_ADD); |
446 | 457 | ||
458 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
459 | if (br_devices_support_netpoll(br)) { | ||
460 | br->dev->priv_flags &= ~IFF_DISABLE_NETPOLL; | ||
461 | if (br->dev->npinfo) | ||
462 | dev->npinfo = br->dev->npinfo; | ||
463 | } else if (!(br->dev->priv_flags & IFF_DISABLE_NETPOLL)) { | ||
464 | br->dev->priv_flags |= IFF_DISABLE_NETPOLL; | ||
465 | printk(KERN_INFO "New device %s does not support netpoll\n", | ||
466 | dev->name); | ||
467 | printk(KERN_INFO "Disabling netpoll for %s\n", | ||
468 | br->dev->name); | ||
469 | } | ||
470 | #endif | ||
471 | |||
447 | return 0; | 472 | return 0; |
448 | err2: | 473 | err2: |
449 | br_fdb_delete_by_port(br, p, 1); | 474 | br_fdb_delete_by_port(br, p, 1); |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 8ccdb8ee3928..c8419e240316 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -24,51 +24,139 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/timer.h> | 25 | #include <linux/timer.h> |
26 | #include <net/ip.h> | 26 | #include <net/ip.h> |
27 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
28 | #include <net/ipv6.h> | ||
29 | #include <net/mld.h> | ||
30 | #include <net/addrconf.h> | ||
31 | #include <net/ip6_checksum.h> | ||
32 | #endif | ||
27 | 33 | ||
28 | #include "br_private.h" | 34 | #include "br_private.h" |
29 | 35 | ||
30 | static inline int br_ip_hash(struct net_bridge_mdb_htable *mdb, __be32 ip) | 36 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
37 | static inline int ipv6_is_local_multicast(const struct in6_addr *addr) | ||
31 | { | 38 | { |
32 | return jhash_1word(mdb->secret, (u32)ip) & (mdb->max - 1); | 39 | if (ipv6_addr_is_multicast(addr) && |
40 | IPV6_ADDR_MC_SCOPE(addr) <= IPV6_ADDR_SCOPE_LINKLOCAL) | ||
41 | return 1; | ||
42 | return 0; | ||
43 | } | ||
44 | #endif | ||
45 | |||
46 | static inline int br_ip_equal(const struct br_ip *a, const struct br_ip *b) | ||
47 | { | ||
48 | if (a->proto != b->proto) | ||
49 | return 0; | ||
50 | switch (a->proto) { | ||
51 | case htons(ETH_P_IP): | ||
52 | return a->u.ip4 == b->u.ip4; | ||
53 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
54 | case htons(ETH_P_IPV6): | ||
55 | return ipv6_addr_equal(&a->u.ip6, &b->u.ip6); | ||
56 | #endif | ||
57 | } | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static inline int __br_ip4_hash(struct net_bridge_mdb_htable *mdb, __be32 ip) | ||
62 | { | ||
63 | return jhash_1word(mdb->secret, (__force u32)ip) & (mdb->max - 1); | ||
64 | } | ||
65 | |||
66 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
67 | static inline int __br_ip6_hash(struct net_bridge_mdb_htable *mdb, | ||
68 | const struct in6_addr *ip) | ||
69 | { | ||
70 | return jhash2((__force u32 *)ip->s6_addr32, 4, mdb->secret) & (mdb->max - 1); | ||
71 | } | ||
72 | #endif | ||
73 | |||
74 | static inline int br_ip_hash(struct net_bridge_mdb_htable *mdb, | ||
75 | struct br_ip *ip) | ||
76 | { | ||
77 | switch (ip->proto) { | ||
78 | case htons(ETH_P_IP): | ||
79 | return __br_ip4_hash(mdb, ip->u.ip4); | ||
80 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
81 | case htons(ETH_P_IPV6): | ||
82 | return __br_ip6_hash(mdb, &ip->u.ip6); | ||
83 | #endif | ||
84 | } | ||
85 | return 0; | ||
33 | } | 86 | } |
34 | 87 | ||
35 | static struct net_bridge_mdb_entry *__br_mdb_ip_get( | 88 | static struct net_bridge_mdb_entry *__br_mdb_ip_get( |
36 | struct net_bridge_mdb_htable *mdb, __be32 dst, int hash) | 89 | struct net_bridge_mdb_htable *mdb, struct br_ip *dst, int hash) |
37 | { | 90 | { |
38 | struct net_bridge_mdb_entry *mp; | 91 | struct net_bridge_mdb_entry *mp; |
39 | struct hlist_node *p; | 92 | struct hlist_node *p; |
40 | 93 | ||
41 | hlist_for_each_entry_rcu(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) { | 94 | hlist_for_each_entry_rcu(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) { |
42 | if (dst == mp->addr) | 95 | if (br_ip_equal(&mp->addr, dst)) |
43 | return mp; | 96 | return mp; |
44 | } | 97 | } |
45 | 98 | ||
46 | return NULL; | 99 | return NULL; |
47 | } | 100 | } |
48 | 101 | ||
49 | static struct net_bridge_mdb_entry *br_mdb_ip_get( | 102 | static struct net_bridge_mdb_entry *br_mdb_ip4_get( |
50 | struct net_bridge_mdb_htable *mdb, __be32 dst) | 103 | struct net_bridge_mdb_htable *mdb, __be32 dst) |
51 | { | 104 | { |
52 | if (!mdb) | 105 | struct br_ip br_dst; |
53 | return NULL; | 106 | |
107 | br_dst.u.ip4 = dst; | ||
108 | br_dst.proto = htons(ETH_P_IP); | ||
109 | |||
110 | return __br_mdb_ip_get(mdb, &br_dst, __br_ip4_hash(mdb, dst)); | ||
111 | } | ||
112 | |||
113 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
114 | static struct net_bridge_mdb_entry *br_mdb_ip6_get( | ||
115 | struct net_bridge_mdb_htable *mdb, const struct in6_addr *dst) | ||
116 | { | ||
117 | struct br_ip br_dst; | ||
54 | 118 | ||
119 | ipv6_addr_copy(&br_dst.u.ip6, dst); | ||
120 | br_dst.proto = htons(ETH_P_IPV6); | ||
121 | |||
122 | return __br_mdb_ip_get(mdb, &br_dst, __br_ip6_hash(mdb, dst)); | ||
123 | } | ||
124 | #endif | ||
125 | |||
126 | static struct net_bridge_mdb_entry *br_mdb_ip_get( | ||
127 | struct net_bridge_mdb_htable *mdb, struct br_ip *dst) | ||
128 | { | ||
55 | return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst)); | 129 | return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst)); |
56 | } | 130 | } |
57 | 131 | ||
58 | struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, | 132 | struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, |
59 | struct sk_buff *skb) | 133 | struct sk_buff *skb) |
60 | { | 134 | { |
61 | if (br->multicast_disabled) | 135 | struct net_bridge_mdb_htable *mdb = br->mdb; |
136 | struct br_ip ip; | ||
137 | |||
138 | if (!mdb || br->multicast_disabled) | ||
139 | return NULL; | ||
140 | |||
141 | if (BR_INPUT_SKB_CB(skb)->igmp) | ||
62 | return NULL; | 142 | return NULL; |
63 | 143 | ||
144 | ip.proto = skb->protocol; | ||
145 | |||
64 | switch (skb->protocol) { | 146 | switch (skb->protocol) { |
65 | case htons(ETH_P_IP): | 147 | case htons(ETH_P_IP): |
66 | if (BR_INPUT_SKB_CB(skb)->igmp) | 148 | ip.u.ip4 = ip_hdr(skb)->daddr; |
67 | break; | 149 | break; |
68 | return br_mdb_ip_get(br->mdb, ip_hdr(skb)->daddr); | 150 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
151 | case htons(ETH_P_IPV6): | ||
152 | ipv6_addr_copy(&ip.u.ip6, &ipv6_hdr(skb)->daddr); | ||
153 | break; | ||
154 | #endif | ||
155 | default: | ||
156 | return NULL; | ||
69 | } | 157 | } |
70 | 158 | ||
71 | return NULL; | 159 | return br_mdb_ip_get(mdb, &ip); |
72 | } | 160 | } |
73 | 161 | ||
74 | static void br_mdb_free(struct rcu_head *head) | 162 | static void br_mdb_free(struct rcu_head *head) |
@@ -95,7 +183,7 @@ static int br_mdb_copy(struct net_bridge_mdb_htable *new, | |||
95 | for (i = 0; i < old->max; i++) | 183 | for (i = 0; i < old->max; i++) |
96 | hlist_for_each_entry(mp, p, &old->mhash[i], hlist[old->ver]) | 184 | hlist_for_each_entry(mp, p, &old->mhash[i], hlist[old->ver]) |
97 | hlist_add_head(&mp->hlist[new->ver], | 185 | hlist_add_head(&mp->hlist[new->ver], |
98 | &new->mhash[br_ip_hash(new, mp->addr)]); | 186 | &new->mhash[br_ip_hash(new, &mp->addr)]); |
99 | 187 | ||
100 | if (!elasticity) | 188 | if (!elasticity) |
101 | return 0; | 189 | return 0; |
@@ -163,7 +251,7 @@ static void br_multicast_del_pg(struct net_bridge *br, | |||
163 | struct net_bridge_port_group *p; | 251 | struct net_bridge_port_group *p; |
164 | struct net_bridge_port_group **pp; | 252 | struct net_bridge_port_group **pp; |
165 | 253 | ||
166 | mp = br_mdb_ip_get(mdb, pg->addr); | 254 | mp = br_mdb_ip_get(mdb, &pg->addr); |
167 | if (WARN_ON(!mp)) | 255 | if (WARN_ON(!mp)) |
168 | return; | 256 | return; |
169 | 257 | ||
@@ -171,7 +259,7 @@ static void br_multicast_del_pg(struct net_bridge *br, | |||
171 | if (p != pg) | 259 | if (p != pg) |
172 | continue; | 260 | continue; |
173 | 261 | ||
174 | *pp = p->next; | 262 | rcu_assign_pointer(*pp, p->next); |
175 | hlist_del_init(&p->mglist); | 263 | hlist_del_init(&p->mglist); |
176 | del_timer(&p->timer); | 264 | del_timer(&p->timer); |
177 | del_timer(&p->query_timer); | 265 | del_timer(&p->query_timer); |
@@ -249,8 +337,8 @@ out: | |||
249 | return 0; | 337 | return 0; |
250 | } | 338 | } |
251 | 339 | ||
252 | static struct sk_buff *br_multicast_alloc_query(struct net_bridge *br, | 340 | static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge *br, |
253 | __be32 group) | 341 | __be32 group) |
254 | { | 342 | { |
255 | struct sk_buff *skb; | 343 | struct sk_buff *skb; |
256 | struct igmphdr *ih; | 344 | struct igmphdr *ih; |
@@ -314,12 +402,104 @@ out: | |||
314 | return skb; | 402 | return skb; |
315 | } | 403 | } |
316 | 404 | ||
405 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
406 | static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, | ||
407 | struct in6_addr *group) | ||
408 | { | ||
409 | struct sk_buff *skb; | ||
410 | struct ipv6hdr *ip6h; | ||
411 | struct mld_msg *mldq; | ||
412 | struct ethhdr *eth; | ||
413 | u8 *hopopt; | ||
414 | unsigned long interval; | ||
415 | |||
416 | skb = netdev_alloc_skb_ip_align(br->dev, sizeof(*eth) + sizeof(*ip6h) + | ||
417 | 8 + sizeof(*mldq)); | ||
418 | if (!skb) | ||
419 | goto out; | ||
420 | |||
421 | skb->protocol = htons(ETH_P_IPV6); | ||
422 | |||
423 | /* Ethernet header */ | ||
424 | skb_reset_mac_header(skb); | ||
425 | eth = eth_hdr(skb); | ||
426 | |||
427 | memcpy(eth->h_source, br->dev->dev_addr, 6); | ||
428 | ipv6_eth_mc_map(group, eth->h_dest); | ||
429 | eth->h_proto = htons(ETH_P_IPV6); | ||
430 | skb_put(skb, sizeof(*eth)); | ||
431 | |||
432 | /* IPv6 header + HbH option */ | ||
433 | skb_set_network_header(skb, skb->len); | ||
434 | ip6h = ipv6_hdr(skb); | ||
435 | |||
436 | *(__force __be32 *)ip6h = htonl(0x60000000); | ||
437 | ip6h->payload_len = 8 + sizeof(*mldq); | ||
438 | ip6h->nexthdr = IPPROTO_HOPOPTS; | ||
439 | ip6h->hop_limit = 1; | ||
440 | ipv6_addr_set(&ip6h->saddr, 0, 0, 0, 0); | ||
441 | ipv6_addr_set(&ip6h->daddr, htonl(0xff020000), 0, 0, htonl(1)); | ||
442 | |||
443 | hopopt = (u8 *)(ip6h + 1); | ||
444 | hopopt[0] = IPPROTO_ICMPV6; /* next hdr */ | ||
445 | hopopt[1] = 0; /* length of HbH */ | ||
446 | hopopt[2] = IPV6_TLV_ROUTERALERT; /* Router Alert */ | ||
447 | hopopt[3] = 2; /* Length of RA Option */ | ||
448 | hopopt[4] = 0; /* Type = 0x0000 (MLD) */ | ||
449 | hopopt[5] = 0; | ||
450 | hopopt[6] = IPV6_TLV_PAD0; /* Pad0 */ | ||
451 | hopopt[7] = IPV6_TLV_PAD0; /* Pad0 */ | ||
452 | |||
453 | skb_put(skb, sizeof(*ip6h) + 8); | ||
454 | |||
455 | /* ICMPv6 */ | ||
456 | skb_set_transport_header(skb, skb->len); | ||
457 | mldq = (struct mld_msg *) icmp6_hdr(skb); | ||
458 | |||
459 | interval = ipv6_addr_any(group) ? br->multicast_last_member_interval : | ||
460 | br->multicast_query_response_interval; | ||
461 | |||
462 | mldq->mld_type = ICMPV6_MGM_QUERY; | ||
463 | mldq->mld_code = 0; | ||
464 | mldq->mld_cksum = 0; | ||
465 | mldq->mld_maxdelay = htons((u16)jiffies_to_msecs(interval)); | ||
466 | mldq->mld_reserved = 0; | ||
467 | ipv6_addr_copy(&mldq->mld_mca, group); | ||
468 | |||
469 | /* checksum */ | ||
470 | mldq->mld_cksum = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, | ||
471 | sizeof(*mldq), IPPROTO_ICMPV6, | ||
472 | csum_partial(mldq, | ||
473 | sizeof(*mldq), 0)); | ||
474 | skb_put(skb, sizeof(*mldq)); | ||
475 | |||
476 | __skb_pull(skb, sizeof(*eth)); | ||
477 | |||
478 | out: | ||
479 | return skb; | ||
480 | } | ||
481 | #endif | ||
482 | |||
483 | static struct sk_buff *br_multicast_alloc_query(struct net_bridge *br, | ||
484 | struct br_ip *addr) | ||
485 | { | ||
486 | switch (addr->proto) { | ||
487 | case htons(ETH_P_IP): | ||
488 | return br_ip4_multicast_alloc_query(br, addr->u.ip4); | ||
489 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
490 | case htons(ETH_P_IPV6): | ||
491 | return br_ip6_multicast_alloc_query(br, &addr->u.ip6); | ||
492 | #endif | ||
493 | } | ||
494 | return NULL; | ||
495 | } | ||
496 | |||
317 | static void br_multicast_send_group_query(struct net_bridge_mdb_entry *mp) | 497 | static void br_multicast_send_group_query(struct net_bridge_mdb_entry *mp) |
318 | { | 498 | { |
319 | struct net_bridge *br = mp->br; | 499 | struct net_bridge *br = mp->br; |
320 | struct sk_buff *skb; | 500 | struct sk_buff *skb; |
321 | 501 | ||
322 | skb = br_multicast_alloc_query(br, mp->addr); | 502 | skb = br_multicast_alloc_query(br, &mp->addr); |
323 | if (!skb) | 503 | if (!skb) |
324 | goto timer; | 504 | goto timer; |
325 | 505 | ||
@@ -353,7 +533,7 @@ static void br_multicast_send_port_group_query(struct net_bridge_port_group *pg) | |||
353 | struct net_bridge *br = port->br; | 533 | struct net_bridge *br = port->br; |
354 | struct sk_buff *skb; | 534 | struct sk_buff *skb; |
355 | 535 | ||
356 | skb = br_multicast_alloc_query(br, pg->addr); | 536 | skb = br_multicast_alloc_query(br, &pg->addr); |
357 | if (!skb) | 537 | if (!skb) |
358 | goto timer; | 538 | goto timer; |
359 | 539 | ||
@@ -383,8 +563,8 @@ out: | |||
383 | } | 563 | } |
384 | 564 | ||
385 | static struct net_bridge_mdb_entry *br_multicast_get_group( | 565 | static struct net_bridge_mdb_entry *br_multicast_get_group( |
386 | struct net_bridge *br, struct net_bridge_port *port, __be32 group, | 566 | struct net_bridge *br, struct net_bridge_port *port, |
387 | int hash) | 567 | struct br_ip *group, int hash) |
388 | { | 568 | { |
389 | struct net_bridge_mdb_htable *mdb = br->mdb; | 569 | struct net_bridge_mdb_htable *mdb = br->mdb; |
390 | struct net_bridge_mdb_entry *mp; | 570 | struct net_bridge_mdb_entry *mp; |
@@ -396,9 +576,8 @@ static struct net_bridge_mdb_entry *br_multicast_get_group( | |||
396 | 576 | ||
397 | hlist_for_each_entry(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) { | 577 | hlist_for_each_entry(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) { |
398 | count++; | 578 | count++; |
399 | if (unlikely(group == mp->addr)) { | 579 | if (unlikely(br_ip_equal(group, &mp->addr))) |
400 | return mp; | 580 | return mp; |
401 | } | ||
402 | } | 581 | } |
403 | 582 | ||
404 | elasticity = 0; | 583 | elasticity = 0; |
@@ -463,7 +642,8 @@ err: | |||
463 | } | 642 | } |
464 | 643 | ||
465 | static struct net_bridge_mdb_entry *br_multicast_new_group( | 644 | static struct net_bridge_mdb_entry *br_multicast_new_group( |
466 | struct net_bridge *br, struct net_bridge_port *port, __be32 group) | 645 | struct net_bridge *br, struct net_bridge_port *port, |
646 | struct br_ip *group) | ||
467 | { | 647 | { |
468 | struct net_bridge_mdb_htable *mdb = br->mdb; | 648 | struct net_bridge_mdb_htable *mdb = br->mdb; |
469 | struct net_bridge_mdb_entry *mp; | 649 | struct net_bridge_mdb_entry *mp; |
@@ -496,7 +676,7 @@ rehash: | |||
496 | goto out; | 676 | goto out; |
497 | 677 | ||
498 | mp->br = br; | 678 | mp->br = br; |
499 | mp->addr = group; | 679 | mp->addr = *group; |
500 | setup_timer(&mp->timer, br_multicast_group_expired, | 680 | setup_timer(&mp->timer, br_multicast_group_expired, |
501 | (unsigned long)mp); | 681 | (unsigned long)mp); |
502 | setup_timer(&mp->query_timer, br_multicast_group_query_expired, | 682 | setup_timer(&mp->query_timer, br_multicast_group_query_expired, |
@@ -510,7 +690,8 @@ out: | |||
510 | } | 690 | } |
511 | 691 | ||
512 | static int br_multicast_add_group(struct net_bridge *br, | 692 | static int br_multicast_add_group(struct net_bridge *br, |
513 | struct net_bridge_port *port, __be32 group) | 693 | struct net_bridge_port *port, |
694 | struct br_ip *group) | ||
514 | { | 695 | { |
515 | struct net_bridge_mdb_entry *mp; | 696 | struct net_bridge_mdb_entry *mp; |
516 | struct net_bridge_port_group *p; | 697 | struct net_bridge_port_group *p; |
@@ -518,9 +699,6 @@ static int br_multicast_add_group(struct net_bridge *br, | |||
518 | unsigned long now = jiffies; | 699 | unsigned long now = jiffies; |
519 | int err; | 700 | int err; |
520 | 701 | ||
521 | if (ipv4_is_local_multicast(group)) | ||
522 | return 0; | ||
523 | |||
524 | spin_lock(&br->multicast_lock); | 702 | spin_lock(&br->multicast_lock); |
525 | if (!netif_running(br->dev) || | 703 | if (!netif_running(br->dev) || |
526 | (port && port->state == BR_STATE_DISABLED)) | 704 | (port && port->state == BR_STATE_DISABLED)) |
@@ -549,7 +727,7 @@ static int br_multicast_add_group(struct net_bridge *br, | |||
549 | if (unlikely(!p)) | 727 | if (unlikely(!p)) |
550 | goto err; | 728 | goto err; |
551 | 729 | ||
552 | p->addr = group; | 730 | p->addr = *group; |
553 | p->port = port; | 731 | p->port = port; |
554 | p->next = *pp; | 732 | p->next = *pp; |
555 | hlist_add_head(&p->mglist, &port->mglist); | 733 | hlist_add_head(&p->mglist, &port->mglist); |
@@ -570,6 +748,38 @@ err: | |||
570 | return err; | 748 | return err; |
571 | } | 749 | } |
572 | 750 | ||
751 | static int br_ip4_multicast_add_group(struct net_bridge *br, | ||
752 | struct net_bridge_port *port, | ||
753 | __be32 group) | ||
754 | { | ||
755 | struct br_ip br_group; | ||
756 | |||
757 | if (ipv4_is_local_multicast(group)) | ||
758 | return 0; | ||
759 | |||
760 | br_group.u.ip4 = group; | ||
761 | br_group.proto = htons(ETH_P_IP); | ||
762 | |||
763 | return br_multicast_add_group(br, port, &br_group); | ||
764 | } | ||
765 | |||
766 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
767 | static int br_ip6_multicast_add_group(struct net_bridge *br, | ||
768 | struct net_bridge_port *port, | ||
769 | const struct in6_addr *group) | ||
770 | { | ||
771 | struct br_ip br_group; | ||
772 | |||
773 | if (ipv6_is_local_multicast(group)) | ||
774 | return 0; | ||
775 | |||
776 | ipv6_addr_copy(&br_group.u.ip6, group); | ||
777 | br_group.proto = htons(ETH_P_IP); | ||
778 | |||
779 | return br_multicast_add_group(br, port, &br_group); | ||
780 | } | ||
781 | #endif | ||
782 | |||
573 | static void br_multicast_router_expired(unsigned long data) | 783 | static void br_multicast_router_expired(unsigned long data) |
574 | { | 784 | { |
575 | struct net_bridge_port *port = (void *)data; | 785 | struct net_bridge_port *port = (void *)data; |
@@ -591,19 +801,15 @@ static void br_multicast_local_router_expired(unsigned long data) | |||
591 | { | 801 | { |
592 | } | 802 | } |
593 | 803 | ||
594 | static void br_multicast_send_query(struct net_bridge *br, | 804 | static void __br_multicast_send_query(struct net_bridge *br, |
595 | struct net_bridge_port *port, u32 sent) | 805 | struct net_bridge_port *port, |
806 | struct br_ip *ip) | ||
596 | { | 807 | { |
597 | unsigned long time; | ||
598 | struct sk_buff *skb; | 808 | struct sk_buff *skb; |
599 | 809 | ||
600 | if (!netif_running(br->dev) || br->multicast_disabled || | 810 | skb = br_multicast_alloc_query(br, ip); |
601 | timer_pending(&br->multicast_querier_timer)) | ||
602 | return; | ||
603 | |||
604 | skb = br_multicast_alloc_query(br, 0); | ||
605 | if (!skb) | 811 | if (!skb) |
606 | goto timer; | 812 | return; |
607 | 813 | ||
608 | if (port) { | 814 | if (port) { |
609 | __skb_push(skb, sizeof(struct ethhdr)); | 815 | __skb_push(skb, sizeof(struct ethhdr)); |
@@ -612,8 +818,28 @@ static void br_multicast_send_query(struct net_bridge *br, | |||
612 | dev_queue_xmit); | 818 | dev_queue_xmit); |
613 | } else | 819 | } else |
614 | netif_rx(skb); | 820 | netif_rx(skb); |
821 | } | ||
822 | |||
823 | static void br_multicast_send_query(struct net_bridge *br, | ||
824 | struct net_bridge_port *port, u32 sent) | ||
825 | { | ||
826 | unsigned long time; | ||
827 | struct br_ip br_group; | ||
828 | |||
829 | if (!netif_running(br->dev) || br->multicast_disabled || | ||
830 | timer_pending(&br->multicast_querier_timer)) | ||
831 | return; | ||
832 | |||
833 | memset(&br_group.u, 0, sizeof(br_group.u)); | ||
834 | |||
835 | br_group.proto = htons(ETH_P_IP); | ||
836 | __br_multicast_send_query(br, port, &br_group); | ||
837 | |||
838 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
839 | br_group.proto = htons(ETH_P_IPV6); | ||
840 | __br_multicast_send_query(br, port, &br_group); | ||
841 | #endif | ||
615 | 842 | ||
616 | timer: | ||
617 | time = jiffies; | 843 | time = jiffies; |
618 | time += sent < br->multicast_startup_query_count ? | 844 | time += sent < br->multicast_startup_query_count ? |
619 | br->multicast_startup_query_interval : | 845 | br->multicast_startup_query_interval : |
@@ -698,9 +924,9 @@ void br_multicast_disable_port(struct net_bridge_port *port) | |||
698 | spin_unlock(&br->multicast_lock); | 924 | spin_unlock(&br->multicast_lock); |
699 | } | 925 | } |
700 | 926 | ||
701 | static int br_multicast_igmp3_report(struct net_bridge *br, | 927 | static int br_ip4_multicast_igmp3_report(struct net_bridge *br, |
702 | struct net_bridge_port *port, | 928 | struct net_bridge_port *port, |
703 | struct sk_buff *skb) | 929 | struct sk_buff *skb) |
704 | { | 930 | { |
705 | struct igmpv3_report *ih; | 931 | struct igmpv3_report *ih; |
706 | struct igmpv3_grec *grec; | 932 | struct igmpv3_grec *grec; |
@@ -727,7 +953,7 @@ static int br_multicast_igmp3_report(struct net_bridge *br, | |||
727 | group = grec->grec_mca; | 953 | group = grec->grec_mca; |
728 | type = grec->grec_type; | 954 | type = grec->grec_type; |
729 | 955 | ||
730 | len += grec->grec_nsrcs * 4; | 956 | len += ntohs(grec->grec_nsrcs) * 4; |
731 | if (!pskb_may_pull(skb, len)) | 957 | if (!pskb_may_pull(skb, len)) |
732 | return -EINVAL; | 958 | return -EINVAL; |
733 | 959 | ||
@@ -745,7 +971,7 @@ static int br_multicast_igmp3_report(struct net_bridge *br, | |||
745 | continue; | 971 | continue; |
746 | } | 972 | } |
747 | 973 | ||
748 | err = br_multicast_add_group(br, port, group); | 974 | err = br_ip4_multicast_add_group(br, port, group); |
749 | if (err) | 975 | if (err) |
750 | break; | 976 | break; |
751 | } | 977 | } |
@@ -753,24 +979,87 @@ static int br_multicast_igmp3_report(struct net_bridge *br, | |||
753 | return err; | 979 | return err; |
754 | } | 980 | } |
755 | 981 | ||
982 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
983 | static int br_ip6_multicast_mld2_report(struct net_bridge *br, | ||
984 | struct net_bridge_port *port, | ||
985 | struct sk_buff *skb) | ||
986 | { | ||
987 | struct icmp6hdr *icmp6h; | ||
988 | struct mld2_grec *grec; | ||
989 | int i; | ||
990 | int len; | ||
991 | int num; | ||
992 | int err = 0; | ||
993 | |||
994 | if (!pskb_may_pull(skb, sizeof(*icmp6h))) | ||
995 | return -EINVAL; | ||
996 | |||
997 | icmp6h = icmp6_hdr(skb); | ||
998 | num = ntohs(icmp6h->icmp6_dataun.un_data16[1]); | ||
999 | len = sizeof(*icmp6h); | ||
1000 | |||
1001 | for (i = 0; i < num; i++) { | ||
1002 | __be16 *nsrcs, _nsrcs; | ||
1003 | |||
1004 | nsrcs = skb_header_pointer(skb, | ||
1005 | len + offsetof(struct mld2_grec, | ||
1006 | grec_mca), | ||
1007 | sizeof(_nsrcs), &_nsrcs); | ||
1008 | if (!nsrcs) | ||
1009 | return -EINVAL; | ||
1010 | |||
1011 | if (!pskb_may_pull(skb, | ||
1012 | len + sizeof(*grec) + | ||
1013 | sizeof(struct in6_addr) * (*nsrcs))) | ||
1014 | return -EINVAL; | ||
1015 | |||
1016 | grec = (struct mld2_grec *)(skb->data + len); | ||
1017 | len += sizeof(*grec) + sizeof(struct in6_addr) * (*nsrcs); | ||
1018 | |||
1019 | /* We treat these as MLDv1 reports for now. */ | ||
1020 | switch (grec->grec_type) { | ||
1021 | case MLD2_MODE_IS_INCLUDE: | ||
1022 | case MLD2_MODE_IS_EXCLUDE: | ||
1023 | case MLD2_CHANGE_TO_INCLUDE: | ||
1024 | case MLD2_CHANGE_TO_EXCLUDE: | ||
1025 | case MLD2_ALLOW_NEW_SOURCES: | ||
1026 | case MLD2_BLOCK_OLD_SOURCES: | ||
1027 | break; | ||
1028 | |||
1029 | default: | ||
1030 | continue; | ||
1031 | } | ||
1032 | |||
1033 | err = br_ip6_multicast_add_group(br, port, &grec->grec_mca); | ||
1034 | if (!err) | ||
1035 | break; | ||
1036 | } | ||
1037 | |||
1038 | return err; | ||
1039 | } | ||
1040 | #endif | ||
1041 | |||
1042 | /* | ||
1043 | * Add port to rotuer_list | ||
1044 | * list is maintained ordered by pointer value | ||
1045 | * and locked by br->multicast_lock and RCU | ||
1046 | */ | ||
756 | static void br_multicast_add_router(struct net_bridge *br, | 1047 | static void br_multicast_add_router(struct net_bridge *br, |
757 | struct net_bridge_port *port) | 1048 | struct net_bridge_port *port) |
758 | { | 1049 | { |
759 | struct hlist_node *p; | 1050 | struct net_bridge_port *p; |
760 | struct hlist_node **h; | 1051 | struct hlist_node *n, *slot = NULL; |
761 | 1052 | ||
762 | for (h = &br->router_list.first; | 1053 | hlist_for_each_entry(p, n, &br->router_list, rlist) { |
763 | (p = *h) && | 1054 | if ((unsigned long) port >= (unsigned long) p) |
764 | (unsigned long)container_of(p, struct net_bridge_port, rlist) > | 1055 | break; |
765 | (unsigned long)port; | 1056 | slot = n; |
766 | h = &p->next) | 1057 | } |
767 | ; | 1058 | |
768 | 1059 | if (slot) | |
769 | port->rlist.pprev = h; | 1060 | hlist_add_after_rcu(slot, &port->rlist); |
770 | port->rlist.next = p; | 1061 | else |
771 | rcu_assign_pointer(*h, &port->rlist); | 1062 | hlist_add_head_rcu(&port->rlist, &br->router_list); |
772 | if (p) | ||
773 | p->pprev = &port->rlist.next; | ||
774 | } | 1063 | } |
775 | 1064 | ||
776 | static void br_multicast_mark_router(struct net_bridge *br, | 1065 | static void br_multicast_mark_router(struct net_bridge *br, |
@@ -800,7 +1089,7 @@ timer: | |||
800 | 1089 | ||
801 | static void br_multicast_query_received(struct net_bridge *br, | 1090 | static void br_multicast_query_received(struct net_bridge *br, |
802 | struct net_bridge_port *port, | 1091 | struct net_bridge_port *port, |
803 | __be32 saddr) | 1092 | int saddr) |
804 | { | 1093 | { |
805 | if (saddr) | 1094 | if (saddr) |
806 | mod_timer(&br->multicast_querier_timer, | 1095 | mod_timer(&br->multicast_querier_timer, |
@@ -811,9 +1100,9 @@ static void br_multicast_query_received(struct net_bridge *br, | |||
811 | br_multicast_mark_router(br, port); | 1100 | br_multicast_mark_router(br, port); |
812 | } | 1101 | } |
813 | 1102 | ||
814 | static int br_multicast_query(struct net_bridge *br, | 1103 | static int br_ip4_multicast_query(struct net_bridge *br, |
815 | struct net_bridge_port *port, | 1104 | struct net_bridge_port *port, |
816 | struct sk_buff *skb) | 1105 | struct sk_buff *skb) |
817 | { | 1106 | { |
818 | struct iphdr *iph = ip_hdr(skb); | 1107 | struct iphdr *iph = ip_hdr(skb); |
819 | struct igmphdr *ih = igmp_hdr(skb); | 1108 | struct igmphdr *ih = igmp_hdr(skb); |
@@ -831,7 +1120,7 @@ static int br_multicast_query(struct net_bridge *br, | |||
831 | (port && port->state == BR_STATE_DISABLED)) | 1120 | (port && port->state == BR_STATE_DISABLED)) |
832 | goto out; | 1121 | goto out; |
833 | 1122 | ||
834 | br_multicast_query_received(br, port, iph->saddr); | 1123 | br_multicast_query_received(br, port, !!iph->saddr); |
835 | 1124 | ||
836 | group = ih->group; | 1125 | group = ih->group; |
837 | 1126 | ||
@@ -859,7 +1148,7 @@ static int br_multicast_query(struct net_bridge *br, | |||
859 | if (!group) | 1148 | if (!group) |
860 | goto out; | 1149 | goto out; |
861 | 1150 | ||
862 | mp = br_mdb_ip_get(br->mdb, group); | 1151 | mp = br_mdb_ip4_get(br->mdb, group); |
863 | if (!mp) | 1152 | if (!mp) |
864 | goto out; | 1153 | goto out; |
865 | 1154 | ||
@@ -883,9 +1172,78 @@ out: | |||
883 | return err; | 1172 | return err; |
884 | } | 1173 | } |
885 | 1174 | ||
1175 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
1176 | static int br_ip6_multicast_query(struct net_bridge *br, | ||
1177 | struct net_bridge_port *port, | ||
1178 | struct sk_buff *skb) | ||
1179 | { | ||
1180 | struct ipv6hdr *ip6h = ipv6_hdr(skb); | ||
1181 | struct mld_msg *mld = (struct mld_msg *) icmp6_hdr(skb); | ||
1182 | struct net_bridge_mdb_entry *mp; | ||
1183 | struct mld2_query *mld2q; | ||
1184 | struct net_bridge_port_group *p, **pp; | ||
1185 | unsigned long max_delay; | ||
1186 | unsigned long now = jiffies; | ||
1187 | struct in6_addr *group = NULL; | ||
1188 | int err = 0; | ||
1189 | |||
1190 | spin_lock(&br->multicast_lock); | ||
1191 | if (!netif_running(br->dev) || | ||
1192 | (port && port->state == BR_STATE_DISABLED)) | ||
1193 | goto out; | ||
1194 | |||
1195 | br_multicast_query_received(br, port, !ipv6_addr_any(&ip6h->saddr)); | ||
1196 | |||
1197 | if (skb->len == sizeof(*mld)) { | ||
1198 | if (!pskb_may_pull(skb, sizeof(*mld))) { | ||
1199 | err = -EINVAL; | ||
1200 | goto out; | ||
1201 | } | ||
1202 | mld = (struct mld_msg *) icmp6_hdr(skb); | ||
1203 | max_delay = msecs_to_jiffies(htons(mld->mld_maxdelay)); | ||
1204 | if (max_delay) | ||
1205 | group = &mld->mld_mca; | ||
1206 | } else if (skb->len >= sizeof(*mld2q)) { | ||
1207 | if (!pskb_may_pull(skb, sizeof(*mld2q))) { | ||
1208 | err = -EINVAL; | ||
1209 | goto out; | ||
1210 | } | ||
1211 | mld2q = (struct mld2_query *)icmp6_hdr(skb); | ||
1212 | if (!mld2q->mld2q_nsrcs) | ||
1213 | group = &mld2q->mld2q_mca; | ||
1214 | max_delay = mld2q->mld2q_mrc ? MLDV2_MRC(mld2q->mld2q_mrc) : 1; | ||
1215 | } | ||
1216 | |||
1217 | if (!group) | ||
1218 | goto out; | ||
1219 | |||
1220 | mp = br_mdb_ip6_get(br->mdb, group); | ||
1221 | if (!mp) | ||
1222 | goto out; | ||
1223 | |||
1224 | max_delay *= br->multicast_last_member_count; | ||
1225 | if (!hlist_unhashed(&mp->mglist) && | ||
1226 | (timer_pending(&mp->timer) ? | ||
1227 | time_after(mp->timer.expires, now + max_delay) : | ||
1228 | try_to_del_timer_sync(&mp->timer) >= 0)) | ||
1229 | mod_timer(&mp->timer, now + max_delay); | ||
1230 | |||
1231 | for (pp = &mp->ports; (p = *pp); pp = &p->next) { | ||
1232 | if (timer_pending(&p->timer) ? | ||
1233 | time_after(p->timer.expires, now + max_delay) : | ||
1234 | try_to_del_timer_sync(&p->timer) >= 0) | ||
1235 | mod_timer(&mp->timer, now + max_delay); | ||
1236 | } | ||
1237 | |||
1238 | out: | ||
1239 | spin_unlock(&br->multicast_lock); | ||
1240 | return err; | ||
1241 | } | ||
1242 | #endif | ||
1243 | |||
886 | static void br_multicast_leave_group(struct net_bridge *br, | 1244 | static void br_multicast_leave_group(struct net_bridge *br, |
887 | struct net_bridge_port *port, | 1245 | struct net_bridge_port *port, |
888 | __be32 group) | 1246 | struct br_ip *group) |
889 | { | 1247 | { |
890 | struct net_bridge_mdb_htable *mdb; | 1248 | struct net_bridge_mdb_htable *mdb; |
891 | struct net_bridge_mdb_entry *mp; | 1249 | struct net_bridge_mdb_entry *mp; |
@@ -893,9 +1251,6 @@ static void br_multicast_leave_group(struct net_bridge *br, | |||
893 | unsigned long now; | 1251 | unsigned long now; |
894 | unsigned long time; | 1252 | unsigned long time; |
895 | 1253 | ||
896 | if (ipv4_is_local_multicast(group)) | ||
897 | return; | ||
898 | |||
899 | spin_lock(&br->multicast_lock); | 1254 | spin_lock(&br->multicast_lock); |
900 | if (!netif_running(br->dev) || | 1255 | if (!netif_running(br->dev) || |
901 | (port && port->state == BR_STATE_DISABLED) || | 1256 | (port && port->state == BR_STATE_DISABLED) || |
@@ -946,6 +1301,38 @@ out: | |||
946 | spin_unlock(&br->multicast_lock); | 1301 | spin_unlock(&br->multicast_lock); |
947 | } | 1302 | } |
948 | 1303 | ||
1304 | static void br_ip4_multicast_leave_group(struct net_bridge *br, | ||
1305 | struct net_bridge_port *port, | ||
1306 | __be32 group) | ||
1307 | { | ||
1308 | struct br_ip br_group; | ||
1309 | |||
1310 | if (ipv4_is_local_multicast(group)) | ||
1311 | return; | ||
1312 | |||
1313 | br_group.u.ip4 = group; | ||
1314 | br_group.proto = htons(ETH_P_IP); | ||
1315 | |||
1316 | br_multicast_leave_group(br, port, &br_group); | ||
1317 | } | ||
1318 | |||
1319 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
1320 | static void br_ip6_multicast_leave_group(struct net_bridge *br, | ||
1321 | struct net_bridge_port *port, | ||
1322 | const struct in6_addr *group) | ||
1323 | { | ||
1324 | struct br_ip br_group; | ||
1325 | |||
1326 | if (ipv6_is_local_multicast(group)) | ||
1327 | return; | ||
1328 | |||
1329 | ipv6_addr_copy(&br_group.u.ip6, group); | ||
1330 | br_group.proto = htons(ETH_P_IPV6); | ||
1331 | |||
1332 | br_multicast_leave_group(br, port, &br_group); | ||
1333 | } | ||
1334 | #endif | ||
1335 | |||
949 | static int br_multicast_ipv4_rcv(struct net_bridge *br, | 1336 | static int br_multicast_ipv4_rcv(struct net_bridge *br, |
950 | struct net_bridge_port *port, | 1337 | struct net_bridge_port *port, |
951 | struct sk_buff *skb) | 1338 | struct sk_buff *skb) |
@@ -957,9 +1344,6 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, | |||
957 | unsigned offset; | 1344 | unsigned offset; |
958 | int err; | 1345 | int err; |
959 | 1346 | ||
960 | BR_INPUT_SKB_CB(skb)->igmp = 0; | ||
961 | BR_INPUT_SKB_CB(skb)->mrouters_only = 0; | ||
962 | |||
963 | /* We treat OOM as packet loss for now. */ | 1347 | /* We treat OOM as packet loss for now. */ |
964 | if (!pskb_may_pull(skb, sizeof(*iph))) | 1348 | if (!pskb_may_pull(skb, sizeof(*iph))) |
965 | return -EINVAL; | 1349 | return -EINVAL; |
@@ -1023,16 +1407,16 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, | |||
1023 | case IGMP_HOST_MEMBERSHIP_REPORT: | 1407 | case IGMP_HOST_MEMBERSHIP_REPORT: |
1024 | case IGMPV2_HOST_MEMBERSHIP_REPORT: | 1408 | case IGMPV2_HOST_MEMBERSHIP_REPORT: |
1025 | BR_INPUT_SKB_CB(skb2)->mrouters_only = 1; | 1409 | BR_INPUT_SKB_CB(skb2)->mrouters_only = 1; |
1026 | err = br_multicast_add_group(br, port, ih->group); | 1410 | err = br_ip4_multicast_add_group(br, port, ih->group); |
1027 | break; | 1411 | break; |
1028 | case IGMPV3_HOST_MEMBERSHIP_REPORT: | 1412 | case IGMPV3_HOST_MEMBERSHIP_REPORT: |
1029 | err = br_multicast_igmp3_report(br, port, skb2); | 1413 | err = br_ip4_multicast_igmp3_report(br, port, skb2); |
1030 | break; | 1414 | break; |
1031 | case IGMP_HOST_MEMBERSHIP_QUERY: | 1415 | case IGMP_HOST_MEMBERSHIP_QUERY: |
1032 | err = br_multicast_query(br, port, skb2); | 1416 | err = br_ip4_multicast_query(br, port, skb2); |
1033 | break; | 1417 | break; |
1034 | case IGMP_HOST_LEAVE_MESSAGE: | 1418 | case IGMP_HOST_LEAVE_MESSAGE: |
1035 | br_multicast_leave_group(br, port, ih->group); | 1419 | br_ip4_multicast_leave_group(br, port, ih->group); |
1036 | break; | 1420 | break; |
1037 | } | 1421 | } |
1038 | 1422 | ||
@@ -1044,15 +1428,139 @@ err_out: | |||
1044 | return err; | 1428 | return err; |
1045 | } | 1429 | } |
1046 | 1430 | ||
1431 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
1432 | static int br_multicast_ipv6_rcv(struct net_bridge *br, | ||
1433 | struct net_bridge_port *port, | ||
1434 | struct sk_buff *skb) | ||
1435 | { | ||
1436 | struct sk_buff *skb2 = skb; | ||
1437 | struct ipv6hdr *ip6h; | ||
1438 | struct icmp6hdr *icmp6h; | ||
1439 | u8 nexthdr; | ||
1440 | unsigned len; | ||
1441 | unsigned offset; | ||
1442 | int err; | ||
1443 | |||
1444 | if (!pskb_may_pull(skb, sizeof(*ip6h))) | ||
1445 | return -EINVAL; | ||
1446 | |||
1447 | ip6h = ipv6_hdr(skb); | ||
1448 | |||
1449 | /* | ||
1450 | * We're interested in MLD messages only. | ||
1451 | * - Version is 6 | ||
1452 | * - MLD has always Router Alert hop-by-hop option | ||
1453 | * - But we do not support jumbrograms. | ||
1454 | */ | ||
1455 | if (ip6h->version != 6 || | ||
1456 | ip6h->nexthdr != IPPROTO_HOPOPTS || | ||
1457 | ip6h->payload_len == 0) | ||
1458 | return 0; | ||
1459 | |||
1460 | len = ntohs(ip6h->payload_len); | ||
1461 | if (skb->len < len) | ||
1462 | return -EINVAL; | ||
1463 | |||
1464 | nexthdr = ip6h->nexthdr; | ||
1465 | offset = ipv6_skip_exthdr(skb, sizeof(*ip6h), &nexthdr); | ||
1466 | |||
1467 | if (offset < 0 || nexthdr != IPPROTO_ICMPV6) | ||
1468 | return 0; | ||
1469 | |||
1470 | /* Okay, we found ICMPv6 header */ | ||
1471 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
1472 | if (!skb2) | ||
1473 | return -ENOMEM; | ||
1474 | |||
1475 | len -= offset - skb_network_offset(skb2); | ||
1476 | |||
1477 | __skb_pull(skb2, offset); | ||
1478 | skb_reset_transport_header(skb2); | ||
1479 | |||
1480 | err = -EINVAL; | ||
1481 | if (!pskb_may_pull(skb2, sizeof(*icmp6h))) | ||
1482 | goto out; | ||
1483 | |||
1484 | icmp6h = icmp6_hdr(skb2); | ||
1485 | |||
1486 | switch (icmp6h->icmp6_type) { | ||
1487 | case ICMPV6_MGM_QUERY: | ||
1488 | case ICMPV6_MGM_REPORT: | ||
1489 | case ICMPV6_MGM_REDUCTION: | ||
1490 | case ICMPV6_MLD2_REPORT: | ||
1491 | break; | ||
1492 | default: | ||
1493 | err = 0; | ||
1494 | goto out; | ||
1495 | } | ||
1496 | |||
1497 | /* Okay, we found MLD message. Check further. */ | ||
1498 | if (skb2->len > len) { | ||
1499 | err = pskb_trim_rcsum(skb2, len); | ||
1500 | if (err) | ||
1501 | goto out; | ||
1502 | } | ||
1503 | |||
1504 | switch (skb2->ip_summed) { | ||
1505 | case CHECKSUM_COMPLETE: | ||
1506 | if (!csum_fold(skb2->csum)) | ||
1507 | break; | ||
1508 | /*FALLTHROUGH*/ | ||
1509 | case CHECKSUM_NONE: | ||
1510 | skb2->csum = 0; | ||
1511 | if (skb_checksum_complete(skb2)) | ||
1512 | goto out; | ||
1513 | } | ||
1514 | |||
1515 | err = 0; | ||
1516 | |||
1517 | BR_INPUT_SKB_CB(skb)->igmp = 1; | ||
1518 | |||
1519 | switch (icmp6h->icmp6_type) { | ||
1520 | case ICMPV6_MGM_REPORT: | ||
1521 | { | ||
1522 | struct mld_msg *mld = (struct mld_msg *)icmp6h; | ||
1523 | BR_INPUT_SKB_CB(skb2)->mrouters_only = 1; | ||
1524 | err = br_ip6_multicast_add_group(br, port, &mld->mld_mca); | ||
1525 | break; | ||
1526 | } | ||
1527 | case ICMPV6_MLD2_REPORT: | ||
1528 | err = br_ip6_multicast_mld2_report(br, port, skb2); | ||
1529 | break; | ||
1530 | case ICMPV6_MGM_QUERY: | ||
1531 | err = br_ip6_multicast_query(br, port, skb2); | ||
1532 | break; | ||
1533 | case ICMPV6_MGM_REDUCTION: | ||
1534 | { | ||
1535 | struct mld_msg *mld = (struct mld_msg *)icmp6h; | ||
1536 | br_ip6_multicast_leave_group(br, port, &mld->mld_mca); | ||
1537 | } | ||
1538 | } | ||
1539 | |||
1540 | out: | ||
1541 | __skb_push(skb2, offset); | ||
1542 | if (skb2 != skb) | ||
1543 | kfree_skb(skb2); | ||
1544 | return err; | ||
1545 | } | ||
1546 | #endif | ||
1547 | |||
1047 | int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port, | 1548 | int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port, |
1048 | struct sk_buff *skb) | 1549 | struct sk_buff *skb) |
1049 | { | 1550 | { |
1551 | BR_INPUT_SKB_CB(skb)->igmp = 0; | ||
1552 | BR_INPUT_SKB_CB(skb)->mrouters_only = 0; | ||
1553 | |||
1050 | if (br->multicast_disabled) | 1554 | if (br->multicast_disabled) |
1051 | return 0; | 1555 | return 0; |
1052 | 1556 | ||
1053 | switch (skb->protocol) { | 1557 | switch (skb->protocol) { |
1054 | case htons(ETH_P_IP): | 1558 | case htons(ETH_P_IP): |
1055 | return br_multicast_ipv4_rcv(br, port, skb); | 1559 | return br_multicast_ipv4_rcv(br, port, skb); |
1560 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
1561 | case htons(ETH_P_IPV6): | ||
1562 | return br_multicast_ipv6_rcv(br, port, skb); | ||
1563 | #endif | ||
1056 | } | 1564 | } |
1057 | 1565 | ||
1058 | return 0; | 1566 | return 0; |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 791d4ab0fd4d..3d2d3fe0a97e 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -45,6 +45,17 @@ struct mac_addr | |||
45 | unsigned char addr[6]; | 45 | unsigned char addr[6]; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | struct br_ip | ||
49 | { | ||
50 | union { | ||
51 | __be32 ip4; | ||
52 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
53 | struct in6_addr ip6; | ||
54 | #endif | ||
55 | } u; | ||
56 | __be16 proto; | ||
57 | }; | ||
58 | |||
48 | struct net_bridge_fdb_entry | 59 | struct net_bridge_fdb_entry |
49 | { | 60 | { |
50 | struct hlist_node hlist; | 61 | struct hlist_node hlist; |
@@ -64,7 +75,7 @@ struct net_bridge_port_group { | |||
64 | struct rcu_head rcu; | 75 | struct rcu_head rcu; |
65 | struct timer_list timer; | 76 | struct timer_list timer; |
66 | struct timer_list query_timer; | 77 | struct timer_list query_timer; |
67 | __be32 addr; | 78 | struct br_ip addr; |
68 | u32 queries_sent; | 79 | u32 queries_sent; |
69 | }; | 80 | }; |
70 | 81 | ||
@@ -77,7 +88,7 @@ struct net_bridge_mdb_entry | |||
77 | struct rcu_head rcu; | 88 | struct rcu_head rcu; |
78 | struct timer_list timer; | 89 | struct timer_list timer; |
79 | struct timer_list query_timer; | 90 | struct timer_list query_timer; |
80 | __be32 addr; | 91 | struct br_ip addr; |
81 | u32 queries_sent; | 92 | u32 queries_sent; |
82 | }; | 93 | }; |
83 | 94 | ||
@@ -130,19 +141,20 @@ struct net_bridge_port | |||
130 | #endif | 141 | #endif |
131 | }; | 142 | }; |
132 | 143 | ||
144 | struct br_cpu_netstats { | ||
145 | unsigned long rx_packets; | ||
146 | unsigned long rx_bytes; | ||
147 | unsigned long tx_packets; | ||
148 | unsigned long tx_bytes; | ||
149 | }; | ||
150 | |||
133 | struct net_bridge | 151 | struct net_bridge |
134 | { | 152 | { |
135 | spinlock_t lock; | 153 | spinlock_t lock; |
136 | struct list_head port_list; | 154 | struct list_head port_list; |
137 | struct net_device *dev; | 155 | struct net_device *dev; |
138 | 156 | ||
139 | struct br_cpu_netstats __percpu { | 157 | struct br_cpu_netstats __percpu *stats; |
140 | unsigned long rx_packets; | ||
141 | unsigned long rx_bytes; | ||
142 | unsigned long tx_packets; | ||
143 | unsigned long tx_bytes; | ||
144 | } *stats; | ||
145 | |||
146 | spinlock_t hash_lock; | 158 | spinlock_t hash_lock; |
147 | struct hlist_head hash[BR_HASH_SIZE]; | 159 | struct hlist_head hash[BR_HASH_SIZE]; |
148 | unsigned long feature_mask; | 160 | unsigned long feature_mask; |
@@ -241,6 +253,8 @@ static inline int br_is_root_bridge(const struct net_bridge *br) | |||
241 | extern void br_dev_setup(struct net_device *dev); | 253 | extern void br_dev_setup(struct net_device *dev); |
242 | extern netdev_tx_t br_dev_xmit(struct sk_buff *skb, | 254 | extern netdev_tx_t br_dev_xmit(struct sk_buff *skb, |
243 | struct net_device *dev); | 255 | struct net_device *dev); |
256 | extern bool br_devices_support_netpoll(struct net_bridge *br); | ||
257 | extern void br_netpoll_cleanup(struct net_device *br_dev); | ||
244 | 258 | ||
245 | /* br_fdb.c */ | 259 | /* br_fdb.c */ |
246 | extern int br_fdb_init(void); | 260 | extern int br_fdb_init(void); |
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index e84837e1bc86..024fd5bb2d39 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c | |||
@@ -247,10 +247,10 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, | |||
247 | 247 | ||
248 | switch (caifdev->link_select) { | 248 | switch (caifdev->link_select) { |
249 | case CAIF_LINK_HIGH_BANDW: | 249 | case CAIF_LINK_HIGH_BANDW: |
250 | pref = CFPHYPREF_LOW_LAT; | 250 | pref = CFPHYPREF_HIGH_BW; |
251 | break; | 251 | break; |
252 | case CAIF_LINK_LOW_LATENCY: | 252 | case CAIF_LINK_LOW_LATENCY: |
253 | pref = CFPHYPREF_HIGH_BW; | 253 | pref = CFPHYPREF_LOW_LAT; |
254 | break; | 254 | break; |
255 | default: | 255 | default: |
256 | pref = CFPHYPREF_HIGH_BW; | 256 | pref = CFPHYPREF_HIGH_BW; |
@@ -330,23 +330,28 @@ int caif_connect_client(struct caif_connect_request *conn_req, | |||
330 | struct cflayer *client_layer) | 330 | struct cflayer *client_layer) |
331 | { | 331 | { |
332 | struct cfctrl_link_param param; | 332 | struct cfctrl_link_param param; |
333 | if (connect_req_to_link_param(get_caif_conf(), conn_req, ¶m) == 0) | 333 | int ret; |
334 | /* Hook up the adaptation layer. */ | 334 | ret = connect_req_to_link_param(get_caif_conf(), conn_req, ¶m); |
335 | return cfcnfg_add_adaptation_layer(get_caif_conf(), | 335 | if (ret) |
336 | return ret; | ||
337 | /* Hook up the adaptation layer. */ | ||
338 | return cfcnfg_add_adaptation_layer(get_caif_conf(), | ||
336 | ¶m, client_layer); | 339 | ¶m, client_layer); |
337 | |||
338 | return -EINVAL; | ||
339 | |||
340 | caif_assert(0); | ||
341 | } | 340 | } |
342 | EXPORT_SYMBOL(caif_connect_client); | 341 | EXPORT_SYMBOL(caif_connect_client); |
343 | 342 | ||
344 | int caif_disconnect_client(struct cflayer *adap_layer) | 343 | int caif_disconnect_client(struct cflayer *adap_layer) |
345 | { | 344 | { |
346 | return cfcnfg_del_adapt_layer(get_caif_conf(), adap_layer); | 345 | return cfcnfg_disconn_adapt_layer(get_caif_conf(), adap_layer); |
347 | } | 346 | } |
348 | EXPORT_SYMBOL(caif_disconnect_client); | 347 | EXPORT_SYMBOL(caif_disconnect_client); |
349 | 348 | ||
349 | void caif_release_client(struct cflayer *adap_layer) | ||
350 | { | ||
351 | cfcnfg_release_adap_layer(adap_layer); | ||
352 | } | ||
353 | EXPORT_SYMBOL(caif_release_client); | ||
354 | |||
350 | /* Per-namespace Caif devices handling */ | 355 | /* Per-namespace Caif devices handling */ |
351 | static int caif_init_net(struct net *net) | 356 | static int caif_init_net(struct net *net) |
352 | { | 357 | { |
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index cdf62b9fefac..c3a70c5c893a 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) ST-Ericsson AB 2010 | 2 | * Copyright (C) ST-Ericsson AB 2010 |
3 | * Author: Sjur Brendeland sjur.brandeland@stericsson.com | 3 | * Author: Sjur Brendeland sjur.brandeland@stericsson.com |
4 | * Per Sigmond per.sigmond@stericsson.com | ||
5 | * License terms: GNU General Public License (GPL) version 2 | 4 | * License terms: GNU General Public License (GPL) version 2 |
6 | */ | 5 | */ |
7 | 6 | ||
@@ -16,91 +15,52 @@ | |||
16 | #include <linux/poll.h> | 15 | #include <linux/poll.h> |
17 | #include <linux/tcp.h> | 16 | #include <linux/tcp.h> |
18 | #include <linux/uaccess.h> | 17 | #include <linux/uaccess.h> |
19 | #include <asm/atomic.h> | 18 | #include <linux/mutex.h> |
20 | 19 | #include <linux/debugfs.h> | |
21 | #include <linux/caif/caif_socket.h> | 20 | #include <linux/caif/caif_socket.h> |
21 | #include <asm/atomic.h> | ||
22 | #include <net/sock.h> | ||
23 | #include <net/tcp_states.h> | ||
22 | #include <net/caif/caif_layer.h> | 24 | #include <net/caif/caif_layer.h> |
23 | #include <net/caif/caif_dev.h> | 25 | #include <net/caif/caif_dev.h> |
24 | #include <net/caif/cfpkt.h> | 26 | #include <net/caif/cfpkt.h> |
25 | 27 | ||
26 | MODULE_LICENSE("GPL"); | 28 | MODULE_LICENSE("GPL"); |
29 | MODULE_ALIAS_NETPROTO(AF_CAIF); | ||
30 | |||
31 | #define CAIF_DEF_SNDBUF (CAIF_MAX_PAYLOAD_SIZE*10) | ||
32 | #define CAIF_DEF_RCVBUF (CAIF_MAX_PAYLOAD_SIZE*100) | ||
33 | |||
34 | /* | ||
35 | * CAIF state is re-using the TCP socket states. | ||
36 | * caif_states stored in sk_state reflect the state as reported by | ||
37 | * the CAIF stack, while sk_socket->state is the state of the socket. | ||
38 | */ | ||
39 | enum caif_states { | ||
40 | CAIF_CONNECTED = TCP_ESTABLISHED, | ||
41 | CAIF_CONNECTING = TCP_SYN_SENT, | ||
42 | CAIF_DISCONNECTED = TCP_CLOSE | ||
43 | }; | ||
44 | |||
45 | #define TX_FLOW_ON_BIT 1 | ||
46 | #define RX_FLOW_ON_BIT 2 | ||
27 | 47 | ||
28 | #define CHNL_SKT_READ_QUEUE_HIGH 200 | ||
29 | #define CHNL_SKT_READ_QUEUE_LOW 100 | ||
30 | |||
31 | static int caif_sockbuf_size = 40000; | ||
32 | static atomic_t caif_nr_socks = ATOMIC_INIT(0); | ||
33 | |||
34 | #define CONN_STATE_OPEN_BIT 1 | ||
35 | #define CONN_STATE_PENDING_BIT 2 | ||
36 | #define CONN_STATE_PEND_DESTROY_BIT 3 | ||
37 | #define CONN_REMOTE_SHUTDOWN_BIT 4 | ||
38 | |||
39 | #define TX_FLOW_ON_BIT 1 | ||
40 | #define RX_FLOW_ON_BIT 2 | ||
41 | |||
42 | #define STATE_IS_OPEN(cf_sk) test_bit(CONN_STATE_OPEN_BIT,\ | ||
43 | (void *) &(cf_sk)->conn_state) | ||
44 | #define STATE_IS_REMOTE_SHUTDOWN(cf_sk) test_bit(CONN_REMOTE_SHUTDOWN_BIT,\ | ||
45 | (void *) &(cf_sk)->conn_state) | ||
46 | #define STATE_IS_PENDING(cf_sk) test_bit(CONN_STATE_PENDING_BIT,\ | ||
47 | (void *) &(cf_sk)->conn_state) | ||
48 | #define STATE_IS_PENDING_DESTROY(cf_sk) test_bit(CONN_STATE_PEND_DESTROY_BIT,\ | ||
49 | (void *) &(cf_sk)->conn_state) | ||
50 | |||
51 | #define SET_STATE_PENDING_DESTROY(cf_sk) set_bit(CONN_STATE_PEND_DESTROY_BIT,\ | ||
52 | (void *) &(cf_sk)->conn_state) | ||
53 | #define SET_STATE_OPEN(cf_sk) set_bit(CONN_STATE_OPEN_BIT,\ | ||
54 | (void *) &(cf_sk)->conn_state) | ||
55 | #define SET_STATE_CLOSED(cf_sk) clear_bit(CONN_STATE_OPEN_BIT,\ | ||
56 | (void *) &(cf_sk)->conn_state) | ||
57 | #define SET_PENDING_ON(cf_sk) set_bit(CONN_STATE_PENDING_BIT,\ | ||
58 | (void *) &(cf_sk)->conn_state) | ||
59 | #define SET_PENDING_OFF(cf_sk) clear_bit(CONN_STATE_PENDING_BIT,\ | ||
60 | (void *) &(cf_sk)->conn_state) | ||
61 | #define SET_REMOTE_SHUTDOWN(cf_sk) set_bit(CONN_REMOTE_SHUTDOWN_BIT,\ | ||
62 | (void *) &(cf_sk)->conn_state) | ||
63 | |||
64 | #define SET_REMOTE_SHUTDOWN_OFF(dev) clear_bit(CONN_REMOTE_SHUTDOWN_BIT,\ | ||
65 | (void *) &(dev)->conn_state) | ||
66 | #define RX_FLOW_IS_ON(cf_sk) test_bit(RX_FLOW_ON_BIT,\ | ||
67 | (void *) &(cf_sk)->flow_state) | ||
68 | #define TX_FLOW_IS_ON(cf_sk) test_bit(TX_FLOW_ON_BIT,\ | ||
69 | (void *) &(cf_sk)->flow_state) | ||
70 | |||
71 | #define SET_RX_FLOW_OFF(cf_sk) clear_bit(RX_FLOW_ON_BIT,\ | ||
72 | (void *) &(cf_sk)->flow_state) | ||
73 | #define SET_RX_FLOW_ON(cf_sk) set_bit(RX_FLOW_ON_BIT,\ | ||
74 | (void *) &(cf_sk)->flow_state) | ||
75 | #define SET_TX_FLOW_OFF(cf_sk) clear_bit(TX_FLOW_ON_BIT,\ | ||
76 | (void *) &(cf_sk)->flow_state) | ||
77 | #define SET_TX_FLOW_ON(cf_sk) set_bit(TX_FLOW_ON_BIT,\ | ||
78 | (void *) &(cf_sk)->flow_state) | ||
79 | |||
80 | #define SKT_READ_FLAG 0x01 | ||
81 | #define SKT_WRITE_FLAG 0x02 | ||
82 | static struct dentry *debugfsdir; | 48 | static struct dentry *debugfsdir; |
83 | #include <linux/debugfs.h> | ||
84 | 49 | ||
85 | #ifdef CONFIG_DEBUG_FS | 50 | #ifdef CONFIG_DEBUG_FS |
86 | struct debug_fs_counter { | 51 | struct debug_fs_counter { |
87 | atomic_t num_open; | 52 | atomic_t caif_nr_socks; |
88 | atomic_t num_close; | 53 | atomic_t num_connect_req; |
89 | atomic_t num_init; | 54 | atomic_t num_connect_resp; |
90 | atomic_t num_init_resp; | 55 | atomic_t num_connect_fail_resp; |
91 | atomic_t num_init_fail_resp; | 56 | atomic_t num_disconnect; |
92 | atomic_t num_deinit; | ||
93 | atomic_t num_deinit_resp; | ||
94 | atomic_t num_remote_shutdown_ind; | 57 | atomic_t num_remote_shutdown_ind; |
95 | atomic_t num_tx_flow_off_ind; | 58 | atomic_t num_tx_flow_off_ind; |
96 | atomic_t num_tx_flow_on_ind; | 59 | atomic_t num_tx_flow_on_ind; |
97 | atomic_t num_rx_flow_off; | 60 | atomic_t num_rx_flow_off; |
98 | atomic_t num_rx_flow_on; | 61 | atomic_t num_rx_flow_on; |
99 | atomic_t skb_in_use; | ||
100 | atomic_t skb_alloc; | ||
101 | atomic_t skb_free; | ||
102 | }; | 62 | }; |
103 | static struct debug_fs_counter cnt; | 63 | struct debug_fs_counter cnt; |
104 | #define dbfs_atomic_inc(v) atomic_inc(v) | 64 | #define dbfs_atomic_inc(v) atomic_inc(v) |
105 | #define dbfs_atomic_dec(v) atomic_dec(v) | 65 | #define dbfs_atomic_dec(v) atomic_dec(v) |
106 | #else | 66 | #else |
@@ -108,624 +68,666 @@ static struct debug_fs_counter cnt; | |||
108 | #define dbfs_atomic_dec(v) | 68 | #define dbfs_atomic_dec(v) |
109 | #endif | 69 | #endif |
110 | 70 | ||
111 | /* The AF_CAIF socket */ | ||
112 | struct caifsock { | 71 | struct caifsock { |
113 | /* NOTE: sk has to be the first member */ | 72 | struct sock sk; /* must be first member */ |
114 | struct sock sk; | ||
115 | struct cflayer layer; | 73 | struct cflayer layer; |
116 | char name[CAIF_LAYER_NAME_SZ]; | 74 | char name[CAIF_LAYER_NAME_SZ]; /* Used for debugging */ |
117 | u32 conn_state; | ||
118 | u32 flow_state; | 75 | u32 flow_state; |
119 | struct cfpktq *pktq; | ||
120 | int file_mode; | ||
121 | struct caif_connect_request conn_req; | 76 | struct caif_connect_request conn_req; |
122 | int read_queue_len; | 77 | struct mutex readlock; |
123 | /* protect updates of read_queue_len */ | ||
124 | spinlock_t read_queue_len_lock; | ||
125 | struct dentry *debugfs_socket_dir; | 78 | struct dentry *debugfs_socket_dir; |
126 | }; | 79 | }; |
127 | 80 | ||
128 | static void drain_queue(struct caifsock *cf_sk); | 81 | static int rx_flow_is_on(struct caifsock *cf_sk) |
82 | { | ||
83 | return test_bit(RX_FLOW_ON_BIT, | ||
84 | (void *) &cf_sk->flow_state); | ||
85 | } | ||
86 | |||
87 | static int tx_flow_is_on(struct caifsock *cf_sk) | ||
88 | { | ||
89 | return test_bit(TX_FLOW_ON_BIT, | ||
90 | (void *) &cf_sk->flow_state); | ||
91 | } | ||
129 | 92 | ||
130 | /* Packet Receive Callback function called from CAIF Stack */ | 93 | static void set_rx_flow_off(struct caifsock *cf_sk) |
131 | static int caif_sktrecv_cb(struct cflayer *layr, struct cfpkt *pkt) | ||
132 | { | 94 | { |
133 | struct caifsock *cf_sk; | 95 | clear_bit(RX_FLOW_ON_BIT, |
134 | int read_queue_high; | 96 | (void *) &cf_sk->flow_state); |
135 | cf_sk = container_of(layr, struct caifsock, layer); | 97 | } |
136 | 98 | ||
137 | if (!STATE_IS_OPEN(cf_sk)) { | 99 | static void set_rx_flow_on(struct caifsock *cf_sk) |
138 | /*FIXME: This should be allowed finally!*/ | 100 | { |
139 | pr_debug("CAIF: %s(): called after close request\n", __func__); | 101 | set_bit(RX_FLOW_ON_BIT, |
140 | cfpkt_destroy(pkt); | 102 | (void *) &cf_sk->flow_state); |
141 | return 0; | 103 | } |
142 | } | ||
143 | /* NOTE: This function may be called in Tasklet context! */ | ||
144 | 104 | ||
145 | /* The queue has its own lock */ | 105 | static void set_tx_flow_off(struct caifsock *cf_sk) |
146 | cfpkt_queue(cf_sk->pktq, pkt, 0); | 106 | { |
107 | clear_bit(TX_FLOW_ON_BIT, | ||
108 | (void *) &cf_sk->flow_state); | ||
109 | } | ||
147 | 110 | ||
148 | spin_lock(&cf_sk->read_queue_len_lock); | 111 | static void set_tx_flow_on(struct caifsock *cf_sk) |
149 | cf_sk->read_queue_len++; | 112 | { |
113 | set_bit(TX_FLOW_ON_BIT, | ||
114 | (void *) &cf_sk->flow_state); | ||
115 | } | ||
150 | 116 | ||
151 | read_queue_high = (cf_sk->read_queue_len > CHNL_SKT_READ_QUEUE_HIGH); | 117 | static void caif_read_lock(struct sock *sk) |
152 | spin_unlock(&cf_sk->read_queue_len_lock); | 118 | { |
119 | struct caifsock *cf_sk; | ||
120 | cf_sk = container_of(sk, struct caifsock, sk); | ||
121 | mutex_lock(&cf_sk->readlock); | ||
122 | } | ||
153 | 123 | ||
154 | if (RX_FLOW_IS_ON(cf_sk) && read_queue_high) { | 124 | static void caif_read_unlock(struct sock *sk) |
155 | dbfs_atomic_inc(&cnt.num_rx_flow_off); | 125 | { |
156 | SET_RX_FLOW_OFF(cf_sk); | 126 | struct caifsock *cf_sk; |
127 | cf_sk = container_of(sk, struct caifsock, sk); | ||
128 | mutex_unlock(&cf_sk->readlock); | ||
129 | } | ||
157 | 130 | ||
158 | /* Send flow off (NOTE: must not sleep) */ | 131 | int sk_rcvbuf_lowwater(struct caifsock *cf_sk) |
159 | pr_debug("CAIF: %s():" | 132 | { |
160 | " sending flow OFF (queue len = %d)\n", | 133 | /* A quarter of full buffer is used a low water mark */ |
161 | __func__, | 134 | return cf_sk->sk.sk_rcvbuf / 4; |
162 | cf_sk->read_queue_len); | 135 | } |
163 | caif_assert(cf_sk->layer.dn); | ||
164 | caif_assert(cf_sk->layer.dn->ctrlcmd); | ||
165 | 136 | ||
166 | (void) cf_sk->layer.dn->modemcmd(cf_sk->layer.dn, | 137 | void caif_flow_ctrl(struct sock *sk, int mode) |
167 | CAIF_MODEMCMD_FLOW_OFF_REQ); | 138 | { |
168 | } | 139 | struct caifsock *cf_sk; |
140 | cf_sk = container_of(sk, struct caifsock, sk); | ||
141 | if (cf_sk->layer.dn) | ||
142 | cf_sk->layer.dn->modemcmd(cf_sk->layer.dn, mode); | ||
143 | } | ||
169 | 144 | ||
170 | /* Signal reader that data is available. */ | 145 | /* |
146 | * Copied from sock.c:sock_queue_rcv_skb(), but changed so packets are | ||
147 | * not dropped, but CAIF is sending flow off instead. | ||
148 | */ | ||
149 | int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | ||
150 | { | ||
151 | int err; | ||
152 | int skb_len; | ||
153 | unsigned long flags; | ||
154 | struct sk_buff_head *list = &sk->sk_receive_queue; | ||
155 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); | ||
171 | 156 | ||
172 | wake_up_interruptible(cf_sk->sk.sk_sleep); | 157 | if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= |
158 | (unsigned)sk->sk_rcvbuf && rx_flow_is_on(cf_sk)) { | ||
159 | trace_printk("CAIF: %s():" | ||
160 | " sending flow OFF (queue len = %d %d)\n", | ||
161 | __func__, | ||
162 | atomic_read(&cf_sk->sk.sk_rmem_alloc), | ||
163 | sk_rcvbuf_lowwater(cf_sk)); | ||
164 | set_rx_flow_off(cf_sk); | ||
165 | if (cf_sk->layer.dn) | ||
166 | cf_sk->layer.dn->modemcmd(cf_sk->layer.dn, | ||
167 | CAIF_MODEMCMD_FLOW_OFF_REQ); | ||
168 | } | ||
173 | 169 | ||
170 | err = sk_filter(sk, skb); | ||
171 | if (err) | ||
172 | return err; | ||
173 | if (!sk_rmem_schedule(sk, skb->truesize) && rx_flow_is_on(cf_sk)) { | ||
174 | set_rx_flow_off(cf_sk); | ||
175 | trace_printk("CAIF: %s():" | ||
176 | " sending flow OFF due to rmem_schedule\n", | ||
177 | __func__); | ||
178 | if (cf_sk->layer.dn) | ||
179 | cf_sk->layer.dn->modemcmd(cf_sk->layer.dn, | ||
180 | CAIF_MODEMCMD_FLOW_OFF_REQ); | ||
181 | } | ||
182 | skb->dev = NULL; | ||
183 | skb_set_owner_r(skb, sk); | ||
184 | /* Cache the SKB length before we tack it onto the receive | ||
185 | * queue. Once it is added it no longer belongs to us and | ||
186 | * may be freed by other threads of control pulling packets | ||
187 | * from the queue. | ||
188 | */ | ||
189 | skb_len = skb->len; | ||
190 | spin_lock_irqsave(&list->lock, flags); | ||
191 | if (!sock_flag(sk, SOCK_DEAD)) | ||
192 | __skb_queue_tail(list, skb); | ||
193 | spin_unlock_irqrestore(&list->lock, flags); | ||
194 | |||
195 | if (!sock_flag(sk, SOCK_DEAD)) | ||
196 | sk->sk_data_ready(sk, skb_len); | ||
197 | else | ||
198 | kfree_skb(skb); | ||
174 | return 0; | 199 | return 0; |
175 | } | 200 | } |
176 | 201 | ||
177 | /* Packet Flow Control Callback function called from CAIF */ | 202 | /* Packet Receive Callback function called from CAIF Stack */ |
178 | static void caif_sktflowctrl_cb(struct cflayer *layr, | 203 | static int caif_sktrecv_cb(struct cflayer *layr, struct cfpkt *pkt) |
179 | enum caif_ctrlcmd flow, | ||
180 | int phyid) | ||
181 | { | 204 | { |
182 | struct caifsock *cf_sk; | 205 | struct caifsock *cf_sk; |
183 | 206 | struct sk_buff *skb; | |
184 | /* NOTE: This function may be called in Tasklet context! */ | ||
185 | pr_debug("CAIF: %s(): flowctrl func called: %s.\n", | ||
186 | __func__, | ||
187 | flow == CAIF_CTRLCMD_FLOW_ON_IND ? "ON" : | ||
188 | flow == CAIF_CTRLCMD_FLOW_OFF_IND ? "OFF" : | ||
189 | flow == CAIF_CTRLCMD_INIT_RSP ? "INIT_RSP" : | ||
190 | flow == CAIF_CTRLCMD_DEINIT_RSP ? "DEINIT_RSP" : | ||
191 | flow == CAIF_CTRLCMD_INIT_FAIL_RSP ? "INIT_FAIL_RSP" : | ||
192 | flow == | ||
193 | CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND ? "REMOTE_SHUTDOWN" : | ||
194 | "UKNOWN CTRL COMMAND"); | ||
195 | |||
196 | if (layr == NULL) | ||
197 | return; | ||
198 | 207 | ||
199 | cf_sk = container_of(layr, struct caifsock, layer); | 208 | cf_sk = container_of(layr, struct caifsock, layer); |
209 | skb = cfpkt_tonative(pkt); | ||
210 | |||
211 | if (unlikely(cf_sk->sk.sk_state != CAIF_CONNECTED)) { | ||
212 | cfpkt_destroy(pkt); | ||
213 | return 0; | ||
214 | } | ||
215 | caif_queue_rcv_skb(&cf_sk->sk, skb); | ||
216 | return 0; | ||
217 | } | ||
200 | 218 | ||
219 | /* Packet Control Callback function called from CAIF */ | ||
220 | static void caif_ctrl_cb(struct cflayer *layr, | ||
221 | enum caif_ctrlcmd flow, | ||
222 | int phyid) | ||
223 | { | ||
224 | struct caifsock *cf_sk = container_of(layr, struct caifsock, layer); | ||
201 | switch (flow) { | 225 | switch (flow) { |
202 | case CAIF_CTRLCMD_FLOW_ON_IND: | 226 | case CAIF_CTRLCMD_FLOW_ON_IND: |
227 | /* OK from modem to start sending again */ | ||
203 | dbfs_atomic_inc(&cnt.num_tx_flow_on_ind); | 228 | dbfs_atomic_inc(&cnt.num_tx_flow_on_ind); |
204 | /* Signal reader that data is available. */ | 229 | set_tx_flow_on(cf_sk); |
205 | SET_TX_FLOW_ON(cf_sk); | 230 | cf_sk->sk.sk_state_change(&cf_sk->sk); |
206 | wake_up_interruptible(cf_sk->sk.sk_sleep); | ||
207 | break; | 231 | break; |
208 | 232 | ||
209 | case CAIF_CTRLCMD_FLOW_OFF_IND: | 233 | case CAIF_CTRLCMD_FLOW_OFF_IND: |
234 | /* Modem asks us to shut up */ | ||
210 | dbfs_atomic_inc(&cnt.num_tx_flow_off_ind); | 235 | dbfs_atomic_inc(&cnt.num_tx_flow_off_ind); |
211 | SET_TX_FLOW_OFF(cf_sk); | 236 | set_tx_flow_off(cf_sk); |
237 | cf_sk->sk.sk_state_change(&cf_sk->sk); | ||
212 | break; | 238 | break; |
213 | 239 | ||
214 | case CAIF_CTRLCMD_INIT_RSP: | 240 | case CAIF_CTRLCMD_INIT_RSP: |
215 | dbfs_atomic_inc(&cnt.num_init_resp); | 241 | /* We're now connected */ |
216 | /* Signal reader that data is available. */ | 242 | dbfs_atomic_inc(&cnt.num_connect_resp); |
217 | caif_assert(STATE_IS_OPEN(cf_sk)); | 243 | cf_sk->sk.sk_state = CAIF_CONNECTED; |
218 | SET_PENDING_OFF(cf_sk); | 244 | set_tx_flow_on(cf_sk); |
219 | SET_TX_FLOW_ON(cf_sk); | 245 | cf_sk->sk.sk_state_change(&cf_sk->sk); |
220 | wake_up_interruptible(cf_sk->sk.sk_sleep); | ||
221 | break; | 246 | break; |
222 | 247 | ||
223 | case CAIF_CTRLCMD_DEINIT_RSP: | 248 | case CAIF_CTRLCMD_DEINIT_RSP: |
224 | dbfs_atomic_inc(&cnt.num_deinit_resp); | 249 | /* We're now disconnected */ |
225 | caif_assert(!STATE_IS_OPEN(cf_sk)); | 250 | cf_sk->sk.sk_state = CAIF_DISCONNECTED; |
226 | SET_PENDING_OFF(cf_sk); | 251 | cf_sk->sk.sk_state_change(&cf_sk->sk); |
227 | if (!STATE_IS_PENDING_DESTROY(cf_sk)) { | 252 | cfcnfg_release_adap_layer(&cf_sk->layer); |
228 | if (cf_sk->sk.sk_sleep != NULL) | ||
229 | wake_up_interruptible(cf_sk->sk.sk_sleep); | ||
230 | } | ||
231 | dbfs_atomic_inc(&cnt.num_deinit); | ||
232 | sock_put(&cf_sk->sk); | ||
233 | break; | 253 | break; |
234 | 254 | ||
235 | case CAIF_CTRLCMD_INIT_FAIL_RSP: | 255 | case CAIF_CTRLCMD_INIT_FAIL_RSP: |
236 | dbfs_atomic_inc(&cnt.num_init_fail_resp); | 256 | /* Connect request failed */ |
237 | caif_assert(STATE_IS_OPEN(cf_sk)); | 257 | dbfs_atomic_inc(&cnt.num_connect_fail_resp); |
238 | SET_STATE_CLOSED(cf_sk); | 258 | cf_sk->sk.sk_err = ECONNREFUSED; |
239 | SET_PENDING_OFF(cf_sk); | 259 | cf_sk->sk.sk_state = CAIF_DISCONNECTED; |
240 | SET_TX_FLOW_OFF(cf_sk); | 260 | cf_sk->sk.sk_shutdown = SHUTDOWN_MASK; |
241 | wake_up_interruptible(cf_sk->sk.sk_sleep); | 261 | /* |
262 | * Socket "standards" seems to require POLLOUT to | ||
263 | * be set at connect failure. | ||
264 | */ | ||
265 | set_tx_flow_on(cf_sk); | ||
266 | cf_sk->sk.sk_state_change(&cf_sk->sk); | ||
242 | break; | 267 | break; |
243 | 268 | ||
244 | case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND: | 269 | case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND: |
270 | /* Modem has closed this connection, or device is down. */ | ||
245 | dbfs_atomic_inc(&cnt.num_remote_shutdown_ind); | 271 | dbfs_atomic_inc(&cnt.num_remote_shutdown_ind); |
246 | SET_REMOTE_SHUTDOWN(cf_sk); | 272 | cf_sk->sk.sk_shutdown = SHUTDOWN_MASK; |
247 | /* Use sk_shutdown to indicate remote shutdown indication */ | 273 | cf_sk->sk.sk_err = ECONNRESET; |
248 | cf_sk->sk.sk_shutdown |= RCV_SHUTDOWN; | 274 | set_rx_flow_on(cf_sk); |
249 | cf_sk->file_mode = 0; | 275 | cf_sk->sk.sk_error_report(&cf_sk->sk); |
250 | wake_up_interruptible(cf_sk->sk.sk_sleep); | ||
251 | break; | 276 | break; |
252 | 277 | ||
253 | default: | 278 | default: |
254 | pr_debug("CAIF: %s(): Unexpected flow command %d\n", | 279 | pr_debug("CAIF: %s(): Unexpected flow command %d\n", |
255 | __func__, flow); | 280 | __func__, flow); |
256 | } | 281 | } |
257 | } | 282 | } |
258 | 283 | ||
259 | static void skb_destructor(struct sk_buff *skb) | 284 | static void caif_check_flow_release(struct sock *sk) |
260 | { | 285 | { |
261 | dbfs_atomic_inc(&cnt.skb_free); | 286 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); |
262 | dbfs_atomic_dec(&cnt.skb_in_use); | ||
263 | } | ||
264 | 287 | ||
288 | if (cf_sk->layer.dn == NULL || cf_sk->layer.dn->modemcmd == NULL) | ||
289 | return; | ||
290 | if (rx_flow_is_on(cf_sk)) | ||
291 | return; | ||
265 | 292 | ||
266 | static int caif_recvmsg(struct kiocb *iocb, struct socket *sock, | 293 | if (atomic_read(&sk->sk_rmem_alloc) <= sk_rcvbuf_lowwater(cf_sk)) { |
294 | dbfs_atomic_inc(&cnt.num_rx_flow_on); | ||
295 | set_rx_flow_on(cf_sk); | ||
296 | cf_sk->layer.dn->modemcmd(cf_sk->layer.dn, | ||
297 | CAIF_MODEMCMD_FLOW_ON_REQ); | ||
298 | } | ||
299 | } | ||
300 | /* | ||
301 | * Copied from sock.c:sock_queue_rcv_skb(), and added check that user buffer | ||
302 | * has sufficient size. | ||
303 | */ | ||
304 | |||
305 | static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock, | ||
267 | struct msghdr *m, size_t buf_len, int flags) | 306 | struct msghdr *m, size_t buf_len, int flags) |
268 | 307 | ||
269 | { | 308 | { |
270 | struct sock *sk = sock->sk; | 309 | struct sock *sk = sock->sk; |
271 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); | ||
272 | struct cfpkt *pkt = NULL; | ||
273 | size_t len; | ||
274 | int result; | ||
275 | struct sk_buff *skb; | 310 | struct sk_buff *skb; |
276 | ssize_t ret = -EIO; | 311 | int ret = 0; |
277 | int read_queue_low; | 312 | int len; |
278 | |||
279 | if (cf_sk == NULL) { | ||
280 | pr_debug("CAIF: %s(): private_data not set!\n", | ||
281 | __func__); | ||
282 | ret = -EBADFD; | ||
283 | goto read_error; | ||
284 | } | ||
285 | |||
286 | /* Don't do multiple iovec entries yet */ | ||
287 | if (m->msg_iovlen != 1) | ||
288 | return -EOPNOTSUPP; | ||
289 | 313 | ||
290 | if (unlikely(!buf_len)) | 314 | if (unlikely(!buf_len)) |
291 | return -EINVAL; | 315 | return -EINVAL; |
292 | 316 | ||
293 | lock_sock(&(cf_sk->sk)); | 317 | skb = skb_recv_datagram(sk, flags, 0 , &ret); |
294 | 318 | if (!skb) | |
295 | caif_assert(cf_sk->pktq); | ||
296 | |||
297 | if (!STATE_IS_OPEN(cf_sk)) { | ||
298 | /* Socket is closed or closing. */ | ||
299 | if (!STATE_IS_PENDING(cf_sk)) { | ||
300 | pr_debug("CAIF: %s(): socket is closed (by remote)\n", | ||
301 | __func__); | ||
302 | ret = -EPIPE; | ||
303 | } else { | ||
304 | pr_debug("CAIF: %s(): socket is closing..\n", __func__); | ||
305 | ret = -EBADF; | ||
306 | } | ||
307 | goto read_error; | 319 | goto read_error; |
308 | } | ||
309 | /* Socket is open or opening. */ | ||
310 | if (STATE_IS_PENDING(cf_sk)) { | ||
311 | pr_debug("CAIF: %s(): socket is opening...\n", __func__); | ||
312 | |||
313 | if (flags & MSG_DONTWAIT) { | ||
314 | /* We can't block. */ | ||
315 | pr_debug("CAIF: %s():state pending and MSG_DONTWAIT\n", | ||
316 | __func__); | ||
317 | ret = -EAGAIN; | ||
318 | goto read_error; | ||
319 | } | ||
320 | 320 | ||
321 | len = skb->len; | ||
322 | |||
323 | if (skb && skb->len > buf_len && !(flags & MSG_PEEK)) { | ||
324 | len = buf_len; | ||
321 | /* | 325 | /* |
322 | * Blocking mode; state is pending and we need to wait | 326 | * Push skb back on receive queue if buffer too small. |
323 | * for its conclusion. | 327 | * This has a built-in race where multi-threaded receive |
328 | * may get packet in wrong order, but multiple read does | ||
329 | * not really guarantee ordered delivery anyway. | ||
330 | * Let's optimize for speed without taking locks. | ||
324 | */ | 331 | */ |
325 | release_sock(&cf_sk->sk); | ||
326 | |||
327 | result = | ||
328 | wait_event_interruptible(*cf_sk->sk.sk_sleep, | ||
329 | !STATE_IS_PENDING(cf_sk)); | ||
330 | 332 | ||
331 | lock_sock(&(cf_sk->sk)); | 333 | skb_queue_head(&sk->sk_receive_queue, skb); |
332 | 334 | ret = -EMSGSIZE; | |
333 | if (result == -ERESTARTSYS) { | 335 | goto read_error; |
334 | pr_debug("CAIF: %s(): wait_event_interruptible" | ||
335 | " woken by a signal (1)", __func__); | ||
336 | ret = -ERESTARTSYS; | ||
337 | goto read_error; | ||
338 | } | ||
339 | } | 336 | } |
340 | 337 | ||
341 | if (STATE_IS_REMOTE_SHUTDOWN(cf_sk) || | 338 | ret = skb_copy_datagram_iovec(skb, 0, m->msg_iov, len); |
342 | !STATE_IS_OPEN(cf_sk) || | 339 | if (ret) |
343 | STATE_IS_PENDING(cf_sk)) { | ||
344 | |||
345 | pr_debug("CAIF: %s(): socket closed\n", | ||
346 | __func__); | ||
347 | ret = -ESHUTDOWN; | ||
348 | goto read_error; | 340 | goto read_error; |
349 | } | ||
350 | 341 | ||
351 | /* | 342 | skb_free_datagram(sk, skb); |
352 | * Block if we don't have any received buffers. | ||
353 | * The queue has its own lock. | ||
354 | */ | ||
355 | while ((pkt = cfpkt_qpeek(cf_sk->pktq)) == NULL) { | ||
356 | 343 | ||
357 | if (flags & MSG_DONTWAIT) { | 344 | caif_check_flow_release(sk); |
358 | pr_debug("CAIF: %s(): MSG_DONTWAIT\n", __func__); | ||
359 | ret = -EAGAIN; | ||
360 | goto read_error; | ||
361 | } | ||
362 | trace_printk("CAIF: %s() wait_event\n", __func__); | ||
363 | 345 | ||
364 | /* Let writers in. */ | 346 | return len; |
365 | release_sock(&cf_sk->sk); | ||
366 | 347 | ||
367 | /* Block reader until data arrives or socket is closed. */ | 348 | read_error: |
368 | if (wait_event_interruptible(*cf_sk->sk.sk_sleep, | 349 | return ret; |
369 | cfpkt_qpeek(cf_sk->pktq) | 350 | } |
370 | || STATE_IS_REMOTE_SHUTDOWN(cf_sk) | ||
371 | || !STATE_IS_OPEN(cf_sk)) == | ||
372 | -ERESTARTSYS) { | ||
373 | pr_debug("CAIF: %s():" | ||
374 | " wait_event_interruptible woken by " | ||
375 | "a signal, signal_pending(current) = %d\n", | ||
376 | __func__, | ||
377 | signal_pending(current)); | ||
378 | return -ERESTARTSYS; | ||
379 | } | ||
380 | 351 | ||
381 | trace_printk("CAIF: %s() awake\n", __func__); | ||
382 | if (STATE_IS_REMOTE_SHUTDOWN(cf_sk)) { | ||
383 | pr_debug("CAIF: %s(): " | ||
384 | "received remote_shutdown indication\n", | ||
385 | __func__); | ||
386 | ret = -ESHUTDOWN; | ||
387 | goto read_error_no_unlock; | ||
388 | } | ||
389 | 352 | ||
390 | /* I want to be alone on cf_sk (except status and queue). */ | 353 | /* Copied from unix_stream_wait_data, identical except for lock call. */ |
391 | lock_sock(&(cf_sk->sk)); | 354 | static long caif_stream_data_wait(struct sock *sk, long timeo) |
355 | { | ||
356 | DEFINE_WAIT(wait); | ||
357 | lock_sock(sk); | ||
358 | |||
359 | for (;;) { | ||
360 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | ||
361 | |||
362 | if (!skb_queue_empty(&sk->sk_receive_queue) || | ||
363 | sk->sk_err || | ||
364 | sk->sk_state != CAIF_CONNECTED || | ||
365 | sock_flag(sk, SOCK_DEAD) || | ||
366 | (sk->sk_shutdown & RCV_SHUTDOWN) || | ||
367 | signal_pending(current) || | ||
368 | !timeo) | ||
369 | break; | ||
392 | 370 | ||
393 | if (!STATE_IS_OPEN(cf_sk)) { | 371 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); |
394 | /* Someone closed the link, report error. */ | 372 | release_sock(sk); |
395 | pr_debug("CAIF: %s(): remote end shutdown!\n", | 373 | timeo = schedule_timeout(timeo); |
396 | __func__); | 374 | lock_sock(sk); |
397 | ret = -EPIPE; | 375 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); |
398 | goto read_error; | ||
399 | } | ||
400 | } | 376 | } |
401 | 377 | ||
402 | /* The queue has its own lock. */ | 378 | finish_wait(sk_sleep(sk), &wait); |
403 | len = cfpkt_getlen(pkt); | 379 | release_sock(sk); |
404 | 380 | return timeo; | |
405 | /* Check max length that can be copied. */ | 381 | } |
406 | if (len <= buf_len) | ||
407 | pkt = cfpkt_dequeue(cf_sk->pktq); | ||
408 | else { | ||
409 | pr_debug("CAIF: %s(): user buffer too small (%ld,%ld)\n", | ||
410 | __func__, (long) len, (long) buf_len); | ||
411 | if (sock->type == SOCK_SEQPACKET) { | ||
412 | ret = -EMSGSIZE; | ||
413 | goto read_error; | ||
414 | } | ||
415 | len = buf_len; | ||
416 | } | ||
417 | 382 | ||
418 | 383 | ||
419 | spin_lock(&cf_sk->read_queue_len_lock); | 384 | /* |
420 | cf_sk->read_queue_len--; | 385 | * Copied from unix_stream_recvmsg, but removed credit checks, |
421 | read_queue_low = (cf_sk->read_queue_len < CHNL_SKT_READ_QUEUE_LOW); | 386 | * changed locking calls, changed address handling. |
422 | spin_unlock(&cf_sk->read_queue_len_lock); | 387 | */ |
388 | static int caif_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | ||
389 | struct msghdr *msg, size_t size, | ||
390 | int flags) | ||
391 | { | ||
392 | struct sock *sk = sock->sk; | ||
393 | int copied = 0; | ||
394 | int target; | ||
395 | int err = 0; | ||
396 | long timeo; | ||
423 | 397 | ||
424 | if (!RX_FLOW_IS_ON(cf_sk) && read_queue_low) { | 398 | err = -EOPNOTSUPP; |
425 | dbfs_atomic_inc(&cnt.num_rx_flow_on); | 399 | if (flags&MSG_OOB) |
426 | SET_RX_FLOW_ON(cf_sk); | 400 | goto out; |
427 | 401 | ||
428 | /* Send flow on. */ | 402 | msg->msg_namelen = 0; |
429 | pr_debug("CAIF: %s(): sending flow ON (queue len = %d)\n", | ||
430 | __func__, cf_sk->read_queue_len); | ||
431 | caif_assert(cf_sk->layer.dn); | ||
432 | caif_assert(cf_sk->layer.dn->ctrlcmd); | ||
433 | (void) cf_sk->layer.dn->modemcmd(cf_sk->layer.dn, | ||
434 | CAIF_MODEMCMD_FLOW_ON_REQ); | ||
435 | 403 | ||
436 | caif_assert(cf_sk->read_queue_len >= 0); | 404 | /* |
437 | } | 405 | * Lock the socket to prevent queue disordering |
406 | * while sleeps in memcpy_tomsg | ||
407 | */ | ||
408 | err = -EAGAIN; | ||
409 | if (sk->sk_state == CAIF_CONNECTING) | ||
410 | goto out; | ||
438 | 411 | ||
439 | skb = cfpkt_tonative(pkt); | 412 | caif_read_lock(sk); |
440 | result = skb_copy_datagram_iovec(skb, 0, m->msg_iov, len); | 413 | target = sock_rcvlowat(sk, flags&MSG_WAITALL, size); |
441 | skb_pull(skb, len); | 414 | timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT); |
442 | 415 | ||
443 | if (result) { | 416 | do { |
444 | pr_debug("CAIF: %s(): copy to_iovec failed\n", __func__); | 417 | int chunk; |
445 | cfpkt_destroy(pkt); | 418 | struct sk_buff *skb; |
446 | ret = -EFAULT; | ||
447 | goto read_error; | ||
448 | } | ||
449 | 419 | ||
450 | /* Free packet and remove from queue */ | 420 | lock_sock(sk); |
451 | if (skb->len == 0) | 421 | skb = skb_dequeue(&sk->sk_receive_queue); |
452 | skb_free_datagram(sk, skb); | 422 | caif_check_flow_release(sk); |
453 | 423 | ||
454 | /* Let the others in. */ | 424 | if (skb == NULL) { |
455 | release_sock(&cf_sk->sk); | 425 | if (copied >= target) |
456 | return len; | 426 | goto unlock; |
427 | /* | ||
428 | * POSIX 1003.1g mandates this order. | ||
429 | */ | ||
430 | err = sock_error(sk); | ||
431 | if (err) | ||
432 | goto unlock; | ||
433 | err = -ECONNRESET; | ||
434 | if (sk->sk_shutdown & RCV_SHUTDOWN) | ||
435 | goto unlock; | ||
457 | 436 | ||
458 | read_error: | 437 | err = -EPIPE; |
459 | release_sock(&cf_sk->sk); | 438 | if (sk->sk_state != CAIF_CONNECTED) |
460 | read_error_no_unlock: | 439 | goto unlock; |
461 | return ret; | 440 | if (sock_flag(sk, SOCK_DEAD)) |
462 | } | 441 | goto unlock; |
463 | 442 | ||
464 | /* Send a signal as a consequence of sendmsg, sendto or caif_sendmsg. */ | 443 | release_sock(sk); |
465 | static int caif_sendmsg(struct kiocb *kiocb, struct socket *sock, | ||
466 | struct msghdr *msg, size_t len) | ||
467 | { | ||
468 | 444 | ||
469 | struct sock *sk = sock->sk; | 445 | err = -EAGAIN; |
470 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); | 446 | if (!timeo) |
471 | size_t payload_size = msg->msg_iov->iov_len; | 447 | break; |
472 | struct cfpkt *pkt = NULL; | ||
473 | struct caif_payload_info info; | ||
474 | unsigned char *txbuf; | ||
475 | ssize_t ret = -EIO; | ||
476 | int result; | ||
477 | struct sk_buff *skb; | ||
478 | caif_assert(msg->msg_iovlen == 1); | ||
479 | 448 | ||
480 | if (cf_sk == NULL) { | 449 | caif_read_unlock(sk); |
481 | pr_debug("CAIF: %s(): private_data not set!\n", | ||
482 | __func__); | ||
483 | ret = -EBADFD; | ||
484 | goto write_error_no_unlock; | ||
485 | } | ||
486 | 450 | ||
487 | if (unlikely(msg->msg_iov->iov_base == NULL)) { | 451 | timeo = caif_stream_data_wait(sk, timeo); |
488 | pr_warning("CAIF: %s(): Buffer is NULL.\n", __func__); | ||
489 | ret = -EINVAL; | ||
490 | goto write_error_no_unlock; | ||
491 | } | ||
492 | 452 | ||
493 | if (payload_size > CAIF_MAX_PAYLOAD_SIZE) { | 453 | if (signal_pending(current)) { |
494 | pr_debug("CAIF: %s(): buffer too long\n", __func__); | 454 | err = sock_intr_errno(timeo); |
495 | if (sock->type == SOCK_SEQPACKET) { | 455 | goto out; |
496 | ret = -EINVAL; | 456 | } |
497 | goto write_error_no_unlock; | 457 | caif_read_lock(sk); |
458 | continue; | ||
459 | unlock: | ||
460 | release_sock(sk); | ||
461 | break; | ||
498 | } | 462 | } |
499 | payload_size = CAIF_MAX_PAYLOAD_SIZE; | 463 | release_sock(sk); |
500 | } | 464 | chunk = min_t(unsigned int, skb->len, size); |
465 | if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { | ||
466 | skb_queue_head(&sk->sk_receive_queue, skb); | ||
467 | if (copied == 0) | ||
468 | copied = -EFAULT; | ||
469 | break; | ||
470 | } | ||
471 | copied += chunk; | ||
472 | size -= chunk; | ||
501 | 473 | ||
502 | /* I want to be alone on cf_sk (except status and queue) */ | 474 | /* Mark read part of skb as used */ |
503 | lock_sock(&(cf_sk->sk)); | 475 | if (!(flags & MSG_PEEK)) { |
476 | skb_pull(skb, chunk); | ||
504 | 477 | ||
505 | caif_assert(cf_sk->pktq); | 478 | /* put the skb back if we didn't use it up. */ |
479 | if (skb->len) { | ||
480 | skb_queue_head(&sk->sk_receive_queue, skb); | ||
481 | break; | ||
482 | } | ||
483 | kfree_skb(skb); | ||
506 | 484 | ||
507 | if (!STATE_IS_OPEN(cf_sk)) { | ||
508 | /* Socket is closed or closing */ | ||
509 | if (!STATE_IS_PENDING(cf_sk)) { | ||
510 | pr_debug("CAIF: %s(): socket is closed (by remote)\n", | ||
511 | __func__); | ||
512 | ret = -EPIPE; | ||
513 | } else { | 485 | } else { |
514 | pr_debug("CAIF: %s(): socket is closing...\n", | 486 | /* |
515 | __func__); | 487 | * It is questionable, see note in unix_dgram_recvmsg. |
516 | ret = -EBADF; | 488 | */ |
517 | } | 489 | /* put message back and return */ |
518 | goto write_error; | 490 | skb_queue_head(&sk->sk_receive_queue, skb); |
519 | } | 491 | break; |
520 | |||
521 | /* Socket is open or opening */ | ||
522 | if (STATE_IS_PENDING(cf_sk)) { | ||
523 | pr_debug("CAIF: %s(): socket is opening...\n", __func__); | ||
524 | |||
525 | if (msg->msg_flags & MSG_DONTWAIT) { | ||
526 | /* We can't block */ | ||
527 | trace_printk("CAIF: %s():state pending:" | ||
528 | "state=MSG_DONTWAIT\n", __func__); | ||
529 | ret = -EAGAIN; | ||
530 | goto write_error; | ||
531 | } | 492 | } |
532 | /* Let readers in */ | 493 | } while (size); |
533 | release_sock(&cf_sk->sk); | 494 | caif_read_unlock(sk); |
534 | |||
535 | /* | ||
536 | * Blocking mode; state is pending and we need to wait | ||
537 | * for its conclusion. | ||
538 | */ | ||
539 | result = | ||
540 | wait_event_interruptible(*cf_sk->sk.sk_sleep, | ||
541 | !STATE_IS_PENDING(cf_sk)); | ||
542 | /* I want to be alone on cf_sk (except status and queue) */ | ||
543 | lock_sock(&(cf_sk->sk)); | ||
544 | 495 | ||
545 | if (result == -ERESTARTSYS) { | 496 | out: |
546 | pr_debug("CAIF: %s(): wait_event_interruptible" | 497 | return copied ? : err; |
547 | " woken by a signal (1)", __func__); | 498 | } |
548 | ret = -ERESTARTSYS; | ||
549 | goto write_error; | ||
550 | } | ||
551 | } | ||
552 | if (STATE_IS_REMOTE_SHUTDOWN(cf_sk) || | ||
553 | !STATE_IS_OPEN(cf_sk) || | ||
554 | STATE_IS_PENDING(cf_sk)) { | ||
555 | 499 | ||
556 | pr_debug("CAIF: %s(): socket closed\n", | 500 | /* |
557 | __func__); | 501 | * Copied from sock.c:sock_wait_for_wmem, but change to wait for |
558 | ret = -ESHUTDOWN; | 502 | * CAIF flow-on and sock_writable. |
559 | goto write_error; | 503 | */ |
504 | static long caif_wait_for_flow_on(struct caifsock *cf_sk, | ||
505 | int wait_writeable, long timeo, int *err) | ||
506 | { | ||
507 | struct sock *sk = &cf_sk->sk; | ||
508 | DEFINE_WAIT(wait); | ||
509 | for (;;) { | ||
510 | *err = 0; | ||
511 | if (tx_flow_is_on(cf_sk) && | ||
512 | (!wait_writeable || sock_writeable(&cf_sk->sk))) | ||
513 | break; | ||
514 | *err = -ETIMEDOUT; | ||
515 | if (!timeo) | ||
516 | break; | ||
517 | *err = -ERESTARTSYS; | ||
518 | if (signal_pending(current)) | ||
519 | break; | ||
520 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | ||
521 | *err = -ECONNRESET; | ||
522 | if (sk->sk_shutdown & SHUTDOWN_MASK) | ||
523 | break; | ||
524 | *err = -sk->sk_err; | ||
525 | if (sk->sk_err) | ||
526 | break; | ||
527 | *err = -EPIPE; | ||
528 | if (cf_sk->sk.sk_state != CAIF_CONNECTED) | ||
529 | break; | ||
530 | timeo = schedule_timeout(timeo); | ||
560 | } | 531 | } |
532 | finish_wait(sk_sleep(sk), &wait); | ||
533 | return timeo; | ||
534 | } | ||
561 | 535 | ||
562 | if (!TX_FLOW_IS_ON(cf_sk)) { | 536 | /* |
537 | * Transmit a SKB. The device may temporarily request re-transmission | ||
538 | * by returning EAGAIN. | ||
539 | */ | ||
540 | static int transmit_skb(struct sk_buff *skb, struct caifsock *cf_sk, | ||
541 | int noblock, long timeo) | ||
542 | { | ||
543 | struct cfpkt *pkt; | ||
544 | int ret, loopcnt = 0; | ||
563 | 545 | ||
564 | /* Flow is off. Check non-block flag */ | 546 | pkt = cfpkt_fromnative(CAIF_DIR_OUT, skb); |
565 | if (msg->msg_flags & MSG_DONTWAIT) { | 547 | memset(cfpkt_info(pkt), 0, sizeof(struct caif_payload_info)); |
566 | trace_printk("CAIF: %s(): MSG_DONTWAIT and tx flow off", | 548 | do { |
567 | __func__); | ||
568 | ret = -EAGAIN; | ||
569 | goto write_error; | ||
570 | } | ||
571 | 549 | ||
572 | /* release lock before waiting */ | 550 | ret = -ETIMEDOUT; |
573 | release_sock(&cf_sk->sk); | ||
574 | 551 | ||
575 | /* Wait until flow is on or socket is closed */ | 552 | /* Slight paranoia, probably not needed. */ |
576 | if (wait_event_interruptible(*cf_sk->sk.sk_sleep, | 553 | if (unlikely(loopcnt++ > 1000)) { |
577 | TX_FLOW_IS_ON(cf_sk) | 554 | pr_warning("CAIF: %s(): transmit retries failed," |
578 | || !STATE_IS_OPEN(cf_sk) | 555 | " error = %d\n", __func__, ret); |
579 | || STATE_IS_REMOTE_SHUTDOWN(cf_sk) | 556 | break; |
580 | ) == -ERESTARTSYS) { | ||
581 | pr_debug("CAIF: %s():" | ||
582 | " wait_event_interruptible woken by a signal", | ||
583 | __func__); | ||
584 | ret = -ERESTARTSYS; | ||
585 | goto write_error_no_unlock; | ||
586 | } | 557 | } |
587 | 558 | ||
588 | /* I want to be alone on cf_sk (except status and queue) */ | 559 | if (cf_sk->layer.dn != NULL) |
589 | lock_sock(&(cf_sk->sk)); | 560 | ret = cf_sk->layer.dn->transmit(cf_sk->layer.dn, pkt); |
590 | 561 | if (likely(ret >= 0)) | |
591 | if (!STATE_IS_OPEN(cf_sk)) { | 562 | break; |
592 | /* someone closed the link, report error */ | 563 | /* if transmit return -EAGAIN, then retry */ |
593 | pr_debug("CAIF: %s(): remote end shutdown!\n", | 564 | if (noblock && ret == -EAGAIN) |
594 | __func__); | 565 | break; |
595 | ret = -EPIPE; | 566 | timeo = caif_wait_for_flow_on(cf_sk, 0, timeo, &ret); |
596 | goto write_error; | 567 | if (signal_pending(current)) { |
568 | ret = sock_intr_errno(timeo); | ||
569 | break; | ||
597 | } | 570 | } |
598 | 571 | if (ret) | |
599 | if (STATE_IS_REMOTE_SHUTDOWN(cf_sk)) { | 572 | break; |
600 | pr_debug("CAIF: %s(): " | 573 | if (cf_sk->sk.sk_state != CAIF_CONNECTED || |
601 | "received remote_shutdown indication\n", | 574 | sock_flag(&cf_sk->sk, SOCK_DEAD) || |
602 | __func__); | 575 | (cf_sk->sk.sk_shutdown & RCV_SHUTDOWN)) { |
603 | ret = -ESHUTDOWN; | 576 | ret = -EPIPE; |
604 | goto write_error; | 577 | cf_sk->sk.sk_err = EPIPE; |
578 | break; | ||
605 | } | 579 | } |
606 | } | 580 | } while (ret == -EAGAIN); |
581 | return ret; | ||
582 | } | ||
607 | 583 | ||
608 | pkt = cfpkt_create(payload_size); | 584 | /* Copied from af_unix:unix_dgram_sendmsg, and adapted to CAIF */ |
609 | skb = (struct sk_buff *)pkt; | 585 | static int caif_seqpkt_sendmsg(struct kiocb *kiocb, struct socket *sock, |
610 | skb->destructor = skb_destructor; | 586 | struct msghdr *msg, size_t len) |
611 | skb->sk = sk; | 587 | { |
612 | dbfs_atomic_inc(&cnt.skb_alloc); | 588 | struct sock *sk = sock->sk; |
613 | dbfs_atomic_inc(&cnt.skb_in_use); | 589 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); |
614 | if (cfpkt_raw_append(pkt, (void **) &txbuf, payload_size) < 0) { | 590 | int buffer_size; |
615 | pr_debug("CAIF: %s(): cfpkt_raw_append failed\n", __func__); | 591 | int ret = 0; |
616 | cfpkt_destroy(pkt); | 592 | struct sk_buff *skb = NULL; |
617 | ret = -EINVAL; | 593 | int noblock; |
618 | goto write_error; | 594 | long timeo; |
619 | } | 595 | caif_assert(cf_sk); |
596 | ret = sock_error(sk); | ||
597 | if (ret) | ||
598 | goto err; | ||
599 | |||
600 | ret = -EOPNOTSUPP; | ||
601 | if (msg->msg_flags&MSG_OOB) | ||
602 | goto err; | ||
603 | |||
604 | ret = -EOPNOTSUPP; | ||
605 | if (msg->msg_namelen) | ||
606 | goto err; | ||
607 | |||
608 | ret = -EINVAL; | ||
609 | if (unlikely(msg->msg_iov->iov_base == NULL)) | ||
610 | goto err; | ||
611 | noblock = msg->msg_flags & MSG_DONTWAIT; | ||
612 | |||
613 | buffer_size = len + CAIF_NEEDED_HEADROOM + CAIF_NEEDED_TAILROOM; | ||
614 | |||
615 | ret = -EMSGSIZE; | ||
616 | if (buffer_size > CAIF_MAX_PAYLOAD_SIZE) | ||
617 | goto err; | ||
618 | |||
619 | timeo = sock_sndtimeo(sk, noblock); | ||
620 | timeo = caif_wait_for_flow_on(container_of(sk, struct caifsock, sk), | ||
621 | 1, timeo, &ret); | ||
622 | |||
623 | ret = -EPIPE; | ||
624 | if (cf_sk->sk.sk_state != CAIF_CONNECTED || | ||
625 | sock_flag(sk, SOCK_DEAD) || | ||
626 | (sk->sk_shutdown & RCV_SHUTDOWN)) | ||
627 | goto err; | ||
628 | |||
629 | ret = -ENOMEM; | ||
630 | skb = sock_alloc_send_skb(sk, buffer_size, noblock, &ret); | ||
631 | if (!skb) | ||
632 | goto err; | ||
633 | skb_reserve(skb, CAIF_NEEDED_HEADROOM); | ||
634 | |||
635 | ret = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); | ||
636 | |||
637 | if (ret) | ||
638 | goto err; | ||
639 | ret = transmit_skb(skb, cf_sk, noblock, timeo); | ||
640 | if (ret < 0) | ||
641 | goto err; | ||
642 | return len; | ||
643 | err: | ||
644 | kfree_skb(skb); | ||
645 | return ret; | ||
646 | } | ||
620 | 647 | ||
621 | /* Copy data into buffer. */ | 648 | /* |
622 | if (copy_from_user(txbuf, msg->msg_iov->iov_base, payload_size)) { | 649 | * Copied from unix_stream_sendmsg and adapted to CAIF: |
623 | pr_debug("CAIF: %s(): copy_from_user returned non zero.\n", | 650 | * Changed removed permission handling and added waiting for flow on |
624 | __func__); | 651 | * and other minor adaptations. |
625 | cfpkt_destroy(pkt); | 652 | */ |
626 | ret = -EINVAL; | 653 | static int caif_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, |
627 | goto write_error; | 654 | struct msghdr *msg, size_t len) |
628 | } | 655 | { |
629 | memset(&info, 0, sizeof(info)); | 656 | struct sock *sk = sock->sk; |
657 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); | ||
658 | int err, size; | ||
659 | struct sk_buff *skb; | ||
660 | int sent = 0; | ||
661 | long timeo; | ||
630 | 662 | ||
631 | /* Send the packet down the stack. */ | 663 | err = -EOPNOTSUPP; |
632 | caif_assert(cf_sk->layer.dn); | ||
633 | caif_assert(cf_sk->layer.dn->transmit); | ||
634 | 664 | ||
635 | do { | 665 | if (unlikely(msg->msg_flags&MSG_OOB)) |
636 | ret = cf_sk->layer.dn->transmit(cf_sk->layer.dn, pkt); | 666 | goto out_err; |
637 | 667 | ||
638 | if (likely((ret >= 0) || (ret != -EAGAIN))) | 668 | if (unlikely(msg->msg_namelen)) |
639 | break; | 669 | goto out_err; |
640 | 670 | ||
641 | /* EAGAIN - retry */ | 671 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); |
642 | if (msg->msg_flags & MSG_DONTWAIT) { | 672 | timeo = caif_wait_for_flow_on(cf_sk, 1, timeo, &err); |
643 | pr_debug("CAIF: %s(): NONBLOCK and transmit failed," | ||
644 | " error = %ld\n", __func__, (long) ret); | ||
645 | ret = -EAGAIN; | ||
646 | goto write_error; | ||
647 | } | ||
648 | 673 | ||
649 | /* Let readers in */ | 674 | if (unlikely(sk->sk_shutdown & SEND_SHUTDOWN)) |
650 | release_sock(&cf_sk->sk); | 675 | goto pipe_err; |
651 | 676 | ||
652 | /* Wait until flow is on or socket is closed */ | 677 | while (sent < len) { |
653 | if (wait_event_interruptible(*cf_sk->sk.sk_sleep, | ||
654 | TX_FLOW_IS_ON(cf_sk) | ||
655 | || !STATE_IS_OPEN(cf_sk) | ||
656 | || STATE_IS_REMOTE_SHUTDOWN(cf_sk) | ||
657 | ) == -ERESTARTSYS) { | ||
658 | pr_debug("CAIF: %s(): wait_event_interruptible" | ||
659 | " woken by a signal", __func__); | ||
660 | ret = -ERESTARTSYS; | ||
661 | goto write_error_no_unlock; | ||
662 | } | ||
663 | 678 | ||
664 | /* I want to be alone on cf_sk (except status and queue) */ | 679 | size = len-sent; |
665 | lock_sock(&(cf_sk->sk)); | ||
666 | 680 | ||
667 | } while (ret == -EAGAIN); | 681 | if (size > CAIF_MAX_PAYLOAD_SIZE) |
682 | size = CAIF_MAX_PAYLOAD_SIZE; | ||
668 | 683 | ||
669 | if (ret < 0) { | 684 | /* If size is more than half of sndbuf, chop up message */ |
670 | cfpkt_destroy(pkt); | 685 | if (size > ((sk->sk_sndbuf >> 1) - 64)) |
671 | pr_debug("CAIF: %s(): transmit failed, error = %ld\n", | 686 | size = (sk->sk_sndbuf >> 1) - 64; |
672 | __func__, (long) ret); | ||
673 | 687 | ||
674 | goto write_error; | 688 | if (size > SKB_MAX_ALLOC) |
675 | } | 689 | size = SKB_MAX_ALLOC; |
676 | 690 | ||
677 | release_sock(&cf_sk->sk); | 691 | skb = sock_alloc_send_skb(sk, |
678 | return payload_size; | 692 | size + CAIF_NEEDED_HEADROOM |
693 | + CAIF_NEEDED_TAILROOM, | ||
694 | msg->msg_flags&MSG_DONTWAIT, | ||
695 | &err); | ||
696 | if (skb == NULL) | ||
697 | goto out_err; | ||
679 | 698 | ||
680 | write_error: | 699 | skb_reserve(skb, CAIF_NEEDED_HEADROOM); |
681 | release_sock(&cf_sk->sk); | 700 | /* |
682 | write_error_no_unlock: | 701 | * If you pass two values to the sock_alloc_send_skb |
683 | return ret; | 702 | * it tries to grab the large buffer with GFP_NOFS |
684 | } | 703 | * (which can fail easily), and if it fails grab the |
704 | * fallback size buffer which is under a page and will | ||
705 | * succeed. [Alan] | ||
706 | */ | ||
707 | size = min_t(int, size, skb_tailroom(skb)); | ||
685 | 708 | ||
686 | static unsigned int caif_poll(struct file *file, struct socket *sock, | 709 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); |
687 | poll_table *wait) | 710 | if (err) { |
688 | { | 711 | kfree_skb(skb); |
689 | struct sock *sk = sock->sk; | 712 | goto out_err; |
690 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); | 713 | } |
691 | u32 mask = 0; | 714 | err = transmit_skb(skb, cf_sk, |
692 | poll_wait(file, sk->sk_sleep, wait); | 715 | msg->msg_flags&MSG_DONTWAIT, timeo); |
693 | lock_sock(&(cf_sk->sk)); | 716 | if (err < 0) { |
694 | if (!STATE_IS_OPEN(cf_sk)) { | 717 | kfree_skb(skb); |
695 | if (!STATE_IS_PENDING(cf_sk)) | 718 | goto pipe_err; |
696 | mask |= POLLHUP; | 719 | } |
697 | } else { | 720 | sent += size; |
698 | if (cfpkt_qpeek(cf_sk->pktq) != NULL) | ||
699 | mask |= (POLLIN | POLLRDNORM); | ||
700 | if (TX_FLOW_IS_ON(cf_sk)) | ||
701 | mask |= (POLLOUT | POLLWRNORM); | ||
702 | } | 721 | } |
703 | release_sock(&cf_sk->sk); | ||
704 | trace_printk("CAIF: %s(): poll mask=0x%04x\n", | ||
705 | __func__, mask); | ||
706 | return mask; | ||
707 | } | ||
708 | |||
709 | static void drain_queue(struct caifsock *cf_sk) | ||
710 | { | ||
711 | struct cfpkt *pkt = NULL; | ||
712 | |||
713 | /* Empty the queue */ | ||
714 | do { | ||
715 | /* The queue has its own lock */ | ||
716 | if (!cf_sk->pktq) | ||
717 | break; | ||
718 | |||
719 | pkt = cfpkt_dequeue(cf_sk->pktq); | ||
720 | if (!pkt) | ||
721 | break; | ||
722 | pr_debug("CAIF: %s(): freeing packet from read queue\n", | ||
723 | __func__); | ||
724 | cfpkt_destroy(pkt); | ||
725 | 722 | ||
726 | } while (1); | 723 | return sent; |
727 | 724 | ||
728 | cf_sk->read_queue_len = 0; | 725 | pipe_err: |
726 | if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL)) | ||
727 | send_sig(SIGPIPE, current, 0); | ||
728 | err = -EPIPE; | ||
729 | out_err: | ||
730 | return sent ? : err; | ||
729 | } | 731 | } |
730 | 732 | ||
731 | static int setsockopt(struct socket *sock, | 733 | static int setsockopt(struct socket *sock, |
@@ -736,19 +738,13 @@ static int setsockopt(struct socket *sock, | |||
736 | int prio, linksel; | 738 | int prio, linksel; |
737 | struct ifreq ifreq; | 739 | struct ifreq ifreq; |
738 | 740 | ||
739 | if (STATE_IS_OPEN(cf_sk)) { | 741 | if (cf_sk->sk.sk_socket->state != SS_UNCONNECTED) |
740 | pr_debug("CAIF: %s(): setsockopt " | ||
741 | "cannot be done on a connected socket\n", | ||
742 | __func__); | ||
743 | return -ENOPROTOOPT; | 742 | return -ENOPROTOOPT; |
744 | } | 743 | |
745 | switch (opt) { | 744 | switch (opt) { |
746 | case CAIFSO_LINK_SELECT: | 745 | case CAIFSO_LINK_SELECT: |
747 | if (ol < sizeof(int)) { | 746 | if (ol < sizeof(int)) |
748 | pr_debug("CAIF: %s(): setsockopt" | ||
749 | " CAIFSO_CHANNEL_CONFIG bad size\n", __func__); | ||
750 | return -EINVAL; | 747 | return -EINVAL; |
751 | } | ||
752 | if (lvl != SOL_CAIF) | 748 | if (lvl != SOL_CAIF) |
753 | goto bad_sol; | 749 | goto bad_sol; |
754 | if (copy_from_user(&linksel, ov, sizeof(int))) | 750 | if (copy_from_user(&linksel, ov, sizeof(int))) |
@@ -761,28 +757,20 @@ static int setsockopt(struct socket *sock, | |||
761 | case SO_PRIORITY: | 757 | case SO_PRIORITY: |
762 | if (lvl != SOL_SOCKET) | 758 | if (lvl != SOL_SOCKET) |
763 | goto bad_sol; | 759 | goto bad_sol; |
764 | if (ol < sizeof(int)) { | 760 | if (ol < sizeof(int)) |
765 | pr_debug("CAIF: %s(): setsockopt" | ||
766 | " SO_PRIORITY bad size\n", __func__); | ||
767 | return -EINVAL; | 761 | return -EINVAL; |
768 | } | ||
769 | if (copy_from_user(&prio, ov, sizeof(int))) | 762 | if (copy_from_user(&prio, ov, sizeof(int))) |
770 | return -EINVAL; | 763 | return -EINVAL; |
771 | lock_sock(&(cf_sk->sk)); | 764 | lock_sock(&(cf_sk->sk)); |
772 | cf_sk->conn_req.priority = prio; | 765 | cf_sk->conn_req.priority = prio; |
773 | pr_debug("CAIF: %s(): Setting sockopt priority=%d\n", __func__, | ||
774 | cf_sk->conn_req.priority); | ||
775 | release_sock(&cf_sk->sk); | 766 | release_sock(&cf_sk->sk); |
776 | return 0; | 767 | return 0; |
777 | 768 | ||
778 | case SO_BINDTODEVICE: | 769 | case SO_BINDTODEVICE: |
779 | if (lvl != SOL_SOCKET) | 770 | if (lvl != SOL_SOCKET) |
780 | goto bad_sol; | 771 | goto bad_sol; |
781 | if (ol < sizeof(struct ifreq)) { | 772 | if (ol < sizeof(struct ifreq)) |
782 | pr_debug("CAIF: %s(): setsockopt" | ||
783 | " SO_PRIORITY bad size\n", __func__); | ||
784 | return -EINVAL; | 773 | return -EINVAL; |
785 | } | ||
786 | if (copy_from_user(&ifreq, ov, sizeof(ifreq))) | 774 | if (copy_from_user(&ifreq, ov, sizeof(ifreq))) |
787 | return -EFAULT; | 775 | return -EFAULT; |
788 | lock_sock(&(cf_sk->sk)); | 776 | lock_sock(&(cf_sk->sk)); |
@@ -798,359 +786,275 @@ static int setsockopt(struct socket *sock, | |||
798 | goto bad_sol; | 786 | goto bad_sol; |
799 | if (cf_sk->sk.sk_protocol != CAIFPROTO_UTIL) | 787 | if (cf_sk->sk.sk_protocol != CAIFPROTO_UTIL) |
800 | return -ENOPROTOOPT; | 788 | return -ENOPROTOOPT; |
801 | if (ol > sizeof(cf_sk->conn_req.param.data)) | ||
802 | goto req_param_bad_size; | ||
803 | |||
804 | lock_sock(&(cf_sk->sk)); | 789 | lock_sock(&(cf_sk->sk)); |
805 | cf_sk->conn_req.param.size = ol; | 790 | cf_sk->conn_req.param.size = ol; |
806 | if (copy_from_user(&cf_sk->conn_req.param.data, ov, ol)) { | 791 | if (ol > sizeof(cf_sk->conn_req.param.data) || |
792 | copy_from_user(&cf_sk->conn_req.param.data, ov, ol)) { | ||
807 | release_sock(&cf_sk->sk); | 793 | release_sock(&cf_sk->sk); |
808 | req_param_bad_size: | ||
809 | pr_debug("CAIF: %s(): setsockopt" | ||
810 | " CAIFSO_CHANNEL_CONFIG bad size\n", __func__); | ||
811 | return -EINVAL; | 794 | return -EINVAL; |
812 | } | 795 | } |
813 | |||
814 | release_sock(&cf_sk->sk); | 796 | release_sock(&cf_sk->sk); |
815 | return 0; | 797 | return 0; |
816 | 798 | ||
817 | default: | 799 | default: |
818 | pr_debug("CAIF: %s(): unhandled option %d\n", __func__, opt); | 800 | return -ENOPROTOOPT; |
819 | return -EINVAL; | ||
820 | } | 801 | } |
821 | 802 | ||
822 | return 0; | 803 | return 0; |
823 | bad_sol: | 804 | bad_sol: |
824 | pr_debug("CAIF: %s(): setsockopt bad level\n", __func__); | ||
825 | return -ENOPROTOOPT; | 805 | return -ENOPROTOOPT; |
826 | 806 | ||
827 | } | 807 | } |
828 | 808 | ||
829 | static int caif_connect(struct socket *sock, struct sockaddr *uservaddr, | 809 | /* |
830 | int sockaddr_len, int flags) | 810 | * caif_connect() - Connect a CAIF Socket |
811 | * Copied and modified af_irda.c:irda_connect(). | ||
812 | * | ||
813 | * Note : by consulting "errno", the user space caller may learn the cause | ||
814 | * of the failure. Most of them are visible in the function, others may come | ||
815 | * from subroutines called and are listed here : | ||
816 | * o -EAFNOSUPPORT: bad socket family or type. | ||
817 | * o -ESOCKTNOSUPPORT: bad socket type or protocol | ||
818 | * o -EINVAL: bad socket address, or CAIF link type | ||
819 | * o -ECONNREFUSED: remote end refused the connection. | ||
820 | * o -EINPROGRESS: connect request sent but timed out (or non-blocking) | ||
821 | * o -EISCONN: already connected. | ||
822 | * o -ETIMEDOUT: Connection timed out (send timeout) | ||
823 | * o -ENODEV: No link layer to send request | ||
824 | * o -ECONNRESET: Received Shutdown indication or lost link layer | ||
825 | * o -ENOMEM: Out of memory | ||
826 | * | ||
827 | * State Strategy: | ||
828 | * o sk_state: holds the CAIF_* protocol state, it's updated by | ||
829 | * caif_ctrl_cb. | ||
830 | * o sock->state: holds the SS_* socket state and is updated by connect and | ||
831 | * disconnect. | ||
832 | */ | ||
833 | static int caif_connect(struct socket *sock, struct sockaddr *uaddr, | ||
834 | int addr_len, int flags) | ||
831 | { | 835 | { |
832 | struct caifsock *cf_sk = NULL; | ||
833 | int result = -1; | ||
834 | int mode = 0; | ||
835 | int ret = -EIO; | ||
836 | struct sock *sk = sock->sk; | 836 | struct sock *sk = sock->sk; |
837 | BUG_ON(sk == NULL); | 837 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); |
838 | 838 | long timeo; | |
839 | cf_sk = container_of(sk, struct caifsock, sk); | 839 | int err; |
840 | 840 | lock_sock(sk); | |
841 | trace_printk("CAIF: %s(): cf_sk=%p OPEN=%d, TX_FLOW=%d, RX_FLOW=%d\n", | ||
842 | __func__, cf_sk, | ||
843 | STATE_IS_OPEN(cf_sk), | ||
844 | TX_FLOW_IS_ON(cf_sk), RX_FLOW_IS_ON(cf_sk)); | ||
845 | |||
846 | 841 | ||
847 | if (sock->type == SOCK_SEQPACKET || sock->type == SOCK_STREAM) | 842 | err = -EAFNOSUPPORT; |
848 | sock->state = SS_CONNECTING; | 843 | if (uaddr->sa_family != AF_CAIF) |
849 | else | ||
850 | goto out; | 844 | goto out; |
851 | 845 | ||
852 | /* I want to be alone on cf_sk (except status and queue) */ | 846 | err = -ESOCKTNOSUPPORT; |
853 | lock_sock(&(cf_sk->sk)); | 847 | if (unlikely(!(sk->sk_type == SOCK_STREAM && |
854 | 848 | cf_sk->sk.sk_protocol == CAIFPROTO_AT) && | |
855 | if (sockaddr_len != sizeof(struct sockaddr_caif)) { | 849 | sk->sk_type != SOCK_SEQPACKET)) |
856 | pr_debug("CAIF: %s(): Bad address len (%ld,%lu)\n", | 850 | goto out; |
857 | __func__, (long) sockaddr_len, | 851 | switch (sock->state) { |
858 | (long unsigned) sizeof(struct sockaddr_caif)); | 852 | case SS_UNCONNECTED: |
859 | ret = -EINVAL; | 853 | /* Normal case, a fresh connect */ |
860 | goto open_error; | 854 | caif_assert(sk->sk_state == CAIF_DISCONNECTED); |
855 | break; | ||
856 | case SS_CONNECTING: | ||
857 | switch (sk->sk_state) { | ||
858 | case CAIF_CONNECTED: | ||
859 | sock->state = SS_CONNECTED; | ||
860 | err = -EISCONN; | ||
861 | goto out; | ||
862 | case CAIF_DISCONNECTED: | ||
863 | /* Reconnect allowed */ | ||
864 | break; | ||
865 | case CAIF_CONNECTING: | ||
866 | err = -EALREADY; | ||
867 | if (flags & O_NONBLOCK) | ||
868 | goto out; | ||
869 | goto wait_connect; | ||
870 | } | ||
871 | break; | ||
872 | case SS_CONNECTED: | ||
873 | caif_assert(sk->sk_state == CAIF_CONNECTED || | ||
874 | sk->sk_state == CAIF_DISCONNECTED); | ||
875 | if (sk->sk_shutdown & SHUTDOWN_MASK) { | ||
876 | /* Allow re-connect after SHUTDOWN_IND */ | ||
877 | caif_disconnect_client(&cf_sk->layer); | ||
878 | break; | ||
879 | } | ||
880 | /* No reconnect on a seqpacket socket */ | ||
881 | err = -EISCONN; | ||
882 | goto out; | ||
883 | case SS_DISCONNECTING: | ||
884 | case SS_FREE: | ||
885 | caif_assert(1); /*Should never happen */ | ||
886 | break; | ||
861 | } | 887 | } |
888 | sk->sk_state = CAIF_DISCONNECTED; | ||
889 | sock->state = SS_UNCONNECTED; | ||
890 | sk_stream_kill_queues(&cf_sk->sk); | ||
862 | 891 | ||
863 | if (uservaddr->sa_family != AF_CAIF) { | 892 | err = -EINVAL; |
864 | pr_debug("CAIF: %s(): Bad address family (%d)\n", | 893 | if (addr_len != sizeof(struct sockaddr_caif) || |
865 | __func__, uservaddr->sa_family); | 894 | !uaddr) |
866 | ret = -EAFNOSUPPORT; | 895 | goto out; |
867 | goto open_error; | ||
868 | } | ||
869 | 896 | ||
870 | memcpy(&cf_sk->conn_req.sockaddr, uservaddr, | 897 | memcpy(&cf_sk->conn_req.sockaddr, uaddr, |
871 | sizeof(struct sockaddr_caif)); | 898 | sizeof(struct sockaddr_caif)); |
872 | 899 | ||
873 | dbfs_atomic_inc(&cnt.num_open); | 900 | /* Move to connecting socket, start sending Connect Requests */ |
874 | mode = SKT_READ_FLAG | SKT_WRITE_FLAG; | 901 | sock->state = SS_CONNECTING; |
875 | 902 | sk->sk_state = CAIF_CONNECTING; | |
876 | /* If socket is not open, make sure socket is in fully closed state */ | 903 | |
877 | if (!STATE_IS_OPEN(cf_sk)) { | 904 | dbfs_atomic_inc(&cnt.num_connect_req); |
878 | /* Has link close response been received (if we ever sent it)?*/ | 905 | cf_sk->layer.receive = caif_sktrecv_cb; |
879 | if (STATE_IS_PENDING(cf_sk)) { | 906 | err = caif_connect_client(&cf_sk->conn_req, |
880 | /* | 907 | &cf_sk->layer); |
881 | * Still waiting for close response from remote. | 908 | if (err < 0) { |
882 | * If opened non-blocking, report "would block" | 909 | cf_sk->sk.sk_socket->state = SS_UNCONNECTED; |
883 | */ | 910 | cf_sk->sk.sk_state = CAIF_DISCONNECTED; |
884 | if (flags & O_NONBLOCK) { | 911 | goto out; |
885 | pr_debug("CAIF: %s(): O_NONBLOCK" | ||
886 | " && close pending\n", __func__); | ||
887 | ret = -EAGAIN; | ||
888 | goto open_error; | ||
889 | } | ||
890 | |||
891 | pr_debug("CAIF: %s(): Wait for close response" | ||
892 | " from remote...\n", __func__); | ||
893 | |||
894 | release_sock(&cf_sk->sk); | ||
895 | |||
896 | /* | ||
897 | * Blocking mode; close is pending and we need to wait | ||
898 | * for its conclusion. | ||
899 | */ | ||
900 | result = | ||
901 | wait_event_interruptible(*cf_sk->sk.sk_sleep, | ||
902 | !STATE_IS_PENDING(cf_sk)); | ||
903 | |||
904 | lock_sock(&(cf_sk->sk)); | ||
905 | if (result == -ERESTARTSYS) { | ||
906 | pr_debug("CAIF: %s(): wait_event_interruptible" | ||
907 | "woken by a signal (1)", __func__); | ||
908 | ret = -ERESTARTSYS; | ||
909 | goto open_error; | ||
910 | } | ||
911 | } | ||
912 | } | 912 | } |
913 | 913 | ||
914 | /* socket is now either closed, pending open or open */ | 914 | err = -EINPROGRESS; |
915 | if (STATE_IS_OPEN(cf_sk) && !STATE_IS_PENDING(cf_sk)) { | 915 | wait_connect: |
916 | /* Open */ | ||
917 | pr_debug("CAIF: %s(): Socket is already opened (cf_sk=%p)" | ||
918 | " check access f_flags = 0x%x file_mode = 0x%x\n", | ||
919 | __func__, cf_sk, mode, cf_sk->file_mode); | ||
920 | |||
921 | } else { | ||
922 | /* We are closed or pending open. | ||
923 | * If closed: send link setup | ||
924 | * If pending open: link setup already sent (we could have been | ||
925 | * interrupted by a signal last time) | ||
926 | */ | ||
927 | if (!STATE_IS_OPEN(cf_sk)) { | ||
928 | /* First opening of file; connect lower layers: */ | ||
929 | /* Drain queue (very unlikely) */ | ||
930 | drain_queue(cf_sk); | ||
931 | |||
932 | cf_sk->layer.receive = caif_sktrecv_cb; | ||
933 | SET_STATE_OPEN(cf_sk); | ||
934 | SET_PENDING_ON(cf_sk); | ||
935 | |||
936 | /* Register this channel. */ | ||
937 | result = | ||
938 | caif_connect_client(&cf_sk->conn_req, | ||
939 | &cf_sk->layer); | ||
940 | if (result < 0) { | ||
941 | pr_debug("CAIF: %s(): can't register channel\n", | ||
942 | __func__); | ||
943 | ret = -EIO; | ||
944 | SET_STATE_CLOSED(cf_sk); | ||
945 | SET_PENDING_OFF(cf_sk); | ||
946 | goto open_error; | ||
947 | } | ||
948 | dbfs_atomic_inc(&cnt.num_init); | ||
949 | } | ||
950 | |||
951 | /* If opened non-blocking, report "success". | ||
952 | */ | ||
953 | if (flags & O_NONBLOCK) { | ||
954 | pr_debug("CAIF: %s(): O_NONBLOCK success\n", | ||
955 | __func__); | ||
956 | ret = -EINPROGRESS; | ||
957 | cf_sk->sk.sk_err = -EINPROGRESS; | ||
958 | goto open_error; | ||
959 | } | ||
960 | |||
961 | trace_printk("CAIF: %s(): Wait for connect response\n", | ||
962 | __func__); | ||
963 | 916 | ||
964 | /* release lock before waiting */ | 917 | if (sk->sk_state != CAIF_CONNECTED && (flags & O_NONBLOCK)) |
965 | release_sock(&cf_sk->sk); | 918 | goto out; |
966 | |||
967 | result = | ||
968 | wait_event_interruptible(*cf_sk->sk.sk_sleep, | ||
969 | !STATE_IS_PENDING(cf_sk)); | ||
970 | |||
971 | lock_sock(&(cf_sk->sk)); | ||
972 | |||
973 | if (result == -ERESTARTSYS) { | ||
974 | pr_debug("CAIF: %s(): wait_event_interruptible" | ||
975 | "woken by a signal (2)", __func__); | ||
976 | ret = -ERESTARTSYS; | ||
977 | goto open_error; | ||
978 | } | ||
979 | |||
980 | if (!STATE_IS_OPEN(cf_sk)) { | ||
981 | /* Lower layers said "no" */ | ||
982 | pr_debug("CAIF: %s(): Closed received\n", __func__); | ||
983 | ret = -EPIPE; | ||
984 | goto open_error; | ||
985 | } | ||
986 | 919 | ||
987 | trace_printk("CAIF: %s(): Connect received\n", __func__); | 920 | timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); |
921 | |||
922 | release_sock(sk); | ||
923 | err = wait_event_interruptible_timeout(*sk_sleep(sk), | ||
924 | sk->sk_state != CAIF_CONNECTING, | ||
925 | timeo); | ||
926 | lock_sock(sk); | ||
927 | if (err < 0) | ||
928 | goto out; /* -ERESTARTSYS */ | ||
929 | if (err == 0 && sk->sk_state != CAIF_CONNECTED) { | ||
930 | err = -ETIMEDOUT; | ||
931 | goto out; | ||
988 | } | 932 | } |
989 | /* Open is ok */ | ||
990 | cf_sk->file_mode |= mode; | ||
991 | 933 | ||
992 | trace_printk("CAIF: %s(): Connected - file mode = %x\n", | 934 | if (sk->sk_state != CAIF_CONNECTED) { |
993 | __func__, cf_sk->file_mode); | 935 | sock->state = SS_UNCONNECTED; |
994 | 936 | err = sock_error(sk); | |
995 | release_sock(&cf_sk->sk); | 937 | if (!err) |
996 | return 0; | 938 | err = -ECONNREFUSED; |
997 | open_error: | 939 | goto out; |
998 | sock->state = SS_UNCONNECTED; | 940 | } |
999 | release_sock(&cf_sk->sk); | 941 | sock->state = SS_CONNECTED; |
942 | err = 0; | ||
1000 | out: | 943 | out: |
1001 | return ret; | 944 | release_sock(sk); |
945 | return err; | ||
1002 | } | 946 | } |
1003 | 947 | ||
1004 | static int caif_shutdown(struct socket *sock, int how) | 948 | |
949 | /* | ||
950 | * caif_release() - Disconnect a CAIF Socket | ||
951 | * Copied and modified af_irda.c:irda_release(). | ||
952 | */ | ||
953 | static int caif_release(struct socket *sock) | ||
1005 | { | 954 | { |
1006 | struct caifsock *cf_sk = NULL; | ||
1007 | int result = 0; | ||
1008 | int tx_flow_state_was_on; | ||
1009 | struct sock *sk = sock->sk; | 955 | struct sock *sk = sock->sk; |
956 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); | ||
957 | int res = 0; | ||
1010 | 958 | ||
1011 | trace_printk("CAIF: %s(): enter\n", __func__); | 959 | if (!sk) |
1012 | pr_debug("f_flags=%x\n", sock->file->f_flags); | 960 | return 0; |
1013 | |||
1014 | if (how != SHUT_RDWR) | ||
1015 | return -EOPNOTSUPP; | ||
1016 | |||
1017 | cf_sk = container_of(sk, struct caifsock, sk); | ||
1018 | if (cf_sk == NULL) { | ||
1019 | pr_debug("CAIF: %s(): COULD NOT FIND SOCKET\n", __func__); | ||
1020 | return -EBADF; | ||
1021 | } | ||
1022 | |||
1023 | /* I want to be alone on cf_sk (except status queue) */ | ||
1024 | lock_sock(&(cf_sk->sk)); | ||
1025 | sock_hold(&cf_sk->sk); | ||
1026 | |||
1027 | /* IS_CLOSED have double meaning: | ||
1028 | * 1) Spontanous Remote Shutdown Request. | ||
1029 | * 2) Ack on a channel teardown(disconnect) | ||
1030 | * Must clear bit in case we previously received | ||
1031 | * remote shudown request. | ||
1032 | */ | ||
1033 | if (STATE_IS_OPEN(cf_sk) && !STATE_IS_PENDING(cf_sk)) { | ||
1034 | SET_STATE_CLOSED(cf_sk); | ||
1035 | SET_PENDING_ON(cf_sk); | ||
1036 | tx_flow_state_was_on = TX_FLOW_IS_ON(cf_sk); | ||
1037 | SET_TX_FLOW_OFF(cf_sk); | ||
1038 | |||
1039 | /* Hold the socket until DEINIT_RSP is received */ | ||
1040 | sock_hold(&cf_sk->sk); | ||
1041 | result = caif_disconnect_client(&cf_sk->layer); | ||
1042 | |||
1043 | if (result < 0) { | ||
1044 | pr_debug("CAIF: %s(): " | ||
1045 | "caif_disconnect_client() failed\n", | ||
1046 | __func__); | ||
1047 | SET_STATE_CLOSED(cf_sk); | ||
1048 | SET_PENDING_OFF(cf_sk); | ||
1049 | SET_TX_FLOW_OFF(cf_sk); | ||
1050 | release_sock(&cf_sk->sk); | ||
1051 | sock_put(&cf_sk->sk); | ||
1052 | return -EIO; | ||
1053 | } | ||
1054 | 961 | ||
1055 | } | 962 | set_tx_flow_off(cf_sk); |
1056 | if (STATE_IS_REMOTE_SHUTDOWN(cf_sk)) { | ||
1057 | SET_PENDING_OFF(cf_sk); | ||
1058 | SET_REMOTE_SHUTDOWN_OFF(cf_sk); | ||
1059 | } | ||
1060 | 963 | ||
1061 | /* | 964 | /* |
1062 | * Socket is no longer in state pending close, | 965 | * Ensure that packets are not queued after this point in time. |
1063 | * and we can release the reference. | 966 | * caif_queue_rcv_skb checks SOCK_DEAD holding the queue lock, |
967 | * this ensures no packets when sock is dead. | ||
1064 | */ | 968 | */ |
969 | spin_lock(&sk->sk_receive_queue.lock); | ||
970 | sock_set_flag(sk, SOCK_DEAD); | ||
971 | spin_unlock(&sk->sk_receive_queue.lock); | ||
972 | sock->sk = NULL; | ||
1065 | 973 | ||
1066 | dbfs_atomic_inc(&cnt.num_close); | 974 | dbfs_atomic_inc(&cnt.num_disconnect); |
1067 | drain_queue(cf_sk); | ||
1068 | SET_RX_FLOW_ON(cf_sk); | ||
1069 | cf_sk->file_mode = 0; | ||
1070 | sock_put(&cf_sk->sk); | ||
1071 | release_sock(&cf_sk->sk); | ||
1072 | if (!result && (sock->file->f_flags & O_NONBLOCK)) { | ||
1073 | pr_debug("nonblocking shutdown returing -EAGAIN\n"); | ||
1074 | return -EAGAIN; | ||
1075 | } else | ||
1076 | return result; | ||
1077 | } | ||
1078 | |||
1079 | static ssize_t caif_sock_no_sendpage(struct socket *sock, | ||
1080 | struct page *page, | ||
1081 | int offset, size_t size, int flags) | ||
1082 | { | ||
1083 | return -EOPNOTSUPP; | ||
1084 | } | ||
1085 | |||
1086 | /* This function is called as part of close. */ | ||
1087 | static int caif_release(struct socket *sock) | ||
1088 | { | ||
1089 | struct sock *sk = sock->sk; | ||
1090 | struct caifsock *cf_sk = NULL; | ||
1091 | int res; | ||
1092 | caif_assert(sk != NULL); | ||
1093 | cf_sk = container_of(sk, struct caifsock, sk); | ||
1094 | 975 | ||
1095 | if (cf_sk->debugfs_socket_dir != NULL) | 976 | if (cf_sk->debugfs_socket_dir != NULL) |
1096 | debugfs_remove_recursive(cf_sk->debugfs_socket_dir); | 977 | debugfs_remove_recursive(cf_sk->debugfs_socket_dir); |
1097 | 978 | ||
1098 | res = caif_shutdown(sock, SHUT_RDWR); | ||
1099 | if (res && res != -EINPROGRESS) | ||
1100 | return res; | ||
1101 | |||
1102 | /* | ||
1103 | * FIXME: Shutdown should probably be possible to do async | ||
1104 | * without flushing queues, allowing reception of frames while | ||
1105 | * waiting for DEINIT_IND. | ||
1106 | * Release should always block, to allow secure decoupling of | ||
1107 | * CAIF stack. | ||
1108 | */ | ||
1109 | if (!(sock->file->f_flags & O_NONBLOCK)) { | ||
1110 | res = wait_event_interruptible(*cf_sk->sk.sk_sleep, | ||
1111 | !STATE_IS_PENDING(cf_sk)); | ||
1112 | |||
1113 | if (res == -ERESTARTSYS) { | ||
1114 | pr_debug("CAIF: %s(): wait_event_interruptible" | ||
1115 | "woken by a signal (1)", __func__); | ||
1116 | } | ||
1117 | } | ||
1118 | lock_sock(&(cf_sk->sk)); | 979 | lock_sock(&(cf_sk->sk)); |
980 | sk->sk_state = CAIF_DISCONNECTED; | ||
981 | sk->sk_shutdown = SHUTDOWN_MASK; | ||
1119 | 982 | ||
1120 | sock->sk = NULL; | 983 | if (cf_sk->sk.sk_socket->state == SS_CONNECTED || |
984 | cf_sk->sk.sk_socket->state == SS_CONNECTING) | ||
985 | res = caif_disconnect_client(&cf_sk->layer); | ||
1121 | 986 | ||
1122 | /* Detach the socket from its process context by making it orphan. */ | 987 | cf_sk->sk.sk_socket->state = SS_DISCONNECTING; |
1123 | sock_orphan(sk); | 988 | wake_up_interruptible_poll(sk_sleep(sk), POLLERR|POLLHUP); |
1124 | 989 | ||
1125 | /* | 990 | sock_orphan(sk); |
1126 | * Setting SHUTDOWN_MASK means that both send and receive are shutdown | 991 | cf_sk->layer.dn = NULL; |
1127 | * for the socket. | 992 | sk_stream_kill_queues(&cf_sk->sk); |
1128 | */ | 993 | release_sock(sk); |
1129 | sk->sk_shutdown = SHUTDOWN_MASK; | 994 | sock_put(sk); |
995 | return res; | ||
996 | } | ||
1130 | 997 | ||
1131 | /* | 998 | /* Copied from af_unix.c:unix_poll(), added CAIF tx_flow handling */ |
1132 | * Set the socket state to closed, the TCP_CLOSE macro is used when | 999 | static unsigned int caif_poll(struct file *file, |
1133 | * closing any socket. | 1000 | struct socket *sock, poll_table *wait) |
1134 | */ | 1001 | { |
1002 | struct sock *sk = sock->sk; | ||
1003 | unsigned int mask; | ||
1004 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); | ||
1135 | 1005 | ||
1136 | /* Flush out this sockets receive queue. */ | 1006 | sock_poll_wait(file, sk_sleep(sk), wait); |
1137 | drain_queue(cf_sk); | 1007 | mask = 0; |
1138 | 1008 | ||
1139 | /* Finally release the socket. */ | 1009 | /* exceptional events? */ |
1140 | SET_STATE_PENDING_DESTROY(cf_sk); | 1010 | if (sk->sk_err) |
1011 | mask |= POLLERR; | ||
1012 | if (sk->sk_shutdown == SHUTDOWN_MASK) | ||
1013 | mask |= POLLHUP; | ||
1014 | if (sk->sk_shutdown & RCV_SHUTDOWN) | ||
1015 | mask |= POLLRDHUP; | ||
1141 | 1016 | ||
1142 | release_sock(&cf_sk->sk); | 1017 | /* readable? */ |
1018 | if (!skb_queue_empty(&sk->sk_receive_queue) || | ||
1019 | (sk->sk_shutdown & RCV_SHUTDOWN)) | ||
1020 | mask |= POLLIN | POLLRDNORM; | ||
1143 | 1021 | ||
1144 | sock_put(sk); | 1022 | /* Connection-based need to check for termination and startup */ |
1023 | if (sk->sk_state == CAIF_DISCONNECTED) | ||
1024 | mask |= POLLHUP; | ||
1145 | 1025 | ||
1146 | /* | 1026 | /* |
1147 | * The rest of the cleanup will be handled from the | 1027 | * we set writable also when the other side has shut down the |
1148 | * caif_sock_destructor | 1028 | * connection. This prevents stuck sockets. |
1149 | */ | 1029 | */ |
1150 | return res; | 1030 | if (sock_writeable(sk) && tx_flow_is_on(cf_sk)) |
1031 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; | ||
1032 | |||
1033 | return mask; | ||
1151 | } | 1034 | } |
1152 | 1035 | ||
1153 | static const struct proto_ops caif_ops = { | 1036 | static const struct proto_ops caif_seqpacket_ops = { |
1037 | .family = PF_CAIF, | ||
1038 | .owner = THIS_MODULE, | ||
1039 | .release = caif_release, | ||
1040 | .bind = sock_no_bind, | ||
1041 | .connect = caif_connect, | ||
1042 | .socketpair = sock_no_socketpair, | ||
1043 | .accept = sock_no_accept, | ||
1044 | .getname = sock_no_getname, | ||
1045 | .poll = caif_poll, | ||
1046 | .ioctl = sock_no_ioctl, | ||
1047 | .listen = sock_no_listen, | ||
1048 | .shutdown = sock_no_shutdown, | ||
1049 | .setsockopt = setsockopt, | ||
1050 | .getsockopt = sock_no_getsockopt, | ||
1051 | .sendmsg = caif_seqpkt_sendmsg, | ||
1052 | .recvmsg = caif_seqpkt_recvmsg, | ||
1053 | .mmap = sock_no_mmap, | ||
1054 | .sendpage = sock_no_sendpage, | ||
1055 | }; | ||
1056 | |||
1057 | static const struct proto_ops caif_stream_ops = { | ||
1154 | .family = PF_CAIF, | 1058 | .family = PF_CAIF, |
1155 | .owner = THIS_MODULE, | 1059 | .owner = THIS_MODULE, |
1156 | .release = caif_release, | 1060 | .release = caif_release, |
@@ -1162,73 +1066,62 @@ static const struct proto_ops caif_ops = { | |||
1162 | .poll = caif_poll, | 1066 | .poll = caif_poll, |
1163 | .ioctl = sock_no_ioctl, | 1067 | .ioctl = sock_no_ioctl, |
1164 | .listen = sock_no_listen, | 1068 | .listen = sock_no_listen, |
1165 | .shutdown = caif_shutdown, | 1069 | .shutdown = sock_no_shutdown, |
1166 | .setsockopt = setsockopt, | 1070 | .setsockopt = setsockopt, |
1167 | .getsockopt = sock_no_getsockopt, | 1071 | .getsockopt = sock_no_getsockopt, |
1168 | .sendmsg = caif_sendmsg, | 1072 | .sendmsg = caif_stream_sendmsg, |
1169 | .recvmsg = caif_recvmsg, | 1073 | .recvmsg = caif_stream_recvmsg, |
1170 | .mmap = sock_no_mmap, | 1074 | .mmap = sock_no_mmap, |
1171 | .sendpage = caif_sock_no_sendpage, | 1075 | .sendpage = sock_no_sendpage, |
1172 | }; | 1076 | }; |
1173 | 1077 | ||
1174 | /* This function is called when a socket is finally destroyed. */ | 1078 | /* This function is called when a socket is finally destroyed. */ |
1175 | static void caif_sock_destructor(struct sock *sk) | 1079 | static void caif_sock_destructor(struct sock *sk) |
1176 | { | 1080 | { |
1177 | struct caifsock *cf_sk = NULL; | 1081 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); |
1178 | cf_sk = container_of(sk, struct caifsock, sk); | ||
1179 | /* Error checks. */ | ||
1180 | caif_assert(!atomic_read(&sk->sk_wmem_alloc)); | 1082 | caif_assert(!atomic_read(&sk->sk_wmem_alloc)); |
1181 | caif_assert(sk_unhashed(sk)); | 1083 | caif_assert(sk_unhashed(sk)); |
1182 | caif_assert(!sk->sk_socket); | 1084 | caif_assert(!sk->sk_socket); |
1183 | if (!sock_flag(sk, SOCK_DEAD)) { | 1085 | if (!sock_flag(sk, SOCK_DEAD)) { |
1184 | pr_debug("CAIF: %s(): 0x%p", __func__, sk); | 1086 | pr_info("Attempt to release alive CAIF socket: %p\n", sk); |
1185 | return; | 1087 | return; |
1186 | } | 1088 | } |
1187 | 1089 | sk_stream_kill_queues(&cf_sk->sk); | |
1188 | if (STATE_IS_OPEN(cf_sk)) { | 1090 | dbfs_atomic_dec(&cnt.caif_nr_socks); |
1189 | pr_debug("CAIF: %s(): socket is opened (cf_sk=%p)" | ||
1190 | " file_mode = 0x%x\n", __func__, | ||
1191 | cf_sk, cf_sk->file_mode); | ||
1192 | return; | ||
1193 | } | ||
1194 | drain_queue(cf_sk); | ||
1195 | kfree(cf_sk->pktq); | ||
1196 | |||
1197 | trace_printk("CAIF: %s(): caif_sock_destructor: Removing socket %s\n", | ||
1198 | __func__, cf_sk->name); | ||
1199 | atomic_dec(&caif_nr_socks); | ||
1200 | } | 1091 | } |
1201 | 1092 | ||
1202 | static int caif_create(struct net *net, struct socket *sock, int protocol, | 1093 | static int caif_create(struct net *net, struct socket *sock, int protocol, |
1203 | int kern) | 1094 | int kern) |
1204 | { | 1095 | { |
1205 | struct sock *sk = NULL; | 1096 | struct sock *sk = NULL; |
1206 | struct caifsock *cf_sk = NULL; | 1097 | struct caifsock *cf_sk = NULL; |
1207 | int result = 0; | ||
1208 | static struct proto prot = {.name = "PF_CAIF", | 1098 | static struct proto prot = {.name = "PF_CAIF", |
1209 | .owner = THIS_MODULE, | 1099 | .owner = THIS_MODULE, |
1210 | .obj_size = sizeof(struct caifsock), | 1100 | .obj_size = sizeof(struct caifsock), |
1211 | }; | 1101 | }; |
1212 | 1102 | ||
1103 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_NET_ADMIN)) | ||
1104 | return -EPERM; | ||
1213 | /* | 1105 | /* |
1214 | * The sock->type specifies the socket type to use. | 1106 | * The sock->type specifies the socket type to use. |
1215 | * in SEQPACKET mode packet boundaries are enforced. | 1107 | * The CAIF socket is a packet stream in the sense |
1108 | * that it is packet based. CAIF trusts the reliability | ||
1109 | * of the link, no resending is implemented. | ||
1216 | */ | 1110 | */ |
1217 | if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM) | 1111 | if (sock->type == SOCK_SEQPACKET) |
1112 | sock->ops = &caif_seqpacket_ops; | ||
1113 | else if (sock->type == SOCK_STREAM) | ||
1114 | sock->ops = &caif_stream_ops; | ||
1115 | else | ||
1218 | return -ESOCKTNOSUPPORT; | 1116 | return -ESOCKTNOSUPPORT; |
1219 | 1117 | ||
1220 | if (net != &init_net) | ||
1221 | return -EAFNOSUPPORT; | ||
1222 | |||
1223 | if (protocol < 0 || protocol >= CAIFPROTO_MAX) | 1118 | if (protocol < 0 || protocol >= CAIFPROTO_MAX) |
1224 | return -EPROTONOSUPPORT; | 1119 | return -EPROTONOSUPPORT; |
1225 | /* | 1120 | /* |
1226 | * Set the socket state to unconnected. The socket state is really | 1121 | * Set the socket state to unconnected. The socket state |
1227 | * not used at all in the net/core or socket.c but the | 1122 | * is really not used at all in the net/core or socket.c but the |
1228 | * initialization makes sure that sock->state is not uninitialized. | 1123 | * initialization makes sure that sock->state is not uninitialized. |
1229 | */ | 1124 | */ |
1230 | sock->state = SS_UNCONNECTED; | ||
1231 | |||
1232 | sk = sk_alloc(net, PF_CAIF, GFP_KERNEL, &prot); | 1125 | sk = sk_alloc(net, PF_CAIF, GFP_KERNEL, &prot); |
1233 | if (!sk) | 1126 | if (!sk) |
1234 | return -ENOMEM; | 1127 | return -ENOMEM; |
@@ -1238,11 +1131,9 @@ static int caif_create(struct net *net, struct socket *sock, int protocol, | |||
1238 | /* Store the protocol */ | 1131 | /* Store the protocol */ |
1239 | sk->sk_protocol = (unsigned char) protocol; | 1132 | sk->sk_protocol = (unsigned char) protocol; |
1240 | 1133 | ||
1241 | spin_lock_init(&cf_sk->read_queue_len_lock); | 1134 | /* Sendbuf dictates the amount of outbound packets not yet sent */ |
1242 | 1135 | sk->sk_sndbuf = CAIF_DEF_SNDBUF; | |
1243 | /* Fill in some information concerning the misc socket. */ | 1136 | sk->sk_rcvbuf = CAIF_DEF_RCVBUF; |
1244 | snprintf(cf_sk->name, sizeof(cf_sk->name), "cf_sk%d", | ||
1245 | atomic_read(&caif_nr_socks)); | ||
1246 | 1137 | ||
1247 | /* | 1138 | /* |
1248 | * Lock in order to try to stop someone from opening the socket | 1139 | * Lock in order to try to stop someone from opening the socket |
@@ -1252,108 +1143,85 @@ static int caif_create(struct net *net, struct socket *sock, int protocol, | |||
1252 | 1143 | ||
1253 | /* Initialize the nozero default sock structure data. */ | 1144 | /* Initialize the nozero default sock structure data. */ |
1254 | sock_init_data(sock, sk); | 1145 | sock_init_data(sock, sk); |
1255 | sock->ops = &caif_ops; | ||
1256 | sk->sk_destruct = caif_sock_destructor; | 1146 | sk->sk_destruct = caif_sock_destructor; |
1257 | sk->sk_sndbuf = caif_sockbuf_size; | ||
1258 | sk->sk_rcvbuf = caif_sockbuf_size; | ||
1259 | 1147 | ||
1260 | cf_sk->pktq = cfpktq_create(); | 1148 | mutex_init(&cf_sk->readlock); /* single task reading lock */ |
1149 | cf_sk->layer.ctrlcmd = caif_ctrl_cb; | ||
1150 | cf_sk->sk.sk_socket->state = SS_UNCONNECTED; | ||
1151 | cf_sk->sk.sk_state = CAIF_DISCONNECTED; | ||
1261 | 1152 | ||
1262 | if (!cf_sk->pktq) { | 1153 | set_tx_flow_off(cf_sk); |
1263 | pr_err("CAIF: %s(): queue create failed.\n", __func__); | 1154 | set_rx_flow_on(cf_sk); |
1264 | result = -ENOMEM; | ||
1265 | release_sock(&cf_sk->sk); | ||
1266 | goto err_failed; | ||
1267 | } | ||
1268 | cf_sk->layer.ctrlcmd = caif_sktflowctrl_cb; | ||
1269 | SET_STATE_CLOSED(cf_sk); | ||
1270 | SET_PENDING_OFF(cf_sk); | ||
1271 | SET_TX_FLOW_OFF(cf_sk); | ||
1272 | SET_RX_FLOW_ON(cf_sk); | ||
1273 | 1155 | ||
1274 | /* Set default options on configuration */ | 1156 | /* Set default options on configuration */ |
1275 | cf_sk->conn_req.priority = CAIF_PRIO_NORMAL; | 1157 | cf_sk->conn_req.priority = CAIF_PRIO_NORMAL; |
1276 | cf_sk->conn_req.link_selector = CAIF_LINK_HIGH_BANDW; | 1158 | cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY; |
1277 | cf_sk->conn_req.protocol = protocol; | 1159 | cf_sk->conn_req.protocol = protocol; |
1278 | /* Increase the number of sockets created. */ | 1160 | /* Increase the number of sockets created. */ |
1279 | atomic_inc(&caif_nr_socks); | 1161 | dbfs_atomic_inc(&cnt.caif_nr_socks); |
1162 | #ifdef CONFIG_DEBUG_FS | ||
1280 | if (!IS_ERR(debugfsdir)) { | 1163 | if (!IS_ERR(debugfsdir)) { |
1164 | /* Fill in some information concerning the misc socket. */ | ||
1165 | snprintf(cf_sk->name, sizeof(cf_sk->name), "cfsk%d", | ||
1166 | atomic_read(&cnt.caif_nr_socks)); | ||
1167 | |||
1281 | cf_sk->debugfs_socket_dir = | 1168 | cf_sk->debugfs_socket_dir = |
1282 | debugfs_create_dir(cf_sk->name, debugfsdir); | 1169 | debugfs_create_dir(cf_sk->name, debugfsdir); |
1283 | debugfs_create_u32("conn_state", S_IRUSR | S_IWUSR, | 1170 | debugfs_create_u32("sk_state", S_IRUSR | S_IWUSR, |
1284 | cf_sk->debugfs_socket_dir, &cf_sk->conn_state); | 1171 | cf_sk->debugfs_socket_dir, |
1172 | (u32 *) &cf_sk->sk.sk_state); | ||
1285 | debugfs_create_u32("flow_state", S_IRUSR | S_IWUSR, | 1173 | debugfs_create_u32("flow_state", S_IRUSR | S_IWUSR, |
1286 | cf_sk->debugfs_socket_dir, &cf_sk->flow_state); | 1174 | cf_sk->debugfs_socket_dir, &cf_sk->flow_state); |
1287 | debugfs_create_u32("read_queue_len", S_IRUSR | S_IWUSR, | 1175 | debugfs_create_u32("sk_rmem_alloc", S_IRUSR | S_IWUSR, |
1176 | cf_sk->debugfs_socket_dir, | ||
1177 | (u32 *) &cf_sk->sk.sk_rmem_alloc); | ||
1178 | debugfs_create_u32("sk_wmem_alloc", S_IRUSR | S_IWUSR, | ||
1288 | cf_sk->debugfs_socket_dir, | 1179 | cf_sk->debugfs_socket_dir, |
1289 | (u32 *) &cf_sk->read_queue_len); | 1180 | (u32 *) &cf_sk->sk.sk_wmem_alloc); |
1290 | debugfs_create_u32("identity", S_IRUSR | S_IWUSR, | 1181 | debugfs_create_u32("identity", S_IRUSR | S_IWUSR, |
1291 | cf_sk->debugfs_socket_dir, | 1182 | cf_sk->debugfs_socket_dir, |
1292 | (u32 *) &cf_sk->layer.id); | 1183 | (u32 *) &cf_sk->layer.id); |
1293 | } | 1184 | } |
1185 | #endif | ||
1294 | release_sock(&cf_sk->sk); | 1186 | release_sock(&cf_sk->sk); |
1295 | return 0; | 1187 | return 0; |
1296 | err_failed: | ||
1297 | sk_free(sk); | ||
1298 | return result; | ||
1299 | } | 1188 | } |
1300 | 1189 | ||
1190 | |||
1301 | static struct net_proto_family caif_family_ops = { | 1191 | static struct net_proto_family caif_family_ops = { |
1302 | .family = PF_CAIF, | 1192 | .family = PF_CAIF, |
1303 | .create = caif_create, | 1193 | .create = caif_create, |
1304 | .owner = THIS_MODULE, | 1194 | .owner = THIS_MODULE, |
1305 | }; | 1195 | }; |
1306 | 1196 | ||
1307 | static int af_caif_init(void) | 1197 | int af_caif_init(void) |
1308 | { | 1198 | { |
1309 | int err; | 1199 | int err = sock_register(&caif_family_ops); |
1310 | err = sock_register(&caif_family_ops); | ||
1311 | |||
1312 | if (!err) | 1200 | if (!err) |
1313 | return err; | 1201 | return err; |
1314 | |||
1315 | return 0; | 1202 | return 0; |
1316 | } | 1203 | } |
1317 | 1204 | ||
1318 | static int __init caif_sktinit_module(void) | 1205 | static int __init caif_sktinit_module(void) |
1319 | { | 1206 | { |
1320 | int stat; | ||
1321 | #ifdef CONFIG_DEBUG_FS | 1207 | #ifdef CONFIG_DEBUG_FS |
1322 | debugfsdir = debugfs_create_dir("chnl_skt", NULL); | 1208 | debugfsdir = debugfs_create_dir("caif_sk", NULL); |
1323 | if (!IS_ERR(debugfsdir)) { | 1209 | if (!IS_ERR(debugfsdir)) { |
1324 | debugfs_create_u32("skb_inuse", S_IRUSR | S_IWUSR, | ||
1325 | debugfsdir, | ||
1326 | (u32 *) &cnt.skb_in_use); | ||
1327 | debugfs_create_u32("skb_alloc", S_IRUSR | S_IWUSR, | ||
1328 | debugfsdir, | ||
1329 | (u32 *) &cnt.skb_alloc); | ||
1330 | debugfs_create_u32("skb_free", S_IRUSR | S_IWUSR, | ||
1331 | debugfsdir, | ||
1332 | (u32 *) &cnt.skb_free); | ||
1333 | debugfs_create_u32("num_sockets", S_IRUSR | S_IWUSR, | 1210 | debugfs_create_u32("num_sockets", S_IRUSR | S_IWUSR, |
1334 | debugfsdir, | 1211 | debugfsdir, |
1335 | (u32 *) &caif_nr_socks); | 1212 | (u32 *) &cnt.caif_nr_socks); |
1336 | debugfs_create_u32("num_open", S_IRUSR | S_IWUSR, | 1213 | debugfs_create_u32("num_connect_req", S_IRUSR | S_IWUSR, |
1337 | debugfsdir, | 1214 | debugfsdir, |
1338 | (u32 *) &cnt.num_open); | 1215 | (u32 *) &cnt.num_connect_req); |
1339 | debugfs_create_u32("num_close", S_IRUSR | S_IWUSR, | 1216 | debugfs_create_u32("num_connect_resp", S_IRUSR | S_IWUSR, |
1340 | debugfsdir, | 1217 | debugfsdir, |
1341 | (u32 *) &cnt.num_close); | 1218 | (u32 *) &cnt.num_connect_resp); |
1342 | debugfs_create_u32("num_init", S_IRUSR | S_IWUSR, | 1219 | debugfs_create_u32("num_connect_fail_resp", S_IRUSR | S_IWUSR, |
1343 | debugfsdir, | 1220 | debugfsdir, |
1344 | (u32 *) &cnt.num_init); | 1221 | (u32 *) &cnt.num_connect_fail_resp); |
1345 | debugfs_create_u32("num_init_resp", S_IRUSR | S_IWUSR, | 1222 | debugfs_create_u32("num_disconnect", S_IRUSR | S_IWUSR, |
1346 | debugfsdir, | 1223 | debugfsdir, |
1347 | (u32 *) &cnt.num_init_resp); | 1224 | (u32 *) &cnt.num_disconnect); |
1348 | debugfs_create_u32("num_init_fail_resp", S_IRUSR | S_IWUSR, | ||
1349 | debugfsdir, | ||
1350 | (u32 *) &cnt.num_init_fail_resp); | ||
1351 | debugfs_create_u32("num_deinit", S_IRUSR | S_IWUSR, | ||
1352 | debugfsdir, | ||
1353 | (u32 *) &cnt.num_deinit); | ||
1354 | debugfs_create_u32("num_deinit_resp", S_IRUSR | S_IWUSR, | ||
1355 | debugfsdir, | ||
1356 | (u32 *) &cnt.num_deinit_resp); | ||
1357 | debugfs_create_u32("num_remote_shutdown_ind", | 1225 | debugfs_create_u32("num_remote_shutdown_ind", |
1358 | S_IRUSR | S_IWUSR, debugfsdir, | 1226 | S_IRUSR | S_IWUSR, debugfsdir, |
1359 | (u32 *) &cnt.num_remote_shutdown_ind); | 1227 | (u32 *) &cnt.num_remote_shutdown_ind); |
@@ -1371,13 +1239,7 @@ static int __init caif_sktinit_module(void) | |||
1371 | (u32 *) &cnt.num_rx_flow_on); | 1239 | (u32 *) &cnt.num_rx_flow_on); |
1372 | } | 1240 | } |
1373 | #endif | 1241 | #endif |
1374 | stat = af_caif_init(); | 1242 | return af_caif_init(); |
1375 | if (stat) { | ||
1376 | pr_err("CAIF: %s(): Failed to initialize CAIF socket layer.", | ||
1377 | __func__); | ||
1378 | return stat; | ||
1379 | } | ||
1380 | return 0; | ||
1381 | } | 1243 | } |
1382 | 1244 | ||
1383 | static void __exit caif_sktexit_module(void) | 1245 | static void __exit caif_sktexit_module(void) |
@@ -1386,6 +1248,5 @@ static void __exit caif_sktexit_module(void) | |||
1386 | if (debugfsdir != NULL) | 1248 | if (debugfsdir != NULL) |
1387 | debugfs_remove_recursive(debugfsdir); | 1249 | debugfs_remove_recursive(debugfsdir); |
1388 | } | 1250 | } |
1389 | |||
1390 | module_init(caif_sktinit_module); | 1251 | module_init(caif_sktinit_module); |
1391 | module_exit(caif_sktexit_module); | 1252 | module_exit(caif_sktexit_module); |
diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index c873e3d4387c..471c62939fad 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c | |||
@@ -51,12 +51,11 @@ struct cfcnfg { | |||
51 | struct cfcnfg_phyinfo phy_layers[MAX_PHY_LAYERS]; | 51 | struct cfcnfg_phyinfo phy_layers[MAX_PHY_LAYERS]; |
52 | }; | 52 | }; |
53 | 53 | ||
54 | static void cncfg_linkup_rsp(struct cflayer *layer, u8 linkid, | 54 | static void cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, |
55 | enum cfctrl_srv serv, u8 phyid, | 55 | enum cfctrl_srv serv, u8 phyid, |
56 | struct cflayer *adapt_layer); | 56 | struct cflayer *adapt_layer); |
57 | static void cncfg_linkdestroy_rsp(struct cflayer *layer, u8 linkid, | 57 | static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id); |
58 | struct cflayer *client_layer); | 58 | static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id, |
59 | static void cncfg_reject_rsp(struct cflayer *layer, u8 linkid, | ||
60 | struct cflayer *adapt_layer); | 59 | struct cflayer *adapt_layer); |
61 | static void cfctrl_resp_func(void); | 60 | static void cfctrl_resp_func(void); |
62 | static void cfctrl_enum_resp(void); | 61 | static void cfctrl_enum_resp(void); |
@@ -82,13 +81,13 @@ struct cfcnfg *cfcnfg_create(void) | |||
82 | resp = cfctrl_get_respfuncs(this->ctrl); | 81 | resp = cfctrl_get_respfuncs(this->ctrl); |
83 | resp->enum_rsp = cfctrl_enum_resp; | 82 | resp->enum_rsp = cfctrl_enum_resp; |
84 | resp->linkerror_ind = cfctrl_resp_func; | 83 | resp->linkerror_ind = cfctrl_resp_func; |
85 | resp->linkdestroy_rsp = cncfg_linkdestroy_rsp; | 84 | resp->linkdestroy_rsp = cfcnfg_linkdestroy_rsp; |
86 | resp->sleep_rsp = cfctrl_resp_func; | 85 | resp->sleep_rsp = cfctrl_resp_func; |
87 | resp->wake_rsp = cfctrl_resp_func; | 86 | resp->wake_rsp = cfctrl_resp_func; |
88 | resp->restart_rsp = cfctrl_resp_func; | 87 | resp->restart_rsp = cfctrl_resp_func; |
89 | resp->radioset_rsp = cfctrl_resp_func; | 88 | resp->radioset_rsp = cfctrl_resp_func; |
90 | resp->linksetup_rsp = cncfg_linkup_rsp; | 89 | resp->linksetup_rsp = cfcnfg_linkup_rsp; |
91 | resp->reject_rsp = cncfg_reject_rsp; | 90 | resp->reject_rsp = cfcnfg_reject_rsp; |
92 | 91 | ||
93 | this->last_phyid = 1; | 92 | this->last_phyid = 1; |
94 | 93 | ||
@@ -175,142 +174,82 @@ int cfcnfg_get_named(struct cfcnfg *cnfg, char *name) | |||
175 | return 0; | 174 | return 0; |
176 | } | 175 | } |
177 | 176 | ||
178 | /* | 177 | int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) |
179 | * NOTE: What happens on destroy failure: | ||
180 | * 1a) No response - Too early | ||
181 | * This will not happen because enumerate has already | ||
182 | * completed. | ||
183 | * 1b) No response - FATAL | ||
184 | * Not handled, but this should be a CAIF PROTOCOL ERROR | ||
185 | * Modem error, response is really expected - this | ||
186 | * case is not really handled. | ||
187 | * 2) O/E-bit indicate error | ||
188 | * Ignored - this link is destroyed anyway. | ||
189 | * 3) Not able to match on request | ||
190 | * Not handled, but this should be a CAIF PROTOCOL ERROR | ||
191 | * 4) Link-Error - (no response) | ||
192 | * Not handled, but this should be a CAIF PROTOCOL ERROR | ||
193 | */ | ||
194 | |||
195 | int cfcnfg_del_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) | ||
196 | { | 178 | { |
197 | u8 channel_id = 0; | 179 | u8 channel_id = 0; |
198 | int ret = 0; | 180 | int ret = 0; |
181 | struct cflayer *servl = NULL; | ||
199 | struct cfcnfg_phyinfo *phyinfo = NULL; | 182 | struct cfcnfg_phyinfo *phyinfo = NULL; |
200 | u8 phyid = 0; | 183 | u8 phyid = 0; |
201 | |||
202 | caif_assert(adap_layer != NULL); | 184 | caif_assert(adap_layer != NULL); |
203 | channel_id = adap_layer->id; | 185 | channel_id = adap_layer->id; |
204 | if (channel_id == 0) { | 186 | if (adap_layer->dn == NULL || channel_id == 0) { |
205 | pr_err("CAIF: %s():adap_layer->id is 0\n", __func__); | 187 | pr_err("CAIF: %s():adap_layer->id is 0\n", __func__); |
206 | ret = -ENOTCONN; | 188 | ret = -ENOTCONN; |
207 | goto end; | 189 | goto end; |
208 | } | 190 | } |
209 | 191 | servl = cfmuxl_remove_uplayer(cnfg->mux, channel_id); | |
210 | if (adap_layer->dn == NULL) { | 192 | if (servl == NULL) |
211 | pr_err("CAIF: %s():adap_layer->dn is NULL\n", __func__); | ||
212 | ret = -ENODEV; | ||
213 | goto end; | ||
214 | } | ||
215 | |||
216 | if (adap_layer->dn != NULL) | ||
217 | phyid = cfsrvl_getphyid(adap_layer->dn); | ||
218 | |||
219 | phyinfo = cfcnfg_get_phyinfo(cnfg, phyid); | ||
220 | if (phyinfo == NULL) { | ||
221 | pr_warning("CAIF: %s(): No interface to send disconnect to\n", | ||
222 | __func__); | ||
223 | ret = -ENODEV; | ||
224 | goto end; | 193 | goto end; |
225 | } | 194 | layer_set_up(servl, NULL); |
226 | 195 | ret = cfctrl_linkdown_req(cnfg->ctrl, channel_id, adap_layer); | |
227 | if (phyinfo->id != phyid | 196 | if (servl == NULL) { |
228 | || phyinfo->phy_layer->id != phyid | 197 | pr_err("CAIF: %s(): PROTOCOL ERROR " |
229 | || phyinfo->frm_layer->id != phyid) { | 198 | "- Error removing service_layer Channel_Id(%d)", |
230 | 199 | __func__, channel_id); | |
231 | pr_err("CAIF: %s(): Inconsistency in phy registration\n", | ||
232 | __func__); | ||
233 | ret = -EINVAL; | 200 | ret = -EINVAL; |
234 | goto end; | 201 | goto end; |
235 | } | 202 | } |
203 | caif_assert(channel_id == servl->id); | ||
204 | if (adap_layer->dn != NULL) { | ||
205 | phyid = cfsrvl_getphyid(adap_layer->dn); | ||
236 | 206 | ||
237 | ret = cfctrl_linkdown_req(cnfg->ctrl, channel_id, adap_layer); | 207 | phyinfo = cfcnfg_get_phyinfo(cnfg, phyid); |
238 | 208 | if (phyinfo == NULL) { | |
239 | end: | 209 | pr_warning("CAIF: %s(): " |
210 | "No interface to send disconnect to\n", | ||
211 | __func__); | ||
212 | ret = -ENODEV; | ||
213 | goto end; | ||
214 | } | ||
215 | if (phyinfo->id != phyid || | ||
216 | phyinfo->phy_layer->id != phyid || | ||
217 | phyinfo->frm_layer->id != phyid) { | ||
218 | pr_err("CAIF: %s(): " | ||
219 | "Inconsistency in phy registration\n", | ||
220 | __func__); | ||
221 | ret = -EINVAL; | ||
222 | goto end; | ||
223 | } | ||
224 | } | ||
240 | if (phyinfo != NULL && --phyinfo->phy_ref_count == 0 && | 225 | if (phyinfo != NULL && --phyinfo->phy_ref_count == 0 && |
241 | phyinfo->phy_layer != NULL && | 226 | phyinfo->phy_layer != NULL && |
242 | phyinfo->phy_layer->modemcmd != NULL) { | 227 | phyinfo->phy_layer->modemcmd != NULL) { |
243 | phyinfo->phy_layer->modemcmd(phyinfo->phy_layer, | 228 | phyinfo->phy_layer->modemcmd(phyinfo->phy_layer, |
244 | _CAIF_MODEMCMD_PHYIF_USELESS); | 229 | _CAIF_MODEMCMD_PHYIF_USELESS); |
245 | } | 230 | } |
231 | end: | ||
232 | cfsrvl_put(servl); | ||
233 | cfctrl_cancel_req(cnfg->ctrl, adap_layer); | ||
234 | if (adap_layer->ctrlcmd != NULL) | ||
235 | adap_layer->ctrlcmd(adap_layer, CAIF_CTRLCMD_DEINIT_RSP, 0); | ||
246 | return ret; | 236 | return ret; |
247 | 237 | ||
248 | } | 238 | } |
249 | EXPORT_SYMBOL(cfcnfg_del_adapt_layer); | 239 | EXPORT_SYMBOL(cfcnfg_disconn_adapt_layer); |
250 | 240 | ||
251 | static void cncfg_linkdestroy_rsp(struct cflayer *layer, u8 linkid, | 241 | void cfcnfg_release_adap_layer(struct cflayer *adap_layer) |
252 | struct cflayer *client_layer) | ||
253 | { | 242 | { |
254 | struct cfcnfg *cnfg = container_obj(layer); | 243 | if (adap_layer->dn) |
255 | struct cflayer *servl; | 244 | cfsrvl_put(adap_layer->dn); |
256 | |||
257 | /* | ||
258 | * 1) Remove service from the MUX layer. The MUX must | ||
259 | * guarante that no more payload sent "upwards" (receive) | ||
260 | */ | ||
261 | servl = cfmuxl_remove_uplayer(cnfg->mux, linkid); | ||
262 | |||
263 | if (servl == NULL) { | ||
264 | pr_err("CAIF: %s(): PROTOCOL ERROR " | ||
265 | "- Error removing service_layer Linkid(%d)", | ||
266 | __func__, linkid); | ||
267 | return; | ||
268 | } | ||
269 | caif_assert(linkid == servl->id); | ||
270 | |||
271 | if (servl != client_layer && servl->up != client_layer) { | ||
272 | pr_err("CAIF: %s(): Error removing service_layer " | ||
273 | "Linkid(%d) %p %p", | ||
274 | __func__, linkid, (void *) servl, | ||
275 | (void *) client_layer); | ||
276 | return; | ||
277 | } | ||
278 | |||
279 | /* | ||
280 | * 2) DEINIT_RSP must guarantee that no more packets are transmitted | ||
281 | * from client (adap_layer) when it returns. | ||
282 | */ | ||
283 | |||
284 | if (servl->ctrlcmd == NULL) { | ||
285 | pr_err("CAIF: %s(): Error servl->ctrlcmd == NULL", __func__); | ||
286 | return; | ||
287 | } | ||
288 | |||
289 | servl->ctrlcmd(servl, CAIF_CTRLCMD_DEINIT_RSP, 0); | ||
290 | |||
291 | /* 3) It is now safe to destroy the service layer. */ | ||
292 | cfservl_destroy(servl); | ||
293 | } | 245 | } |
246 | EXPORT_SYMBOL(cfcnfg_release_adap_layer); | ||
294 | 247 | ||
295 | /* | 248 | static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id) |
296 | * NOTE: What happens on linksetup failure: | 249 | { |
297 | * 1a) No response - Too early | 250 | } |
298 | * This will not happen because enumerate is secured | ||
299 | * before using interface. | ||
300 | * 1b) No response - FATAL | ||
301 | * Not handled, but this should be a CAIF PROTOCOL ERROR | ||
302 | * Modem error, response is really expected - this case is | ||
303 | * not really handled. | ||
304 | * 2) O/E-bit indicate error | ||
305 | * Handled in cnfg_reject_rsp | ||
306 | * 3) Not able to match on request | ||
307 | * Not handled, but this should be a CAIF PROTOCOL ERROR | ||
308 | * 4) Link-Error - (no response) | ||
309 | * Not handled, but this should be a CAIF PROTOCOL ERROR | ||
310 | */ | ||
311 | 251 | ||
312 | int | 252 | int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, |
313 | cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, | ||
314 | struct cfctrl_link_param *param, | 253 | struct cfctrl_link_param *param, |
315 | struct cflayer *adap_layer) | 254 | struct cflayer *adap_layer) |
316 | { | 255 | { |
@@ -340,12 +279,11 @@ cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, | |||
340 | param->phyid); | 279 | param->phyid); |
341 | /* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */ | 280 | /* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */ |
342 | cfctrl_enum_req(cnfg->ctrl, param->phyid); | 281 | cfctrl_enum_req(cnfg->ctrl, param->phyid); |
343 | cfctrl_linkup_request(cnfg->ctrl, param, adap_layer); | 282 | return cfctrl_linkup_request(cnfg->ctrl, param, adap_layer); |
344 | return 0; | ||
345 | } | 283 | } |
346 | EXPORT_SYMBOL(cfcnfg_add_adaptation_layer); | 284 | EXPORT_SYMBOL(cfcnfg_add_adaptation_layer); |
347 | 285 | ||
348 | static void cncfg_reject_rsp(struct cflayer *layer, u8 linkid, | 286 | static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id, |
349 | struct cflayer *adapt_layer) | 287 | struct cflayer *adapt_layer) |
350 | { | 288 | { |
351 | if (adapt_layer != NULL && adapt_layer->ctrlcmd != NULL) | 289 | if (adapt_layer != NULL && adapt_layer->ctrlcmd != NULL) |
@@ -354,15 +292,17 @@ static void cncfg_reject_rsp(struct cflayer *layer, u8 linkid, | |||
354 | } | 292 | } |
355 | 293 | ||
356 | static void | 294 | static void |
357 | cncfg_linkup_rsp(struct cflayer *layer, u8 linkid, enum cfctrl_srv serv, | 295 | cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv, |
358 | u8 phyid, struct cflayer *adapt_layer) | 296 | u8 phyid, struct cflayer *adapt_layer) |
359 | { | 297 | { |
360 | struct cfcnfg *cnfg = container_obj(layer); | 298 | struct cfcnfg *cnfg = container_obj(layer); |
361 | struct cflayer *servicel = NULL; | 299 | struct cflayer *servicel = NULL; |
362 | struct cfcnfg_phyinfo *phyinfo; | 300 | struct cfcnfg_phyinfo *phyinfo; |
363 | if (adapt_layer == NULL) { | 301 | if (adapt_layer == NULL) { |
364 | pr_err("CAIF: %s(): PROTOCOL ERROR " | 302 | pr_debug("CAIF: %s(): link setup response " |
365 | "- LinkUp Request/Response did not match\n", __func__); | 303 | "but no client exist, send linkdown back\n", |
304 | __func__); | ||
305 | cfctrl_linkdown_req(cnfg->ctrl, channel_id, NULL); | ||
366 | return; | 306 | return; |
367 | } | 307 | } |
368 | 308 | ||
@@ -383,26 +323,26 @@ cncfg_linkup_rsp(struct cflayer *layer, u8 linkid, enum cfctrl_srv serv, | |||
383 | _CAIF_MODEMCMD_PHYIF_USEFULL); | 323 | _CAIF_MODEMCMD_PHYIF_USEFULL); |
384 | 324 | ||
385 | } | 325 | } |
386 | adapt_layer->id = linkid; | 326 | adapt_layer->id = channel_id; |
387 | 327 | ||
388 | switch (serv) { | 328 | switch (serv) { |
389 | case CFCTRL_SRV_VEI: | 329 | case CFCTRL_SRV_VEI: |
390 | servicel = cfvei_create(linkid, &phyinfo->dev_info); | 330 | servicel = cfvei_create(channel_id, &phyinfo->dev_info); |
391 | break; | 331 | break; |
392 | case CFCTRL_SRV_DATAGRAM: | 332 | case CFCTRL_SRV_DATAGRAM: |
393 | servicel = cfdgml_create(linkid, &phyinfo->dev_info); | 333 | servicel = cfdgml_create(channel_id, &phyinfo->dev_info); |
394 | break; | 334 | break; |
395 | case CFCTRL_SRV_RFM: | 335 | case CFCTRL_SRV_RFM: |
396 | servicel = cfrfml_create(linkid, &phyinfo->dev_info); | 336 | servicel = cfrfml_create(channel_id, &phyinfo->dev_info); |
397 | break; | 337 | break; |
398 | case CFCTRL_SRV_UTIL: | 338 | case CFCTRL_SRV_UTIL: |
399 | servicel = cfutill_create(linkid, &phyinfo->dev_info); | 339 | servicel = cfutill_create(channel_id, &phyinfo->dev_info); |
400 | break; | 340 | break; |
401 | case CFCTRL_SRV_VIDEO: | 341 | case CFCTRL_SRV_VIDEO: |
402 | servicel = cfvidl_create(linkid, &phyinfo->dev_info); | 342 | servicel = cfvidl_create(channel_id, &phyinfo->dev_info); |
403 | break; | 343 | break; |
404 | case CFCTRL_SRV_DBG: | 344 | case CFCTRL_SRV_DBG: |
405 | servicel = cfdbgl_create(linkid, &phyinfo->dev_info); | 345 | servicel = cfdbgl_create(channel_id, &phyinfo->dev_info); |
406 | break; | 346 | break; |
407 | default: | 347 | default: |
408 | pr_err("CAIF: %s(): Protocol error. " | 348 | pr_err("CAIF: %s(): Protocol error. " |
@@ -415,9 +355,10 @@ cncfg_linkup_rsp(struct cflayer *layer, u8 linkid, enum cfctrl_srv serv, | |||
415 | return; | 355 | return; |
416 | } | 356 | } |
417 | layer_set_dn(servicel, cnfg->mux); | 357 | layer_set_dn(servicel, cnfg->mux); |
418 | cfmuxl_set_uplayer(cnfg->mux, servicel, linkid); | 358 | cfmuxl_set_uplayer(cnfg->mux, servicel, channel_id); |
419 | layer_set_up(servicel, adapt_layer); | 359 | layer_set_up(servicel, adapt_layer); |
420 | layer_set_dn(adapt_layer, servicel); | 360 | layer_set_dn(adapt_layer, servicel); |
361 | cfsrvl_get(servicel); | ||
421 | servicel->ctrlcmd(servicel, CAIF_CTRLCMD_INIT_RSP, 0); | 362 | servicel->ctrlcmd(servicel, CAIF_CTRLCMD_INIT_RSP, 0); |
422 | } | 363 | } |
423 | 364 | ||
diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index 11f80140f3cb..a521d32cfe56 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c | |||
@@ -32,6 +32,7 @@ static void cfctrl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, | |||
32 | 32 | ||
33 | struct cflayer *cfctrl_create(void) | 33 | struct cflayer *cfctrl_create(void) |
34 | { | 34 | { |
35 | struct dev_info dev_info; | ||
35 | struct cfctrl *this = | 36 | struct cfctrl *this = |
36 | kmalloc(sizeof(struct cfctrl), GFP_ATOMIC); | 37 | kmalloc(sizeof(struct cfctrl), GFP_ATOMIC); |
37 | if (!this) { | 38 | if (!this) { |
@@ -39,12 +40,13 @@ struct cflayer *cfctrl_create(void) | |||
39 | return NULL; | 40 | return NULL; |
40 | } | 41 | } |
41 | caif_assert(offsetof(struct cfctrl, serv.layer) == 0); | 42 | caif_assert(offsetof(struct cfctrl, serv.layer) == 0); |
43 | memset(&dev_info, 0, sizeof(dev_info)); | ||
44 | dev_info.id = 0xff; | ||
42 | memset(this, 0, sizeof(*this)); | 45 | memset(this, 0, sizeof(*this)); |
46 | cfsrvl_init(&this->serv, 0, &dev_info); | ||
43 | spin_lock_init(&this->info_list_lock); | 47 | spin_lock_init(&this->info_list_lock); |
44 | atomic_set(&this->req_seq_no, 1); | 48 | atomic_set(&this->req_seq_no, 1); |
45 | atomic_set(&this->rsp_seq_no, 1); | 49 | atomic_set(&this->rsp_seq_no, 1); |
46 | this->serv.dev_info.id = 0xff; | ||
47 | this->serv.layer.id = 0; | ||
48 | this->serv.layer.receive = cfctrl_recv; | 50 | this->serv.layer.receive = cfctrl_recv; |
49 | sprintf(this->serv.layer.name, "ctrl"); | 51 | sprintf(this->serv.layer.name, "ctrl"); |
50 | this->serv.layer.ctrlcmd = cfctrl_ctrlcmd; | 52 | this->serv.layer.ctrlcmd = cfctrl_ctrlcmd; |
@@ -127,20 +129,6 @@ void cfctrl_insert_req(struct cfctrl *ctrl, | |||
127 | spin_unlock(&ctrl->info_list_lock); | 129 | spin_unlock(&ctrl->info_list_lock); |
128 | } | 130 | } |
129 | 131 | ||
130 | static void cfctrl_insert_req2(struct cfctrl *ctrl, enum cfctrl_cmd cmd, | ||
131 | u8 linkid, struct cflayer *user_layer) | ||
132 | { | ||
133 | struct cfctrl_request_info *req = kmalloc(sizeof(*req), GFP_KERNEL); | ||
134 | if (!req) { | ||
135 | pr_warning("CAIF: %s(): Out of memory\n", __func__); | ||
136 | return; | ||
137 | } | ||
138 | req->client_layer = user_layer; | ||
139 | req->cmd = cmd; | ||
140 | req->channel_id = linkid; | ||
141 | cfctrl_insert_req(ctrl, req); | ||
142 | } | ||
143 | |||
144 | /* Compare and remove request */ | 132 | /* Compare and remove request */ |
145 | struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl, | 133 | struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl, |
146 | struct cfctrl_request_info *req) | 134 | struct cfctrl_request_info *req) |
@@ -234,7 +222,7 @@ void cfctrl_enum_req(struct cflayer *layer, u8 physlinkid) | |||
234 | } | 222 | } |
235 | } | 223 | } |
236 | 224 | ||
237 | void cfctrl_linkup_request(struct cflayer *layer, | 225 | int cfctrl_linkup_request(struct cflayer *layer, |
238 | struct cfctrl_link_param *param, | 226 | struct cfctrl_link_param *param, |
239 | struct cflayer *user_layer) | 227 | struct cflayer *user_layer) |
240 | { | 228 | { |
@@ -248,7 +236,7 @@ void cfctrl_linkup_request(struct cflayer *layer, | |||
248 | struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); | 236 | struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); |
249 | if (!pkt) { | 237 | if (!pkt) { |
250 | pr_warning("CAIF: %s(): Out of memory\n", __func__); | 238 | pr_warning("CAIF: %s(): Out of memory\n", __func__); |
251 | return; | 239 | return -ENOMEM; |
252 | } | 240 | } |
253 | cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_SETUP); | 241 | cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_SETUP); |
254 | cfpkt_addbdy(pkt, (param->chtype << 4) + param->linktype); | 242 | cfpkt_addbdy(pkt, (param->chtype << 4) + param->linktype); |
@@ -294,11 +282,12 @@ void cfctrl_linkup_request(struct cflayer *layer, | |||
294 | default: | 282 | default: |
295 | pr_warning("CAIF: %s():Request setup of bad link type = %d\n", | 283 | pr_warning("CAIF: %s():Request setup of bad link type = %d\n", |
296 | __func__, param->linktype); | 284 | __func__, param->linktype); |
285 | return -EINVAL; | ||
297 | } | 286 | } |
298 | req = kmalloc(sizeof(*req), GFP_KERNEL); | 287 | req = kmalloc(sizeof(*req), GFP_KERNEL); |
299 | if (!req) { | 288 | if (!req) { |
300 | pr_warning("CAIF: %s(): Out of memory\n", __func__); | 289 | pr_warning("CAIF: %s(): Out of memory\n", __func__); |
301 | return; | 290 | return -ENOMEM; |
302 | } | 291 | } |
303 | memset(req, 0, sizeof(*req)); | 292 | memset(req, 0, sizeof(*req)); |
304 | req->client_layer = user_layer; | 293 | req->client_layer = user_layer; |
@@ -306,6 +295,11 @@ void cfctrl_linkup_request(struct cflayer *layer, | |||
306 | req->param = *param; | 295 | req->param = *param; |
307 | cfctrl_insert_req(cfctrl, req); | 296 | cfctrl_insert_req(cfctrl, req); |
308 | init_info(cfpkt_info(pkt), cfctrl); | 297 | init_info(cfpkt_info(pkt), cfctrl); |
298 | /* | ||
299 | * NOTE:Always send linkup and linkdown request on the same | ||
300 | * device as the payload. Otherwise old queued up payload | ||
301 | * might arrive with the newly allocated channel ID. | ||
302 | */ | ||
309 | cfpkt_info(pkt)->dev_info->id = param->phyid; | 303 | cfpkt_info(pkt)->dev_info->id = param->phyid; |
310 | ret = | 304 | ret = |
311 | cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); | 305 | cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); |
@@ -313,7 +307,9 @@ void cfctrl_linkup_request(struct cflayer *layer, | |||
313 | pr_err("CAIF: %s(): Could not transmit linksetup request\n", | 307 | pr_err("CAIF: %s(): Could not transmit linksetup request\n", |
314 | __func__); | 308 | __func__); |
315 | cfpkt_destroy(pkt); | 309 | cfpkt_destroy(pkt); |
310 | return -ENODEV; | ||
316 | } | 311 | } |
312 | return 0; | ||
317 | } | 313 | } |
318 | 314 | ||
319 | int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid, | 315 | int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid, |
@@ -326,7 +322,6 @@ int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid, | |||
326 | pr_warning("CAIF: %s(): Out of memory\n", __func__); | 322 | pr_warning("CAIF: %s(): Out of memory\n", __func__); |
327 | return -ENOMEM; | 323 | return -ENOMEM; |
328 | } | 324 | } |
329 | cfctrl_insert_req2(cfctrl, CFCTRL_CMD_LINK_DESTROY, channelid, client); | ||
330 | cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_DESTROY); | 325 | cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_DESTROY); |
331 | cfpkt_addbdy(pkt, channelid); | 326 | cfpkt_addbdy(pkt, channelid); |
332 | init_info(cfpkt_info(pkt), cfctrl); | 327 | init_info(cfpkt_info(pkt), cfctrl); |
@@ -392,6 +387,38 @@ void cfctrl_getstartreason_req(struct cflayer *layer) | |||
392 | } | 387 | } |
393 | 388 | ||
394 | 389 | ||
390 | void cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer) | ||
391 | { | ||
392 | struct cfctrl_request_info *p, *req; | ||
393 | struct cfctrl *ctrl = container_obj(layr); | ||
394 | spin_lock(&ctrl->info_list_lock); | ||
395 | |||
396 | if (ctrl->first_req == NULL) { | ||
397 | spin_unlock(&ctrl->info_list_lock); | ||
398 | return; | ||
399 | } | ||
400 | |||
401 | if (ctrl->first_req->client_layer == adap_layer) { | ||
402 | |||
403 | req = ctrl->first_req; | ||
404 | ctrl->first_req = ctrl->first_req->next; | ||
405 | kfree(req); | ||
406 | } | ||
407 | |||
408 | p = ctrl->first_req; | ||
409 | while (p != NULL && p->next != NULL) { | ||
410 | if (p->next->client_layer == adap_layer) { | ||
411 | |||
412 | req = p->next; | ||
413 | p->next = p->next->next; | ||
414 | kfree(p->next); | ||
415 | } | ||
416 | p = p->next; | ||
417 | } | ||
418 | |||
419 | spin_unlock(&ctrl->info_list_lock); | ||
420 | } | ||
421 | |||
395 | static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) | 422 | static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) |
396 | { | 423 | { |
397 | u8 cmdrsp; | 424 | u8 cmdrsp; |
@@ -409,11 +436,8 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) | |||
409 | cmd = cmdrsp & CFCTRL_CMD_MASK; | 436 | cmd = cmdrsp & CFCTRL_CMD_MASK; |
410 | if (cmd != CFCTRL_CMD_LINK_ERR | 437 | if (cmd != CFCTRL_CMD_LINK_ERR |
411 | && CFCTRL_RSP_BIT != (CFCTRL_RSP_BIT & cmdrsp)) { | 438 | && CFCTRL_RSP_BIT != (CFCTRL_RSP_BIT & cmdrsp)) { |
412 | if (handle_loop(cfctrl, cmd, pkt) == CAIF_FAILURE) { | 439 | if (handle_loop(cfctrl, cmd, pkt) == CAIF_FAILURE) |
413 | pr_info("CAIF: %s() CAIF Protocol error:" | 440 | cmdrsp |= CFCTRL_ERR_BIT; |
414 | "Response bit not set\n", __func__); | ||
415 | goto error; | ||
416 | } | ||
417 | } | 441 | } |
418 | 442 | ||
419 | switch (cmd) { | 443 | switch (cmd) { |
@@ -451,12 +475,16 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) | |||
451 | switch (serv) { | 475 | switch (serv) { |
452 | case CFCTRL_SRV_VEI: | 476 | case CFCTRL_SRV_VEI: |
453 | case CFCTRL_SRV_DBG: | 477 | case CFCTRL_SRV_DBG: |
478 | if (CFCTRL_ERR_BIT & cmdrsp) | ||
479 | break; | ||
454 | /* Link ID */ | 480 | /* Link ID */ |
455 | cfpkt_extr_head(pkt, &linkid, 1); | 481 | cfpkt_extr_head(pkt, &linkid, 1); |
456 | break; | 482 | break; |
457 | case CFCTRL_SRV_VIDEO: | 483 | case CFCTRL_SRV_VIDEO: |
458 | cfpkt_extr_head(pkt, &tmp, 1); | 484 | cfpkt_extr_head(pkt, &tmp, 1); |
459 | linkparam.u.video.connid = tmp; | 485 | linkparam.u.video.connid = tmp; |
486 | if (CFCTRL_ERR_BIT & cmdrsp) | ||
487 | break; | ||
460 | /* Link ID */ | 488 | /* Link ID */ |
461 | cfpkt_extr_head(pkt, &linkid, 1); | 489 | cfpkt_extr_head(pkt, &linkid, 1); |
462 | break; | 490 | break; |
@@ -465,6 +493,8 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) | |||
465 | cfpkt_extr_head(pkt, &tmp32, 4); | 493 | cfpkt_extr_head(pkt, &tmp32, 4); |
466 | linkparam.u.datagram.connid = | 494 | linkparam.u.datagram.connid = |
467 | le32_to_cpu(tmp32); | 495 | le32_to_cpu(tmp32); |
496 | if (CFCTRL_ERR_BIT & cmdrsp) | ||
497 | break; | ||
468 | /* Link ID */ | 498 | /* Link ID */ |
469 | cfpkt_extr_head(pkt, &linkid, 1); | 499 | cfpkt_extr_head(pkt, &linkid, 1); |
470 | break; | 500 | break; |
@@ -483,6 +513,8 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) | |||
483 | *cp++ = tmp; | 513 | *cp++ = tmp; |
484 | *cp = '\0'; | 514 | *cp = '\0'; |
485 | 515 | ||
516 | if (CFCTRL_ERR_BIT & cmdrsp) | ||
517 | break; | ||
486 | /* Link ID */ | 518 | /* Link ID */ |
487 | cfpkt_extr_head(pkt, &linkid, 1); | 519 | cfpkt_extr_head(pkt, &linkid, 1); |
488 | 520 | ||
@@ -519,6 +551,8 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) | |||
519 | cfpkt_extr_head(pkt, &tmp, 1); | 551 | cfpkt_extr_head(pkt, &tmp, 1); |
520 | *cp++ = tmp; | 552 | *cp++ = tmp; |
521 | } | 553 | } |
554 | if (CFCTRL_ERR_BIT & cmdrsp) | ||
555 | break; | ||
522 | /* Link ID */ | 556 | /* Link ID */ |
523 | cfpkt_extr_head(pkt, &linkid, 1); | 557 | cfpkt_extr_head(pkt, &linkid, 1); |
524 | /* Length */ | 558 | /* Length */ |
@@ -560,13 +594,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) | |||
560 | break; | 594 | break; |
561 | case CFCTRL_CMD_LINK_DESTROY: | 595 | case CFCTRL_CMD_LINK_DESTROY: |
562 | cfpkt_extr_head(pkt, &linkid, 1); | 596 | cfpkt_extr_head(pkt, &linkid, 1); |
563 | rsp.cmd = cmd; | 597 | cfctrl->res.linkdestroy_rsp(cfctrl->serv.layer.up, linkid); |
564 | rsp.channel_id = linkid; | ||
565 | req = cfctrl_remove_req(cfctrl, &rsp); | ||
566 | cfctrl->res.linkdestroy_rsp(cfctrl->serv.layer.up, linkid, | ||
567 | req ? req->client_layer : NULL); | ||
568 | if (req != NULL) | ||
569 | kfree(req); | ||
570 | break; | 598 | break; |
571 | case CFCTRL_CMD_LINK_ERR: | 599 | case CFCTRL_CMD_LINK_ERR: |
572 | pr_err("CAIF: %s(): Frame Error Indication received\n", | 600 | pr_err("CAIF: %s(): Frame Error Indication received\n", |
@@ -608,7 +636,7 @@ static void cfctrl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, | |||
608 | case CAIF_CTRLCMD_FLOW_OFF_IND: | 636 | case CAIF_CTRLCMD_FLOW_OFF_IND: |
609 | spin_lock(&this->info_list_lock); | 637 | spin_lock(&this->info_list_lock); |
610 | if (this->first_req != NULL) { | 638 | if (this->first_req != NULL) { |
611 | pr_warning("CAIF: %s(): Received flow off in " | 639 | pr_debug("CAIF: %s(): Received flow off in " |
612 | "control layer", __func__); | 640 | "control layer", __func__); |
613 | } | 641 | } |
614 | spin_unlock(&this->info_list_lock); | 642 | spin_unlock(&this->info_list_lock); |
@@ -633,6 +661,7 @@ static int handle_loop(struct cfctrl *ctrl, int cmd, struct cfpkt *pkt) | |||
633 | if (!ctrl->loop_linkused[linkid]) | 661 | if (!ctrl->loop_linkused[linkid]) |
634 | goto found; | 662 | goto found; |
635 | spin_unlock(&ctrl->loop_linkid_lock); | 663 | spin_unlock(&ctrl->loop_linkid_lock); |
664 | pr_err("CAIF: %s(): Out of link-ids\n", __func__); | ||
636 | return -EINVAL; | 665 | return -EINVAL; |
637 | found: | 666 | found: |
638 | if (!ctrl->loop_linkused[linkid]) | 667 | if (!ctrl->loop_linkused[linkid]) |
diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c index 6fb9f9e96cf8..7372f27f1d32 100644 --- a/net/caif/cfmuxl.c +++ b/net/caif/cfmuxl.c | |||
@@ -62,6 +62,7 @@ int cfmuxl_set_uplayer(struct cflayer *layr, struct cflayer *up, u8 linkid) | |||
62 | { | 62 | { |
63 | struct cfmuxl *muxl = container_obj(layr); | 63 | struct cfmuxl *muxl = container_obj(layr); |
64 | spin_lock(&muxl->receive_lock); | 64 | spin_lock(&muxl->receive_lock); |
65 | cfsrvl_get(up); | ||
65 | list_add(&up->node, &muxl->srvl_list); | 66 | list_add(&up->node, &muxl->srvl_list); |
66 | spin_unlock(&muxl->receive_lock); | 67 | spin_unlock(&muxl->receive_lock); |
67 | return 0; | 68 | return 0; |
@@ -172,8 +173,11 @@ struct cflayer *cfmuxl_remove_uplayer(struct cflayer *layr, u8 id) | |||
172 | struct cfmuxl *muxl = container_obj(layr); | 173 | struct cfmuxl *muxl = container_obj(layr); |
173 | spin_lock(&muxl->receive_lock); | 174 | spin_lock(&muxl->receive_lock); |
174 | up = get_up(muxl, id); | 175 | up = get_up(muxl, id); |
176 | if (up == NULL) | ||
177 | return NULL; | ||
175 | memset(muxl->up_cache, 0, sizeof(muxl->up_cache)); | 178 | memset(muxl->up_cache, 0, sizeof(muxl->up_cache)); |
176 | list_del(&up->node); | 179 | list_del(&up->node); |
180 | cfsrvl_put(up); | ||
177 | spin_unlock(&muxl->receive_lock); | 181 | spin_unlock(&muxl->receive_lock); |
178 | return up; | 182 | return up; |
179 | } | 183 | } |
@@ -203,8 +207,9 @@ static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt) | |||
203 | */ | 207 | */ |
204 | return /* CFGLU_EPROT; */ 0; | 208 | return /* CFGLU_EPROT; */ 0; |
205 | } | 209 | } |
206 | 210 | cfsrvl_get(up); | |
207 | ret = up->receive(up, pkt); | 211 | ret = up->receive(up, pkt); |
212 | cfsrvl_put(up); | ||
208 | return ret; | 213 | return ret; |
209 | } | 214 | } |
210 | 215 | ||
diff --git a/net/caif/cfsrvl.c b/net/caif/cfsrvl.c index d470c51c6431..aff31f34528f 100644 --- a/net/caif/cfsrvl.c +++ b/net/caif/cfsrvl.c | |||
@@ -158,6 +158,13 @@ void cfsrvl_init(struct cfsrvl *service, | |||
158 | service->layer.ctrlcmd = cfservl_ctrlcmd; | 158 | service->layer.ctrlcmd = cfservl_ctrlcmd; |
159 | service->layer.modemcmd = cfservl_modemcmd; | 159 | service->layer.modemcmd = cfservl_modemcmd; |
160 | service->dev_info = *dev_info; | 160 | service->dev_info = *dev_info; |
161 | kref_init(&service->ref); | ||
162 | } | ||
163 | |||
164 | void cfsrvl_release(struct kref *kref) | ||
165 | { | ||
166 | struct cfsrvl *service = container_of(kref, struct cfsrvl, ref); | ||
167 | kfree(service); | ||
161 | } | 168 | } |
162 | 169 | ||
163 | bool cfsrvl_ready(struct cfsrvl *service, int *err) | 170 | bool cfsrvl_ready(struct cfsrvl *service, int *err) |
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c index f622ff1d39ba..610966abe2dc 100644 --- a/net/caif/chnl_net.c +++ b/net/caif/chnl_net.c | |||
@@ -22,10 +22,10 @@ | |||
22 | #include <net/caif/cfpkt.h> | 22 | #include <net/caif/cfpkt.h> |
23 | #include <net/caif/caif_dev.h> | 23 | #include <net/caif/caif_dev.h> |
24 | 24 | ||
25 | #define CAIF_CONNECT_TIMEOUT 30 | 25 | /* GPRS PDP connection has MTU to 1500 */ |
26 | #define SIZE_MTU 1500 | 26 | #define SIZE_MTU 1500 |
27 | #define SIZE_MTU_MAX 4080 | 27 | /* 5 sec. connect timeout */ |
28 | #define SIZE_MTU_MIN 68 | 28 | #define CONNECT_TIMEOUT (5 * HZ) |
29 | #define CAIF_NET_DEFAULT_QUEUE_LEN 500 | 29 | #define CAIF_NET_DEFAULT_QUEUE_LEN 500 |
30 | 30 | ||
31 | #undef pr_debug | 31 | #undef pr_debug |
@@ -37,6 +37,13 @@ static LIST_HEAD(chnl_net_list); | |||
37 | MODULE_LICENSE("GPL"); | 37 | MODULE_LICENSE("GPL"); |
38 | MODULE_ALIAS_RTNL_LINK("caif"); | 38 | MODULE_ALIAS_RTNL_LINK("caif"); |
39 | 39 | ||
40 | enum caif_states { | ||
41 | CAIF_CONNECTED = 1, | ||
42 | CAIF_CONNECTING, | ||
43 | CAIF_DISCONNECTED, | ||
44 | CAIF_SHUTDOWN | ||
45 | }; | ||
46 | |||
40 | struct chnl_net { | 47 | struct chnl_net { |
41 | struct cflayer chnl; | 48 | struct cflayer chnl; |
42 | struct net_device_stats stats; | 49 | struct net_device_stats stats; |
@@ -47,7 +54,7 @@ struct chnl_net { | |||
47 | wait_queue_head_t netmgmt_wq; | 54 | wait_queue_head_t netmgmt_wq; |
48 | /* Flow status to remember and control the transmission. */ | 55 | /* Flow status to remember and control the transmission. */ |
49 | bool flowenabled; | 56 | bool flowenabled; |
50 | bool pending_close; | 57 | enum caif_states state; |
51 | }; | 58 | }; |
52 | 59 | ||
53 | static void robust_list_del(struct list_head *delete_node) | 60 | static void robust_list_del(struct list_head *delete_node) |
@@ -58,15 +65,16 @@ static void robust_list_del(struct list_head *delete_node) | |||
58 | list_for_each_safe(list_node, n, &chnl_net_list) { | 65 | list_for_each_safe(list_node, n, &chnl_net_list) { |
59 | if (list_node == delete_node) { | 66 | if (list_node == delete_node) { |
60 | list_del(list_node); | 67 | list_del(list_node); |
61 | break; | 68 | return; |
62 | } | 69 | } |
63 | } | 70 | } |
71 | WARN_ON(1); | ||
64 | } | 72 | } |
65 | 73 | ||
66 | static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt) | 74 | static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt) |
67 | { | 75 | { |
68 | struct sk_buff *skb; | 76 | struct sk_buff *skb; |
69 | struct chnl_net *priv = NULL; | 77 | struct chnl_net *priv = container_of(layr, struct chnl_net, chnl); |
70 | int pktlen; | 78 | int pktlen; |
71 | int err = 0; | 79 | int err = 0; |
72 | 80 | ||
@@ -91,7 +99,6 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt) | |||
91 | else | 99 | else |
92 | skb->ip_summed = CHECKSUM_NONE; | 100 | skb->ip_summed = CHECKSUM_NONE; |
93 | 101 | ||
94 | /* FIXME: Drivers should call this in tasklet context. */ | ||
95 | if (in_interrupt()) | 102 | if (in_interrupt()) |
96 | netif_rx(skb); | 103 | netif_rx(skb); |
97 | else | 104 | else |
@@ -117,23 +124,25 @@ static void close_work(struct work_struct *work) | |||
117 | struct chnl_net *dev = NULL; | 124 | struct chnl_net *dev = NULL; |
118 | struct list_head *list_node; | 125 | struct list_head *list_node; |
119 | struct list_head *_tmp; | 126 | struct list_head *_tmp; |
120 | rtnl_lock(); | 127 | /* May be called with or without RTNL lock held */ |
128 | int islocked = rtnl_is_locked(); | ||
129 | if (!islocked) | ||
130 | rtnl_lock(); | ||
121 | list_for_each_safe(list_node, _tmp, &chnl_net_list) { | 131 | list_for_each_safe(list_node, _tmp, &chnl_net_list) { |
122 | dev = list_entry(list_node, struct chnl_net, list_field); | 132 | dev = list_entry(list_node, struct chnl_net, list_field); |
123 | if (!dev->pending_close) | 133 | if (dev->state == CAIF_SHUTDOWN) |
124 | continue; | 134 | dev_close(dev->netdev); |
125 | list_del(list_node); | ||
126 | delete_device(dev); | ||
127 | } | 135 | } |
128 | rtnl_unlock(); | 136 | if (!islocked) |
137 | rtnl_unlock(); | ||
129 | } | 138 | } |
130 | static DECLARE_WORK(close_worker, close_work); | 139 | static DECLARE_WORK(close_worker, close_work); |
131 | 140 | ||
132 | static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow, | 141 | static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow, |
133 | int phyid) | 142 | int phyid) |
134 | { | 143 | { |
135 | struct chnl_net *priv; | 144 | struct chnl_net *priv = container_of(layr, struct chnl_net, chnl); |
136 | pr_debug("CAIF: %s(): NET flowctrl func called flow: %s.\n", | 145 | pr_debug("CAIF: %s(): NET flowctrl func called flow: %s\n", |
137 | __func__, | 146 | __func__, |
138 | flow == CAIF_CTRLCMD_FLOW_ON_IND ? "ON" : | 147 | flow == CAIF_CTRLCMD_FLOW_ON_IND ? "ON" : |
139 | flow == CAIF_CTRLCMD_INIT_RSP ? "INIT" : | 148 | flow == CAIF_CTRLCMD_INIT_RSP ? "INIT" : |
@@ -143,21 +152,31 @@ static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow, | |||
143 | flow == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND ? | 152 | flow == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND ? |
144 | "REMOTE_SHUTDOWN" : "UKNOWN CTRL COMMAND"); | 153 | "REMOTE_SHUTDOWN" : "UKNOWN CTRL COMMAND"); |
145 | 154 | ||
146 | priv = container_of(layr, struct chnl_net, chnl); | 155 | |
147 | 156 | ||
148 | switch (flow) { | 157 | switch (flow) { |
149 | case CAIF_CTRLCMD_FLOW_OFF_IND: | 158 | case CAIF_CTRLCMD_FLOW_OFF_IND: |
159 | priv->flowenabled = false; | ||
160 | netif_stop_queue(priv->netdev); | ||
161 | break; | ||
150 | case CAIF_CTRLCMD_DEINIT_RSP: | 162 | case CAIF_CTRLCMD_DEINIT_RSP: |
163 | priv->state = CAIF_DISCONNECTED; | ||
164 | break; | ||
151 | case CAIF_CTRLCMD_INIT_FAIL_RSP: | 165 | case CAIF_CTRLCMD_INIT_FAIL_RSP: |
166 | priv->state = CAIF_DISCONNECTED; | ||
167 | wake_up_interruptible(&priv->netmgmt_wq); | ||
168 | break; | ||
152 | case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND: | 169 | case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND: |
153 | priv->flowenabled = false; | 170 | priv->state = CAIF_SHUTDOWN; |
154 | netif_tx_disable(priv->netdev); | 171 | netif_tx_disable(priv->netdev); |
155 | pr_warning("CAIF: %s(): done\n", __func__); | ||
156 | priv->pending_close = 1; | ||
157 | schedule_work(&close_worker); | 172 | schedule_work(&close_worker); |
158 | break; | 173 | break; |
159 | case CAIF_CTRLCMD_FLOW_ON_IND: | 174 | case CAIF_CTRLCMD_FLOW_ON_IND: |
175 | priv->flowenabled = true; | ||
176 | netif_wake_queue(priv->netdev); | ||
177 | break; | ||
160 | case CAIF_CTRLCMD_INIT_RSP: | 178 | case CAIF_CTRLCMD_INIT_RSP: |
179 | priv->state = CAIF_CONNECTED; | ||
161 | priv->flowenabled = true; | 180 | priv->flowenabled = true; |
162 | netif_wake_queue(priv->netdev); | 181 | netif_wake_queue(priv->netdev); |
163 | wake_up_interruptible(&priv->netmgmt_wq); | 182 | wake_up_interruptible(&priv->netmgmt_wq); |
@@ -194,9 +213,6 @@ static int chnl_net_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
194 | 213 | ||
195 | pkt = cfpkt_fromnative(CAIF_DIR_OUT, (void *) skb); | 214 | pkt = cfpkt_fromnative(CAIF_DIR_OUT, (void *) skb); |
196 | 215 | ||
197 | pr_debug("CAIF: %s(): transmit inst %s %d,%p\n", | ||
198 | __func__, dev->name, priv->chnl.dn->id, &priv->chnl.dn); | ||
199 | |||
200 | /* Send the packet down the stack. */ | 216 | /* Send the packet down the stack. */ |
201 | result = priv->chnl.dn->transmit(priv->chnl.dn, pkt); | 217 | result = priv->chnl.dn->transmit(priv->chnl.dn, pkt); |
202 | if (result) { | 218 | if (result) { |
@@ -217,61 +233,59 @@ static int chnl_net_open(struct net_device *dev) | |||
217 | struct chnl_net *priv = NULL; | 233 | struct chnl_net *priv = NULL; |
218 | int result = -1; | 234 | int result = -1; |
219 | ASSERT_RTNL(); | 235 | ASSERT_RTNL(); |
220 | |||
221 | priv = netdev_priv(dev); | 236 | priv = netdev_priv(dev); |
222 | pr_debug("CAIF: %s(): dev name: %s\n", __func__, priv->name); | ||
223 | |||
224 | if (!priv) { | 237 | if (!priv) { |
225 | pr_debug("CAIF: %s(): chnl_net_open: no priv\n", __func__); | 238 | pr_debug("CAIF: %s(): chnl_net_open: no priv\n", __func__); |
226 | return -ENODEV; | 239 | return -ENODEV; |
227 | } | 240 | } |
228 | result = caif_connect_client(&priv->conn_req, &priv->chnl); | 241 | |
229 | if (result != 0) { | 242 | if (priv->state != CAIF_CONNECTING) { |
230 | pr_debug("CAIF: %s(): err: " | 243 | priv->state = CAIF_CONNECTING; |
231 | "Unable to register and open device, Err:%d\n", | 244 | result = caif_connect_client(&priv->conn_req, &priv->chnl); |
232 | __func__, | 245 | if (result != 0) { |
233 | result); | 246 | priv->state = CAIF_DISCONNECTED; |
234 | return -ENODEV; | 247 | pr_debug("CAIF: %s(): err: " |
248 | "Unable to register and open device," | ||
249 | " Err:%d\n", | ||
250 | __func__, | ||
251 | result); | ||
252 | return result; | ||
253 | } | ||
235 | } | 254 | } |
236 | result = wait_event_interruptible(priv->netmgmt_wq, priv->flowenabled); | 255 | |
256 | result = wait_event_interruptible_timeout(priv->netmgmt_wq, | ||
257 | priv->state != CAIF_CONNECTING, | ||
258 | CONNECT_TIMEOUT); | ||
237 | 259 | ||
238 | if (result == -ERESTARTSYS) { | 260 | if (result == -ERESTARTSYS) { |
239 | pr_debug("CAIF: %s(): wait_event_interruptible" | 261 | pr_debug("CAIF: %s(): wait_event_interruptible" |
240 | " woken by a signal\n", __func__); | 262 | " woken by a signal\n", __func__); |
241 | return -ERESTARTSYS; | 263 | return -ERESTARTSYS; |
242 | } else | 264 | } |
243 | pr_debug("CAIF: %s(): Flow on recieved\n", __func__); | 265 | if (result == 0) { |
266 | pr_debug("CAIF: %s(): connect timeout\n", __func__); | ||
267 | caif_disconnect_client(&priv->chnl); | ||
268 | priv->state = CAIF_DISCONNECTED; | ||
269 | pr_debug("CAIF: %s(): state disconnected\n", __func__); | ||
270 | return -ETIMEDOUT; | ||
271 | } | ||
244 | 272 | ||
273 | if (priv->state != CAIF_CONNECTED) { | ||
274 | pr_debug("CAIF: %s(): connect failed\n", __func__); | ||
275 | return -ECONNREFUSED; | ||
276 | } | ||
277 | pr_debug("CAIF: %s(): CAIF Netdevice connected\n", __func__); | ||
245 | return 0; | 278 | return 0; |
246 | } | 279 | } |
247 | 280 | ||
248 | static int chnl_net_stop(struct net_device *dev) | 281 | static int chnl_net_stop(struct net_device *dev) |
249 | { | 282 | { |
250 | struct chnl_net *priv; | 283 | struct chnl_net *priv; |
251 | int result = -1; | 284 | |
252 | ASSERT_RTNL(); | 285 | ASSERT_RTNL(); |
253 | priv = netdev_priv(dev); | 286 | priv = netdev_priv(dev); |
254 | 287 | priv->state = CAIF_DISCONNECTED; | |
255 | result = caif_disconnect_client(&priv->chnl); | 288 | caif_disconnect_client(&priv->chnl); |
256 | if (result != 0) { | ||
257 | pr_debug("CAIF: %s(): chnl_net_stop: err: " | ||
258 | "Unable to STOP device, Err:%d\n", | ||
259 | __func__, result); | ||
260 | return -EBUSY; | ||
261 | } | ||
262 | result = wait_event_interruptible(priv->netmgmt_wq, | ||
263 | !priv->flowenabled); | ||
264 | |||
265 | if (result == -ERESTARTSYS) { | ||
266 | pr_debug("CAIF: %s(): wait_event_interruptible woken by" | ||
267 | " signal, signal_pending(current) = %d\n", | ||
268 | __func__, | ||
269 | signal_pending(current)); | ||
270 | } else { | ||
271 | pr_debug("CAIF: %s(): disconnect received\n", __func__); | ||
272 | |||
273 | } | ||
274 | |||
275 | return 0; | 289 | return 0; |
276 | } | 290 | } |
277 | 291 | ||
@@ -377,6 +391,8 @@ static int ipcaif_newlink(struct net *src_net, struct net_device *dev, | |||
377 | ASSERT_RTNL(); | 391 | ASSERT_RTNL(); |
378 | caifdev = netdev_priv(dev); | 392 | caifdev = netdev_priv(dev); |
379 | caif_netlink_parms(data, &caifdev->conn_req); | 393 | caif_netlink_parms(data, &caifdev->conn_req); |
394 | dev_net_set(caifdev->netdev, src_net); | ||
395 | |||
380 | ret = register_netdevice(dev); | 396 | ret = register_netdevice(dev); |
381 | if (ret) | 397 | if (ret) |
382 | pr_warning("CAIF: %s(): device rtml registration failed\n", | 398 | pr_warning("CAIF: %s(): device rtml registration failed\n", |
diff --git a/net/core/datagram.c b/net/core/datagram.c index 2dccd4ee591b..e0097531417a 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -86,7 +86,7 @@ static int wait_for_packet(struct sock *sk, int *err, long *timeo_p) | |||
86 | int error; | 86 | int error; |
87 | DEFINE_WAIT_FUNC(wait, receiver_wake_function); | 87 | DEFINE_WAIT_FUNC(wait, receiver_wake_function); |
88 | 88 | ||
89 | prepare_to_wait_exclusive(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 89 | prepare_to_wait_exclusive(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
90 | 90 | ||
91 | /* Socket errors? */ | 91 | /* Socket errors? */ |
92 | error = sock_error(sk); | 92 | error = sock_error(sk); |
@@ -115,7 +115,7 @@ static int wait_for_packet(struct sock *sk, int *err, long *timeo_p) | |||
115 | error = 0; | 115 | error = 0; |
116 | *timeo_p = schedule_timeout(*timeo_p); | 116 | *timeo_p = schedule_timeout(*timeo_p); |
117 | out: | 117 | out: |
118 | finish_wait(sk->sk_sleep, &wait); | 118 | finish_wait(sk_sleep(sk), &wait); |
119 | return error; | 119 | return error; |
120 | interrupted: | 120 | interrupted: |
121 | error = sock_intr_errno(*timeo_p); | 121 | error = sock_intr_errno(*timeo_p); |
@@ -229,9 +229,18 @@ EXPORT_SYMBOL(skb_free_datagram); | |||
229 | 229 | ||
230 | void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb) | 230 | void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb) |
231 | { | 231 | { |
232 | lock_sock(sk); | 232 | if (likely(atomic_read(&skb->users) == 1)) |
233 | skb_free_datagram(sk, skb); | 233 | smp_rmb(); |
234 | release_sock(sk); | 234 | else if (likely(!atomic_dec_and_test(&skb->users))) |
235 | return; | ||
236 | |||
237 | lock_sock_bh(sk); | ||
238 | skb_orphan(skb); | ||
239 | sk_mem_reclaim_partial(sk); | ||
240 | unlock_sock_bh(sk); | ||
241 | |||
242 | /* skb is now orphaned, can be freed outside of locked section */ | ||
243 | __kfree_skb(skb); | ||
235 | } | 244 | } |
236 | EXPORT_SYMBOL(skb_free_datagram_locked); | 245 | EXPORT_SYMBOL(skb_free_datagram_locked); |
237 | 246 | ||
@@ -726,7 +735,7 @@ unsigned int datagram_poll(struct file *file, struct socket *sock, | |||
726 | struct sock *sk = sock->sk; | 735 | struct sock *sk = sock->sk; |
727 | unsigned int mask; | 736 | unsigned int mask; |
728 | 737 | ||
729 | sock_poll_wait(file, sk->sk_sleep, wait); | 738 | sock_poll_wait(file, sk_sleep(sk), wait); |
730 | mask = 0; | 739 | mask = 0; |
731 | 740 | ||
732 | /* exceptional events? */ | 741 | /* exceptional events? */ |
diff --git a/net/core/dev.c b/net/core/dev.c index b31d5d69a467..32611c8f1219 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1557,8 +1557,9 @@ static inline void __netif_reschedule(struct Qdisc *q) | |||
1557 | 1557 | ||
1558 | local_irq_save(flags); | 1558 | local_irq_save(flags); |
1559 | sd = &__get_cpu_var(softnet_data); | 1559 | sd = &__get_cpu_var(softnet_data); |
1560 | q->next_sched = sd->output_queue; | 1560 | q->next_sched = NULL; |
1561 | sd->output_queue = q; | 1561 | *sd->output_queue_tailp = q; |
1562 | sd->output_queue_tailp = &q->next_sched; | ||
1562 | raise_softirq_irqoff(NET_TX_SOFTIRQ); | 1563 | raise_softirq_irqoff(NET_TX_SOFTIRQ); |
1563 | local_irq_restore(flags); | 1564 | local_irq_restore(flags); |
1564 | } | 1565 | } |
@@ -1902,13 +1903,6 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
1902 | if (!list_empty(&ptype_all)) | 1903 | if (!list_empty(&ptype_all)) |
1903 | dev_queue_xmit_nit(skb, dev); | 1904 | dev_queue_xmit_nit(skb, dev); |
1904 | 1905 | ||
1905 | if (netif_needs_gso(dev, skb)) { | ||
1906 | if (unlikely(dev_gso_segment(skb))) | ||
1907 | goto out_kfree_skb; | ||
1908 | if (skb->next) | ||
1909 | goto gso; | ||
1910 | } | ||
1911 | |||
1912 | /* | 1906 | /* |
1913 | * If device doesnt need skb->dst, release it right now while | 1907 | * If device doesnt need skb->dst, release it right now while |
1914 | * its hot in this cpu cache | 1908 | * its hot in this cpu cache |
@@ -1917,6 +1911,14 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
1917 | skb_dst_drop(skb); | 1911 | skb_dst_drop(skb); |
1918 | 1912 | ||
1919 | skb_orphan_try(skb); | 1913 | skb_orphan_try(skb); |
1914 | |||
1915 | if (netif_needs_gso(dev, skb)) { | ||
1916 | if (unlikely(dev_gso_segment(skb))) | ||
1917 | goto out_kfree_skb; | ||
1918 | if (skb->next) | ||
1919 | goto gso; | ||
1920 | } | ||
1921 | |||
1920 | rc = ops->ndo_start_xmit(skb, dev); | 1922 | rc = ops->ndo_start_xmit(skb, dev); |
1921 | if (rc == NETDEV_TX_OK) | 1923 | if (rc == NETDEV_TX_OK) |
1922 | txq_trans_update(txq); | 1924 | txq_trans_update(txq); |
@@ -1937,7 +1939,6 @@ gso: | |||
1937 | if (dev->priv_flags & IFF_XMIT_DST_RELEASE) | 1939 | if (dev->priv_flags & IFF_XMIT_DST_RELEASE) |
1938 | skb_dst_drop(nskb); | 1940 | skb_dst_drop(nskb); |
1939 | 1941 | ||
1940 | skb_orphan_try(nskb); | ||
1941 | rc = ops->ndo_start_xmit(nskb, dev); | 1942 | rc = ops->ndo_start_xmit(nskb, dev); |
1942 | if (unlikely(rc != NETDEV_TX_OK)) { | 1943 | if (unlikely(rc != NETDEV_TX_OK)) { |
1943 | if (rc & ~NETDEV_TX_MASK) | 1944 | if (rc & ~NETDEV_TX_MASK) |
@@ -2015,8 +2016,12 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev, | |||
2015 | if (dev->real_num_tx_queues > 1) | 2016 | if (dev->real_num_tx_queues > 1) |
2016 | queue_index = skb_tx_hash(dev, skb); | 2017 | queue_index = skb_tx_hash(dev, skb); |
2017 | 2018 | ||
2018 | if (sk && rcu_dereference_check(sk->sk_dst_cache, 1)) | 2019 | if (sk) { |
2019 | sk_tx_queue_set(sk, queue_index); | 2020 | struct dst_entry *dst = rcu_dereference_check(sk->sk_dst_cache, 1); |
2021 | |||
2022 | if (dst && skb_dst(skb) == dst) | ||
2023 | sk_tx_queue_set(sk, queue_index); | ||
2024 | } | ||
2020 | } | 2025 | } |
2021 | } | 2026 | } |
2022 | 2027 | ||
@@ -2200,7 +2205,13 @@ int netdev_max_backlog __read_mostly = 1000; | |||
2200 | int netdev_budget __read_mostly = 300; | 2205 | int netdev_budget __read_mostly = 300; |
2201 | int weight_p __read_mostly = 64; /* old backlog weight */ | 2206 | int weight_p __read_mostly = 64; /* old backlog weight */ |
2202 | 2207 | ||
2203 | DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, }; | 2208 | /* Called with irq disabled */ |
2209 | static inline void ____napi_schedule(struct softnet_data *sd, | ||
2210 | struct napi_struct *napi) | ||
2211 | { | ||
2212 | list_add_tail(&napi->poll_list, &sd->poll_list); | ||
2213 | __raise_softirq_irqoff(NET_RX_SOFTIRQ); | ||
2214 | } | ||
2204 | 2215 | ||
2205 | #ifdef CONFIG_RPS | 2216 | #ifdef CONFIG_RPS |
2206 | 2217 | ||
@@ -2225,7 +2236,11 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, | |||
2225 | int cpu = -1; | 2236 | int cpu = -1; |
2226 | u8 ip_proto; | 2237 | u8 ip_proto; |
2227 | u16 tcpu; | 2238 | u16 tcpu; |
2228 | u32 addr1, addr2, ports, ihl; | 2239 | u32 addr1, addr2, ihl; |
2240 | union { | ||
2241 | u32 v32; | ||
2242 | u16 v16[2]; | ||
2243 | } ports; | ||
2229 | 2244 | ||
2230 | if (skb_rx_queue_recorded(skb)) { | 2245 | if (skb_rx_queue_recorded(skb)) { |
2231 | u16 index = skb_get_rx_queue(skb); | 2246 | u16 index = skb_get_rx_queue(skb); |
@@ -2271,7 +2286,6 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, | |||
2271 | default: | 2286 | default: |
2272 | goto done; | 2287 | goto done; |
2273 | } | 2288 | } |
2274 | ports = 0; | ||
2275 | switch (ip_proto) { | 2289 | switch (ip_proto) { |
2276 | case IPPROTO_TCP: | 2290 | case IPPROTO_TCP: |
2277 | case IPPROTO_UDP: | 2291 | case IPPROTO_UDP: |
@@ -2281,25 +2295,20 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, | |||
2281 | case IPPROTO_SCTP: | 2295 | case IPPROTO_SCTP: |
2282 | case IPPROTO_UDPLITE: | 2296 | case IPPROTO_UDPLITE: |
2283 | if (pskb_may_pull(skb, (ihl * 4) + 4)) { | 2297 | if (pskb_may_pull(skb, (ihl * 4) + 4)) { |
2284 | __be16 *hports = (__be16 *) (skb->data + (ihl * 4)); | 2298 | ports.v32 = * (__force u32 *) (skb->data + (ihl * 4)); |
2285 | u32 sport, dport; | 2299 | if (ports.v16[1] < ports.v16[0]) |
2286 | 2300 | swap(ports.v16[0], ports.v16[1]); | |
2287 | sport = (__force u16) hports[0]; | 2301 | break; |
2288 | dport = (__force u16) hports[1]; | ||
2289 | if (dport < sport) | ||
2290 | swap(sport, dport); | ||
2291 | ports = (sport << 16) + dport; | ||
2292 | } | 2302 | } |
2293 | break; | ||
2294 | |||
2295 | default: | 2303 | default: |
2304 | ports.v32 = 0; | ||
2296 | break; | 2305 | break; |
2297 | } | 2306 | } |
2298 | 2307 | ||
2299 | /* get a consistent hash (same value on both flow directions) */ | 2308 | /* get a consistent hash (same value on both flow directions) */ |
2300 | if (addr2 < addr1) | 2309 | if (addr2 < addr1) |
2301 | swap(addr1, addr2); | 2310 | swap(addr1, addr2); |
2302 | skb->rxhash = jhash_3words(addr1, addr2, ports, hashrnd); | 2311 | skb->rxhash = jhash_3words(addr1, addr2, ports.v32, hashrnd); |
2303 | if (!skb->rxhash) | 2312 | if (!skb->rxhash) |
2304 | skb->rxhash = 1; | 2313 | skb->rxhash = 1; |
2305 | 2314 | ||
@@ -2362,8 +2371,8 @@ static void rps_trigger_softirq(void *data) | |||
2362 | { | 2371 | { |
2363 | struct softnet_data *sd = data; | 2372 | struct softnet_data *sd = data; |
2364 | 2373 | ||
2365 | __napi_schedule(&sd->backlog); | 2374 | ____napi_schedule(sd, &sd->backlog); |
2366 | __get_cpu_var(netdev_rx_stat).received_rps++; | 2375 | sd->received_rps++; |
2367 | } | 2376 | } |
2368 | 2377 | ||
2369 | #endif /* CONFIG_RPS */ | 2378 | #endif /* CONFIG_RPS */ |
@@ -2402,15 +2411,15 @@ static int enqueue_to_backlog(struct sk_buff *skb, int cpu, | |||
2402 | sd = &per_cpu(softnet_data, cpu); | 2411 | sd = &per_cpu(softnet_data, cpu); |
2403 | 2412 | ||
2404 | local_irq_save(flags); | 2413 | local_irq_save(flags); |
2405 | __get_cpu_var(netdev_rx_stat).total++; | ||
2406 | 2414 | ||
2407 | rps_lock(sd); | 2415 | rps_lock(sd); |
2408 | if (sd->input_pkt_queue.qlen <= netdev_max_backlog) { | 2416 | if (skb_queue_len(&sd->input_pkt_queue) <= netdev_max_backlog) { |
2409 | if (sd->input_pkt_queue.qlen) { | 2417 | if (skb_queue_len(&sd->input_pkt_queue)) { |
2410 | enqueue: | 2418 | enqueue: |
2411 | __skb_queue_tail(&sd->input_pkt_queue, skb); | 2419 | __skb_queue_tail(&sd->input_pkt_queue, skb); |
2412 | #ifdef CONFIG_RPS | 2420 | #ifdef CONFIG_RPS |
2413 | *qtail = sd->input_queue_head + sd->input_pkt_queue.qlen; | 2421 | *qtail = sd->input_queue_head + |
2422 | skb_queue_len(&sd->input_pkt_queue); | ||
2414 | #endif | 2423 | #endif |
2415 | rps_unlock(sd); | 2424 | rps_unlock(sd); |
2416 | local_irq_restore(flags); | 2425 | local_irq_restore(flags); |
@@ -2420,14 +2429,14 @@ enqueue: | |||
2420 | /* Schedule NAPI for backlog device */ | 2429 | /* Schedule NAPI for backlog device */ |
2421 | if (napi_schedule_prep(&sd->backlog)) { | 2430 | if (napi_schedule_prep(&sd->backlog)) { |
2422 | if (!rps_ipi_queued(sd)) | 2431 | if (!rps_ipi_queued(sd)) |
2423 | __napi_schedule(&sd->backlog); | 2432 | ____napi_schedule(sd, &sd->backlog); |
2424 | } | 2433 | } |
2425 | goto enqueue; | 2434 | goto enqueue; |
2426 | } | 2435 | } |
2427 | 2436 | ||
2437 | sd->dropped++; | ||
2428 | rps_unlock(sd); | 2438 | rps_unlock(sd); |
2429 | 2439 | ||
2430 | __get_cpu_var(netdev_rx_stat).dropped++; | ||
2431 | local_irq_restore(flags); | 2440 | local_irq_restore(flags); |
2432 | 2441 | ||
2433 | kfree_skb(skb); | 2442 | kfree_skb(skb); |
@@ -2527,6 +2536,7 @@ static void net_tx_action(struct softirq_action *h) | |||
2527 | local_irq_disable(); | 2536 | local_irq_disable(); |
2528 | head = sd->output_queue; | 2537 | head = sd->output_queue; |
2529 | sd->output_queue = NULL; | 2538 | sd->output_queue = NULL; |
2539 | sd->output_queue_tailp = &sd->output_queue; | ||
2530 | local_irq_enable(); | 2540 | local_irq_enable(); |
2531 | 2541 | ||
2532 | while (head) { | 2542 | while (head) { |
@@ -2801,7 +2811,7 @@ static int __netif_receive_skb(struct sk_buff *skb) | |||
2801 | skb->dev = master; | 2811 | skb->dev = master; |
2802 | } | 2812 | } |
2803 | 2813 | ||
2804 | __get_cpu_var(netdev_rx_stat).total++; | 2814 | __get_cpu_var(softnet_data).processed++; |
2805 | 2815 | ||
2806 | skb_reset_network_header(skb); | 2816 | skb_reset_network_header(skb); |
2807 | skb_reset_transport_header(skb); | 2817 | skb_reset_transport_header(skb); |
@@ -2930,13 +2940,21 @@ static void flush_backlog(void *arg) | |||
2930 | struct sk_buff *skb, *tmp; | 2940 | struct sk_buff *skb, *tmp; |
2931 | 2941 | ||
2932 | rps_lock(sd); | 2942 | rps_lock(sd); |
2933 | skb_queue_walk_safe(&sd->input_pkt_queue, skb, tmp) | 2943 | skb_queue_walk_safe(&sd->input_pkt_queue, skb, tmp) { |
2934 | if (skb->dev == dev) { | 2944 | if (skb->dev == dev) { |
2935 | __skb_unlink(skb, &sd->input_pkt_queue); | 2945 | __skb_unlink(skb, &sd->input_pkt_queue); |
2936 | kfree_skb(skb); | 2946 | kfree_skb(skb); |
2937 | input_queue_head_incr(sd); | 2947 | input_queue_head_add(sd, 1); |
2938 | } | 2948 | } |
2949 | } | ||
2939 | rps_unlock(sd); | 2950 | rps_unlock(sd); |
2951 | |||
2952 | skb_queue_walk_safe(&sd->process_queue, skb, tmp) { | ||
2953 | if (skb->dev == dev) { | ||
2954 | __skb_unlink(skb, &sd->process_queue); | ||
2955 | kfree_skb(skb); | ||
2956 | } | ||
2957 | } | ||
2940 | } | 2958 | } |
2941 | 2959 | ||
2942 | static int napi_gro_complete(struct sk_buff *skb) | 2960 | static int napi_gro_complete(struct sk_buff *skb) |
@@ -3239,30 +3257,85 @@ gro_result_t napi_gro_frags(struct napi_struct *napi) | |||
3239 | } | 3257 | } |
3240 | EXPORT_SYMBOL(napi_gro_frags); | 3258 | EXPORT_SYMBOL(napi_gro_frags); |
3241 | 3259 | ||
3260 | /* | ||
3261 | * net_rps_action sends any pending IPI's for rps. | ||
3262 | * Note: called with local irq disabled, but exits with local irq enabled. | ||
3263 | */ | ||
3264 | static void net_rps_action_and_irq_enable(struct softnet_data *sd) | ||
3265 | { | ||
3266 | #ifdef CONFIG_RPS | ||
3267 | struct softnet_data *remsd = sd->rps_ipi_list; | ||
3268 | |||
3269 | if (remsd) { | ||
3270 | sd->rps_ipi_list = NULL; | ||
3271 | |||
3272 | local_irq_enable(); | ||
3273 | |||
3274 | /* Send pending IPI's to kick RPS processing on remote cpus. */ | ||
3275 | while (remsd) { | ||
3276 | struct softnet_data *next = remsd->rps_ipi_next; | ||
3277 | |||
3278 | if (cpu_online(remsd->cpu)) | ||
3279 | __smp_call_function_single(remsd->cpu, | ||
3280 | &remsd->csd, 0); | ||
3281 | remsd = next; | ||
3282 | } | ||
3283 | } else | ||
3284 | #endif | ||
3285 | local_irq_enable(); | ||
3286 | } | ||
3287 | |||
3242 | static int process_backlog(struct napi_struct *napi, int quota) | 3288 | static int process_backlog(struct napi_struct *napi, int quota) |
3243 | { | 3289 | { |
3244 | int work = 0; | 3290 | int work = 0; |
3245 | struct softnet_data *sd = &__get_cpu_var(softnet_data); | 3291 | struct softnet_data *sd = container_of(napi, struct softnet_data, backlog); |
3246 | 3292 | ||
3293 | #ifdef CONFIG_RPS | ||
3294 | /* Check if we have pending ipi, its better to send them now, | ||
3295 | * not waiting net_rx_action() end. | ||
3296 | */ | ||
3297 | if (sd->rps_ipi_list) { | ||
3298 | local_irq_disable(); | ||
3299 | net_rps_action_and_irq_enable(sd); | ||
3300 | } | ||
3301 | #endif | ||
3247 | napi->weight = weight_p; | 3302 | napi->weight = weight_p; |
3248 | do { | 3303 | local_irq_disable(); |
3304 | while (work < quota) { | ||
3249 | struct sk_buff *skb; | 3305 | struct sk_buff *skb; |
3306 | unsigned int qlen; | ||
3250 | 3307 | ||
3251 | local_irq_disable(); | 3308 | while ((skb = __skb_dequeue(&sd->process_queue))) { |
3252 | rps_lock(sd); | ||
3253 | skb = __skb_dequeue(&sd->input_pkt_queue); | ||
3254 | if (!skb) { | ||
3255 | __napi_complete(napi); | ||
3256 | rps_unlock(sd); | ||
3257 | local_irq_enable(); | 3309 | local_irq_enable(); |
3258 | break; | 3310 | __netif_receive_skb(skb); |
3311 | if (++work >= quota) | ||
3312 | return work; | ||
3313 | local_irq_disable(); | ||
3259 | } | 3314 | } |
3260 | input_queue_head_incr(sd); | ||
3261 | rps_unlock(sd); | ||
3262 | local_irq_enable(); | ||
3263 | 3315 | ||
3264 | __netif_receive_skb(skb); | 3316 | rps_lock(sd); |
3265 | } while (++work < quota); | 3317 | qlen = skb_queue_len(&sd->input_pkt_queue); |
3318 | if (qlen) { | ||
3319 | input_queue_head_add(sd, qlen); | ||
3320 | skb_queue_splice_tail_init(&sd->input_pkt_queue, | ||
3321 | &sd->process_queue); | ||
3322 | } | ||
3323 | if (qlen < quota - work) { | ||
3324 | /* | ||
3325 | * Inline a custom version of __napi_complete(). | ||
3326 | * only current cpu owns and manipulates this napi, | ||
3327 | * and NAPI_STATE_SCHED is the only possible flag set on backlog. | ||
3328 | * we can use a plain write instead of clear_bit(), | ||
3329 | * and we dont need an smp_mb() memory barrier. | ||
3330 | */ | ||
3331 | list_del(&napi->poll_list); | ||
3332 | napi->state = 0; | ||
3333 | |||
3334 | quota = work + qlen; | ||
3335 | } | ||
3336 | rps_unlock(sd); | ||
3337 | } | ||
3338 | local_irq_enable(); | ||
3266 | 3339 | ||
3267 | return work; | 3340 | return work; |
3268 | } | 3341 | } |
@@ -3278,8 +3351,7 @@ void __napi_schedule(struct napi_struct *n) | |||
3278 | unsigned long flags; | 3351 | unsigned long flags; |
3279 | 3352 | ||
3280 | local_irq_save(flags); | 3353 | local_irq_save(flags); |
3281 | list_add_tail(&n->poll_list, &__get_cpu_var(softnet_data).poll_list); | 3354 | ____napi_schedule(&__get_cpu_var(softnet_data), n); |
3282 | __raise_softirq_irqoff(NET_RX_SOFTIRQ); | ||
3283 | local_irq_restore(flags); | 3355 | local_irq_restore(flags); |
3284 | } | 3356 | } |
3285 | EXPORT_SYMBOL(__napi_schedule); | 3357 | EXPORT_SYMBOL(__napi_schedule); |
@@ -3350,45 +3422,16 @@ void netif_napi_del(struct napi_struct *napi) | |||
3350 | } | 3422 | } |
3351 | EXPORT_SYMBOL(netif_napi_del); | 3423 | EXPORT_SYMBOL(netif_napi_del); |
3352 | 3424 | ||
3353 | /* | ||
3354 | * net_rps_action sends any pending IPI's for rps. | ||
3355 | * Note: called with local irq disabled, but exits with local irq enabled. | ||
3356 | */ | ||
3357 | static void net_rps_action_and_irq_disable(void) | ||
3358 | { | ||
3359 | #ifdef CONFIG_RPS | ||
3360 | struct softnet_data *sd = &__get_cpu_var(softnet_data); | ||
3361 | struct softnet_data *remsd = sd->rps_ipi_list; | ||
3362 | |||
3363 | if (remsd) { | ||
3364 | sd->rps_ipi_list = NULL; | ||
3365 | |||
3366 | local_irq_enable(); | ||
3367 | |||
3368 | /* Send pending IPI's to kick RPS processing on remote cpus. */ | ||
3369 | while (remsd) { | ||
3370 | struct softnet_data *next = remsd->rps_ipi_next; | ||
3371 | |||
3372 | if (cpu_online(remsd->cpu)) | ||
3373 | __smp_call_function_single(remsd->cpu, | ||
3374 | &remsd->csd, 0); | ||
3375 | remsd = next; | ||
3376 | } | ||
3377 | } else | ||
3378 | #endif | ||
3379 | local_irq_enable(); | ||
3380 | } | ||
3381 | |||
3382 | static void net_rx_action(struct softirq_action *h) | 3425 | static void net_rx_action(struct softirq_action *h) |
3383 | { | 3426 | { |
3384 | struct list_head *list = &__get_cpu_var(softnet_data).poll_list; | 3427 | struct softnet_data *sd = &__get_cpu_var(softnet_data); |
3385 | unsigned long time_limit = jiffies + 2; | 3428 | unsigned long time_limit = jiffies + 2; |
3386 | int budget = netdev_budget; | 3429 | int budget = netdev_budget; |
3387 | void *have; | 3430 | void *have; |
3388 | 3431 | ||
3389 | local_irq_disable(); | 3432 | local_irq_disable(); |
3390 | 3433 | ||
3391 | while (!list_empty(list)) { | 3434 | while (!list_empty(&sd->poll_list)) { |
3392 | struct napi_struct *n; | 3435 | struct napi_struct *n; |
3393 | int work, weight; | 3436 | int work, weight; |
3394 | 3437 | ||
@@ -3406,7 +3449,7 @@ static void net_rx_action(struct softirq_action *h) | |||
3406 | * entries to the tail of this list, and only ->poll() | 3449 | * entries to the tail of this list, and only ->poll() |
3407 | * calls can remove this head entry from the list. | 3450 | * calls can remove this head entry from the list. |
3408 | */ | 3451 | */ |
3409 | n = list_first_entry(list, struct napi_struct, poll_list); | 3452 | n = list_first_entry(&sd->poll_list, struct napi_struct, poll_list); |
3410 | 3453 | ||
3411 | have = netpoll_poll_lock(n); | 3454 | have = netpoll_poll_lock(n); |
3412 | 3455 | ||
@@ -3441,13 +3484,13 @@ static void net_rx_action(struct softirq_action *h) | |||
3441 | napi_complete(n); | 3484 | napi_complete(n); |
3442 | local_irq_disable(); | 3485 | local_irq_disable(); |
3443 | } else | 3486 | } else |
3444 | list_move_tail(&n->poll_list, list); | 3487 | list_move_tail(&n->poll_list, &sd->poll_list); |
3445 | } | 3488 | } |
3446 | 3489 | ||
3447 | netpoll_poll_unlock(have); | 3490 | netpoll_poll_unlock(have); |
3448 | } | 3491 | } |
3449 | out: | 3492 | out: |
3450 | net_rps_action_and_irq_disable(); | 3493 | net_rps_action_and_irq_enable(sd); |
3451 | 3494 | ||
3452 | #ifdef CONFIG_NET_DMA | 3495 | #ifdef CONFIG_NET_DMA |
3453 | /* | 3496 | /* |
@@ -3460,7 +3503,7 @@ out: | |||
3460 | return; | 3503 | return; |
3461 | 3504 | ||
3462 | softnet_break: | 3505 | softnet_break: |
3463 | __get_cpu_var(netdev_rx_stat).time_squeeze++; | 3506 | sd->time_squeeze++; |
3464 | __raise_softirq_irqoff(NET_RX_SOFTIRQ); | 3507 | __raise_softirq_irqoff(NET_RX_SOFTIRQ); |
3465 | goto out; | 3508 | goto out; |
3466 | } | 3509 | } |
@@ -3661,17 +3704,17 @@ static int dev_seq_show(struct seq_file *seq, void *v) | |||
3661 | return 0; | 3704 | return 0; |
3662 | } | 3705 | } |
3663 | 3706 | ||
3664 | static struct netif_rx_stats *softnet_get_online(loff_t *pos) | 3707 | static struct softnet_data *softnet_get_online(loff_t *pos) |
3665 | { | 3708 | { |
3666 | struct netif_rx_stats *rc = NULL; | 3709 | struct softnet_data *sd = NULL; |
3667 | 3710 | ||
3668 | while (*pos < nr_cpu_ids) | 3711 | while (*pos < nr_cpu_ids) |
3669 | if (cpu_online(*pos)) { | 3712 | if (cpu_online(*pos)) { |
3670 | rc = &per_cpu(netdev_rx_stat, *pos); | 3713 | sd = &per_cpu(softnet_data, *pos); |
3671 | break; | 3714 | break; |
3672 | } else | 3715 | } else |
3673 | ++*pos; | 3716 | ++*pos; |
3674 | return rc; | 3717 | return sd; |
3675 | } | 3718 | } |
3676 | 3719 | ||
3677 | static void *softnet_seq_start(struct seq_file *seq, loff_t *pos) | 3720 | static void *softnet_seq_start(struct seq_file *seq, loff_t *pos) |
@@ -3691,12 +3734,12 @@ static void softnet_seq_stop(struct seq_file *seq, void *v) | |||
3691 | 3734 | ||
3692 | static int softnet_seq_show(struct seq_file *seq, void *v) | 3735 | static int softnet_seq_show(struct seq_file *seq, void *v) |
3693 | { | 3736 | { |
3694 | struct netif_rx_stats *s = v; | 3737 | struct softnet_data *sd = v; |
3695 | 3738 | ||
3696 | seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x %08x %08x\n", | 3739 | seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x %08x %08x\n", |
3697 | s->total, s->dropped, s->time_squeeze, 0, | 3740 | sd->processed, sd->dropped, sd->time_squeeze, 0, |
3698 | 0, 0, 0, 0, /* was fastroute */ | 3741 | 0, 0, 0, 0, /* was fastroute */ |
3699 | s->cpu_collision, s->received_rps); | 3742 | sd->cpu_collision, sd->received_rps); |
3700 | return 0; | 3743 | return 0; |
3701 | } | 3744 | } |
3702 | 3745 | ||
@@ -5584,7 +5627,6 @@ static int dev_cpu_callback(struct notifier_block *nfb, | |||
5584 | void *ocpu) | 5627 | void *ocpu) |
5585 | { | 5628 | { |
5586 | struct sk_buff **list_skb; | 5629 | struct sk_buff **list_skb; |
5587 | struct Qdisc **list_net; | ||
5588 | struct sk_buff *skb; | 5630 | struct sk_buff *skb; |
5589 | unsigned int cpu, oldcpu = (unsigned long)ocpu; | 5631 | unsigned int cpu, oldcpu = (unsigned long)ocpu; |
5590 | struct softnet_data *sd, *oldsd; | 5632 | struct softnet_data *sd, *oldsd; |
@@ -5605,13 +5647,13 @@ static int dev_cpu_callback(struct notifier_block *nfb, | |||
5605 | *list_skb = oldsd->completion_queue; | 5647 | *list_skb = oldsd->completion_queue; |
5606 | oldsd->completion_queue = NULL; | 5648 | oldsd->completion_queue = NULL; |
5607 | 5649 | ||
5608 | /* Find end of our output_queue. */ | ||
5609 | list_net = &sd->output_queue; | ||
5610 | while (*list_net) | ||
5611 | list_net = &(*list_net)->next_sched; | ||
5612 | /* Append output queue from offline CPU. */ | 5650 | /* Append output queue from offline CPU. */ |
5613 | *list_net = oldsd->output_queue; | 5651 | if (oldsd->output_queue) { |
5614 | oldsd->output_queue = NULL; | 5652 | *sd->output_queue_tailp = oldsd->output_queue; |
5653 | sd->output_queue_tailp = oldsd->output_queue_tailp; | ||
5654 | oldsd->output_queue = NULL; | ||
5655 | oldsd->output_queue_tailp = &oldsd->output_queue; | ||
5656 | } | ||
5615 | 5657 | ||
5616 | raise_softirq_irqoff(NET_TX_SOFTIRQ); | 5658 | raise_softirq_irqoff(NET_TX_SOFTIRQ); |
5617 | local_irq_enable(); | 5659 | local_irq_enable(); |
@@ -5619,8 +5661,10 @@ static int dev_cpu_callback(struct notifier_block *nfb, | |||
5619 | /* Process offline CPU's input_pkt_queue */ | 5661 | /* Process offline CPU's input_pkt_queue */ |
5620 | while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) { | 5662 | while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) { |
5621 | netif_rx(skb); | 5663 | netif_rx(skb); |
5622 | input_queue_head_incr(oldsd); | 5664 | input_queue_head_add(oldsd, 1); |
5623 | } | 5665 | } |
5666 | while ((skb = __skb_dequeue(&oldsd->process_queue))) | ||
5667 | netif_rx(skb); | ||
5624 | 5668 | ||
5625 | return NOTIFY_OK; | 5669 | return NOTIFY_OK; |
5626 | } | 5670 | } |
@@ -5838,10 +5882,13 @@ static int __init net_dev_init(void) | |||
5838 | for_each_possible_cpu(i) { | 5882 | for_each_possible_cpu(i) { |
5839 | struct softnet_data *sd = &per_cpu(softnet_data, i); | 5883 | struct softnet_data *sd = &per_cpu(softnet_data, i); |
5840 | 5884 | ||
5885 | memset(sd, 0, sizeof(*sd)); | ||
5841 | skb_queue_head_init(&sd->input_pkt_queue); | 5886 | skb_queue_head_init(&sd->input_pkt_queue); |
5887 | skb_queue_head_init(&sd->process_queue); | ||
5842 | sd->completion_queue = NULL; | 5888 | sd->completion_queue = NULL; |
5843 | INIT_LIST_HEAD(&sd->poll_list); | 5889 | INIT_LIST_HEAD(&sd->poll_list); |
5844 | 5890 | sd->output_queue = NULL; | |
5891 | sd->output_queue_tailp = &sd->output_queue; | ||
5845 | #ifdef CONFIG_RPS | 5892 | #ifdef CONFIG_RPS |
5846 | sd->csd.func = rps_trigger_softirq; | 5893 | sd->csd.func = rps_trigger_softirq; |
5847 | sd->csd.info = sd; | 5894 | sd->csd.info = sd; |
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 1bc66592453c..42e84e08a1be 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
@@ -122,7 +122,7 @@ errout: | |||
122 | } | 122 | } |
123 | 123 | ||
124 | struct fib_rules_ops * | 124 | struct fib_rules_ops * |
125 | fib_rules_register(struct fib_rules_ops *tmpl, struct net *net) | 125 | fib_rules_register(const struct fib_rules_ops *tmpl, struct net *net) |
126 | { | 126 | { |
127 | struct fib_rules_ops *ops; | 127 | struct fib_rules_ops *ops; |
128 | int err; | 128 | int err; |
diff --git a/net/core/filter.c b/net/core/filter.c index ff943bed21af..da69fb728d32 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -302,6 +302,8 @@ load_b: | |||
302 | A = skb->pkt_type; | 302 | A = skb->pkt_type; |
303 | continue; | 303 | continue; |
304 | case SKF_AD_IFINDEX: | 304 | case SKF_AD_IFINDEX: |
305 | if (!skb->dev) | ||
306 | return 0; | ||
305 | A = skb->dev->ifindex; | 307 | A = skb->dev->ifindex; |
306 | continue; | 308 | continue; |
307 | case SKF_AD_MARK: | 309 | case SKF_AD_MARK: |
@@ -310,6 +312,11 @@ load_b: | |||
310 | case SKF_AD_QUEUE: | 312 | case SKF_AD_QUEUE: |
311 | A = skb->queue_mapping; | 313 | A = skb->queue_mapping; |
312 | continue; | 314 | continue; |
315 | case SKF_AD_HATYPE: | ||
316 | if (!skb->dev) | ||
317 | return 0; | ||
318 | A = skb->dev->type; | ||
319 | continue; | ||
313 | case SKF_AD_NLATTR: { | 320 | case SKF_AD_NLATTR: { |
314 | struct nlattr *nla; | 321 | struct nlattr *nla; |
315 | 322 | ||
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index bd8c4712ea24..c988e685433a 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -27,6 +27,51 @@ EXPORT_SYMBOL(init_net); | |||
27 | 27 | ||
28 | #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ | 28 | #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ |
29 | 29 | ||
30 | static void net_generic_release(struct rcu_head *rcu) | ||
31 | { | ||
32 | struct net_generic *ng; | ||
33 | |||
34 | ng = container_of(rcu, struct net_generic, rcu); | ||
35 | kfree(ng); | ||
36 | } | ||
37 | |||
38 | static int net_assign_generic(struct net *net, int id, void *data) | ||
39 | { | ||
40 | struct net_generic *ng, *old_ng; | ||
41 | |||
42 | BUG_ON(!mutex_is_locked(&net_mutex)); | ||
43 | BUG_ON(id == 0); | ||
44 | |||
45 | ng = old_ng = net->gen; | ||
46 | if (old_ng->len >= id) | ||
47 | goto assign; | ||
48 | |||
49 | ng = kzalloc(sizeof(struct net_generic) + | ||
50 | id * sizeof(void *), GFP_KERNEL); | ||
51 | if (ng == NULL) | ||
52 | return -ENOMEM; | ||
53 | |||
54 | /* | ||
55 | * Some synchronisation notes: | ||
56 | * | ||
57 | * The net_generic explores the net->gen array inside rcu | ||
58 | * read section. Besides once set the net->gen->ptr[x] | ||
59 | * pointer never changes (see rules in netns/generic.h). | ||
60 | * | ||
61 | * That said, we simply duplicate this array and schedule | ||
62 | * the old copy for kfree after a grace period. | ||
63 | */ | ||
64 | |||
65 | ng->len = id; | ||
66 | memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*)); | ||
67 | |||
68 | rcu_assign_pointer(net->gen, ng); | ||
69 | call_rcu(&old_ng->rcu, net_generic_release); | ||
70 | assign: | ||
71 | ng->ptr[id - 1] = data; | ||
72 | return 0; | ||
73 | } | ||
74 | |||
30 | static int ops_init(const struct pernet_operations *ops, struct net *net) | 75 | static int ops_init(const struct pernet_operations *ops, struct net *net) |
31 | { | 76 | { |
32 | int err; | 77 | int err; |
@@ -469,10 +514,10 @@ EXPORT_SYMBOL_GPL(register_pernet_subsys); | |||
469 | * addition run the exit method for all existing network | 514 | * addition run the exit method for all existing network |
470 | * namespaces. | 515 | * namespaces. |
471 | */ | 516 | */ |
472 | void unregister_pernet_subsys(struct pernet_operations *module) | 517 | void unregister_pernet_subsys(struct pernet_operations *ops) |
473 | { | 518 | { |
474 | mutex_lock(&net_mutex); | 519 | mutex_lock(&net_mutex); |
475 | unregister_pernet_operations(module); | 520 | unregister_pernet_operations(ops); |
476 | mutex_unlock(&net_mutex); | 521 | mutex_unlock(&net_mutex); |
477 | } | 522 | } |
478 | EXPORT_SYMBOL_GPL(unregister_pernet_subsys); | 523 | EXPORT_SYMBOL_GPL(unregister_pernet_subsys); |
@@ -526,49 +571,3 @@ void unregister_pernet_device(struct pernet_operations *ops) | |||
526 | mutex_unlock(&net_mutex); | 571 | mutex_unlock(&net_mutex); |
527 | } | 572 | } |
528 | EXPORT_SYMBOL_GPL(unregister_pernet_device); | 573 | EXPORT_SYMBOL_GPL(unregister_pernet_device); |
529 | |||
530 | static void net_generic_release(struct rcu_head *rcu) | ||
531 | { | ||
532 | struct net_generic *ng; | ||
533 | |||
534 | ng = container_of(rcu, struct net_generic, rcu); | ||
535 | kfree(ng); | ||
536 | } | ||
537 | |||
538 | int net_assign_generic(struct net *net, int id, void *data) | ||
539 | { | ||
540 | struct net_generic *ng, *old_ng; | ||
541 | |||
542 | BUG_ON(!mutex_is_locked(&net_mutex)); | ||
543 | BUG_ON(id == 0); | ||
544 | |||
545 | ng = old_ng = net->gen; | ||
546 | if (old_ng->len >= id) | ||
547 | goto assign; | ||
548 | |||
549 | ng = kzalloc(sizeof(struct net_generic) + | ||
550 | id * sizeof(void *), GFP_KERNEL); | ||
551 | if (ng == NULL) | ||
552 | return -ENOMEM; | ||
553 | |||
554 | /* | ||
555 | * Some synchronisation notes: | ||
556 | * | ||
557 | * The net_generic explores the net->gen array inside rcu | ||
558 | * read section. Besides once set the net->gen->ptr[x] | ||
559 | * pointer never changes (see rules in netns/generic.h). | ||
560 | * | ||
561 | * That said, we simply duplicate this array and schedule | ||
562 | * the old copy for kfree after a grace period. | ||
563 | */ | ||
564 | |||
565 | ng->len = id; | ||
566 | memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*)); | ||
567 | |||
568 | rcu_assign_pointer(net->gen, ng); | ||
569 | call_rcu(&old_ng->rcu, net_generic_release); | ||
570 | assign: | ||
571 | ng->ptr[id - 1] = data; | ||
572 | return 0; | ||
573 | } | ||
574 | EXPORT_SYMBOL_GPL(net_assign_generic); | ||
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index a58f59b97597..94825b109551 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -179,9 +179,8 @@ static void service_arp_queue(struct netpoll_info *npi) | |||
179 | } | 179 | } |
180 | } | 180 | } |
181 | 181 | ||
182 | void netpoll_poll(struct netpoll *np) | 182 | void netpoll_poll_dev(struct net_device *dev) |
183 | { | 183 | { |
184 | struct net_device *dev = np->dev; | ||
185 | const struct net_device_ops *ops; | 184 | const struct net_device_ops *ops; |
186 | 185 | ||
187 | if (!dev || !netif_running(dev)) | 186 | if (!dev || !netif_running(dev)) |
@@ -201,6 +200,11 @@ void netpoll_poll(struct netpoll *np) | |||
201 | zap_completion_queue(); | 200 | zap_completion_queue(); |
202 | } | 201 | } |
203 | 202 | ||
203 | void netpoll_poll(struct netpoll *np) | ||
204 | { | ||
205 | netpoll_poll_dev(np->dev); | ||
206 | } | ||
207 | |||
204 | static void refill_skbs(void) | 208 | static void refill_skbs(void) |
205 | { | 209 | { |
206 | struct sk_buff *skb; | 210 | struct sk_buff *skb; |
@@ -282,7 +286,7 @@ static int netpoll_owner_active(struct net_device *dev) | |||
282 | return 0; | 286 | return 0; |
283 | } | 287 | } |
284 | 288 | ||
285 | static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) | 289 | void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) |
286 | { | 290 | { |
287 | int status = NETDEV_TX_BUSY; | 291 | int status = NETDEV_TX_BUSY; |
288 | unsigned long tries; | 292 | unsigned long tries; |
@@ -308,7 +312,9 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) | |||
308 | tries > 0; --tries) { | 312 | tries > 0; --tries) { |
309 | if (__netif_tx_trylock(txq)) { | 313 | if (__netif_tx_trylock(txq)) { |
310 | if (!netif_tx_queue_stopped(txq)) { | 314 | if (!netif_tx_queue_stopped(txq)) { |
315 | dev->priv_flags |= IFF_IN_NETPOLL; | ||
311 | status = ops->ndo_start_xmit(skb, dev); | 316 | status = ops->ndo_start_xmit(skb, dev); |
317 | dev->priv_flags &= ~IFF_IN_NETPOLL; | ||
312 | if (status == NETDEV_TX_OK) | 318 | if (status == NETDEV_TX_OK) |
313 | txq_trans_update(txq); | 319 | txq_trans_update(txq); |
314 | } | 320 | } |
@@ -756,7 +762,10 @@ int netpoll_setup(struct netpoll *np) | |||
756 | atomic_inc(&npinfo->refcnt); | 762 | atomic_inc(&npinfo->refcnt); |
757 | } | 763 | } |
758 | 764 | ||
759 | if (!ndev->netdev_ops->ndo_poll_controller) { | 765 | npinfo->netpoll = np; |
766 | |||
767 | if ((ndev->priv_flags & IFF_DISABLE_NETPOLL) || | ||
768 | !ndev->netdev_ops->ndo_poll_controller) { | ||
760 | printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n", | 769 | printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n", |
761 | np->name, np->dev_name); | 770 | np->name, np->dev_name); |
762 | err = -ENOTSUPP; | 771 | err = -ENOTSUPP; |
@@ -878,6 +887,7 @@ void netpoll_cleanup(struct netpoll *np) | |||
878 | } | 887 | } |
879 | 888 | ||
880 | if (atomic_dec_and_test(&npinfo->refcnt)) { | 889 | if (atomic_dec_and_test(&npinfo->refcnt)) { |
890 | const struct net_device_ops *ops; | ||
881 | skb_queue_purge(&npinfo->arp_tx); | 891 | skb_queue_purge(&npinfo->arp_tx); |
882 | skb_queue_purge(&npinfo->txq); | 892 | skb_queue_purge(&npinfo->txq); |
883 | cancel_rearming_delayed_work(&npinfo->tx_work); | 893 | cancel_rearming_delayed_work(&npinfo->tx_work); |
@@ -885,7 +895,11 @@ void netpoll_cleanup(struct netpoll *np) | |||
885 | /* clean after last, unfinished work */ | 895 | /* clean after last, unfinished work */ |
886 | __skb_queue_purge(&npinfo->txq); | 896 | __skb_queue_purge(&npinfo->txq); |
887 | kfree(npinfo); | 897 | kfree(npinfo); |
888 | np->dev->npinfo = NULL; | 898 | ops = np->dev->netdev_ops; |
899 | if (ops->ndo_netpoll_cleanup) | ||
900 | ops->ndo_netpoll_cleanup(np->dev); | ||
901 | else | ||
902 | np->dev->npinfo = NULL; | ||
889 | } | 903 | } |
890 | } | 904 | } |
891 | 905 | ||
@@ -908,6 +922,7 @@ void netpoll_set_trap(int trap) | |||
908 | atomic_dec(&trapped); | 922 | atomic_dec(&trapped); |
909 | } | 923 | } |
910 | 924 | ||
925 | EXPORT_SYMBOL(netpoll_send_skb); | ||
911 | EXPORT_SYMBOL(netpoll_set_trap); | 926 | EXPORT_SYMBOL(netpoll_set_trap); |
912 | EXPORT_SYMBOL(netpoll_trap); | 927 | EXPORT_SYMBOL(netpoll_trap); |
913 | EXPORT_SYMBOL(netpoll_print_options); | 928 | EXPORT_SYMBOL(netpoll_print_options); |
@@ -915,4 +930,5 @@ EXPORT_SYMBOL(netpoll_parse_options); | |||
915 | EXPORT_SYMBOL(netpoll_setup); | 930 | EXPORT_SYMBOL(netpoll_setup); |
916 | EXPORT_SYMBOL(netpoll_cleanup); | 931 | EXPORT_SYMBOL(netpoll_cleanup); |
917 | EXPORT_SYMBOL(netpoll_send_udp); | 932 | EXPORT_SYMBOL(netpoll_send_udp); |
933 | EXPORT_SYMBOL(netpoll_poll_dev); | ||
918 | EXPORT_SYMBOL(netpoll_poll); | 934 | EXPORT_SYMBOL(netpoll_poll); |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 78c85985cb30..23a71cb21273 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -98,7 +98,7 @@ int lockdep_rtnl_is_held(void) | |||
98 | EXPORT_SYMBOL(lockdep_rtnl_is_held); | 98 | EXPORT_SYMBOL(lockdep_rtnl_is_held); |
99 | #endif /* #ifdef CONFIG_PROVE_LOCKING */ | 99 | #endif /* #ifdef CONFIG_PROVE_LOCKING */ |
100 | 100 | ||
101 | static struct rtnl_link *rtnl_msg_handlers[NPROTO]; | 101 | static struct rtnl_link *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1]; |
102 | 102 | ||
103 | static inline int rtm_msgindex(int msgtype) | 103 | static inline int rtm_msgindex(int msgtype) |
104 | { | 104 | { |
@@ -118,7 +118,7 @@ static rtnl_doit_func rtnl_get_doit(int protocol, int msgindex) | |||
118 | { | 118 | { |
119 | struct rtnl_link *tab; | 119 | struct rtnl_link *tab; |
120 | 120 | ||
121 | if (protocol < NPROTO) | 121 | if (protocol <= RTNL_FAMILY_MAX) |
122 | tab = rtnl_msg_handlers[protocol]; | 122 | tab = rtnl_msg_handlers[protocol]; |
123 | else | 123 | else |
124 | tab = NULL; | 124 | tab = NULL; |
@@ -133,7 +133,7 @@ static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex) | |||
133 | { | 133 | { |
134 | struct rtnl_link *tab; | 134 | struct rtnl_link *tab; |
135 | 135 | ||
136 | if (protocol < NPROTO) | 136 | if (protocol <= RTNL_FAMILY_MAX) |
137 | tab = rtnl_msg_handlers[protocol]; | 137 | tab = rtnl_msg_handlers[protocol]; |
138 | else | 138 | else |
139 | tab = NULL; | 139 | tab = NULL; |
@@ -167,7 +167,7 @@ int __rtnl_register(int protocol, int msgtype, | |||
167 | struct rtnl_link *tab; | 167 | struct rtnl_link *tab; |
168 | int msgindex; | 168 | int msgindex; |
169 | 169 | ||
170 | BUG_ON(protocol < 0 || protocol >= NPROTO); | 170 | BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); |
171 | msgindex = rtm_msgindex(msgtype); | 171 | msgindex = rtm_msgindex(msgtype); |
172 | 172 | ||
173 | tab = rtnl_msg_handlers[protocol]; | 173 | tab = rtnl_msg_handlers[protocol]; |
@@ -219,7 +219,7 @@ int rtnl_unregister(int protocol, int msgtype) | |||
219 | { | 219 | { |
220 | int msgindex; | 220 | int msgindex; |
221 | 221 | ||
222 | BUG_ON(protocol < 0 || protocol >= NPROTO); | 222 | BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); |
223 | msgindex = rtm_msgindex(msgtype); | 223 | msgindex = rtm_msgindex(msgtype); |
224 | 224 | ||
225 | if (rtnl_msg_handlers[protocol] == NULL) | 225 | if (rtnl_msg_handlers[protocol] == NULL) |
@@ -241,7 +241,7 @@ EXPORT_SYMBOL_GPL(rtnl_unregister); | |||
241 | */ | 241 | */ |
242 | void rtnl_unregister_all(int protocol) | 242 | void rtnl_unregister_all(int protocol) |
243 | { | 243 | { |
244 | BUG_ON(protocol < 0 || protocol >= NPROTO); | 244 | BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); |
245 | 245 | ||
246 | kfree(rtnl_msg_handlers[protocol]); | 246 | kfree(rtnl_msg_handlers[protocol]); |
247 | rtnl_msg_handlers[protocol] = NULL; | 247 | rtnl_msg_handlers[protocol] = NULL; |
@@ -1319,10 +1319,11 @@ replay: | |||
1319 | err = ops->newlink(net, dev, tb, data); | 1319 | err = ops->newlink(net, dev, tb, data); |
1320 | else | 1320 | else |
1321 | err = register_netdevice(dev); | 1321 | err = register_netdevice(dev); |
1322 | if (err < 0 && !IS_ERR(dev)) { | 1322 | |
1323 | if (err < 0 && !IS_ERR(dev)) | ||
1323 | free_netdev(dev); | 1324 | free_netdev(dev); |
1325 | if (err < 0) | ||
1324 | goto out; | 1326 | goto out; |
1325 | } | ||
1326 | 1327 | ||
1327 | err = rtnl_configure_link(dev, ifm); | 1328 | err = rtnl_configure_link(dev, ifm); |
1328 | if (err < 0) | 1329 | if (err < 0) |
@@ -1384,7 +1385,7 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) | |||
1384 | 1385 | ||
1385 | if (s_idx == 0) | 1386 | if (s_idx == 0) |
1386 | s_idx = 1; | 1387 | s_idx = 1; |
1387 | for (idx = 1; idx < NPROTO; idx++) { | 1388 | for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) { |
1388 | int type = cb->nlh->nlmsg_type-RTM_BASE; | 1389 | int type = cb->nlh->nlmsg_type-RTM_BASE; |
1389 | if (idx < s_idx || idx == PF_PACKET) | 1390 | if (idx < s_idx || idx == PF_PACKET) |
1390 | continue; | 1391 | continue; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index bdea0efdf8cb..a9b0e1f77806 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -117,7 +117,7 @@ static const struct pipe_buf_operations sock_pipe_buf_ops = { | |||
117 | * | 117 | * |
118 | * Out of line support code for skb_put(). Not user callable. | 118 | * Out of line support code for skb_put(). Not user callable. |
119 | */ | 119 | */ |
120 | void skb_over_panic(struct sk_buff *skb, int sz, void *here) | 120 | static void skb_over_panic(struct sk_buff *skb, int sz, void *here) |
121 | { | 121 | { |
122 | printk(KERN_EMERG "skb_over_panic: text:%p len:%d put:%d head:%p " | 122 | printk(KERN_EMERG "skb_over_panic: text:%p len:%d put:%d head:%p " |
123 | "data:%p tail:%#lx end:%#lx dev:%s\n", | 123 | "data:%p tail:%#lx end:%#lx dev:%s\n", |
@@ -126,7 +126,6 @@ void skb_over_panic(struct sk_buff *skb, int sz, void *here) | |||
126 | skb->dev ? skb->dev->name : "<NULL>"); | 126 | skb->dev ? skb->dev->name : "<NULL>"); |
127 | BUG(); | 127 | BUG(); |
128 | } | 128 | } |
129 | EXPORT_SYMBOL(skb_over_panic); | ||
130 | 129 | ||
131 | /** | 130 | /** |
132 | * skb_under_panic - private function | 131 | * skb_under_panic - private function |
@@ -137,7 +136,7 @@ EXPORT_SYMBOL(skb_over_panic); | |||
137 | * Out of line support code for skb_push(). Not user callable. | 136 | * Out of line support code for skb_push(). Not user callable. |
138 | */ | 137 | */ |
139 | 138 | ||
140 | void skb_under_panic(struct sk_buff *skb, int sz, void *here) | 139 | static void skb_under_panic(struct sk_buff *skb, int sz, void *here) |
141 | { | 140 | { |
142 | printk(KERN_EMERG "skb_under_panic: text:%p len:%d put:%d head:%p " | 141 | printk(KERN_EMERG "skb_under_panic: text:%p len:%d put:%d head:%p " |
143 | "data:%p tail:%#lx end:%#lx dev:%s\n", | 142 | "data:%p tail:%#lx end:%#lx dev:%s\n", |
@@ -146,7 +145,6 @@ void skb_under_panic(struct sk_buff *skb, int sz, void *here) | |||
146 | skb->dev ? skb->dev->name : "<NULL>"); | 145 | skb->dev ? skb->dev->name : "<NULL>"); |
147 | BUG(); | 146 | BUG(); |
148 | } | 147 | } |
149 | EXPORT_SYMBOL(skb_under_panic); | ||
150 | 148 | ||
151 | /* Allocate a new skbuff. We do this ourselves so we can fill in a few | 149 | /* Allocate a new skbuff. We do this ourselves so we can fill in a few |
152 | * 'private' fields and also do memory statistics to find all the | 150 | * 'private' fields and also do memory statistics to find all the |
@@ -183,12 +181,14 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | |||
183 | skb = kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node); | 181 | skb = kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node); |
184 | if (!skb) | 182 | if (!skb) |
185 | goto out; | 183 | goto out; |
184 | prefetchw(skb); | ||
186 | 185 | ||
187 | size = SKB_DATA_ALIGN(size); | 186 | size = SKB_DATA_ALIGN(size); |
188 | data = kmalloc_node_track_caller(size + sizeof(struct skb_shared_info), | 187 | data = kmalloc_node_track_caller(size + sizeof(struct skb_shared_info), |
189 | gfp_mask, node); | 188 | gfp_mask, node); |
190 | if (!data) | 189 | if (!data) |
191 | goto nodata; | 190 | goto nodata; |
191 | prefetchw(data + size); | ||
192 | 192 | ||
193 | /* | 193 | /* |
194 | * Only clear those fields we need to clear, not those that we will | 194 | * Only clear those fields we need to clear, not those that we will |
@@ -210,15 +210,8 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | |||
210 | 210 | ||
211 | /* make sure we initialize shinfo sequentially */ | 211 | /* make sure we initialize shinfo sequentially */ |
212 | shinfo = skb_shinfo(skb); | 212 | shinfo = skb_shinfo(skb); |
213 | memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); | ||
213 | atomic_set(&shinfo->dataref, 1); | 214 | atomic_set(&shinfo->dataref, 1); |
214 | shinfo->nr_frags = 0; | ||
215 | shinfo->gso_size = 0; | ||
216 | shinfo->gso_segs = 0; | ||
217 | shinfo->gso_type = 0; | ||
218 | shinfo->ip6_frag_id = 0; | ||
219 | shinfo->tx_flags.flags = 0; | ||
220 | skb_frag_list_init(skb); | ||
221 | memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps)); | ||
222 | 215 | ||
223 | if (fclone) { | 216 | if (fclone) { |
224 | struct sk_buff *child = skb + 1; | 217 | struct sk_buff *child = skb + 1; |
@@ -507,16 +500,10 @@ int skb_recycle_check(struct sk_buff *skb, int skb_size) | |||
507 | return 0; | 500 | return 0; |
508 | 501 | ||
509 | skb_release_head_state(skb); | 502 | skb_release_head_state(skb); |
503 | |||
510 | shinfo = skb_shinfo(skb); | 504 | shinfo = skb_shinfo(skb); |
505 | memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); | ||
511 | atomic_set(&shinfo->dataref, 1); | 506 | atomic_set(&shinfo->dataref, 1); |
512 | shinfo->nr_frags = 0; | ||
513 | shinfo->gso_size = 0; | ||
514 | shinfo->gso_segs = 0; | ||
515 | shinfo->gso_type = 0; | ||
516 | shinfo->ip6_frag_id = 0; | ||
517 | shinfo->tx_flags.flags = 0; | ||
518 | skb_frag_list_init(skb); | ||
519 | memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps)); | ||
520 | 507 | ||
521 | memset(skb, 0, offsetof(struct sk_buff, tail)); | 508 | memset(skb, 0, offsetof(struct sk_buff, tail)); |
522 | skb->data = skb->head + NET_SKB_PAD; | 509 | skb->data = skb->head + NET_SKB_PAD; |
@@ -1053,7 +1040,7 @@ EXPORT_SYMBOL(skb_push); | |||
1053 | */ | 1040 | */ |
1054 | unsigned char *skb_pull(struct sk_buff *skb, unsigned int len) | 1041 | unsigned char *skb_pull(struct sk_buff *skb, unsigned int len) |
1055 | { | 1042 | { |
1056 | return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len); | 1043 | return skb_pull_inline(skb, len); |
1057 | } | 1044 | } |
1058 | EXPORT_SYMBOL(skb_pull); | 1045 | EXPORT_SYMBOL(skb_pull); |
1059 | 1046 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index 7effa1e689df..94c4affdda9b 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -327,6 +327,10 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested) | |||
327 | 327 | ||
328 | skb->dev = NULL; | 328 | skb->dev = NULL; |
329 | 329 | ||
330 | if (sk_rcvqueues_full(sk, skb)) { | ||
331 | atomic_inc(&sk->sk_drops); | ||
332 | goto discard_and_relse; | ||
333 | } | ||
330 | if (nested) | 334 | if (nested) |
331 | bh_lock_sock_nested(sk); | 335 | bh_lock_sock_nested(sk); |
332 | else | 336 | else |
@@ -1207,7 +1211,7 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) | |||
1207 | */ | 1211 | */ |
1208 | sk_refcnt_debug_inc(newsk); | 1212 | sk_refcnt_debug_inc(newsk); |
1209 | sk_set_socket(newsk, NULL); | 1213 | sk_set_socket(newsk, NULL); |
1210 | newsk->sk_sleep = NULL; | 1214 | newsk->sk_wq = NULL; |
1211 | 1215 | ||
1212 | if (newsk->sk_prot->sockets_allocated) | 1216 | if (newsk->sk_prot->sockets_allocated) |
1213 | percpu_counter_inc(newsk->sk_prot->sockets_allocated); | 1217 | percpu_counter_inc(newsk->sk_prot->sockets_allocated); |
@@ -1395,7 +1399,7 @@ static long sock_wait_for_wmem(struct sock *sk, long timeo) | |||
1395 | if (signal_pending(current)) | 1399 | if (signal_pending(current)) |
1396 | break; | 1400 | break; |
1397 | set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); | 1401 | set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); |
1398 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 1402 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
1399 | if (atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) | 1403 | if (atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) |
1400 | break; | 1404 | break; |
1401 | if (sk->sk_shutdown & SEND_SHUTDOWN) | 1405 | if (sk->sk_shutdown & SEND_SHUTDOWN) |
@@ -1404,7 +1408,7 @@ static long sock_wait_for_wmem(struct sock *sk, long timeo) | |||
1404 | break; | 1408 | break; |
1405 | timeo = schedule_timeout(timeo); | 1409 | timeo = schedule_timeout(timeo); |
1406 | } | 1410 | } |
1407 | finish_wait(sk->sk_sleep, &wait); | 1411 | finish_wait(sk_sleep(sk), &wait); |
1408 | return timeo; | 1412 | return timeo; |
1409 | } | 1413 | } |
1410 | 1414 | ||
@@ -1570,11 +1574,11 @@ int sk_wait_data(struct sock *sk, long *timeo) | |||
1570 | int rc; | 1574 | int rc; |
1571 | DEFINE_WAIT(wait); | 1575 | DEFINE_WAIT(wait); |
1572 | 1576 | ||
1573 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 1577 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
1574 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 1578 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); |
1575 | rc = sk_wait_event(sk, timeo, !skb_queue_empty(&sk->sk_receive_queue)); | 1579 | rc = sk_wait_event(sk, timeo, !skb_queue_empty(&sk->sk_receive_queue)); |
1576 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 1580 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); |
1577 | finish_wait(sk->sk_sleep, &wait); | 1581 | finish_wait(sk_sleep(sk), &wait); |
1578 | return rc; | 1582 | return rc; |
1579 | } | 1583 | } |
1580 | EXPORT_SYMBOL(sk_wait_data); | 1584 | EXPORT_SYMBOL(sk_wait_data); |
@@ -1796,41 +1800,53 @@ EXPORT_SYMBOL(sock_no_sendpage); | |||
1796 | 1800 | ||
1797 | static void sock_def_wakeup(struct sock *sk) | 1801 | static void sock_def_wakeup(struct sock *sk) |
1798 | { | 1802 | { |
1799 | read_lock(&sk->sk_callback_lock); | 1803 | struct socket_wq *wq; |
1800 | if (sk_has_sleeper(sk)) | 1804 | |
1801 | wake_up_interruptible_all(sk->sk_sleep); | 1805 | rcu_read_lock(); |
1802 | read_unlock(&sk->sk_callback_lock); | 1806 | wq = rcu_dereference(sk->sk_wq); |
1807 | if (wq_has_sleeper(wq)) | ||
1808 | wake_up_interruptible_all(&wq->wait); | ||
1809 | rcu_read_unlock(); | ||
1803 | } | 1810 | } |
1804 | 1811 | ||
1805 | static void sock_def_error_report(struct sock *sk) | 1812 | static void sock_def_error_report(struct sock *sk) |
1806 | { | 1813 | { |
1807 | read_lock(&sk->sk_callback_lock); | 1814 | struct socket_wq *wq; |
1808 | if (sk_has_sleeper(sk)) | 1815 | |
1809 | wake_up_interruptible_poll(sk->sk_sleep, POLLERR); | 1816 | rcu_read_lock(); |
1817 | wq = rcu_dereference(sk->sk_wq); | ||
1818 | if (wq_has_sleeper(wq)) | ||
1819 | wake_up_interruptible_poll(&wq->wait, POLLERR); | ||
1810 | sk_wake_async(sk, SOCK_WAKE_IO, POLL_ERR); | 1820 | sk_wake_async(sk, SOCK_WAKE_IO, POLL_ERR); |
1811 | read_unlock(&sk->sk_callback_lock); | 1821 | rcu_read_unlock(); |
1812 | } | 1822 | } |
1813 | 1823 | ||
1814 | static void sock_def_readable(struct sock *sk, int len) | 1824 | static void sock_def_readable(struct sock *sk, int len) |
1815 | { | 1825 | { |
1816 | read_lock(&sk->sk_callback_lock); | 1826 | struct socket_wq *wq; |
1817 | if (sk_has_sleeper(sk)) | 1827 | |
1818 | wake_up_interruptible_sync_poll(sk->sk_sleep, POLLIN | | 1828 | rcu_read_lock(); |
1829 | wq = rcu_dereference(sk->sk_wq); | ||
1830 | if (wq_has_sleeper(wq)) | ||
1831 | wake_up_interruptible_sync_poll(&wq->wait, POLLIN | | ||
1819 | POLLRDNORM | POLLRDBAND); | 1832 | POLLRDNORM | POLLRDBAND); |
1820 | sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); | 1833 | sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); |
1821 | read_unlock(&sk->sk_callback_lock); | 1834 | rcu_read_unlock(); |
1822 | } | 1835 | } |
1823 | 1836 | ||
1824 | static void sock_def_write_space(struct sock *sk) | 1837 | static void sock_def_write_space(struct sock *sk) |
1825 | { | 1838 | { |
1826 | read_lock(&sk->sk_callback_lock); | 1839 | struct socket_wq *wq; |
1840 | |||
1841 | rcu_read_lock(); | ||
1827 | 1842 | ||
1828 | /* Do not wake up a writer until he can make "significant" | 1843 | /* Do not wake up a writer until he can make "significant" |
1829 | * progress. --DaveM | 1844 | * progress. --DaveM |
1830 | */ | 1845 | */ |
1831 | if ((atomic_read(&sk->sk_wmem_alloc) << 1) <= sk->sk_sndbuf) { | 1846 | if ((atomic_read(&sk->sk_wmem_alloc) << 1) <= sk->sk_sndbuf) { |
1832 | if (sk_has_sleeper(sk)) | 1847 | wq = rcu_dereference(sk->sk_wq); |
1833 | wake_up_interruptible_sync_poll(sk->sk_sleep, POLLOUT | | 1848 | if (wq_has_sleeper(wq)) |
1849 | wake_up_interruptible_sync_poll(&wq->wait, POLLOUT | | ||
1834 | POLLWRNORM | POLLWRBAND); | 1850 | POLLWRNORM | POLLWRBAND); |
1835 | 1851 | ||
1836 | /* Should agree with poll, otherwise some programs break */ | 1852 | /* Should agree with poll, otherwise some programs break */ |
@@ -1838,7 +1854,7 @@ static void sock_def_write_space(struct sock *sk) | |||
1838 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); | 1854 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); |
1839 | } | 1855 | } |
1840 | 1856 | ||
1841 | read_unlock(&sk->sk_callback_lock); | 1857 | rcu_read_unlock(); |
1842 | } | 1858 | } |
1843 | 1859 | ||
1844 | static void sock_def_destruct(struct sock *sk) | 1860 | static void sock_def_destruct(struct sock *sk) |
@@ -1885,7 +1901,6 @@ void sock_init_data(struct socket *sock, struct sock *sk) | |||
1885 | sk->sk_allocation = GFP_KERNEL; | 1901 | sk->sk_allocation = GFP_KERNEL; |
1886 | sk->sk_rcvbuf = sysctl_rmem_default; | 1902 | sk->sk_rcvbuf = sysctl_rmem_default; |
1887 | sk->sk_sndbuf = sysctl_wmem_default; | 1903 | sk->sk_sndbuf = sysctl_wmem_default; |
1888 | sk->sk_backlog.limit = sk->sk_rcvbuf << 1; | ||
1889 | sk->sk_state = TCP_CLOSE; | 1904 | sk->sk_state = TCP_CLOSE; |
1890 | sk_set_socket(sk, sock); | 1905 | sk_set_socket(sk, sock); |
1891 | 1906 | ||
@@ -1893,10 +1908,10 @@ void sock_init_data(struct socket *sock, struct sock *sk) | |||
1893 | 1908 | ||
1894 | if (sock) { | 1909 | if (sock) { |
1895 | sk->sk_type = sock->type; | 1910 | sk->sk_type = sock->type; |
1896 | sk->sk_sleep = &sock->wait; | 1911 | sk->sk_wq = sock->wq; |
1897 | sock->sk = sk; | 1912 | sock->sk = sk; |
1898 | } else | 1913 | } else |
1899 | sk->sk_sleep = NULL; | 1914 | sk->sk_wq = NULL; |
1900 | 1915 | ||
1901 | spin_lock_init(&sk->sk_dst_lock); | 1916 | spin_lock_init(&sk->sk_dst_lock); |
1902 | rwlock_init(&sk->sk_callback_lock); | 1917 | rwlock_init(&sk->sk_callback_lock); |
diff --git a/net/core/stream.c b/net/core/stream.c index a37debfeb1b2..cc196f42b8d8 100644 --- a/net/core/stream.c +++ b/net/core/stream.c | |||
@@ -28,15 +28,19 @@ | |||
28 | void sk_stream_write_space(struct sock *sk) | 28 | void sk_stream_write_space(struct sock *sk) |
29 | { | 29 | { |
30 | struct socket *sock = sk->sk_socket; | 30 | struct socket *sock = sk->sk_socket; |
31 | struct socket_wq *wq; | ||
31 | 32 | ||
32 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk) && sock) { | 33 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk) && sock) { |
33 | clear_bit(SOCK_NOSPACE, &sock->flags); | 34 | clear_bit(SOCK_NOSPACE, &sock->flags); |
34 | 35 | ||
35 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 36 | rcu_read_lock(); |
36 | wake_up_interruptible_poll(sk->sk_sleep, POLLOUT | | 37 | wq = rcu_dereference(sk->sk_wq); |
38 | if (wq_has_sleeper(wq)) | ||
39 | wake_up_interruptible_poll(&wq->wait, POLLOUT | | ||
37 | POLLWRNORM | POLLWRBAND); | 40 | POLLWRNORM | POLLWRBAND); |
38 | if (sock->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN)) | 41 | if (wq && wq->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN)) |
39 | sock_wake_async(sock, SOCK_WAKE_SPACE, POLL_OUT); | 42 | sock_wake_async(sock, SOCK_WAKE_SPACE, POLL_OUT); |
43 | rcu_read_unlock(); | ||
40 | } | 44 | } |
41 | } | 45 | } |
42 | 46 | ||
@@ -66,13 +70,13 @@ int sk_stream_wait_connect(struct sock *sk, long *timeo_p) | |||
66 | if (signal_pending(tsk)) | 70 | if (signal_pending(tsk)) |
67 | return sock_intr_errno(*timeo_p); | 71 | return sock_intr_errno(*timeo_p); |
68 | 72 | ||
69 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 73 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
70 | sk->sk_write_pending++; | 74 | sk->sk_write_pending++; |
71 | done = sk_wait_event(sk, timeo_p, | 75 | done = sk_wait_event(sk, timeo_p, |
72 | !sk->sk_err && | 76 | !sk->sk_err && |
73 | !((1 << sk->sk_state) & | 77 | !((1 << sk->sk_state) & |
74 | ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT))); | 78 | ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT))); |
75 | finish_wait(sk->sk_sleep, &wait); | 79 | finish_wait(sk_sleep(sk), &wait); |
76 | sk->sk_write_pending--; | 80 | sk->sk_write_pending--; |
77 | } while (!done); | 81 | } while (!done); |
78 | return 0; | 82 | return 0; |
@@ -96,13 +100,13 @@ void sk_stream_wait_close(struct sock *sk, long timeout) | |||
96 | DEFINE_WAIT(wait); | 100 | DEFINE_WAIT(wait); |
97 | 101 | ||
98 | do { | 102 | do { |
99 | prepare_to_wait(sk->sk_sleep, &wait, | 103 | prepare_to_wait(sk_sleep(sk), &wait, |
100 | TASK_INTERRUPTIBLE); | 104 | TASK_INTERRUPTIBLE); |
101 | if (sk_wait_event(sk, &timeout, !sk_stream_closing(sk))) | 105 | if (sk_wait_event(sk, &timeout, !sk_stream_closing(sk))) |
102 | break; | 106 | break; |
103 | } while (!signal_pending(current) && timeout); | 107 | } while (!signal_pending(current) && timeout); |
104 | 108 | ||
105 | finish_wait(sk->sk_sleep, &wait); | 109 | finish_wait(sk_sleep(sk), &wait); |
106 | } | 110 | } |
107 | } | 111 | } |
108 | 112 | ||
@@ -126,7 +130,7 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p) | |||
126 | while (1) { | 130 | while (1) { |
127 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 131 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); |
128 | 132 | ||
129 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 133 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
130 | 134 | ||
131 | if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) | 135 | if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) |
132 | goto do_error; | 136 | goto do_error; |
@@ -157,7 +161,7 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p) | |||
157 | *timeo_p = current_timeo; | 161 | *timeo_p = current_timeo; |
158 | } | 162 | } |
159 | out: | 163 | out: |
160 | finish_wait(sk->sk_sleep, &wait); | 164 | finish_wait(sk_sleep(sk), &wait); |
161 | return err; | 165 | return err; |
162 | 166 | ||
163 | do_error: | 167 | do_error: |
diff --git a/net/dccp/output.c b/net/dccp/output.c index e98b65e9569f..aadbdb58758b 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c | |||
@@ -195,15 +195,17 @@ EXPORT_SYMBOL_GPL(dccp_sync_mss); | |||
195 | 195 | ||
196 | void dccp_write_space(struct sock *sk) | 196 | void dccp_write_space(struct sock *sk) |
197 | { | 197 | { |
198 | read_lock(&sk->sk_callback_lock); | 198 | struct socket_wq *wq; |
199 | 199 | ||
200 | if (sk_has_sleeper(sk)) | 200 | rcu_read_lock(); |
201 | wake_up_interruptible(sk->sk_sleep); | 201 | wq = rcu_dereference(sk->sk_wq); |
202 | if (wq_has_sleeper(wq)) | ||
203 | wake_up_interruptible(&wq->wait); | ||
202 | /* Should agree with poll, otherwise some programs break */ | 204 | /* Should agree with poll, otherwise some programs break */ |
203 | if (sock_writeable(sk)) | 205 | if (sock_writeable(sk)) |
204 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); | 206 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); |
205 | 207 | ||
206 | read_unlock(&sk->sk_callback_lock); | 208 | rcu_read_unlock(); |
207 | } | 209 | } |
208 | 210 | ||
209 | /** | 211 | /** |
@@ -225,7 +227,7 @@ static int dccp_wait_for_ccid(struct sock *sk, struct sk_buff *skb, int delay) | |||
225 | dccp_pr_debug("delayed send by %d msec\n", delay); | 227 | dccp_pr_debug("delayed send by %d msec\n", delay); |
226 | jiffdelay = msecs_to_jiffies(delay); | 228 | jiffdelay = msecs_to_jiffies(delay); |
227 | 229 | ||
228 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 230 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
229 | 231 | ||
230 | sk->sk_write_pending++; | 232 | sk->sk_write_pending++; |
231 | release_sock(sk); | 233 | release_sock(sk); |
@@ -241,7 +243,7 @@ static int dccp_wait_for_ccid(struct sock *sk, struct sk_buff *skb, int delay) | |||
241 | rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb); | 243 | rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb); |
242 | } while ((delay = rc) > 0); | 244 | } while ((delay = rc) > 0); |
243 | out: | 245 | out: |
244 | finish_wait(sk->sk_sleep, &wait); | 246 | finish_wait(sk_sleep(sk), &wait); |
245 | return rc; | 247 | return rc; |
246 | 248 | ||
247 | do_error: | 249 | do_error: |
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index a0e38d8018f5..b03ecf6b2bb0 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -312,7 +312,7 @@ unsigned int dccp_poll(struct file *file, struct socket *sock, | |||
312 | unsigned int mask; | 312 | unsigned int mask; |
313 | struct sock *sk = sock->sk; | 313 | struct sock *sk = sock->sk; |
314 | 314 | ||
315 | sock_poll_wait(file, sk->sk_sleep, wait); | 315 | sock_poll_wait(file, sk_sleep(sk), wait); |
316 | if (sk->sk_state == DCCP_LISTEN) | 316 | if (sk->sk_state == DCCP_LISTEN) |
317 | return inet_csk_listen_poll(sk); | 317 | return inet_csk_listen_poll(sk); |
318 | 318 | ||
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 55e3b6b0061a..d6b93d19790f 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
@@ -832,7 +832,7 @@ static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation) | |||
832 | scp->segsize_loc = dst_metric(__sk_dst_get(sk), RTAX_ADVMSS); | 832 | scp->segsize_loc = dst_metric(__sk_dst_get(sk), RTAX_ADVMSS); |
833 | dn_send_conn_conf(sk, allocation); | 833 | dn_send_conn_conf(sk, allocation); |
834 | 834 | ||
835 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 835 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
836 | for(;;) { | 836 | for(;;) { |
837 | release_sock(sk); | 837 | release_sock(sk); |
838 | if (scp->state == DN_CC) | 838 | if (scp->state == DN_CC) |
@@ -850,9 +850,9 @@ static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation) | |||
850 | err = -EAGAIN; | 850 | err = -EAGAIN; |
851 | if (!*timeo) | 851 | if (!*timeo) |
852 | break; | 852 | break; |
853 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 853 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
854 | } | 854 | } |
855 | finish_wait(sk->sk_sleep, &wait); | 855 | finish_wait(sk_sleep(sk), &wait); |
856 | if (err == 0) { | 856 | if (err == 0) { |
857 | sk->sk_socket->state = SS_CONNECTED; | 857 | sk->sk_socket->state = SS_CONNECTED; |
858 | } else if (scp->state != DN_CC) { | 858 | } else if (scp->state != DN_CC) { |
@@ -873,7 +873,7 @@ static int dn_wait_run(struct sock *sk, long *timeo) | |||
873 | if (!*timeo) | 873 | if (!*timeo) |
874 | return -EALREADY; | 874 | return -EALREADY; |
875 | 875 | ||
876 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 876 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
877 | for(;;) { | 877 | for(;;) { |
878 | release_sock(sk); | 878 | release_sock(sk); |
879 | if (scp->state == DN_CI || scp->state == DN_CC) | 879 | if (scp->state == DN_CI || scp->state == DN_CC) |
@@ -891,9 +891,9 @@ static int dn_wait_run(struct sock *sk, long *timeo) | |||
891 | err = -ETIMEDOUT; | 891 | err = -ETIMEDOUT; |
892 | if (!*timeo) | 892 | if (!*timeo) |
893 | break; | 893 | break; |
894 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 894 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
895 | } | 895 | } |
896 | finish_wait(sk->sk_sleep, &wait); | 896 | finish_wait(sk_sleep(sk), &wait); |
897 | out: | 897 | out: |
898 | if (err == 0) { | 898 | if (err == 0) { |
899 | sk->sk_socket->state = SS_CONNECTED; | 899 | sk->sk_socket->state = SS_CONNECTED; |
@@ -1040,7 +1040,7 @@ static struct sk_buff *dn_wait_for_connect(struct sock *sk, long *timeo) | |||
1040 | struct sk_buff *skb = NULL; | 1040 | struct sk_buff *skb = NULL; |
1041 | int err = 0; | 1041 | int err = 0; |
1042 | 1042 | ||
1043 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 1043 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
1044 | for(;;) { | 1044 | for(;;) { |
1045 | release_sock(sk); | 1045 | release_sock(sk); |
1046 | skb = skb_dequeue(&sk->sk_receive_queue); | 1046 | skb = skb_dequeue(&sk->sk_receive_queue); |
@@ -1060,9 +1060,9 @@ static struct sk_buff *dn_wait_for_connect(struct sock *sk, long *timeo) | |||
1060 | err = -EAGAIN; | 1060 | err = -EAGAIN; |
1061 | if (!*timeo) | 1061 | if (!*timeo) |
1062 | break; | 1062 | break; |
1063 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 1063 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
1064 | } | 1064 | } |
1065 | finish_wait(sk->sk_sleep, &wait); | 1065 | finish_wait(sk_sleep(sk), &wait); |
1066 | 1066 | ||
1067 | return skb == NULL ? ERR_PTR(err) : skb; | 1067 | return skb == NULL ? ERR_PTR(err) : skb; |
1068 | } | 1068 | } |
@@ -1746,11 +1746,11 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1746 | goto out; | 1746 | goto out; |
1747 | } | 1747 | } |
1748 | 1748 | ||
1749 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 1749 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
1750 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 1750 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); |
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 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); |
1753 | finish_wait(sk->sk_sleep, &wait); | 1753 | finish_wait(sk_sleep(sk), &wait); |
1754 | } | 1754 | } |
1755 | 1755 | ||
1756 | skb_queue_walk_safe(queue, skb, n) { | 1756 | skb_queue_walk_safe(queue, skb, n) { |
@@ -2003,12 +2003,12 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
2003 | goto out; | 2003 | goto out; |
2004 | } | 2004 | } |
2005 | 2005 | ||
2006 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 2006 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
2007 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 2007 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); |
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 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); |
2011 | finish_wait(sk->sk_sleep, &wait); | 2011 | finish_wait(sk_sleep(sk), &wait); |
2012 | continue; | 2012 | continue; |
2013 | } | 2013 | } |
2014 | 2014 | ||
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index af28dcc21844..48fdf10be7a1 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c | |||
@@ -216,8 +216,8 @@ static void dn_fib_rule_flush_cache(struct fib_rules_ops *ops) | |||
216 | dn_rt_cache_flush(-1); | 216 | dn_rt_cache_flush(-1); |
217 | } | 217 | } |
218 | 218 | ||
219 | static struct fib_rules_ops dn_fib_rules_ops_template = { | 219 | static const struct fib_rules_ops __net_initdata dn_fib_rules_ops_template = { |
220 | .family = FIB_RULES_DECNET, | 220 | .family = AF_DECnet, |
221 | .rule_size = sizeof(struct dn_fib_rule), | 221 | .rule_size = sizeof(struct dn_fib_rule), |
222 | .addr_size = sizeof(u16), | 222 | .addr_size = sizeof(u16), |
223 | .action = dn_fib_rule_action, | 223 | .action = dn_fib_rule_action, |
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 205a1c12f3c0..61ec0329316c 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c | |||
@@ -136,7 +136,7 @@ int eth_rebuild_header(struct sk_buff *skb) | |||
136 | default: | 136 | default: |
137 | printk(KERN_DEBUG | 137 | printk(KERN_DEBUG |
138 | "%s: unable to resolve type %X addresses.\n", | 138 | "%s: unable to resolve type %X addresses.\n", |
139 | dev->name, (int)eth->h_proto); | 139 | dev->name, ntohs(eth->h_proto)); |
140 | 140 | ||
141 | memcpy(eth->h_source, dev->dev_addr, ETH_ALEN); | 141 | memcpy(eth->h_source, dev->dev_addr, ETH_ALEN); |
142 | break; | 142 | break; |
@@ -162,7 +162,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev) | |||
162 | 162 | ||
163 | skb->dev = dev; | 163 | skb->dev = dev; |
164 | skb_reset_mac_header(skb); | 164 | skb_reset_mac_header(skb); |
165 | skb_pull(skb, ETH_HLEN); | 165 | skb_pull_inline(skb, ETH_HLEN); |
166 | eth = eth_hdr(skb); | 166 | eth = eth_hdr(skb); |
167 | 167 | ||
168 | if (unlikely(is_multicast_ether_addr(eth->h_dest))) { | 168 | if (unlikely(is_multicast_ether_addr(eth->h_dest))) { |
diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c index c7da600750bb..93c91b633a56 100644 --- a/net/ieee802154/af_ieee802154.c +++ b/net/ieee802154/af_ieee802154.c | |||
@@ -151,6 +151,9 @@ static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg, | |||
151 | dev_load(sock_net(sk), ifr.ifr_name); | 151 | dev_load(sock_net(sk), ifr.ifr_name); |
152 | dev = dev_get_by_name(sock_net(sk), ifr.ifr_name); | 152 | dev = dev_get_by_name(sock_net(sk), ifr.ifr_name); |
153 | 153 | ||
154 | if (!dev) | ||
155 | return -ENODEV; | ||
156 | |||
154 | if (dev->type == ARPHRD_IEEE802154 && dev->netdev_ops->ndo_do_ioctl) | 157 | if (dev->type == ARPHRD_IEEE802154 && dev->netdev_ops->ndo_do_ioctl) |
155 | ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd); | 158 | ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd); |
156 | 159 | ||
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index c5376c725503..c6c43bcd1c6f 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -419,7 +419,7 @@ int inet_release(struct socket *sock) | |||
419 | if (sk) { | 419 | if (sk) { |
420 | long timeout; | 420 | long timeout; |
421 | 421 | ||
422 | inet_rps_reset_flow(sk); | 422 | sock_rps_reset_flow(sk); |
423 | 423 | ||
424 | /* Applications forget to leave groups before exiting */ | 424 | /* Applications forget to leave groups before exiting */ |
425 | ip_mc_drop_socket(sk); | 425 | ip_mc_drop_socket(sk); |
@@ -548,7 +548,7 @@ static long inet_wait_for_connect(struct sock *sk, long timeo) | |||
548 | { | 548 | { |
549 | DEFINE_WAIT(wait); | 549 | DEFINE_WAIT(wait); |
550 | 550 | ||
551 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 551 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
552 | 552 | ||
553 | /* Basic assumption: if someone sets sk->sk_err, he _must_ | 553 | /* Basic assumption: if someone sets sk->sk_err, he _must_ |
554 | * change state of the socket from TCP_SYN_*. | 554 | * change state of the socket from TCP_SYN_*. |
@@ -561,9 +561,9 @@ static long inet_wait_for_connect(struct sock *sk, long timeo) | |||
561 | lock_sock(sk); | 561 | lock_sock(sk); |
562 | if (signal_pending(current) || !timeo) | 562 | if (signal_pending(current) || !timeo) |
563 | break; | 563 | break; |
564 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 564 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
565 | } | 565 | } |
566 | finish_wait(sk->sk_sleep, &wait); | 566 | finish_wait(sk_sleep(sk), &wait); |
567 | return timeo; | 567 | return timeo; |
568 | } | 568 | } |
569 | 569 | ||
@@ -722,7 +722,7 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
722 | { | 722 | { |
723 | struct sock *sk = sock->sk; | 723 | struct sock *sk = sock->sk; |
724 | 724 | ||
725 | inet_rps_record_flow(sk); | 725 | sock_rps_record_flow(sk); |
726 | 726 | ||
727 | /* We may need to bind the socket. */ | 727 | /* We may need to bind the socket. */ |
728 | if (!inet_sk(sk)->inet_num && inet_autobind(sk)) | 728 | if (!inet_sk(sk)->inet_num && inet_autobind(sk)) |
@@ -737,7 +737,7 @@ static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, | |||
737 | { | 737 | { |
738 | struct sock *sk = sock->sk; | 738 | struct sock *sk = sock->sk; |
739 | 739 | ||
740 | inet_rps_record_flow(sk); | 740 | sock_rps_record_flow(sk); |
741 | 741 | ||
742 | /* We may need to bind the socket. */ | 742 | /* We may need to bind the socket. */ |
743 | if (!inet_sk(sk)->inet_num && inet_autobind(sk)) | 743 | if (!inet_sk(sk)->inet_num && inet_autobind(sk)) |
@@ -755,7 +755,7 @@ int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
755 | int addr_len = 0; | 755 | int addr_len = 0; |
756 | int err; | 756 | int err; |
757 | 757 | ||
758 | inet_rps_record_flow(sk); | 758 | sock_rps_record_flow(sk); |
759 | 759 | ||
760 | err = sk->sk_prot->recvmsg(iocb, sk, msg, size, flags & MSG_DONTWAIT, | 760 | err = sk->sk_prot->recvmsg(iocb, sk, msg, size, flags & MSG_DONTWAIT, |
761 | flags & ~MSG_DONTWAIT, &addr_len); | 761 | flags & ~MSG_DONTWAIT, &addr_len); |
@@ -1323,8 +1323,8 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head, | |||
1323 | if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl))) | 1323 | if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl))) |
1324 | goto out_unlock; | 1324 | goto out_unlock; |
1325 | 1325 | ||
1326 | id = ntohl(*(u32 *)&iph->id); | 1326 | id = ntohl(*(__be32 *)&iph->id); |
1327 | flush = (u16)((ntohl(*(u32 *)iph) ^ skb_gro_len(skb)) | (id ^ IP_DF)); | 1327 | flush = (u16)((ntohl(*(__be32 *)iph) ^ skb_gro_len(skb)) | (id ^ IP_DF)); |
1328 | id >>= 16; | 1328 | id >>= 16; |
1329 | 1329 | ||
1330 | for (p = *head; p; p = p->next) { | 1330 | for (p = *head; p; p = p->next) { |
@@ -1337,8 +1337,8 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head, | |||
1337 | 1337 | ||
1338 | if ((iph->protocol ^ iph2->protocol) | | 1338 | if ((iph->protocol ^ iph2->protocol) | |
1339 | (iph->tos ^ iph2->tos) | | 1339 | (iph->tos ^ iph2->tos) | |
1340 | (iph->saddr ^ iph2->saddr) | | 1340 | ((__force u32)iph->saddr ^ (__force u32)iph2->saddr) | |
1341 | (iph->daddr ^ iph2->daddr)) { | 1341 | ((__force u32)iph->daddr ^ (__force u32)iph2->daddr)) { |
1342 | NAPI_GRO_CB(p)->same_flow = 0; | 1342 | NAPI_GRO_CB(p)->same_flow = 0; |
1343 | continue; | 1343 | continue; |
1344 | } | 1344 | } |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 3ec84fea5b71..76daeb5ff564 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -245,8 +245,8 @@ static void fib4_rule_flush_cache(struct fib_rules_ops *ops) | |||
245 | rt_cache_flush(ops->fro_net, -1); | 245 | rt_cache_flush(ops->fro_net, -1); |
246 | } | 246 | } |
247 | 247 | ||
248 | static struct fib_rules_ops fib4_rules_ops_template = { | 248 | static const struct fib_rules_ops __net_initdata fib4_rules_ops_template = { |
249 | .family = FIB_RULES_IPV4, | 249 | .family = AF_INET, |
250 | .rule_size = sizeof(struct fib4_rule), | 250 | .rule_size = sizeof(struct fib4_rule), |
251 | .addr_size = sizeof(u32), | 251 | .addr_size = sizeof(u32), |
252 | .action = fib4_rule_action, | 252 | .action = fib4_rule_action, |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 59a838795e3e..c98f115fb0fd 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -209,7 +209,9 @@ static inline struct node *tnode_get_child_rcu(struct tnode *tn, unsigned int i) | |||
209 | { | 209 | { |
210 | struct node *ret = tnode_get_child(tn, i); | 210 | struct node *ret = tnode_get_child(tn, i); |
211 | 211 | ||
212 | return rcu_dereference(ret); | 212 | return rcu_dereference_check(ret, |
213 | rcu_read_lock_held() || | ||
214 | lockdep_rtnl_is_held()); | ||
213 | } | 215 | } |
214 | 216 | ||
215 | static inline int tnode_child_length(const struct tnode *tn) | 217 | static inline int tnode_child_length(const struct tnode *tn) |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 8da6429269dd..e0a3e3537b14 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -234,7 +234,7 @@ static int inet_csk_wait_for_connect(struct sock *sk, long timeo) | |||
234 | * having to remove and re-insert us on the wait queue. | 234 | * having to remove and re-insert us on the wait queue. |
235 | */ | 235 | */ |
236 | for (;;) { | 236 | for (;;) { |
237 | prepare_to_wait_exclusive(sk->sk_sleep, &wait, | 237 | prepare_to_wait_exclusive(sk_sleep(sk), &wait, |
238 | TASK_INTERRUPTIBLE); | 238 | TASK_INTERRUPTIBLE); |
239 | release_sock(sk); | 239 | release_sock(sk); |
240 | if (reqsk_queue_empty(&icsk->icsk_accept_queue)) | 240 | if (reqsk_queue_empty(&icsk->icsk_accept_queue)) |
@@ -253,7 +253,7 @@ static int inet_csk_wait_for_connect(struct sock *sk, long timeo) | |||
253 | if (!timeo) | 253 | if (!timeo) |
254 | break; | 254 | break; |
255 | } | 255 | } |
256 | finish_wait(sk->sk_sleep, &wait); | 256 | finish_wait(sk_sleep(sk), &wait); |
257 | return err; | 257 | return err; |
258 | } | 258 | } |
259 | 259 | ||
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index d979710684b2..252897443ef9 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -120,7 +120,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb) | |||
120 | newskb->pkt_type = PACKET_LOOPBACK; | 120 | newskb->pkt_type = PACKET_LOOPBACK; |
121 | newskb->ip_summed = CHECKSUM_UNNECESSARY; | 121 | newskb->ip_summed = CHECKSUM_UNNECESSARY; |
122 | WARN_ON(!skb_dst(newskb)); | 122 | WARN_ON(!skb_dst(newskb)); |
123 | netif_rx(newskb); | 123 | netif_rx_ni(newskb); |
124 | return 0; | 124 | return 0; |
125 | } | 125 | } |
126 | 126 | ||
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index b0aa0546a3b3..ce231780a2b1 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -954,6 +954,22 @@ e_inval: | |||
954 | return -EINVAL; | 954 | return -EINVAL; |
955 | } | 955 | } |
956 | 956 | ||
957 | /** | ||
958 | * ip_queue_rcv_skb - Queue an skb into sock receive queue | ||
959 | * @sk: socket | ||
960 | * @skb: buffer | ||
961 | * | ||
962 | * Queues an skb into socket receive queue. If IP_CMSG_PKTINFO option | ||
963 | * is not set, we drop skb dst entry now, while dst cache line is hot. | ||
964 | */ | ||
965 | int ip_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | ||
966 | { | ||
967 | if (!(inet_sk(sk)->cmsg_flags & IP_CMSG_PKTINFO)) | ||
968 | skb_dst_drop(skb); | ||
969 | return sock_queue_rcv_skb(sk, skb); | ||
970 | } | ||
971 | EXPORT_SYMBOL(ip_queue_rcv_skb); | ||
972 | |||
957 | int ip_setsockopt(struct sock *sk, int level, | 973 | int ip_setsockopt(struct sock *sk, int level, |
958 | int optname, char __user *optval, unsigned int optlen) | 974 | int optname, char __user *optval, unsigned int optlen) |
959 | { | 975 | { |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 1aa498d7a0a5..f3f1c6b5c70c 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -128,8 +128,8 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt, | |||
128 | int local); | 128 | int local); |
129 | static int ipmr_cache_report(struct mr_table *mrt, | 129 | static int ipmr_cache_report(struct mr_table *mrt, |
130 | struct sk_buff *pkt, vifi_t vifi, int assert); | 130 | struct sk_buff *pkt, vifi_t vifi, int assert); |
131 | static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, | 131 | static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, |
132 | struct mfc_cache *c, struct rtmsg *rtm); | 132 | struct mfc_cache *c, struct rtmsg *rtm); |
133 | static void ipmr_expire_process(unsigned long arg); | 133 | static void ipmr_expire_process(unsigned long arg); |
134 | 134 | ||
135 | #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES | 135 | #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES |
@@ -216,8 +216,8 @@ static int ipmr_rule_fill(struct fib_rule *rule, struct sk_buff *skb, | |||
216 | return 0; | 216 | return 0; |
217 | } | 217 | } |
218 | 218 | ||
219 | static struct fib_rules_ops ipmr_rules_ops_template = { | 219 | static const struct fib_rules_ops __net_initdata ipmr_rules_ops_template = { |
220 | .family = FIB_RULES_IPMR, | 220 | .family = RTNL_FAMILY_IPMR, |
221 | .rule_size = sizeof(struct ipmr_rule), | 221 | .rule_size = sizeof(struct ipmr_rule), |
222 | .addr_size = sizeof(u32), | 222 | .addr_size = sizeof(u32), |
223 | .action = ipmr_rule_action, | 223 | .action = ipmr_rule_action, |
@@ -831,7 +831,7 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt, | |||
831 | if (ip_hdr(skb)->version == 0) { | 831 | if (ip_hdr(skb)->version == 0) { |
832 | struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr)); | 832 | struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr)); |
833 | 833 | ||
834 | if (ipmr_fill_mroute(mrt, skb, c, NLMSG_DATA(nlh)) > 0) { | 834 | if (__ipmr_fill_mroute(mrt, skb, c, NLMSG_DATA(nlh)) > 0) { |
835 | nlh->nlmsg_len = (skb_tail_pointer(skb) - | 835 | nlh->nlmsg_len = (skb_tail_pointer(skb) - |
836 | (u8 *)nlh); | 836 | (u8 *)nlh); |
837 | } else { | 837 | } else { |
@@ -1772,10 +1772,10 @@ int ip_mr_input(struct sk_buff *skb) | |||
1772 | 1772 | ||
1773 | vif = ipmr_find_vif(mrt, skb->dev); | 1773 | vif = ipmr_find_vif(mrt, skb->dev); |
1774 | if (vif >= 0) { | 1774 | if (vif >= 0) { |
1775 | int err = ipmr_cache_unresolved(mrt, vif, skb); | 1775 | int err2 = ipmr_cache_unresolved(mrt, vif, skb); |
1776 | read_unlock(&mrt_lock); | 1776 | read_unlock(&mrt_lock); |
1777 | 1777 | ||
1778 | return err; | 1778 | return err2; |
1779 | } | 1779 | } |
1780 | read_unlock(&mrt_lock); | 1780 | read_unlock(&mrt_lock); |
1781 | kfree_skb(skb); | 1781 | kfree_skb(skb); |
@@ -1904,9 +1904,8 @@ drop: | |||
1904 | } | 1904 | } |
1905 | #endif | 1905 | #endif |
1906 | 1906 | ||
1907 | static int | 1907 | static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, |
1908 | ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, struct mfc_cache *c, | 1908 | struct mfc_cache *c, struct rtmsg *rtm) |
1909 | struct rtmsg *rtm) | ||
1910 | { | 1909 | { |
1911 | int ct; | 1910 | int ct; |
1912 | struct rtnexthop *nhp; | 1911 | struct rtnexthop *nhp; |
@@ -1994,11 +1993,93 @@ int ipmr_get_route(struct net *net, | |||
1994 | 1993 | ||
1995 | if (!nowait && (rtm->rtm_flags&RTM_F_NOTIFY)) | 1994 | if (!nowait && (rtm->rtm_flags&RTM_F_NOTIFY)) |
1996 | cache->mfc_flags |= MFC_NOTIFY; | 1995 | cache->mfc_flags |= MFC_NOTIFY; |
1997 | err = ipmr_fill_mroute(mrt, skb, cache, rtm); | 1996 | err = __ipmr_fill_mroute(mrt, skb, cache, rtm); |
1998 | read_unlock(&mrt_lock); | 1997 | read_unlock(&mrt_lock); |
1999 | return err; | 1998 | return err; |
2000 | } | 1999 | } |
2001 | 2000 | ||
2001 | static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, | ||
2002 | u32 pid, u32 seq, struct mfc_cache *c) | ||
2003 | { | ||
2004 | struct nlmsghdr *nlh; | ||
2005 | struct rtmsg *rtm; | ||
2006 | |||
2007 | nlh = nlmsg_put(skb, pid, seq, RTM_NEWROUTE, sizeof(*rtm), NLM_F_MULTI); | ||
2008 | if (nlh == NULL) | ||
2009 | return -EMSGSIZE; | ||
2010 | |||
2011 | rtm = nlmsg_data(nlh); | ||
2012 | rtm->rtm_family = RTNL_FAMILY_IPMR; | ||
2013 | rtm->rtm_dst_len = 32; | ||
2014 | rtm->rtm_src_len = 32; | ||
2015 | rtm->rtm_tos = 0; | ||
2016 | rtm->rtm_table = mrt->id; | ||
2017 | NLA_PUT_U32(skb, RTA_TABLE, mrt->id); | ||
2018 | rtm->rtm_type = RTN_MULTICAST; | ||
2019 | rtm->rtm_scope = RT_SCOPE_UNIVERSE; | ||
2020 | rtm->rtm_protocol = RTPROT_UNSPEC; | ||
2021 | rtm->rtm_flags = 0; | ||
2022 | |||
2023 | NLA_PUT_BE32(skb, RTA_SRC, c->mfc_origin); | ||
2024 | NLA_PUT_BE32(skb, RTA_DST, c->mfc_mcastgrp); | ||
2025 | |||
2026 | if (__ipmr_fill_mroute(mrt, skb, c, rtm) < 0) | ||
2027 | goto nla_put_failure; | ||
2028 | |||
2029 | return nlmsg_end(skb, nlh); | ||
2030 | |||
2031 | nla_put_failure: | ||
2032 | nlmsg_cancel(skb, nlh); | ||
2033 | return -EMSGSIZE; | ||
2034 | } | ||
2035 | |||
2036 | static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb) | ||
2037 | { | ||
2038 | struct net *net = sock_net(skb->sk); | ||
2039 | struct mr_table *mrt; | ||
2040 | struct mfc_cache *mfc; | ||
2041 | unsigned int t = 0, s_t; | ||
2042 | unsigned int h = 0, s_h; | ||
2043 | unsigned int e = 0, s_e; | ||
2044 | |||
2045 | s_t = cb->args[0]; | ||
2046 | s_h = cb->args[1]; | ||
2047 | s_e = cb->args[2]; | ||
2048 | |||
2049 | read_lock(&mrt_lock); | ||
2050 | ipmr_for_each_table(mrt, net) { | ||
2051 | if (t < s_t) | ||
2052 | goto next_table; | ||
2053 | if (t > s_t) | ||
2054 | s_h = 0; | ||
2055 | for (h = s_h; h < MFC_LINES; h++) { | ||
2056 | list_for_each_entry(mfc, &mrt->mfc_cache_array[h], list) { | ||
2057 | if (e < s_e) | ||
2058 | goto next_entry; | ||
2059 | if (ipmr_fill_mroute(mrt, skb, | ||
2060 | NETLINK_CB(cb->skb).pid, | ||
2061 | cb->nlh->nlmsg_seq, | ||
2062 | mfc) < 0) | ||
2063 | goto done; | ||
2064 | next_entry: | ||
2065 | e++; | ||
2066 | } | ||
2067 | e = s_e = 0; | ||
2068 | } | ||
2069 | s_h = 0; | ||
2070 | next_table: | ||
2071 | t++; | ||
2072 | } | ||
2073 | done: | ||
2074 | read_unlock(&mrt_lock); | ||
2075 | |||
2076 | cb->args[2] = e; | ||
2077 | cb->args[1] = h; | ||
2078 | cb->args[0] = t; | ||
2079 | |||
2080 | return skb->len; | ||
2081 | } | ||
2082 | |||
2002 | #ifdef CONFIG_PROC_FS | 2083 | #ifdef CONFIG_PROC_FS |
2003 | /* | 2084 | /* |
2004 | * The /proc interfaces to multicast routing /proc/ip_mr_cache /proc/ip_mr_vif | 2085 | * The /proc interfaces to multicast routing /proc/ip_mr_cache /proc/ip_mr_vif |
@@ -2227,9 +2308,9 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) | |||
2227 | const struct ipmr_mfc_iter *it = seq->private; | 2308 | const struct ipmr_mfc_iter *it = seq->private; |
2228 | const struct mr_table *mrt = it->mrt; | 2309 | const struct mr_table *mrt = it->mrt; |
2229 | 2310 | ||
2230 | seq_printf(seq, "%08lX %08lX %-3hd", | 2311 | seq_printf(seq, "%08X %08X %-3hd", |
2231 | (unsigned long) mfc->mfc_mcastgrp, | 2312 | (__force u32) mfc->mfc_mcastgrp, |
2232 | (unsigned long) mfc->mfc_origin, | 2313 | (__force u32) mfc->mfc_origin, |
2233 | mfc->mfc_parent); | 2314 | mfc->mfc_parent); |
2234 | 2315 | ||
2235 | if (it->cache != &mrt->mfc_unres_queue) { | 2316 | if (it->cache != &mrt->mfc_unres_queue) { |
@@ -2355,6 +2436,7 @@ int __init ip_mr_init(void) | |||
2355 | goto add_proto_fail; | 2436 | goto add_proto_fail; |
2356 | } | 2437 | } |
2357 | #endif | 2438 | #endif |
2439 | rtnl_register(RTNL_FAMILY_IPMR, RTM_GETROUTE, NULL, ipmr_rtm_dumproute); | ||
2358 | return 0; | 2440 | return 0; |
2359 | 2441 | ||
2360 | #ifdef CONFIG_IP_PIMSM_V2 | 2442 | #ifdef CONFIG_IP_PIMSM_V2 |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index bbda0d5f9244..2c7a1639388a 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -290,7 +290,7 @@ static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb) | |||
290 | { | 290 | { |
291 | /* Charge it to the socket. */ | 291 | /* Charge it to the socket. */ |
292 | 292 | ||
293 | if (sock_queue_rcv_skb(sk, skb) < 0) { | 293 | if (ip_queue_rcv_skb(sk, skb) < 0) { |
294 | kfree_skb(skb); | 294 | kfree_skb(skb); |
295 | return NET_RX_DROP; | 295 | return NET_RX_DROP; |
296 | } | 296 | } |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index cb562fdd9b9a..dea3f9264250 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -129,7 +129,6 @@ static int ip_rt_gc_elasticity __read_mostly = 8; | |||
129 | static int ip_rt_mtu_expires __read_mostly = 10 * 60 * HZ; | 129 | static int ip_rt_mtu_expires __read_mostly = 10 * 60 * HZ; |
130 | static int ip_rt_min_pmtu __read_mostly = 512 + 20 + 20; | 130 | static int ip_rt_min_pmtu __read_mostly = 512 + 20 + 20; |
131 | static int ip_rt_min_advmss __read_mostly = 256; | 131 | static int ip_rt_min_advmss __read_mostly = 256; |
132 | static int ip_rt_secret_interval __read_mostly = 10 * 60 * HZ; | ||
133 | static int rt_chain_length_max __read_mostly = 20; | 132 | static int rt_chain_length_max __read_mostly = 20; |
134 | 133 | ||
135 | static struct delayed_work expires_work; | 134 | static struct delayed_work expires_work; |
@@ -258,10 +257,9 @@ static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat); | |||
258 | (__raw_get_cpu_var(rt_cache_stat).field++) | 257 | (__raw_get_cpu_var(rt_cache_stat).field++) |
259 | 258 | ||
260 | static inline unsigned int rt_hash(__be32 daddr, __be32 saddr, int idx, | 259 | static inline unsigned int rt_hash(__be32 daddr, __be32 saddr, int idx, |
261 | int genid) | 260 | int genid) |
262 | { | 261 | { |
263 | return jhash_3words((__force u32)(__be32)(daddr), | 262 | return jhash_3words((__force u32)daddr, (__force u32)saddr, |
264 | (__force u32)(__be32)(saddr), | ||
265 | idx, genid) | 263 | idx, genid) |
266 | & rt_hash_mask; | 264 | & rt_hash_mask; |
267 | } | 265 | } |
@@ -378,12 +376,13 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v) | |||
378 | struct rtable *r = v; | 376 | struct rtable *r = v; |
379 | int len; | 377 | int len; |
380 | 378 | ||
381 | seq_printf(seq, "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t" | 379 | seq_printf(seq, "%s\t%08X\t%08X\t%8X\t%d\t%u\t%d\t" |
382 | "%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X%n", | 380 | "%08X\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X%n", |
383 | r->u.dst.dev ? r->u.dst.dev->name : "*", | 381 | r->u.dst.dev ? r->u.dst.dev->name : "*", |
384 | (unsigned long)r->rt_dst, (unsigned long)r->rt_gateway, | 382 | (__force u32)r->rt_dst, |
383 | (__force u32)r->rt_gateway, | ||
385 | r->rt_flags, atomic_read(&r->u.dst.__refcnt), | 384 | r->rt_flags, atomic_read(&r->u.dst.__refcnt), |
386 | r->u.dst.__use, 0, (unsigned long)r->rt_src, | 385 | r->u.dst.__use, 0, (__force u32)r->rt_src, |
387 | (dst_metric(&r->u.dst, RTAX_ADVMSS) ? | 386 | (dst_metric(&r->u.dst, RTAX_ADVMSS) ? |
388 | (int)dst_metric(&r->u.dst, RTAX_ADVMSS) + 40 : 0), | 387 | (int)dst_metric(&r->u.dst, RTAX_ADVMSS) + 40 : 0), |
389 | dst_metric(&r->u.dst, RTAX_WINDOW), | 388 | dst_metric(&r->u.dst, RTAX_WINDOW), |
@@ -685,18 +684,17 @@ static inline bool rt_caching(const struct net *net) | |||
685 | static inline bool compare_hash_inputs(const struct flowi *fl1, | 684 | static inline bool compare_hash_inputs(const struct flowi *fl1, |
686 | const struct flowi *fl2) | 685 | const struct flowi *fl2) |
687 | { | 686 | { |
688 | return (__force u32)(((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) | | 687 | return ((((__force u32)fl1->nl_u.ip4_u.daddr ^ (__force u32)fl2->nl_u.ip4_u.daddr) | |
689 | (fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr) | | 688 | ((__force u32)fl1->nl_u.ip4_u.saddr ^ (__force u32)fl2->nl_u.ip4_u.saddr) | |
690 | (fl1->iif ^ fl2->iif)) == 0); | 689 | (fl1->iif ^ fl2->iif)) == 0); |
691 | } | 690 | } |
692 | 691 | ||
693 | static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) | 692 | static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) |
694 | { | 693 | { |
695 | return ((__force u32)((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) | | 694 | return (((__force u32)fl1->nl_u.ip4_u.daddr ^ (__force u32)fl2->nl_u.ip4_u.daddr) | |
696 | (fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr)) | | 695 | ((__force u32)fl1->nl_u.ip4_u.saddr ^ (__force u32)fl2->nl_u.ip4_u.saddr) | |
697 | (fl1->mark ^ fl2->mark) | | 696 | (fl1->mark ^ fl2->mark) | |
698 | (*(u16 *)&fl1->nl_u.ip4_u.tos ^ | 697 | (*(u16 *)&fl1->nl_u.ip4_u.tos ^ *(u16 *)&fl2->nl_u.ip4_u.tos) | |
699 | *(u16 *)&fl2->nl_u.ip4_u.tos) | | ||
700 | (fl1->oif ^ fl2->oif) | | 698 | (fl1->oif ^ fl2->oif) | |
701 | (fl1->iif ^ fl2->iif)) == 0; | 699 | (fl1->iif ^ fl2->iif)) == 0; |
702 | } | 700 | } |
@@ -919,32 +917,11 @@ void rt_cache_flush_batch(void) | |||
919 | rt_do_flush(!in_softirq()); | 917 | rt_do_flush(!in_softirq()); |
920 | } | 918 | } |
921 | 919 | ||
922 | /* | ||
923 | * We change rt_genid and let gc do the cleanup | ||
924 | */ | ||
925 | static void rt_secret_rebuild(unsigned long __net) | ||
926 | { | ||
927 | struct net *net = (struct net *)__net; | ||
928 | rt_cache_invalidate(net); | ||
929 | mod_timer(&net->ipv4.rt_secret_timer, jiffies + ip_rt_secret_interval); | ||
930 | } | ||
931 | |||
932 | static void rt_secret_rebuild_oneshot(struct net *net) | ||
933 | { | ||
934 | del_timer_sync(&net->ipv4.rt_secret_timer); | ||
935 | rt_cache_invalidate(net); | ||
936 | if (ip_rt_secret_interval) | ||
937 | mod_timer(&net->ipv4.rt_secret_timer, jiffies + ip_rt_secret_interval); | ||
938 | } | ||
939 | |||
940 | static void rt_emergency_hash_rebuild(struct net *net) | 920 | static void rt_emergency_hash_rebuild(struct net *net) |
941 | { | 921 | { |
942 | if (net_ratelimit()) { | 922 | if (net_ratelimit()) |
943 | printk(KERN_WARNING "Route hash chain too long!\n"); | 923 | printk(KERN_WARNING "Route hash chain too long!\n"); |
944 | printk(KERN_WARNING "Adjust your secret_interval!\n"); | 924 | rt_cache_invalidate(net); |
945 | } | ||
946 | |||
947 | rt_secret_rebuild_oneshot(net); | ||
948 | } | 925 | } |
949 | 926 | ||
950 | /* | 927 | /* |
@@ -2319,8 +2296,8 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
2319 | rcu_read_lock(); | 2296 | rcu_read_lock(); |
2320 | for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; | 2297 | for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; |
2321 | rth = rcu_dereference(rth->u.dst.rt_next)) { | 2298 | rth = rcu_dereference(rth->u.dst.rt_next)) { |
2322 | if (((rth->fl.fl4_dst ^ daddr) | | 2299 | if ((((__force u32)rth->fl.fl4_dst ^ (__force u32)daddr) | |
2323 | (rth->fl.fl4_src ^ saddr) | | 2300 | ((__force u32)rth->fl.fl4_src ^ (__force u32)saddr) | |
2324 | (rth->fl.iif ^ iif) | | 2301 | (rth->fl.iif ^ iif) | |
2325 | rth->fl.oif | | 2302 | rth->fl.oif | |
2326 | (rth->fl.fl4_tos ^ tos)) == 0 && | 2303 | (rth->fl.fl4_tos ^ tos)) == 0 && |
@@ -3102,48 +3079,6 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write, | |||
3102 | return -EINVAL; | 3079 | return -EINVAL; |
3103 | } | 3080 | } |
3104 | 3081 | ||
3105 | static void rt_secret_reschedule(int old) | ||
3106 | { | ||
3107 | struct net *net; | ||
3108 | int new = ip_rt_secret_interval; | ||
3109 | int diff = new - old; | ||
3110 | |||
3111 | if (!diff) | ||
3112 | return; | ||
3113 | |||
3114 | rtnl_lock(); | ||
3115 | for_each_net(net) { | ||
3116 | int deleted = del_timer_sync(&net->ipv4.rt_secret_timer); | ||
3117 | long time; | ||
3118 | |||
3119 | if (!new) | ||
3120 | continue; | ||
3121 | |||
3122 | if (deleted) { | ||
3123 | time = net->ipv4.rt_secret_timer.expires - jiffies; | ||
3124 | |||
3125 | if (time <= 0 || (time += diff) <= 0) | ||
3126 | time = 0; | ||
3127 | } else | ||
3128 | time = new; | ||
3129 | |||
3130 | mod_timer(&net->ipv4.rt_secret_timer, jiffies + time); | ||
3131 | } | ||
3132 | rtnl_unlock(); | ||
3133 | } | ||
3134 | |||
3135 | static int ipv4_sysctl_rt_secret_interval(ctl_table *ctl, int write, | ||
3136 | void __user *buffer, size_t *lenp, | ||
3137 | loff_t *ppos) | ||
3138 | { | ||
3139 | int old = ip_rt_secret_interval; | ||
3140 | int ret = proc_dointvec_jiffies(ctl, write, buffer, lenp, ppos); | ||
3141 | |||
3142 | rt_secret_reschedule(old); | ||
3143 | |||
3144 | return ret; | ||
3145 | } | ||
3146 | |||
3147 | static ctl_table ipv4_route_table[] = { | 3082 | static ctl_table ipv4_route_table[] = { |
3148 | { | 3083 | { |
3149 | .procname = "gc_thresh", | 3084 | .procname = "gc_thresh", |
@@ -3252,13 +3187,6 @@ static ctl_table ipv4_route_table[] = { | |||
3252 | .mode = 0644, | 3187 | .mode = 0644, |
3253 | .proc_handler = proc_dointvec, | 3188 | .proc_handler = proc_dointvec, |
3254 | }, | 3189 | }, |
3255 | { | ||
3256 | .procname = "secret_interval", | ||
3257 | .data = &ip_rt_secret_interval, | ||
3258 | .maxlen = sizeof(int), | ||
3259 | .mode = 0644, | ||
3260 | .proc_handler = ipv4_sysctl_rt_secret_interval, | ||
3261 | }, | ||
3262 | { } | 3190 | { } |
3263 | }; | 3191 | }; |
3264 | 3192 | ||
@@ -3337,34 +3265,15 @@ static __net_initdata struct pernet_operations sysctl_route_ops = { | |||
3337 | }; | 3265 | }; |
3338 | #endif | 3266 | #endif |
3339 | 3267 | ||
3340 | 3268 | static __net_init int rt_genid_init(struct net *net) | |
3341 | static __net_init int rt_secret_timer_init(struct net *net) | ||
3342 | { | 3269 | { |
3343 | atomic_set(&net->ipv4.rt_genid, | 3270 | get_random_bytes(&net->ipv4.rt_genid, |
3344 | (int) ((num_physpages ^ (num_physpages>>8)) ^ | 3271 | sizeof(net->ipv4.rt_genid)); |
3345 | (jiffies ^ (jiffies >> 7)))); | ||
3346 | |||
3347 | net->ipv4.rt_secret_timer.function = rt_secret_rebuild; | ||
3348 | net->ipv4.rt_secret_timer.data = (unsigned long)net; | ||
3349 | init_timer_deferrable(&net->ipv4.rt_secret_timer); | ||
3350 | |||
3351 | if (ip_rt_secret_interval) { | ||
3352 | net->ipv4.rt_secret_timer.expires = | ||
3353 | jiffies + net_random() % ip_rt_secret_interval + | ||
3354 | ip_rt_secret_interval; | ||
3355 | add_timer(&net->ipv4.rt_secret_timer); | ||
3356 | } | ||
3357 | return 0; | 3272 | return 0; |
3358 | } | 3273 | } |
3359 | 3274 | ||
3360 | static __net_exit void rt_secret_timer_exit(struct net *net) | 3275 | static __net_initdata struct pernet_operations rt_genid_ops = { |
3361 | { | 3276 | .init = rt_genid_init, |
3362 | del_timer_sync(&net->ipv4.rt_secret_timer); | ||
3363 | } | ||
3364 | |||
3365 | static __net_initdata struct pernet_operations rt_secret_timer_ops = { | ||
3366 | .init = rt_secret_timer_init, | ||
3367 | .exit = rt_secret_timer_exit, | ||
3368 | }; | 3277 | }; |
3369 | 3278 | ||
3370 | 3279 | ||
@@ -3425,9 +3334,6 @@ int __init ip_rt_init(void) | |||
3425 | schedule_delayed_work(&expires_work, | 3334 | schedule_delayed_work(&expires_work, |
3426 | net_random() % ip_rt_gc_interval + ip_rt_gc_interval); | 3335 | net_random() % ip_rt_gc_interval + ip_rt_gc_interval); |
3427 | 3336 | ||
3428 | if (register_pernet_subsys(&rt_secret_timer_ops)) | ||
3429 | printk(KERN_ERR "Unable to setup rt_secret_timer\n"); | ||
3430 | |||
3431 | if (ip_rt_proc_init()) | 3337 | if (ip_rt_proc_init()) |
3432 | printk(KERN_ERR "Unable to create route proc files\n"); | 3338 | printk(KERN_ERR "Unable to create route proc files\n"); |
3433 | #ifdef CONFIG_XFRM | 3339 | #ifdef CONFIG_XFRM |
@@ -3439,6 +3345,7 @@ int __init ip_rt_init(void) | |||
3439 | #ifdef CONFIG_SYSCTL | 3345 | #ifdef CONFIG_SYSCTL |
3440 | register_pernet_subsys(&sysctl_route_ops); | 3346 | register_pernet_subsys(&sysctl_route_ops); |
3441 | #endif | 3347 | #endif |
3348 | register_pernet_subsys(&rt_genid_ops); | ||
3442 | return rc; | 3349 | return rc; |
3443 | } | 3350 | } |
3444 | 3351 | ||
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 0f8caf64caa3..8ce29747ad9b 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -378,7 +378,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
378 | struct sock *sk = sock->sk; | 378 | struct sock *sk = sock->sk; |
379 | struct tcp_sock *tp = tcp_sk(sk); | 379 | struct tcp_sock *tp = tcp_sk(sk); |
380 | 380 | ||
381 | sock_poll_wait(file, sk->sk_sleep, wait); | 381 | sock_poll_wait(file, sk_sleep(sk), wait); |
382 | if (sk->sk_state == TCP_LISTEN) | 382 | if (sk->sk_state == TCP_LISTEN) |
383 | return inet_csk_listen_poll(sk); | 383 | return inet_csk_listen_poll(sk); |
384 | 384 | ||
@@ -2298,7 +2298,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
2298 | if (sock_flag(sk, SOCK_KEEPOPEN) && | 2298 | if (sock_flag(sk, SOCK_KEEPOPEN) && |
2299 | !((1 << sk->sk_state) & | 2299 | !((1 << sk->sk_state) & |
2300 | (TCPF_CLOSE | TCPF_LISTEN))) { | 2300 | (TCPF_CLOSE | TCPF_LISTEN))) { |
2301 | __u32 elapsed = tcp_time_stamp - tp->rcv_tstamp; | 2301 | u32 elapsed = keepalive_time_elapsed(tp); |
2302 | if (tp->keepalive_time > elapsed) | 2302 | if (tp->keepalive_time > elapsed) |
2303 | elapsed = tp->keepalive_time - elapsed; | 2303 | elapsed = tp->keepalive_time - elapsed; |
2304 | else | 2304 | else |
@@ -2721,7 +2721,7 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
2721 | struct tcphdr *th2; | 2721 | struct tcphdr *th2; |
2722 | unsigned int len; | 2722 | unsigned int len; |
2723 | unsigned int thlen; | 2723 | unsigned int thlen; |
2724 | unsigned int flags; | 2724 | __be32 flags; |
2725 | unsigned int mss = 1; | 2725 | unsigned int mss = 1; |
2726 | unsigned int hlen; | 2726 | unsigned int hlen; |
2727 | unsigned int off; | 2727 | unsigned int off; |
@@ -2771,10 +2771,10 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
2771 | 2771 | ||
2772 | found: | 2772 | found: |
2773 | flush = NAPI_GRO_CB(p)->flush; | 2773 | flush = NAPI_GRO_CB(p)->flush; |
2774 | flush |= flags & TCP_FLAG_CWR; | 2774 | flush |= (__force int)(flags & TCP_FLAG_CWR); |
2775 | flush |= (flags ^ tcp_flag_word(th2)) & | 2775 | flush |= (__force int)((flags ^ tcp_flag_word(th2)) & |
2776 | ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH); | 2776 | ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH)); |
2777 | flush |= th->ack_seq ^ th2->ack_seq; | 2777 | flush |= (__force int)(th->ack_seq ^ th2->ack_seq); |
2778 | for (i = sizeof(*th); i < thlen; i += 4) | 2778 | for (i = sizeof(*th); i < thlen; i += 4) |
2779 | flush |= *(u32 *)((u8 *)th + i) ^ | 2779 | flush |= *(u32 *)((u8 *)th + i) ^ |
2780 | *(u32 *)((u8 *)th2 + i); | 2780 | *(u32 *)((u8 *)th2 + i); |
@@ -2795,8 +2795,9 @@ found: | |||
2795 | 2795 | ||
2796 | out_check_final: | 2796 | out_check_final: |
2797 | flush = len < mss; | 2797 | flush = len < mss; |
2798 | flush |= flags & (TCP_FLAG_URG | TCP_FLAG_PSH | TCP_FLAG_RST | | 2798 | flush |= (__force int)(flags & (TCP_FLAG_URG | TCP_FLAG_PSH | |
2799 | TCP_FLAG_SYN | TCP_FLAG_FIN); | 2799 | TCP_FLAG_RST | TCP_FLAG_SYN | |
2800 | TCP_FLAG_FIN)); | ||
2800 | 2801 | ||
2801 | if (p && (!NAPI_GRO_CB(skb)->same_flow || flush)) | 2802 | if (p && (!NAPI_GRO_CB(skb)->same_flow || flush)) |
2802 | pp = head; | 2803 | pp = head; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index ae3ec15fb630..e82162c211bf 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -4367,6 +4367,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) | |||
4367 | if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) | 4367 | if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) |
4368 | goto drop; | 4368 | goto drop; |
4369 | 4369 | ||
4370 | skb_dst_drop(skb); | ||
4370 | __skb_pull(skb, th->doff * 4); | 4371 | __skb_pull(skb, th->doff * 4); |
4371 | 4372 | ||
4372 | TCP_ECN_accept_cwr(tp, skb); | 4373 | TCP_ECN_accept_cwr(tp, skb); |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index ad08392a738c..771f8146a2e5 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -1286,8 +1286,8 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1286 | goto drop_and_release; | 1286 | goto drop_and_release; |
1287 | 1287 | ||
1288 | /* Secret recipe starts with IP addresses */ | 1288 | /* Secret recipe starts with IP addresses */ |
1289 | *mess++ ^= daddr; | 1289 | *mess++ ^= (__force u32)daddr; |
1290 | *mess++ ^= saddr; | 1290 | *mess++ ^= (__force u32)saddr; |
1291 | 1291 | ||
1292 | /* plus variable length Initiator Cookie */ | 1292 | /* plus variable length Initiator Cookie */ |
1293 | c = (u8 *)mess; | 1293 | c = (u8 *)mess; |
@@ -1672,7 +1672,7 @@ process: | |||
1672 | 1672 | ||
1673 | skb->dev = NULL; | 1673 | skb->dev = NULL; |
1674 | 1674 | ||
1675 | inet_rps_save_rxhash(sk, skb->rxhash); | 1675 | sock_rps_save_rxhash(sk, skb->rxhash); |
1676 | 1676 | ||
1677 | bh_lock_sock_nested(sk); | 1677 | bh_lock_sock_nested(sk); |
1678 | ret = 0; | 1678 | ret = 0; |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 2b7d71fb8439..5db3a2c6cb33 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -861,7 +861,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
861 | th->urg_ptr = htons(tp->snd_up - tcb->seq); | 861 | th->urg_ptr = htons(tp->snd_up - tcb->seq); |
862 | th->urg = 1; | 862 | th->urg = 1; |
863 | } else if (after(tcb->seq + 0xFFFF, tp->snd_nxt)) { | 863 | } else if (after(tcb->seq + 0xFFFF, tp->snd_nxt)) { |
864 | th->urg_ptr = 0xFFFF; | 864 | th->urg_ptr = htons(0xFFFF); |
865 | th->urg = 1; | 865 | th->urg = 1; |
866 | } | 866 | } |
867 | } | 867 | } |
@@ -888,7 +888,8 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
888 | tcp_event_data_sent(tp, skb, sk); | 888 | tcp_event_data_sent(tp, skb, sk); |
889 | 889 | ||
890 | if (after(tcb->end_seq, tp->snd_nxt) || tcb->seq == tcb->end_seq) | 890 | if (after(tcb->end_seq, tp->snd_nxt) || tcb->seq == tcb->end_seq) |
891 | TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); | 891 | TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS, |
892 | tcp_skb_pcount(skb)); | ||
892 | 893 | ||
893 | err = icsk->icsk_af_ops->queue_xmit(skb); | 894 | err = icsk->icsk_af_ops->queue_xmit(skb); |
894 | if (likely(err <= 0)) | 895 | if (likely(err <= 0)) |
@@ -2485,7 +2486,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
2485 | *tail-- ^= TCP_SKB_CB(skb)->seq + 1; | 2486 | *tail-- ^= TCP_SKB_CB(skb)->seq + 1; |
2486 | 2487 | ||
2487 | /* recommended */ | 2488 | /* recommended */ |
2488 | *tail-- ^= ((th->dest << 16) | th->source); | 2489 | *tail-- ^= (((__force u32)th->dest << 16) | (__force u32)th->source); |
2489 | *tail-- ^= (u32)(unsigned long)cvp; /* per sockopt */ | 2490 | *tail-- ^= (u32)(unsigned long)cvp; /* per sockopt */ |
2490 | 2491 | ||
2491 | sha_transform((__u32 *)&xvp->cookie_bakery[0], | 2492 | sha_transform((__u32 *)&xvp->cookie_bakery[0], |
@@ -2503,7 +2504,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
2503 | th->window = htons(min(req->rcv_wnd, 65535U)); | 2504 | th->window = htons(min(req->rcv_wnd, 65535U)); |
2504 | tcp_options_write((__be32 *)(th + 1), tp, &opts); | 2505 | tcp_options_write((__be32 *)(th + 1), tp, &opts); |
2505 | th->doff = (tcp_header_size >> 2); | 2506 | th->doff = (tcp_header_size >> 2); |
2506 | TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); | 2507 | TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS, tcp_skb_pcount(skb)); |
2507 | 2508 | ||
2508 | #ifdef CONFIG_TCP_MD5SIG | 2509 | #ifdef CONFIG_TCP_MD5SIG |
2509 | /* Okay, we have all we need - do the md5 hash if needed */ | 2510 | /* Okay, we have all we need - do the md5 hash if needed */ |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index c732be00606b..440a5c6004f6 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -517,7 +517,7 @@ static void tcp_keepalive_timer (unsigned long data) | |||
517 | struct sock *sk = (struct sock *) data; | 517 | struct sock *sk = (struct sock *) data; |
518 | struct inet_connection_sock *icsk = inet_csk(sk); | 518 | struct inet_connection_sock *icsk = inet_csk(sk); |
519 | struct tcp_sock *tp = tcp_sk(sk); | 519 | struct tcp_sock *tp = tcp_sk(sk); |
520 | __u32 elapsed; | 520 | u32 elapsed; |
521 | 521 | ||
522 | /* Only process if socket is not in use. */ | 522 | /* Only process if socket is not in use. */ |
523 | bh_lock_sock(sk); | 523 | bh_lock_sock(sk); |
@@ -554,7 +554,7 @@ static void tcp_keepalive_timer (unsigned long data) | |||
554 | if (tp->packets_out || tcp_send_head(sk)) | 554 | if (tp->packets_out || tcp_send_head(sk)) |
555 | goto resched; | 555 | goto resched; |
556 | 556 | ||
557 | elapsed = tcp_time_stamp - tp->rcv_tstamp; | 557 | elapsed = keepalive_time_elapsed(tp); |
558 | 558 | ||
559 | if (elapsed >= keepalive_time_when(tp)) { | 559 | if (elapsed >= keepalive_time_when(tp)) { |
560 | if (icsk->icsk_probes_out >= keepalive_probes(tp)) { | 560 | if (icsk->icsk_probes_out >= keepalive_probes(tp)) { |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 666b963496ff..4560b291180b 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -307,13 +307,13 @@ static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) | |||
307 | static unsigned int udp4_portaddr_hash(struct net *net, __be32 saddr, | 307 | static unsigned int udp4_portaddr_hash(struct net *net, __be32 saddr, |
308 | unsigned int port) | 308 | unsigned int port) |
309 | { | 309 | { |
310 | return jhash_1word(saddr, net_hash_mix(net)) ^ port; | 310 | return jhash_1word((__force u32)saddr, net_hash_mix(net)) ^ port; |
311 | } | 311 | } |
312 | 312 | ||
313 | int udp_v4_get_port(struct sock *sk, unsigned short snum) | 313 | int udp_v4_get_port(struct sock *sk, unsigned short snum) |
314 | { | 314 | { |
315 | unsigned int hash2_nulladdr = | 315 | unsigned int hash2_nulladdr = |
316 | udp4_portaddr_hash(sock_net(sk), INADDR_ANY, snum); | 316 | udp4_portaddr_hash(sock_net(sk), htonl(INADDR_ANY), snum); |
317 | unsigned int hash2_partial = | 317 | unsigned int hash2_partial = |
318 | udp4_portaddr_hash(sock_net(sk), inet_sk(sk)->inet_rcv_saddr, 0); | 318 | udp4_portaddr_hash(sock_net(sk), inet_sk(sk)->inet_rcv_saddr, 0); |
319 | 319 | ||
@@ -466,14 +466,14 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, | |||
466 | daddr, hnum, dif, | 466 | daddr, hnum, dif, |
467 | hslot2, slot2); | 467 | hslot2, slot2); |
468 | if (!result) { | 468 | if (!result) { |
469 | hash2 = udp4_portaddr_hash(net, INADDR_ANY, hnum); | 469 | hash2 = udp4_portaddr_hash(net, htonl(INADDR_ANY), hnum); |
470 | slot2 = hash2 & udptable->mask; | 470 | slot2 = hash2 & udptable->mask; |
471 | hslot2 = &udptable->hash2[slot2]; | 471 | hslot2 = &udptable->hash2[slot2]; |
472 | if (hslot->count < hslot2->count) | 472 | if (hslot->count < hslot2->count) |
473 | goto begin; | 473 | goto begin; |
474 | 474 | ||
475 | result = udp4_lib_lookup2(net, saddr, sport, | 475 | result = udp4_lib_lookup2(net, saddr, sport, |
476 | INADDR_ANY, hnum, dif, | 476 | htonl(INADDR_ANY), hnum, dif, |
477 | hslot2, slot2); | 477 | hslot2, slot2); |
478 | } | 478 | } |
479 | rcu_read_unlock(); | 479 | rcu_read_unlock(); |
@@ -1062,10 +1062,10 @@ static unsigned int first_packet_length(struct sock *sk) | |||
1062 | spin_unlock_bh(&rcvq->lock); | 1062 | spin_unlock_bh(&rcvq->lock); |
1063 | 1063 | ||
1064 | if (!skb_queue_empty(&list_kill)) { | 1064 | if (!skb_queue_empty(&list_kill)) { |
1065 | lock_sock(sk); | 1065 | lock_sock_bh(sk); |
1066 | __skb_queue_purge(&list_kill); | 1066 | __skb_queue_purge(&list_kill); |
1067 | sk_mem_reclaim_partial(sk); | 1067 | sk_mem_reclaim_partial(sk); |
1068 | release_sock(sk); | 1068 | unlock_sock_bh(sk); |
1069 | } | 1069 | } |
1070 | return res; | 1070 | return res; |
1071 | } | 1071 | } |
@@ -1196,10 +1196,10 @@ out: | |||
1196 | return err; | 1196 | return err; |
1197 | 1197 | ||
1198 | csum_copy_err: | 1198 | csum_copy_err: |
1199 | lock_sock(sk); | 1199 | lock_sock_bh(sk); |
1200 | if (!skb_kill_datagram(sk, skb, flags)) | 1200 | if (!skb_kill_datagram(sk, skb, flags)) |
1201 | UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite); | 1201 | UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite); |
1202 | release_sock(sk); | 1202 | unlock_sock_bh(sk); |
1203 | 1203 | ||
1204 | if (noblock) | 1204 | if (noblock) |
1205 | return -EAGAIN; | 1205 | return -EAGAIN; |
@@ -1217,7 +1217,7 @@ int udp_disconnect(struct sock *sk, int flags) | |||
1217 | sk->sk_state = TCP_CLOSE; | 1217 | sk->sk_state = TCP_CLOSE; |
1218 | inet->inet_daddr = 0; | 1218 | inet->inet_daddr = 0; |
1219 | inet->inet_dport = 0; | 1219 | inet->inet_dport = 0; |
1220 | inet_rps_save_rxhash(sk, 0); | 1220 | sock_rps_save_rxhash(sk, 0); |
1221 | sk->sk_bound_dev_if = 0; | 1221 | sk->sk_bound_dev_if = 0; |
1222 | if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) | 1222 | if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) |
1223 | inet_reset_saddr(sk); | 1223 | inet_reset_saddr(sk); |
@@ -1262,9 +1262,9 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
1262 | int rc; | 1262 | int rc; |
1263 | 1263 | ||
1264 | if (inet_sk(sk)->inet_daddr) | 1264 | if (inet_sk(sk)->inet_daddr) |
1265 | inet_rps_save_rxhash(sk, skb->rxhash); | 1265 | sock_rps_save_rxhash(sk, skb->rxhash); |
1266 | 1266 | ||
1267 | rc = sock_queue_rcv_skb(sk, skb); | 1267 | rc = ip_queue_rcv_skb(sk, skb); |
1268 | if (rc < 0) { | 1268 | if (rc < 0) { |
1269 | int is_udplite = IS_UDPLITE(sk); | 1269 | int is_udplite = IS_UDPLITE(sk); |
1270 | 1270 | ||
@@ -1372,6 +1372,10 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
1372 | goto drop; | 1372 | goto drop; |
1373 | } | 1373 | } |
1374 | 1374 | ||
1375 | |||
1376 | if (sk_rcvqueues_full(sk, skb)) | ||
1377 | goto drop; | ||
1378 | |||
1375 | rc = 0; | 1379 | rc = 0; |
1376 | 1380 | ||
1377 | bh_lock_sock(sk); | 1381 | bh_lock_sock(sk); |
@@ -1620,9 +1624,9 @@ int udp_rcv(struct sk_buff *skb) | |||
1620 | 1624 | ||
1621 | void udp_destroy_sock(struct sock *sk) | 1625 | void udp_destroy_sock(struct sock *sk) |
1622 | { | 1626 | { |
1623 | lock_sock(sk); | 1627 | lock_sock_bh(sk); |
1624 | udp_flush_pending_frames(sk); | 1628 | udp_flush_pending_frames(sk); |
1625 | release_sock(sk); | 1629 | unlock_sock_bh(sk); |
1626 | } | 1630 | } |
1627 | 1631 | ||
1628 | /* | 1632 | /* |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 7cba8845242f..3984f52181f4 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -588,7 +588,8 @@ static u32 ipv6_addr_hash(const struct in6_addr *addr) | |||
588 | * We perform the hash function over the last 64 bits of the address | 588 | * We perform the hash function over the last 64 bits of the address |
589 | * This will include the IEEE address token on links that support it. | 589 | * This will include the IEEE address token on links that support it. |
590 | */ | 590 | */ |
591 | return jhash_2words(addr->s6_addr32[2], addr->s6_addr32[3], 0) | 591 | return jhash_2words((__force u32)addr->s6_addr32[2], |
592 | (__force u32)addr->s6_addr32[3], 0) | ||
592 | & (IN6_ADDR_HSIZE - 1); | 593 | & (IN6_ADDR_HSIZE - 1); |
593 | } | 594 | } |
594 | 595 | ||
@@ -1345,7 +1346,7 @@ struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, const struct in6_addr *add | |||
1345 | struct hlist_node *node; | 1346 | struct hlist_node *node; |
1346 | 1347 | ||
1347 | rcu_read_lock_bh(); | 1348 | rcu_read_lock_bh(); |
1348 | hlist_for_each_entry_rcu(ifp, node, &inet6_addr_lst[hash], addr_lst) { | 1349 | hlist_for_each_entry_rcu_bh(ifp, node, &inet6_addr_lst[hash], addr_lst) { |
1349 | if (!net_eq(dev_net(ifp->idev->dev), net)) | 1350 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
1350 | continue; | 1351 | continue; |
1351 | if (ipv6_addr_equal(&ifp->addr, addr)) { | 1352 | if (ipv6_addr_equal(&ifp->addr, addr)) { |
@@ -2958,7 +2959,7 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq) | |||
2958 | 2959 | ||
2959 | for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) { | 2960 | for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) { |
2960 | struct hlist_node *n; | 2961 | struct hlist_node *n; |
2961 | hlist_for_each_entry_rcu(ifa, n, &inet6_addr_lst[state->bucket], | 2962 | hlist_for_each_entry_rcu_bh(ifa, n, &inet6_addr_lst[state->bucket], |
2962 | addr_lst) | 2963 | addr_lst) |
2963 | if (net_eq(dev_net(ifa->idev->dev), net)) | 2964 | if (net_eq(dev_net(ifa->idev->dev), net)) |
2964 | return ifa; | 2965 | return ifa; |
@@ -2973,12 +2974,12 @@ static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, | |||
2973 | struct net *net = seq_file_net(seq); | 2974 | struct net *net = seq_file_net(seq); |
2974 | struct hlist_node *n = &ifa->addr_lst; | 2975 | struct hlist_node *n = &ifa->addr_lst; |
2975 | 2976 | ||
2976 | hlist_for_each_entry_continue_rcu(ifa, n, addr_lst) | 2977 | hlist_for_each_entry_continue_rcu_bh(ifa, n, addr_lst) |
2977 | if (net_eq(dev_net(ifa->idev->dev), net)) | 2978 | if (net_eq(dev_net(ifa->idev->dev), net)) |
2978 | return ifa; | 2979 | return ifa; |
2979 | 2980 | ||
2980 | while (++state->bucket < IN6_ADDR_HSIZE) { | 2981 | while (++state->bucket < IN6_ADDR_HSIZE) { |
2981 | hlist_for_each_entry(ifa, n, | 2982 | hlist_for_each_entry_rcu_bh(ifa, n, |
2982 | &inet6_addr_lst[state->bucket], addr_lst) { | 2983 | &inet6_addr_lst[state->bucket], addr_lst) { |
2983 | if (net_eq(dev_net(ifa->idev->dev), net)) | 2984 | if (net_eq(dev_net(ifa->idev->dev), net)) |
2984 | return ifa; | 2985 | return ifa; |
@@ -2999,7 +3000,7 @@ static struct inet6_ifaddr *if6_get_idx(struct seq_file *seq, loff_t pos) | |||
2999 | } | 3000 | } |
3000 | 3001 | ||
3001 | static void *if6_seq_start(struct seq_file *seq, loff_t *pos) | 3002 | static void *if6_seq_start(struct seq_file *seq, loff_t *pos) |
3002 | __acquires(rcu) | 3003 | __acquires(rcu_bh) |
3003 | { | 3004 | { |
3004 | rcu_read_lock_bh(); | 3005 | rcu_read_lock_bh(); |
3005 | return if6_get_idx(seq, *pos); | 3006 | return if6_get_idx(seq, *pos); |
@@ -3015,7 +3016,7 @@ static void *if6_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
3015 | } | 3016 | } |
3016 | 3017 | ||
3017 | static void if6_seq_stop(struct seq_file *seq, void *v) | 3018 | static void if6_seq_stop(struct seq_file *seq, void *v) |
3018 | __releases(rcu) | 3019 | __releases(rcu_bh) |
3019 | { | 3020 | { |
3020 | rcu_read_unlock_bh(); | 3021 | rcu_read_unlock_bh(); |
3021 | } | 3022 | } |
@@ -3092,7 +3093,7 @@ int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr) | |||
3092 | unsigned int hash = ipv6_addr_hash(addr); | 3093 | unsigned int hash = ipv6_addr_hash(addr); |
3093 | 3094 | ||
3094 | rcu_read_lock_bh(); | 3095 | rcu_read_lock_bh(); |
3095 | hlist_for_each_entry_rcu(ifp, n, &inet6_addr_lst[hash], addr_lst) { | 3096 | hlist_for_each_entry_rcu_bh(ifp, n, &inet6_addr_lst[hash], addr_lst) { |
3096 | if (!net_eq(dev_net(ifp->idev->dev), net)) | 3097 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
3097 | continue; | 3098 | continue; |
3098 | if (ipv6_addr_equal(&ifp->addr, addr) && | 3099 | if (ipv6_addr_equal(&ifp->addr, addr) && |
@@ -3126,7 +3127,7 @@ static void addrconf_verify(unsigned long foo) | |||
3126 | 3127 | ||
3127 | for (i = 0; i < IN6_ADDR_HSIZE; i++) { | 3128 | for (i = 0; i < IN6_ADDR_HSIZE; i++) { |
3128 | restart: | 3129 | restart: |
3129 | hlist_for_each_entry_rcu(ifp, node, | 3130 | hlist_for_each_entry_rcu_bh(ifp, node, |
3130 | &inet6_addr_lst[i], addr_lst) { | 3131 | &inet6_addr_lst[i], addr_lst) { |
3131 | unsigned long age; | 3132 | unsigned long age; |
3132 | 3133 | ||
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 3192aa02ba5d..d2df3144429b 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -417,6 +417,9 @@ void inet6_destroy_sock(struct sock *sk) | |||
417 | if ((skb = xchg(&np->pktoptions, NULL)) != NULL) | 417 | if ((skb = xchg(&np->pktoptions, NULL)) != NULL) |
418 | kfree_skb(skb); | 418 | kfree_skb(skb); |
419 | 419 | ||
420 | if ((skb = xchg(&np->rxpmtu, NULL)) != NULL) | ||
421 | kfree_skb(skb); | ||
422 | |||
420 | /* Free flowlabels */ | 423 | /* Free flowlabels */ |
421 | fl6_free_socklist(sk); | 424 | fl6_free_socklist(sk); |
422 | 425 | ||
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 622dc7939a1b..5959230bc6c1 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -278,6 +278,45 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info) | |||
278 | kfree_skb(skb); | 278 | kfree_skb(skb); |
279 | } | 279 | } |
280 | 280 | ||
281 | void ipv6_local_rxpmtu(struct sock *sk, struct flowi *fl, u32 mtu) | ||
282 | { | ||
283 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
284 | struct ipv6hdr *iph; | ||
285 | struct sk_buff *skb; | ||
286 | struct ip6_mtuinfo *mtu_info; | ||
287 | |||
288 | if (!np->rxopt.bits.rxpmtu) | ||
289 | return; | ||
290 | |||
291 | skb = alloc_skb(sizeof(struct ipv6hdr), GFP_ATOMIC); | ||
292 | if (!skb) | ||
293 | return; | ||
294 | |||
295 | skb_put(skb, sizeof(struct ipv6hdr)); | ||
296 | skb_reset_network_header(skb); | ||
297 | iph = ipv6_hdr(skb); | ||
298 | ipv6_addr_copy(&iph->daddr, &fl->fl6_dst); | ||
299 | |||
300 | mtu_info = IP6CBMTU(skb); | ||
301 | if (!mtu_info) { | ||
302 | kfree_skb(skb); | ||
303 | return; | ||
304 | } | ||
305 | |||
306 | mtu_info->ip6m_mtu = mtu; | ||
307 | mtu_info->ip6m_addr.sin6_family = AF_INET6; | ||
308 | mtu_info->ip6m_addr.sin6_port = 0; | ||
309 | mtu_info->ip6m_addr.sin6_flowinfo = 0; | ||
310 | mtu_info->ip6m_addr.sin6_scope_id = fl->oif; | ||
311 | ipv6_addr_copy(&mtu_info->ip6m_addr.sin6_addr, &ipv6_hdr(skb)->daddr); | ||
312 | |||
313 | __skb_pull(skb, skb_tail_pointer(skb) - skb->data); | ||
314 | skb_reset_transport_header(skb); | ||
315 | |||
316 | skb = xchg(&np->rxpmtu, skb); | ||
317 | kfree_skb(skb); | ||
318 | } | ||
319 | |||
281 | /* | 320 | /* |
282 | * Handle MSG_ERRQUEUE | 321 | * Handle MSG_ERRQUEUE |
283 | */ | 322 | */ |
@@ -381,6 +420,54 @@ out: | |||
381 | return err; | 420 | return err; |
382 | } | 421 | } |
383 | 422 | ||
423 | /* | ||
424 | * Handle IPV6_RECVPATHMTU | ||
425 | */ | ||
426 | int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len) | ||
427 | { | ||
428 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
429 | struct sk_buff *skb; | ||
430 | struct sockaddr_in6 *sin; | ||
431 | struct ip6_mtuinfo mtu_info; | ||
432 | int err; | ||
433 | int copied; | ||
434 | |||
435 | err = -EAGAIN; | ||
436 | skb = xchg(&np->rxpmtu, NULL); | ||
437 | if (skb == NULL) | ||
438 | goto out; | ||
439 | |||
440 | copied = skb->len; | ||
441 | if (copied > len) { | ||
442 | msg->msg_flags |= MSG_TRUNC; | ||
443 | copied = len; | ||
444 | } | ||
445 | err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); | ||
446 | if (err) | ||
447 | goto out_free_skb; | ||
448 | |||
449 | sock_recv_timestamp(msg, sk, skb); | ||
450 | |||
451 | memcpy(&mtu_info, IP6CBMTU(skb), sizeof(mtu_info)); | ||
452 | |||
453 | sin = (struct sockaddr_in6 *)msg->msg_name; | ||
454 | if (sin) { | ||
455 | sin->sin6_family = AF_INET6; | ||
456 | sin->sin6_flowinfo = 0; | ||
457 | sin->sin6_port = 0; | ||
458 | sin->sin6_scope_id = mtu_info.ip6m_addr.sin6_scope_id; | ||
459 | ipv6_addr_copy(&sin->sin6_addr, &mtu_info.ip6m_addr.sin6_addr); | ||
460 | } | ||
461 | |||
462 | put_cmsg(msg, SOL_IPV6, IPV6_PATHMTU, sizeof(mtu_info), &mtu_info); | ||
463 | |||
464 | err = copied; | ||
465 | |||
466 | out_free_skb: | ||
467 | kfree_skb(skb); | ||
468 | out: | ||
469 | return err; | ||
470 | } | ||
384 | 471 | ||
385 | 472 | ||
386 | int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) | 473 | int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) |
@@ -497,7 +584,7 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) | |||
497 | int datagram_send_ctl(struct net *net, | 584 | int datagram_send_ctl(struct net *net, |
498 | struct msghdr *msg, struct flowi *fl, | 585 | struct msghdr *msg, struct flowi *fl, |
499 | struct ipv6_txoptions *opt, | 586 | struct ipv6_txoptions *opt, |
500 | int *hlimit, int *tclass) | 587 | int *hlimit, int *tclass, int *dontfrag) |
501 | { | 588 | { |
502 | struct in6_pktinfo *src_info; | 589 | struct in6_pktinfo *src_info; |
503 | struct cmsghdr *cmsg; | 590 | struct cmsghdr *cmsg; |
@@ -737,6 +824,25 @@ int datagram_send_ctl(struct net *net, | |||
737 | 824 | ||
738 | break; | 825 | break; |
739 | } | 826 | } |
827 | |||
828 | case IPV6_DONTFRAG: | ||
829 | { | ||
830 | int df; | ||
831 | |||
832 | err = -EINVAL; | ||
833 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) { | ||
834 | goto exit_f; | ||
835 | } | ||
836 | |||
837 | df = *(int *)CMSG_DATA(cmsg); | ||
838 | if (df < 0 || df > 1) | ||
839 | goto exit_f; | ||
840 | |||
841 | err = 0; | ||
842 | *dontfrag = df; | ||
843 | |||
844 | break; | ||
845 | } | ||
740 | default: | 846 | default: |
741 | LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n", | 847 | LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n", |
742 | cmsg->cmsg_type); | 848 | cmsg->cmsg_type); |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 8124f16f2ac2..8e44f8f9c188 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -237,8 +237,8 @@ static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule) | |||
237 | + nla_total_size(16); /* src */ | 237 | + nla_total_size(16); /* src */ |
238 | } | 238 | } |
239 | 239 | ||
240 | static struct fib_rules_ops fib6_rules_ops_template = { | 240 | static const struct fib_rules_ops __net_initdata fib6_rules_ops_template = { |
241 | .family = FIB_RULES_IPV6, | 241 | .family = AF_INET6, |
242 | .rule_size = sizeof(struct fib6_rule), | 242 | .rule_size = sizeof(struct fib6_rule), |
243 | .addr_size = sizeof(struct in6_addr), | 243 | .addr_size = sizeof(struct in6_addr), |
244 | .action = fib6_rule_action, | 244 | .action = fib6_rule_action, |
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 12d2fa42657d..ce7992982557 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -481,7 +481,7 @@ route_done: | |||
481 | len + sizeof(struct icmp6hdr), | 481 | len + sizeof(struct icmp6hdr), |
482 | sizeof(struct icmp6hdr), hlimit, | 482 | sizeof(struct icmp6hdr), hlimit, |
483 | np->tclass, NULL, &fl, (struct rt6_info*)dst, | 483 | np->tclass, NULL, &fl, (struct rt6_info*)dst, |
484 | MSG_DONTWAIT); | 484 | MSG_DONTWAIT, np->dontfrag); |
485 | if (err) { | 485 | if (err) { |
486 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); | 486 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); |
487 | ip6_flush_pending_frames(sk); | 487 | ip6_flush_pending_frames(sk); |
@@ -561,7 +561,8 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
561 | 561 | ||
562 | err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr), | 562 | err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr), |
563 | sizeof(struct icmp6hdr), hlimit, np->tclass, NULL, &fl, | 563 | sizeof(struct icmp6hdr), hlimit, np->tclass, NULL, &fl, |
564 | (struct rt6_info*)dst, MSG_DONTWAIT); | 564 | (struct rt6_info*)dst, MSG_DONTWAIT, |
565 | np->dontfrag); | ||
565 | 566 | ||
566 | if (err) { | 567 | if (err) { |
567 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); | 568 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index dc6e0b8f260d..92a122b7795d 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -144,7 +144,8 @@ static __inline__ __be32 addr_bit_set(void *token, int fn_bit) | |||
144 | * htonl(1 << ((~fn_bit)&0x1F)) | 144 | * htonl(1 << ((~fn_bit)&0x1F)) |
145 | * See include/asm-generic/bitops/le.h. | 145 | * See include/asm-generic/bitops/le.h. |
146 | */ | 146 | */ |
147 | return (1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)) & addr[fn_bit >> 5]; | 147 | return (__force __be32)(1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)) & |
148 | addr[fn_bit >> 5]; | ||
148 | } | 149 | } |
149 | 150 | ||
150 | static __inline__ struct fib6_node * node_alloc(void) | 151 | static __inline__ struct fib6_node * node_alloc(void) |
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 14e23216eb28..13654686aeab 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
@@ -360,7 +360,8 @@ fl_create(struct net *net, struct in6_flowlabel_req *freq, char __user *optval, | |||
360 | msg.msg_control = (void*)(fl->opt+1); | 360 | msg.msg_control = (void*)(fl->opt+1); |
361 | flowi.oif = 0; | 361 | flowi.oif = 0; |
362 | 362 | ||
363 | err = datagram_send_ctl(net, &msg, &flowi, fl->opt, &junk, &junk); | 363 | err = datagram_send_ctl(net, &msg, &flowi, fl->opt, &junk, |
364 | &junk, &junk); | ||
364 | if (err) | 365 | if (err) |
365 | goto done; | 366 | goto done; |
366 | err = -EINVAL; | 367 | err = -EINVAL; |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 7f12e30cfa73..5173acaeb501 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -92,7 +92,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb) | |||
92 | newskb->ip_summed = CHECKSUM_UNNECESSARY; | 92 | newskb->ip_summed = CHECKSUM_UNNECESSARY; |
93 | WARN_ON(!skb_dst(newskb)); | 93 | WARN_ON(!skb_dst(newskb)); |
94 | 94 | ||
95 | netif_rx(newskb); | 95 | netif_rx_ni(newskb); |
96 | return 0; | 96 | return 0; |
97 | } | 97 | } |
98 | 98 | ||
@@ -216,8 +216,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
216 | } | 216 | } |
217 | kfree_skb(skb); | 217 | kfree_skb(skb); |
218 | skb = skb2; | 218 | skb = skb2; |
219 | if (sk) | 219 | skb_set_owner_w(skb, sk); |
220 | skb_set_owner_w(skb, sk); | ||
221 | } | 220 | } |
222 | if (opt->opt_flen) | 221 | if (opt->opt_flen) |
223 | ipv6_push_frag_opts(skb, opt, &proto); | 222 | ipv6_push_frag_opts(skb, opt, &proto); |
@@ -623,7 +622,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
623 | /* We must not fragment if the socket is set to force MTU discovery | 622 | /* We must not fragment if the socket is set to force MTU discovery |
624 | * or if the skb it not generated by a local socket. | 623 | * or if the skb it not generated by a local socket. |
625 | */ | 624 | */ |
626 | if (!skb->local_df) { | 625 | if (!skb->local_df && skb->len > mtu) { |
627 | skb->dev = skb_dst(skb)->dev; | 626 | skb->dev = skb_dst(skb)->dev; |
628 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | 627 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
629 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), | 628 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), |
@@ -1103,7 +1102,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1103 | int offset, int len, int odd, struct sk_buff *skb), | 1102 | int offset, int len, int odd, struct sk_buff *skb), |
1104 | void *from, int length, int transhdrlen, | 1103 | void *from, int length, int transhdrlen, |
1105 | int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi *fl, | 1104 | int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi *fl, |
1106 | struct rt6_info *rt, unsigned int flags) | 1105 | struct rt6_info *rt, unsigned int flags, int dontfrag) |
1107 | { | 1106 | { |
1108 | struct inet_sock *inet = inet_sk(sk); | 1107 | struct inet_sock *inet = inet_sk(sk); |
1109 | struct ipv6_pinfo *np = inet6_sk(sk); | 1108 | struct ipv6_pinfo *np = inet6_sk(sk); |
@@ -1217,15 +1216,23 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1217 | */ | 1216 | */ |
1218 | 1217 | ||
1219 | inet->cork.length += length; | 1218 | inet->cork.length += length; |
1220 | if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) && | 1219 | if (length > mtu) { |
1221 | (rt->u.dst.dev->features & NETIF_F_UFO)) { | 1220 | int proto = sk->sk_protocol; |
1221 | if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){ | ||
1222 | ipv6_local_rxpmtu(sk, fl, mtu-exthdrlen); | ||
1223 | return -EMSGSIZE; | ||
1224 | } | ||
1222 | 1225 | ||
1223 | err = ip6_ufo_append_data(sk, getfrag, from, length, hh_len, | 1226 | if (proto == IPPROTO_UDP && |
1224 | fragheaderlen, transhdrlen, mtu, | 1227 | (rt->u.dst.dev->features & NETIF_F_UFO)) { |
1225 | flags); | 1228 | |
1226 | if (err) | 1229 | err = ip6_ufo_append_data(sk, getfrag, from, length, |
1227 | goto error; | 1230 | hh_len, fragheaderlen, |
1228 | return 0; | 1231 | transhdrlen, mtu, flags); |
1232 | if (err) | ||
1233 | goto error; | ||
1234 | return 0; | ||
1235 | } | ||
1229 | } | 1236 | } |
1230 | 1237 | ||
1231 | if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) | 1238 | if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 1160400e9dbd..bd43f0152c21 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -337,6 +337,13 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
337 | retv = 0; | 337 | retv = 0; |
338 | break; | 338 | break; |
339 | 339 | ||
340 | case IPV6_RECVPATHMTU: | ||
341 | if (optlen < sizeof(int)) | ||
342 | goto e_inval; | ||
343 | np->rxopt.bits.rxpmtu = valbool; | ||
344 | retv = 0; | ||
345 | break; | ||
346 | |||
340 | case IPV6_HOPOPTS: | 347 | case IPV6_HOPOPTS: |
341 | case IPV6_RTHDRDSTOPTS: | 348 | case IPV6_RTHDRDSTOPTS: |
342 | case IPV6_RTHDR: | 349 | case IPV6_RTHDR: |
@@ -451,7 +458,8 @@ sticky_done: | |||
451 | msg.msg_controllen = optlen; | 458 | msg.msg_controllen = optlen; |
452 | msg.msg_control = (void*)(opt+1); | 459 | msg.msg_control = (void*)(opt+1); |
453 | 460 | ||
454 | retv = datagram_send_ctl(net, &msg, &fl, opt, &junk, &junk); | 461 | retv = datagram_send_ctl(net, &msg, &fl, opt, &junk, &junk, |
462 | &junk); | ||
455 | if (retv) | 463 | if (retv) |
456 | goto done; | 464 | goto done; |
457 | update: | 465 | update: |
@@ -767,6 +775,17 @@ pref_skip_coa: | |||
767 | 775 | ||
768 | break; | 776 | break; |
769 | } | 777 | } |
778 | case IPV6_MINHOPCOUNT: | ||
779 | if (optlen < sizeof(int)) | ||
780 | goto e_inval; | ||
781 | if (val < 0 || val > 255) | ||
782 | goto e_inval; | ||
783 | np->min_hopcount = val; | ||
784 | break; | ||
785 | case IPV6_DONTFRAG: | ||
786 | np->dontfrag = valbool; | ||
787 | retv = 0; | ||
788 | break; | ||
770 | } | 789 | } |
771 | 790 | ||
772 | release_sock(sk); | 791 | release_sock(sk); |
@@ -1055,6 +1074,38 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
1055 | val = np->rxopt.bits.rxflow; | 1074 | val = np->rxopt.bits.rxflow; |
1056 | break; | 1075 | break; |
1057 | 1076 | ||
1077 | case IPV6_RECVPATHMTU: | ||
1078 | val = np->rxopt.bits.rxpmtu; | ||
1079 | break; | ||
1080 | |||
1081 | case IPV6_PATHMTU: | ||
1082 | { | ||
1083 | struct dst_entry *dst; | ||
1084 | struct ip6_mtuinfo mtuinfo; | ||
1085 | |||
1086 | if (len < sizeof(mtuinfo)) | ||
1087 | return -EINVAL; | ||
1088 | |||
1089 | len = sizeof(mtuinfo); | ||
1090 | memset(&mtuinfo, 0, sizeof(mtuinfo)); | ||
1091 | |||
1092 | rcu_read_lock(); | ||
1093 | dst = __sk_dst_get(sk); | ||
1094 | if (dst) | ||
1095 | mtuinfo.ip6m_mtu = dst_mtu(dst); | ||
1096 | rcu_read_unlock(); | ||
1097 | if (!mtuinfo.ip6m_mtu) | ||
1098 | return -ENOTCONN; | ||
1099 | |||
1100 | if (put_user(len, optlen)) | ||
1101 | return -EFAULT; | ||
1102 | if (copy_to_user(optval, &mtuinfo, len)) | ||
1103 | return -EFAULT; | ||
1104 | |||
1105 | return 0; | ||
1106 | break; | ||
1107 | } | ||
1108 | |||
1058 | case IPV6_UNICAST_HOPS: | 1109 | case IPV6_UNICAST_HOPS: |
1059 | case IPV6_MULTICAST_HOPS: | 1110 | case IPV6_MULTICAST_HOPS: |
1060 | { | 1111 | { |
@@ -1116,6 +1167,14 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
1116 | val |= IPV6_PREFER_SRC_HOME; | 1167 | val |= IPV6_PREFER_SRC_HOME; |
1117 | break; | 1168 | break; |
1118 | 1169 | ||
1170 | case IPV6_MINHOPCOUNT: | ||
1171 | val = np->min_hopcount; | ||
1172 | break; | ||
1173 | |||
1174 | case IPV6_DONTFRAG: | ||
1175 | val = np->dontfrag; | ||
1176 | break; | ||
1177 | |||
1119 | default: | 1178 | default: |
1120 | return -ENOPROTOOPT; | 1179 | return -ENOPROTOOPT; |
1121 | } | 1180 | } |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index f9d05ce4e03a..59f1881968c7 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/proc_fs.h> | 44 | #include <linux/proc_fs.h> |
45 | #include <linux/seq_file.h> | 45 | #include <linux/seq_file.h> |
46 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
47 | #include <net/mld.h> | ||
47 | 48 | ||
48 | #include <linux/netfilter.h> | 49 | #include <linux/netfilter.h> |
49 | #include <linux/netfilter_ipv6.h> | 50 | #include <linux/netfilter_ipv6.h> |
@@ -71,54 +72,11 @@ | |||
71 | #define MDBG(x) | 72 | #define MDBG(x) |
72 | #endif | 73 | #endif |
73 | 74 | ||
74 | /* | 75 | /* Ensure that we have struct in6_addr aligned on 32bit word. */ |
75 | * These header formats should be in a separate include file, but icmpv6.h | 76 | static void *__mld2_query_bugs[] __attribute__((__unused__)) = { |
76 | * doesn't have in6_addr defined in all cases, there is no __u128, and no | 77 | BUILD_BUG_ON_NULL(offsetof(struct mld2_query, mld2q_srcs) % 4), |
77 | * other files reference these. | 78 | BUILD_BUG_ON_NULL(offsetof(struct mld2_report, mld2r_grec) % 4), |
78 | * | 79 | BUILD_BUG_ON_NULL(offsetof(struct mld2_grec, grec_mca) % 4) |
79 | * +-DLS 4/14/03 | ||
80 | */ | ||
81 | |||
82 | /* Multicast Listener Discovery version 2 headers */ | ||
83 | |||
84 | struct mld2_grec { | ||
85 | __u8 grec_type; | ||
86 | __u8 grec_auxwords; | ||
87 | __be16 grec_nsrcs; | ||
88 | struct in6_addr grec_mca; | ||
89 | struct in6_addr grec_src[0]; | ||
90 | }; | ||
91 | |||
92 | struct mld2_report { | ||
93 | __u8 type; | ||
94 | __u8 resv1; | ||
95 | __sum16 csum; | ||
96 | __be16 resv2; | ||
97 | __be16 ngrec; | ||
98 | struct mld2_grec grec[0]; | ||
99 | }; | ||
100 | |||
101 | struct mld2_query { | ||
102 | __u8 type; | ||
103 | __u8 code; | ||
104 | __sum16 csum; | ||
105 | __be16 mrc; | ||
106 | __be16 resv1; | ||
107 | struct in6_addr mca; | ||
108 | #if defined(__LITTLE_ENDIAN_BITFIELD) | ||
109 | __u8 qrv:3, | ||
110 | suppress:1, | ||
111 | resv2:4; | ||
112 | #elif defined(__BIG_ENDIAN_BITFIELD) | ||
113 | __u8 resv2:4, | ||
114 | suppress:1, | ||
115 | qrv:3; | ||
116 | #else | ||
117 | #error "Please fix <asm/byteorder.h>" | ||
118 | #endif | ||
119 | __u8 qqic; | ||
120 | __be16 nsrcs; | ||
121 | struct in6_addr srcs[0]; | ||
122 | }; | 80 | }; |
123 | 81 | ||
124 | static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT; | 82 | static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT; |
@@ -157,14 +115,6 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml, | |||
157 | ((idev)->mc_v1_seen && \ | 115 | ((idev)->mc_v1_seen && \ |
158 | time_before(jiffies, (idev)->mc_v1_seen))) | 116 | time_before(jiffies, (idev)->mc_v1_seen))) |
159 | 117 | ||
160 | #define MLDV2_MASK(value, nb) ((nb)>=32 ? (value) : ((1<<(nb))-1) & (value)) | ||
161 | #define MLDV2_EXP(thresh, nbmant, nbexp, value) \ | ||
162 | ((value) < (thresh) ? (value) : \ | ||
163 | ((MLDV2_MASK(value, nbmant) | (1<<(nbmant))) << \ | ||
164 | (MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp)))) | ||
165 | |||
166 | #define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value) | ||
167 | |||
168 | #define IPV6_MLD_MAX_MSF 64 | 118 | #define IPV6_MLD_MAX_MSF 64 |
169 | 119 | ||
170 | int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF; | 120 | int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF; |
@@ -1161,7 +1111,7 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1161 | struct in6_addr *group; | 1111 | struct in6_addr *group; |
1162 | unsigned long max_delay; | 1112 | unsigned long max_delay; |
1163 | struct inet6_dev *idev; | 1113 | struct inet6_dev *idev; |
1164 | struct icmp6hdr *hdr; | 1114 | struct mld_msg *mld; |
1165 | int group_type; | 1115 | int group_type; |
1166 | int mark = 0; | 1116 | int mark = 0; |
1167 | int len; | 1117 | int len; |
@@ -1182,8 +1132,8 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1182 | if (idev == NULL) | 1132 | if (idev == NULL) |
1183 | return 0; | 1133 | return 0; |
1184 | 1134 | ||
1185 | hdr = icmp6_hdr(skb); | 1135 | mld = (struct mld_msg *)icmp6_hdr(skb); |
1186 | group = (struct in6_addr *) (hdr + 1); | 1136 | group = &mld->mld_mca; |
1187 | group_type = ipv6_addr_type(group); | 1137 | group_type = ipv6_addr_type(group); |
1188 | 1138 | ||
1189 | if (group_type != IPV6_ADDR_ANY && | 1139 | if (group_type != IPV6_ADDR_ANY && |
@@ -1197,7 +1147,7 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1197 | /* MLDv1 router present */ | 1147 | /* MLDv1 router present */ |
1198 | 1148 | ||
1199 | /* Translate milliseconds to jiffies */ | 1149 | /* Translate milliseconds to jiffies */ |
1200 | max_delay = (ntohs(hdr->icmp6_maxdelay)*HZ)/1000; | 1150 | max_delay = (ntohs(mld->mld_maxdelay)*HZ)/1000; |
1201 | 1151 | ||
1202 | switchback = (idev->mc_qrv + 1) * max_delay; | 1152 | switchback = (idev->mc_qrv + 1) * max_delay; |
1203 | idev->mc_v1_seen = jiffies + switchback; | 1153 | idev->mc_v1_seen = jiffies + switchback; |
@@ -1216,14 +1166,14 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1216 | return -EINVAL; | 1166 | return -EINVAL; |
1217 | } | 1167 | } |
1218 | mlh2 = (struct mld2_query *)skb_transport_header(skb); | 1168 | mlh2 = (struct mld2_query *)skb_transport_header(skb); |
1219 | max_delay = (MLDV2_MRC(ntohs(mlh2->mrc))*HZ)/1000; | 1169 | max_delay = (MLDV2_MRC(ntohs(mlh2->mld2q_mrc))*HZ)/1000; |
1220 | if (!max_delay) | 1170 | if (!max_delay) |
1221 | max_delay = 1; | 1171 | max_delay = 1; |
1222 | idev->mc_maxdelay = max_delay; | 1172 | idev->mc_maxdelay = max_delay; |
1223 | if (mlh2->qrv) | 1173 | if (mlh2->mld2q_qrv) |
1224 | idev->mc_qrv = mlh2->qrv; | 1174 | idev->mc_qrv = mlh2->mld2q_qrv; |
1225 | if (group_type == IPV6_ADDR_ANY) { /* general query */ | 1175 | if (group_type == IPV6_ADDR_ANY) { /* general query */ |
1226 | if (mlh2->nsrcs) { | 1176 | if (mlh2->mld2q_nsrcs) { |
1227 | in6_dev_put(idev); | 1177 | in6_dev_put(idev); |
1228 | return -EINVAL; /* no sources allowed */ | 1178 | return -EINVAL; /* no sources allowed */ |
1229 | } | 1179 | } |
@@ -1232,9 +1182,9 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1232 | return 0; | 1182 | return 0; |
1233 | } | 1183 | } |
1234 | /* mark sources to include, if group & source-specific */ | 1184 | /* mark sources to include, if group & source-specific */ |
1235 | if (mlh2->nsrcs != 0) { | 1185 | if (mlh2->mld2q_nsrcs != 0) { |
1236 | if (!pskb_may_pull(skb, srcs_offset + | 1186 | if (!pskb_may_pull(skb, srcs_offset + |
1237 | ntohs(mlh2->nsrcs) * sizeof(struct in6_addr))) { | 1187 | ntohs(mlh2->mld2q_nsrcs) * sizeof(struct in6_addr))) { |
1238 | in6_dev_put(idev); | 1188 | in6_dev_put(idev); |
1239 | return -EINVAL; | 1189 | return -EINVAL; |
1240 | } | 1190 | } |
@@ -1270,7 +1220,7 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1270 | ma->mca_flags &= ~MAF_GSQUERY; | 1220 | ma->mca_flags &= ~MAF_GSQUERY; |
1271 | } | 1221 | } |
1272 | if (!(ma->mca_flags & MAF_GSQUERY) || | 1222 | if (!(ma->mca_flags & MAF_GSQUERY) || |
1273 | mld_marksources(ma, ntohs(mlh2->nsrcs), mlh2->srcs)) | 1223 | mld_marksources(ma, ntohs(mlh2->mld2q_nsrcs), mlh2->mld2q_srcs)) |
1274 | igmp6_group_queried(ma, max_delay); | 1224 | igmp6_group_queried(ma, max_delay); |
1275 | spin_unlock_bh(&ma->mca_lock); | 1225 | spin_unlock_bh(&ma->mca_lock); |
1276 | break; | 1226 | break; |
@@ -1286,9 +1236,8 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1286 | int igmp6_event_report(struct sk_buff *skb) | 1236 | int igmp6_event_report(struct sk_buff *skb) |
1287 | { | 1237 | { |
1288 | struct ifmcaddr6 *ma; | 1238 | struct ifmcaddr6 *ma; |
1289 | struct in6_addr *addrp; | ||
1290 | struct inet6_dev *idev; | 1239 | struct inet6_dev *idev; |
1291 | struct icmp6hdr *hdr; | 1240 | struct mld_msg *mld; |
1292 | int addr_type; | 1241 | int addr_type; |
1293 | 1242 | ||
1294 | /* Our own report looped back. Ignore it. */ | 1243 | /* Our own report looped back. Ignore it. */ |
@@ -1300,10 +1249,10 @@ int igmp6_event_report(struct sk_buff *skb) | |||
1300 | skb->pkt_type != PACKET_BROADCAST) | 1249 | skb->pkt_type != PACKET_BROADCAST) |
1301 | return 0; | 1250 | return 0; |
1302 | 1251 | ||
1303 | if (!pskb_may_pull(skb, sizeof(struct in6_addr))) | 1252 | if (!pskb_may_pull(skb, sizeof(*mld) - sizeof(struct icmp6hdr))) |
1304 | return -EINVAL; | 1253 | return -EINVAL; |
1305 | 1254 | ||
1306 | hdr = icmp6_hdr(skb); | 1255 | mld = (struct mld_msg *)icmp6_hdr(skb); |
1307 | 1256 | ||
1308 | /* Drop reports with not link local source */ | 1257 | /* Drop reports with not link local source */ |
1309 | addr_type = ipv6_addr_type(&ipv6_hdr(skb)->saddr); | 1258 | addr_type = ipv6_addr_type(&ipv6_hdr(skb)->saddr); |
@@ -1311,8 +1260,6 @@ int igmp6_event_report(struct sk_buff *skb) | |||
1311 | !(addr_type&IPV6_ADDR_LINKLOCAL)) | 1260 | !(addr_type&IPV6_ADDR_LINKLOCAL)) |
1312 | return -EINVAL; | 1261 | return -EINVAL; |
1313 | 1262 | ||
1314 | addrp = (struct in6_addr *) (hdr + 1); | ||
1315 | |||
1316 | idev = in6_dev_get(skb->dev); | 1263 | idev = in6_dev_get(skb->dev); |
1317 | if (idev == NULL) | 1264 | if (idev == NULL) |
1318 | return -ENODEV; | 1265 | return -ENODEV; |
@@ -1323,7 +1270,7 @@ int igmp6_event_report(struct sk_buff *skb) | |||
1323 | 1270 | ||
1324 | read_lock_bh(&idev->lock); | 1271 | read_lock_bh(&idev->lock); |
1325 | for (ma = idev->mc_list; ma; ma=ma->next) { | 1272 | for (ma = idev->mc_list; ma; ma=ma->next) { |
1326 | if (ipv6_addr_equal(&ma->mca_addr, addrp)) { | 1273 | if (ipv6_addr_equal(&ma->mca_addr, &mld->mld_mca)) { |
1327 | spin_lock(&ma->mca_lock); | 1274 | spin_lock(&ma->mca_lock); |
1328 | if (del_timer(&ma->mca_timer)) | 1275 | if (del_timer(&ma->mca_timer)) |
1329 | atomic_dec(&ma->mca_refcnt); | 1276 | atomic_dec(&ma->mca_refcnt); |
@@ -1432,11 +1379,11 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) | |||
1432 | skb_set_transport_header(skb, skb_tail_pointer(skb) - skb->data); | 1379 | skb_set_transport_header(skb, skb_tail_pointer(skb) - skb->data); |
1433 | skb_put(skb, sizeof(*pmr)); | 1380 | skb_put(skb, sizeof(*pmr)); |
1434 | pmr = (struct mld2_report *)skb_transport_header(skb); | 1381 | pmr = (struct mld2_report *)skb_transport_header(skb); |
1435 | pmr->type = ICMPV6_MLD2_REPORT; | 1382 | pmr->mld2r_type = ICMPV6_MLD2_REPORT; |
1436 | pmr->resv1 = 0; | 1383 | pmr->mld2r_resv1 = 0; |
1437 | pmr->csum = 0; | 1384 | pmr->mld2r_cksum = 0; |
1438 | pmr->resv2 = 0; | 1385 | pmr->mld2r_resv2 = 0; |
1439 | pmr->ngrec = 0; | 1386 | pmr->mld2r_ngrec = 0; |
1440 | return skb; | 1387 | return skb; |
1441 | } | 1388 | } |
1442 | 1389 | ||
@@ -1458,9 +1405,10 @@ static void mld_sendpack(struct sk_buff *skb) | |||
1458 | mldlen = skb->tail - skb->transport_header; | 1405 | mldlen = skb->tail - skb->transport_header; |
1459 | pip6->payload_len = htons(payload_len); | 1406 | pip6->payload_len = htons(payload_len); |
1460 | 1407 | ||
1461 | pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen, | 1408 | pmr->mld2r_cksum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen, |
1462 | IPPROTO_ICMPV6, csum_partial(skb_transport_header(skb), | 1409 | IPPROTO_ICMPV6, |
1463 | mldlen, 0)); | 1410 | csum_partial(skb_transport_header(skb), |
1411 | mldlen, 0)); | ||
1464 | 1412 | ||
1465 | dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr); | 1413 | dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr); |
1466 | 1414 | ||
@@ -1521,7 +1469,7 @@ static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1521 | pgr->grec_nsrcs = 0; | 1469 | pgr->grec_nsrcs = 0; |
1522 | pgr->grec_mca = pmc->mca_addr; /* structure copy */ | 1470 | pgr->grec_mca = pmc->mca_addr; /* structure copy */ |
1523 | pmr = (struct mld2_report *)skb_transport_header(skb); | 1471 | pmr = (struct mld2_report *)skb_transport_header(skb); |
1524 | pmr->ngrec = htons(ntohs(pmr->ngrec)+1); | 1472 | pmr->mld2r_ngrec = htons(ntohs(pmr->mld2r_ngrec)+1); |
1525 | *ppgr = pgr; | 1473 | *ppgr = pgr; |
1526 | return skb; | 1474 | return skb; |
1527 | } | 1475 | } |
@@ -1557,7 +1505,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1557 | 1505 | ||
1558 | /* EX and TO_EX get a fresh packet, if needed */ | 1506 | /* EX and TO_EX get a fresh packet, if needed */ |
1559 | if (truncate) { | 1507 | if (truncate) { |
1560 | if (pmr && pmr->ngrec && | 1508 | if (pmr && pmr->mld2r_ngrec && |
1561 | AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { | 1509 | AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { |
1562 | if (skb) | 1510 | if (skb) |
1563 | mld_sendpack(skb); | 1511 | mld_sendpack(skb); |
@@ -1770,9 +1718,8 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1770 | struct sock *sk = net->ipv6.igmp_sk; | 1718 | struct sock *sk = net->ipv6.igmp_sk; |
1771 | struct inet6_dev *idev; | 1719 | struct inet6_dev *idev; |
1772 | struct sk_buff *skb; | 1720 | struct sk_buff *skb; |
1773 | struct icmp6hdr *hdr; | 1721 | struct mld_msg *hdr; |
1774 | const struct in6_addr *snd_addr, *saddr; | 1722 | const struct in6_addr *snd_addr, *saddr; |
1775 | struct in6_addr *addrp; | ||
1776 | struct in6_addr addr_buf; | 1723 | struct in6_addr addr_buf; |
1777 | int err, len, payload_len, full_len; | 1724 | int err, len, payload_len, full_len; |
1778 | u8 ra[8] = { IPPROTO_ICMPV6, 0, | 1725 | u8 ra[8] = { IPPROTO_ICMPV6, 0, |
@@ -1820,16 +1767,14 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1820 | 1767 | ||
1821 | memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra)); | 1768 | memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra)); |
1822 | 1769 | ||
1823 | hdr = (struct icmp6hdr *) skb_put(skb, sizeof(struct icmp6hdr)); | 1770 | hdr = (struct mld_msg *) skb_put(skb, sizeof(struct mld_msg)); |
1824 | memset(hdr, 0, sizeof(struct icmp6hdr)); | 1771 | memset(hdr, 0, sizeof(struct mld_msg)); |
1825 | hdr->icmp6_type = type; | 1772 | hdr->mld_type = type; |
1773 | ipv6_addr_copy(&hdr->mld_mca, addr); | ||
1826 | 1774 | ||
1827 | addrp = (struct in6_addr *) skb_put(skb, sizeof(struct in6_addr)); | 1775 | hdr->mld_cksum = csum_ipv6_magic(saddr, snd_addr, len, |
1828 | ipv6_addr_copy(addrp, addr); | 1776 | IPPROTO_ICMPV6, |
1829 | 1777 | csum_partial(hdr, len, 0)); | |
1830 | hdr->icmp6_cksum = csum_ipv6_magic(saddr, snd_addr, len, | ||
1831 | IPPROTO_ICMPV6, | ||
1832 | csum_partial(hdr, len, 0)); | ||
1833 | 1778 | ||
1834 | idev = in6_dev_get(skb->dev); | 1779 | idev = in6_dev_get(skb->dev); |
1835 | 1780 | ||
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 554b48b6e993..4a4dcbe4f8b2 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -381,7 +381,7 @@ static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb) | |||
381 | } | 381 | } |
382 | 382 | ||
383 | /* Charge it to the socket. */ | 383 | /* Charge it to the socket. */ |
384 | if (sock_queue_rcv_skb(sk, skb) < 0) { | 384 | if (ip_queue_rcv_skb(sk, skb) < 0) { |
385 | kfree_skb(skb); | 385 | kfree_skb(skb); |
386 | return NET_RX_DROP; | 386 | return NET_RX_DROP; |
387 | } | 387 | } |
@@ -461,6 +461,9 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
461 | if (flags & MSG_ERRQUEUE) | 461 | if (flags & MSG_ERRQUEUE) |
462 | return ipv6_recv_error(sk, msg, len); | 462 | return ipv6_recv_error(sk, msg, len); |
463 | 463 | ||
464 | if (np->rxpmtu && np->rxopt.bits.rxpmtu) | ||
465 | return ipv6_recv_rxpmtu(sk, msg, len); | ||
466 | |||
464 | skb = skb_recv_datagram(sk, flags, noblock, &err); | 467 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
465 | if (!skb) | 468 | if (!skb) |
466 | goto out; | 469 | goto out; |
@@ -733,6 +736,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
733 | int addr_len = msg->msg_namelen; | 736 | int addr_len = msg->msg_namelen; |
734 | int hlimit = -1; | 737 | int hlimit = -1; |
735 | int tclass = -1; | 738 | int tclass = -1; |
739 | int dontfrag = -1; | ||
736 | u16 proto; | 740 | u16 proto; |
737 | int err; | 741 | int err; |
738 | 742 | ||
@@ -811,7 +815,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
811 | memset(opt, 0, sizeof(struct ipv6_txoptions)); | 815 | memset(opt, 0, sizeof(struct ipv6_txoptions)); |
812 | opt->tot_len = sizeof(struct ipv6_txoptions); | 816 | opt->tot_len = sizeof(struct ipv6_txoptions); |
813 | 817 | ||
814 | err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit, &tclass); | 818 | err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit, |
819 | &tclass, &dontfrag); | ||
815 | if (err < 0) { | 820 | if (err < 0) { |
816 | fl6_sock_release(flowlabel); | 821 | fl6_sock_release(flowlabel); |
817 | return err; | 822 | return err; |
@@ -880,6 +885,9 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
880 | if (tclass < 0) | 885 | if (tclass < 0) |
881 | tclass = np->tclass; | 886 | tclass = np->tclass; |
882 | 887 | ||
888 | if (dontfrag < 0) | ||
889 | dontfrag = np->dontfrag; | ||
890 | |||
883 | if (msg->msg_flags&MSG_CONFIRM) | 891 | if (msg->msg_flags&MSG_CONFIRM) |
884 | goto do_confirm; | 892 | goto do_confirm; |
885 | 893 | ||
@@ -890,7 +898,7 @@ back_from_confirm: | |||
890 | lock_sock(sk); | 898 | lock_sock(sk); |
891 | err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, | 899 | err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, |
892 | len, 0, hlimit, tclass, opt, &fl, (struct rt6_info*)dst, | 900 | len, 0, hlimit, tclass, opt, &fl, (struct rt6_info*)dst, |
893 | msg->msg_flags); | 901 | msg->msg_flags, dontfrag); |
894 | 902 | ||
895 | if (err) | 903 | if (err) |
896 | ip6_flush_pending_frames(sk); | 904 | ip6_flush_pending_frames(sk); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index c2438e8cb9d0..05ebd7833043 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -815,7 +815,7 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk, | |||
815 | { | 815 | { |
816 | int flags = 0; | 816 | int flags = 0; |
817 | 817 | ||
818 | if (rt6_need_strict(&fl->fl6_dst)) | 818 | if (fl->oif || rt6_need_strict(&fl->fl6_dst)) |
819 | flags |= RT6_LOOKUP_F_IFACE; | 819 | flags |= RT6_LOOKUP_F_IFACE; |
820 | 820 | ||
821 | if (!ipv6_addr_any(&fl->fl6_src)) | 821 | if (!ipv6_addr_any(&fl->fl6_src)) |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index bd5ef7b6e48e..6603511e3673 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -353,6 +353,11 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
353 | if (sk->sk_state == TCP_CLOSE) | 353 | if (sk->sk_state == TCP_CLOSE) |
354 | goto out; | 354 | goto out; |
355 | 355 | ||
356 | if (ipv6_hdr(skb)->hop_limit < inet6_sk(sk)->min_hopcount) { | ||
357 | NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP); | ||
358 | goto out; | ||
359 | } | ||
360 | |||
356 | tp = tcp_sk(sk); | 361 | tp = tcp_sk(sk); |
357 | seq = ntohl(th->seq); | 362 | seq = ntohl(th->seq); |
358 | if (sk->sk_state != TCP_LISTEN && | 363 | if (sk->sk_state != TCP_LISTEN && |
@@ -1018,7 +1023,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | |||
1018 | skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len); | 1023 | skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len); |
1019 | 1024 | ||
1020 | t1 = (struct tcphdr *) skb_push(buff, tot_len); | 1025 | t1 = (struct tcphdr *) skb_push(buff, tot_len); |
1021 | skb_reset_transport_header(skb); | 1026 | skb_reset_transport_header(buff); |
1022 | 1027 | ||
1023 | /* Swap the send and the receive. */ | 1028 | /* Swap the send and the receive. */ |
1024 | memset(t1, 0, sizeof(*t1)); | 1029 | memset(t1, 0, sizeof(*t1)); |
@@ -1050,12 +1055,13 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | |||
1050 | } | 1055 | } |
1051 | #endif | 1056 | #endif |
1052 | 1057 | ||
1053 | buff->csum = csum_partial(t1, tot_len, 0); | ||
1054 | |||
1055 | memset(&fl, 0, sizeof(fl)); | 1058 | memset(&fl, 0, sizeof(fl)); |
1056 | ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); | 1059 | ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); |
1057 | ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr); | 1060 | ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr); |
1058 | 1061 | ||
1062 | buff->ip_summed = CHECKSUM_PARTIAL; | ||
1063 | buff->csum = 0; | ||
1064 | |||
1059 | __tcp_v6_send_check(buff, &fl.fl6_src, &fl.fl6_dst); | 1065 | __tcp_v6_send_check(buff, &fl.fl6_src, &fl.fl6_dst); |
1060 | 1066 | ||
1061 | fl.proto = IPPROTO_TCP; | 1067 | fl.proto = IPPROTO_TCP; |
@@ -1234,12 +1240,12 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1234 | goto drop_and_free; | 1240 | goto drop_and_free; |
1235 | 1241 | ||
1236 | /* Secret recipe starts with IP addresses */ | 1242 | /* Secret recipe starts with IP addresses */ |
1237 | d = &ipv6_hdr(skb)->daddr.s6_addr32[0]; | 1243 | d = (__force u32 *)&ipv6_hdr(skb)->daddr.s6_addr32[0]; |
1238 | *mess++ ^= *d++; | 1244 | *mess++ ^= *d++; |
1239 | *mess++ ^= *d++; | 1245 | *mess++ ^= *d++; |
1240 | *mess++ ^= *d++; | 1246 | *mess++ ^= *d++; |
1241 | *mess++ ^= *d++; | 1247 | *mess++ ^= *d++; |
1242 | d = &ipv6_hdr(skb)->saddr.s6_addr32[0]; | 1248 | d = (__force u32 *)&ipv6_hdr(skb)->saddr.s6_addr32[0]; |
1243 | *mess++ ^= *d++; | 1249 | *mess++ ^= *d++; |
1244 | *mess++ ^= *d++; | 1250 | *mess++ ^= *d++; |
1245 | *mess++ ^= *d++; | 1251 | *mess++ ^= *d++; |
@@ -1677,6 +1683,7 @@ ipv6_pktoptions: | |||
1677 | static int tcp_v6_rcv(struct sk_buff *skb) | 1683 | static int tcp_v6_rcv(struct sk_buff *skb) |
1678 | { | 1684 | { |
1679 | struct tcphdr *th; | 1685 | struct tcphdr *th; |
1686 | struct ipv6hdr *hdr; | ||
1680 | struct sock *sk; | 1687 | struct sock *sk; |
1681 | int ret; | 1688 | int ret; |
1682 | struct net *net = dev_net(skb->dev); | 1689 | struct net *net = dev_net(skb->dev); |
@@ -1703,12 +1710,13 @@ static int tcp_v6_rcv(struct sk_buff *skb) | |||
1703 | goto bad_packet; | 1710 | goto bad_packet; |
1704 | 1711 | ||
1705 | th = tcp_hdr(skb); | 1712 | th = tcp_hdr(skb); |
1713 | hdr = ipv6_hdr(skb); | ||
1706 | TCP_SKB_CB(skb)->seq = ntohl(th->seq); | 1714 | TCP_SKB_CB(skb)->seq = ntohl(th->seq); |
1707 | TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + | 1715 | TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + |
1708 | skb->len - th->doff*4); | 1716 | skb->len - th->doff*4); |
1709 | TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); | 1717 | TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); |
1710 | TCP_SKB_CB(skb)->when = 0; | 1718 | TCP_SKB_CB(skb)->when = 0; |
1711 | TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb)); | 1719 | TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(hdr); |
1712 | TCP_SKB_CB(skb)->sacked = 0; | 1720 | TCP_SKB_CB(skb)->sacked = 0; |
1713 | 1721 | ||
1714 | sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest); | 1722 | sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest); |
@@ -1719,6 +1727,11 @@ process: | |||
1719 | if (sk->sk_state == TCP_TIME_WAIT) | 1727 | if (sk->sk_state == TCP_TIME_WAIT) |
1720 | goto do_time_wait; | 1728 | goto do_time_wait; |
1721 | 1729 | ||
1730 | if (hdr->hop_limit < inet6_sk(sk)->min_hopcount) { | ||
1731 | NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP); | ||
1732 | goto discard_and_relse; | ||
1733 | } | ||
1734 | |||
1722 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) | 1735 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) |
1723 | goto discard_and_relse; | 1736 | goto discard_and_relse; |
1724 | 1737 | ||
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 90824852f598..3d7a2c0b836a 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -91,9 +91,9 @@ static unsigned int udp6_portaddr_hash(struct net *net, | |||
91 | if (ipv6_addr_any(addr6)) | 91 | if (ipv6_addr_any(addr6)) |
92 | hash = jhash_1word(0, mix); | 92 | hash = jhash_1word(0, mix); |
93 | else if (ipv6_addr_v4mapped(addr6)) | 93 | else if (ipv6_addr_v4mapped(addr6)) |
94 | hash = jhash_1word(addr6->s6_addr32[3], mix); | 94 | hash = jhash_1word((__force u32)addr6->s6_addr32[3], mix); |
95 | else | 95 | else |
96 | hash = jhash2(addr6->s6_addr32, 4, mix); | 96 | hash = jhash2((__force u32 *)addr6->s6_addr32, 4, mix); |
97 | 97 | ||
98 | return hash ^ port; | 98 | return hash ^ port; |
99 | } | 99 | } |
@@ -335,6 +335,9 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
335 | if (flags & MSG_ERRQUEUE) | 335 | if (flags & MSG_ERRQUEUE) |
336 | return ipv6_recv_error(sk, msg, len); | 336 | return ipv6_recv_error(sk, msg, len); |
337 | 337 | ||
338 | if (np->rxpmtu && np->rxopt.bits.rxpmtu) | ||
339 | return ipv6_recv_rxpmtu(sk, msg, len); | ||
340 | |||
338 | try_again: | 341 | try_again: |
339 | skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), | 342 | skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), |
340 | &peeked, &err); | 343 | &peeked, &err); |
@@ -421,7 +424,7 @@ out: | |||
421 | return err; | 424 | return err; |
422 | 425 | ||
423 | csum_copy_err: | 426 | csum_copy_err: |
424 | lock_sock(sk); | 427 | lock_sock_bh(sk); |
425 | if (!skb_kill_datagram(sk, skb, flags)) { | 428 | if (!skb_kill_datagram(sk, skb, flags)) { |
426 | if (is_udp4) | 429 | if (is_udp4) |
427 | UDP_INC_STATS_USER(sock_net(sk), | 430 | UDP_INC_STATS_USER(sock_net(sk), |
@@ -430,7 +433,7 @@ csum_copy_err: | |||
430 | UDP6_INC_STATS_USER(sock_net(sk), | 433 | UDP6_INC_STATS_USER(sock_net(sk), |
431 | UDP_MIB_INERRORS, is_udplite); | 434 | UDP_MIB_INERRORS, is_udplite); |
432 | } | 435 | } |
433 | release_sock(sk); | 436 | unlock_sock_bh(sk); |
434 | 437 | ||
435 | if (flags & MSG_DONTWAIT) | 438 | if (flags & MSG_DONTWAIT) |
436 | return -EAGAIN; | 439 | return -EAGAIN; |
@@ -511,7 +514,7 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) | |||
511 | goto drop; | 514 | goto drop; |
512 | } | 515 | } |
513 | 516 | ||
514 | if ((rc = sock_queue_rcv_skb(sk, skb)) < 0) { | 517 | if ((rc = ip_queue_rcv_skb(sk, skb)) < 0) { |
515 | /* Note that an ENOMEM error is charged twice */ | 518 | /* Note that an ENOMEM error is charged twice */ |
516 | if (rc == -ENOMEM) | 519 | if (rc == -ENOMEM) |
517 | UDP6_INC_STATS_BH(sock_net(sk), | 520 | UDP6_INC_STATS_BH(sock_net(sk), |
@@ -581,6 +584,10 @@ static void flush_stack(struct sock **stack, unsigned int count, | |||
581 | 584 | ||
582 | sk = stack[i]; | 585 | sk = stack[i]; |
583 | if (skb1) { | 586 | if (skb1) { |
587 | if (sk_rcvqueues_full(sk, skb)) { | ||
588 | kfree_skb(skb1); | ||
589 | goto drop; | ||
590 | } | ||
584 | bh_lock_sock(sk); | 591 | bh_lock_sock(sk); |
585 | if (!sock_owned_by_user(sk)) | 592 | if (!sock_owned_by_user(sk)) |
586 | udpv6_queue_rcv_skb(sk, skb1); | 593 | udpv6_queue_rcv_skb(sk, skb1); |
@@ -692,7 +699,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, | |||
692 | u32 ulen = 0; | 699 | u32 ulen = 0; |
693 | 700 | ||
694 | if (!pskb_may_pull(skb, sizeof(struct udphdr))) | 701 | if (!pskb_may_pull(skb, sizeof(struct udphdr))) |
695 | goto short_packet; | 702 | goto discard; |
696 | 703 | ||
697 | saddr = &ipv6_hdr(skb)->saddr; | 704 | saddr = &ipv6_hdr(skb)->saddr; |
698 | daddr = &ipv6_hdr(skb)->daddr; | 705 | daddr = &ipv6_hdr(skb)->daddr; |
@@ -756,6 +763,10 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, | |||
756 | 763 | ||
757 | /* deliver */ | 764 | /* deliver */ |
758 | 765 | ||
766 | if (sk_rcvqueues_full(sk, skb)) { | ||
767 | sock_put(sk); | ||
768 | goto discard; | ||
769 | } | ||
759 | bh_lock_sock(sk); | 770 | bh_lock_sock(sk); |
760 | if (!sock_owned_by_user(sk)) | 771 | if (!sock_owned_by_user(sk)) |
761 | udpv6_queue_rcv_skb(sk, skb); | 772 | udpv6_queue_rcv_skb(sk, skb); |
@@ -770,9 +781,14 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, | |||
770 | return 0; | 781 | return 0; |
771 | 782 | ||
772 | short_packet: | 783 | short_packet: |
773 | LIMIT_NETDEBUG(KERN_DEBUG "UDP%sv6: short packet: %d/%u\n", | 784 | LIMIT_NETDEBUG(KERN_DEBUG "UDP%sv6: short packet: From [%pI6c]:%u %d/%d to [%pI6c]:%u\n", |
774 | proto == IPPROTO_UDPLITE ? "-Lite" : "", | 785 | proto == IPPROTO_UDPLITE ? "-Lite" : "", |
775 | ulen, skb->len); | 786 | saddr, |
787 | ntohs(uh->source), | ||
788 | ulen, | ||
789 | skb->len, | ||
790 | daddr, | ||
791 | ntohs(uh->dest)); | ||
776 | 792 | ||
777 | discard: | 793 | discard: |
778 | UDP6_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); | 794 | UDP6_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); |
@@ -919,6 +935,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
919 | int ulen = len; | 935 | int ulen = len; |
920 | int hlimit = -1; | 936 | int hlimit = -1; |
921 | int tclass = -1; | 937 | int tclass = -1; |
938 | int dontfrag = -1; | ||
922 | int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; | 939 | int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; |
923 | int err; | 940 | int err; |
924 | int connected = 0; | 941 | int connected = 0; |
@@ -1049,7 +1066,8 @@ do_udp_sendmsg: | |||
1049 | memset(opt, 0, sizeof(struct ipv6_txoptions)); | 1066 | memset(opt, 0, sizeof(struct ipv6_txoptions)); |
1050 | opt->tot_len = sizeof(*opt); | 1067 | opt->tot_len = sizeof(*opt); |
1051 | 1068 | ||
1052 | err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit, &tclass); | 1069 | err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit, |
1070 | &tclass, &dontfrag); | ||
1053 | if (err < 0) { | 1071 | if (err < 0) { |
1054 | fl6_sock_release(flowlabel); | 1072 | fl6_sock_release(flowlabel); |
1055 | return err; | 1073 | return err; |
@@ -1120,6 +1138,9 @@ do_udp_sendmsg: | |||
1120 | if (tclass < 0) | 1138 | if (tclass < 0) |
1121 | tclass = np->tclass; | 1139 | tclass = np->tclass; |
1122 | 1140 | ||
1141 | if (dontfrag < 0) | ||
1142 | dontfrag = np->dontfrag; | ||
1143 | |||
1123 | if (msg->msg_flags&MSG_CONFIRM) | 1144 | if (msg->msg_flags&MSG_CONFIRM) |
1124 | goto do_confirm; | 1145 | goto do_confirm; |
1125 | back_from_confirm: | 1146 | back_from_confirm: |
@@ -1143,7 +1164,7 @@ do_append_data: | |||
1143 | err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen, | 1164 | err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen, |
1144 | sizeof(struct udphdr), hlimit, tclass, opt, &fl, | 1165 | sizeof(struct udphdr), hlimit, tclass, opt, &fl, |
1145 | (struct rt6_info*)dst, | 1166 | (struct rt6_info*)dst, |
1146 | corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags); | 1167 | corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, dontfrag); |
1147 | if (err) | 1168 | if (err) |
1148 | udp_v6_flush_pending_frames(sk); | 1169 | udp_v6_flush_pending_frames(sk); |
1149 | else if (!corkreq) | 1170 | else if (!corkreq) |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 8c452fd5ceae..4a0e77e14468 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -94,7 +94,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, | |||
94 | xdst->u.dst.dev = dev; | 94 | xdst->u.dst.dev = dev; |
95 | dev_hold(dev); | 95 | dev_hold(dev); |
96 | 96 | ||
97 | xdst->u.rt6.rt6i_idev = in6_dev_get(rt->u.dst.dev); | 97 | xdst->u.rt6.rt6i_idev = in6_dev_get(dev); |
98 | if (!xdst->u.rt6.rt6i_idev) | 98 | if (!xdst->u.rt6.rt6i_idev) |
99 | return -ENODEV; | 99 | return -ENODEV; |
100 | 100 | ||
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 2a4efcea3423..79986a674f6e 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
@@ -347,7 +347,7 @@ static void irda_flow_indication(void *instance, void *sap, LOCAL_FLOW flow) | |||
347 | self->tx_flow = flow; | 347 | self->tx_flow = flow; |
348 | IRDA_DEBUG(1, "%s(), IrTTP wants us to start again\n", | 348 | IRDA_DEBUG(1, "%s(), IrTTP wants us to start again\n", |
349 | __func__); | 349 | __func__); |
350 | wake_up_interruptible(sk->sk_sleep); | 350 | wake_up_interruptible(sk_sleep(sk)); |
351 | break; | 351 | break; |
352 | default: | 352 | default: |
353 | IRDA_DEBUG(0, "%s(), Unknown flow command!\n", __func__); | 353 | IRDA_DEBUG(0, "%s(), Unknown flow command!\n", __func__); |
@@ -900,7 +900,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
900 | if (flags & O_NONBLOCK) | 900 | if (flags & O_NONBLOCK) |
901 | goto out; | 901 | goto out; |
902 | 902 | ||
903 | err = wait_event_interruptible(*(sk->sk_sleep), | 903 | err = wait_event_interruptible(*(sk_sleep(sk)), |
904 | skb_peek(&sk->sk_receive_queue)); | 904 | skb_peek(&sk->sk_receive_queue)); |
905 | if (err) | 905 | if (err) |
906 | goto out; | 906 | goto out; |
@@ -1066,7 +1066,7 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, | |||
1066 | goto out; | 1066 | goto out; |
1067 | 1067 | ||
1068 | err = -ERESTARTSYS; | 1068 | err = -ERESTARTSYS; |
1069 | if (wait_event_interruptible(*(sk->sk_sleep), | 1069 | if (wait_event_interruptible(*(sk_sleep(sk)), |
1070 | (sk->sk_state != TCP_SYN_SENT))) | 1070 | (sk->sk_state != TCP_SYN_SENT))) |
1071 | goto out; | 1071 | goto out; |
1072 | 1072 | ||
@@ -1318,7 +1318,7 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1318 | 1318 | ||
1319 | /* Check if IrTTP is wants us to slow down */ | 1319 | /* Check if IrTTP is wants us to slow down */ |
1320 | 1320 | ||
1321 | if (wait_event_interruptible(*(sk->sk_sleep), | 1321 | if (wait_event_interruptible(*(sk_sleep(sk)), |
1322 | (self->tx_flow != FLOW_STOP || sk->sk_state != TCP_ESTABLISHED))) { | 1322 | (self->tx_flow != FLOW_STOP || sk->sk_state != TCP_ESTABLISHED))) { |
1323 | err = -ERESTARTSYS; | 1323 | err = -ERESTARTSYS; |
1324 | goto out; | 1324 | goto out; |
@@ -1477,7 +1477,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, | |||
1477 | if (copied >= target) | 1477 | if (copied >= target) |
1478 | break; | 1478 | break; |
1479 | 1479 | ||
1480 | prepare_to_wait_exclusive(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 1480 | prepare_to_wait_exclusive(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
1481 | 1481 | ||
1482 | /* | 1482 | /* |
1483 | * POSIX 1003.1g mandates this order. | 1483 | * POSIX 1003.1g mandates this order. |
@@ -1497,7 +1497,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, | |||
1497 | /* Wait process until data arrives */ | 1497 | /* Wait process until data arrives */ |
1498 | schedule(); | 1498 | schedule(); |
1499 | 1499 | ||
1500 | finish_wait(sk->sk_sleep, &wait); | 1500 | finish_wait(sk_sleep(sk), &wait); |
1501 | 1501 | ||
1502 | if (err) | 1502 | if (err) |
1503 | goto out; | 1503 | goto out; |
@@ -1787,7 +1787,7 @@ static unsigned int irda_poll(struct file * file, struct socket *sock, | |||
1787 | IRDA_DEBUG(4, "%s()\n", __func__); | 1787 | IRDA_DEBUG(4, "%s()\n", __func__); |
1788 | 1788 | ||
1789 | lock_kernel(); | 1789 | lock_kernel(); |
1790 | poll_wait(file, sk->sk_sleep, wait); | 1790 | poll_wait(file, sk_sleep(sk), wait); |
1791 | mask = 0; | 1791 | mask = 0; |
1792 | 1792 | ||
1793 | /* Exceptional events? */ | 1793 | /* Exceptional events? */ |
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index c18286a2167b..8be324fe08b9 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
@@ -59,7 +59,7 @@ do { \ | |||
59 | DEFINE_WAIT(__wait); \ | 59 | DEFINE_WAIT(__wait); \ |
60 | long __timeo = timeo; \ | 60 | long __timeo = timeo; \ |
61 | ret = 0; \ | 61 | ret = 0; \ |
62 | prepare_to_wait(sk->sk_sleep, &__wait, TASK_INTERRUPTIBLE); \ | 62 | prepare_to_wait(sk_sleep(sk), &__wait, TASK_INTERRUPTIBLE); \ |
63 | while (!(condition)) { \ | 63 | while (!(condition)) { \ |
64 | if (!__timeo) { \ | 64 | if (!__timeo) { \ |
65 | ret = -EAGAIN; \ | 65 | ret = -EAGAIN; \ |
@@ -76,7 +76,7 @@ do { \ | |||
76 | if (ret) \ | 76 | if (ret) \ |
77 | break; \ | 77 | break; \ |
78 | } \ | 78 | } \ |
79 | finish_wait(sk->sk_sleep, &__wait); \ | 79 | finish_wait(sk_sleep(sk), &__wait); \ |
80 | } while (0) | 80 | } while (0) |
81 | 81 | ||
82 | #define iucv_sock_wait(sk, condition, timeo) \ | 82 | #define iucv_sock_wait(sk, condition, timeo) \ |
@@ -305,11 +305,14 @@ static inline int iucv_below_msglim(struct sock *sk) | |||
305 | */ | 305 | */ |
306 | static void iucv_sock_wake_msglim(struct sock *sk) | 306 | static void iucv_sock_wake_msglim(struct sock *sk) |
307 | { | 307 | { |
308 | read_lock(&sk->sk_callback_lock); | 308 | struct socket_wq *wq; |
309 | if (sk_has_sleeper(sk)) | 309 | |
310 | wake_up_interruptible_all(sk->sk_sleep); | 310 | rcu_read_lock(); |
311 | wq = rcu_dereference(sk->sk_wq); | ||
312 | if (wq_has_sleeper(wq)) | ||
313 | wake_up_interruptible_all(&wq->wait); | ||
311 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); | 314 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); |
312 | read_unlock(&sk->sk_callback_lock); | 315 | rcu_read_unlock(); |
313 | } | 316 | } |
314 | 317 | ||
315 | /* Timers */ | 318 | /* Timers */ |
@@ -795,7 +798,7 @@ static int iucv_sock_accept(struct socket *sock, struct socket *newsock, | |||
795 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); | 798 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); |
796 | 799 | ||
797 | /* Wait for an incoming connection */ | 800 | /* Wait for an incoming connection */ |
798 | add_wait_queue_exclusive(sk->sk_sleep, &wait); | 801 | add_wait_queue_exclusive(sk_sleep(sk), &wait); |
799 | while (!(nsk = iucv_accept_dequeue(sk, newsock))) { | 802 | while (!(nsk = iucv_accept_dequeue(sk, newsock))) { |
800 | set_current_state(TASK_INTERRUPTIBLE); | 803 | set_current_state(TASK_INTERRUPTIBLE); |
801 | if (!timeo) { | 804 | if (!timeo) { |
@@ -819,7 +822,7 @@ static int iucv_sock_accept(struct socket *sock, struct socket *newsock, | |||
819 | } | 822 | } |
820 | 823 | ||
821 | set_current_state(TASK_RUNNING); | 824 | set_current_state(TASK_RUNNING); |
822 | remove_wait_queue(sk->sk_sleep, &wait); | 825 | remove_wait_queue(sk_sleep(sk), &wait); |
823 | 826 | ||
824 | if (err) | 827 | if (err) |
825 | goto done; | 828 | goto done; |
@@ -1269,7 +1272,7 @@ unsigned int iucv_sock_poll(struct file *file, struct socket *sock, | |||
1269 | struct sock *sk = sock->sk; | 1272 | struct sock *sk = sock->sk; |
1270 | unsigned int mask = 0; | 1273 | unsigned int mask = 0; |
1271 | 1274 | ||
1272 | sock_poll_wait(file, sk->sk_sleep, wait); | 1275 | sock_poll_wait(file, sk_sleep(sk), wait); |
1273 | 1276 | ||
1274 | if (sk->sk_state == IUCV_LISTEN) | 1277 | if (sk->sk_state == IUCV_LISTEN) |
1275 | return iucv_accept_poll(sk); | 1278 | return iucv_accept_poll(sk); |
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index ecc7aea9efe4..1712af1c7b3f 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
@@ -1617,14 +1617,9 @@ EXPORT_SYMBOL_GPL(l2tp_session_create); | |||
1617 | 1617 | ||
1618 | static __net_init int l2tp_init_net(struct net *net) | 1618 | static __net_init int l2tp_init_net(struct net *net) |
1619 | { | 1619 | { |
1620 | struct l2tp_net *pn; | 1620 | struct l2tp_net *pn = net_generic(net, l2tp_net_id); |
1621 | int err; | ||
1622 | int hash; | 1621 | int hash; |
1623 | 1622 | ||
1624 | pn = kzalloc(sizeof(*pn), GFP_KERNEL); | ||
1625 | if (!pn) | ||
1626 | return -ENOMEM; | ||
1627 | |||
1628 | INIT_LIST_HEAD(&pn->l2tp_tunnel_list); | 1623 | INIT_LIST_HEAD(&pn->l2tp_tunnel_list); |
1629 | spin_lock_init(&pn->l2tp_tunnel_list_lock); | 1624 | spin_lock_init(&pn->l2tp_tunnel_list_lock); |
1630 | 1625 | ||
@@ -1633,33 +1628,11 @@ static __net_init int l2tp_init_net(struct net *net) | |||
1633 | 1628 | ||
1634 | spin_lock_init(&pn->l2tp_session_hlist_lock); | 1629 | spin_lock_init(&pn->l2tp_session_hlist_lock); |
1635 | 1630 | ||
1636 | err = net_assign_generic(net, l2tp_net_id, pn); | ||
1637 | if (err) | ||
1638 | goto out; | ||
1639 | |||
1640 | return 0; | 1631 | return 0; |
1641 | |||
1642 | out: | ||
1643 | kfree(pn); | ||
1644 | return err; | ||
1645 | } | ||
1646 | |||
1647 | static __net_exit void l2tp_exit_net(struct net *net) | ||
1648 | { | ||
1649 | struct l2tp_net *pn; | ||
1650 | |||
1651 | pn = net_generic(net, l2tp_net_id); | ||
1652 | /* | ||
1653 | * if someone has cached our net then | ||
1654 | * further net_generic call will return NULL | ||
1655 | */ | ||
1656 | net_assign_generic(net, l2tp_net_id, NULL); | ||
1657 | kfree(pn); | ||
1658 | } | 1632 | } |
1659 | 1633 | ||
1660 | static struct pernet_operations l2tp_net_ops = { | 1634 | static struct pernet_operations l2tp_net_ops = { |
1661 | .init = l2tp_init_net, | 1635 | .init = l2tp_init_net, |
1662 | .exit = l2tp_exit_net, | ||
1663 | .id = &l2tp_net_id, | 1636 | .id = &l2tp_net_id, |
1664 | .size = sizeof(struct l2tp_net), | 1637 | .size = sizeof(struct l2tp_net), |
1665 | }; | 1638 | }; |
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index ca1164afeb74..58c6c4cda73b 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c | |||
@@ -276,43 +276,16 @@ out: | |||
276 | 276 | ||
277 | static __net_init int l2tp_eth_init_net(struct net *net) | 277 | static __net_init int l2tp_eth_init_net(struct net *net) |
278 | { | 278 | { |
279 | struct l2tp_eth_net *pn; | 279 | struct l2tp_eth_net *pn = net_generic(net, l2tp_eth_net_id); |
280 | int err; | ||
281 | |||
282 | pn = kzalloc(sizeof(*pn), GFP_KERNEL); | ||
283 | if (!pn) | ||
284 | return -ENOMEM; | ||
285 | 280 | ||
286 | INIT_LIST_HEAD(&pn->l2tp_eth_dev_list); | 281 | INIT_LIST_HEAD(&pn->l2tp_eth_dev_list); |
287 | spin_lock_init(&pn->l2tp_eth_lock); | 282 | spin_lock_init(&pn->l2tp_eth_lock); |
288 | 283 | ||
289 | err = net_assign_generic(net, l2tp_eth_net_id, pn); | ||
290 | if (err) | ||
291 | goto out; | ||
292 | |||
293 | return 0; | 284 | return 0; |
294 | |||
295 | out: | ||
296 | kfree(pn); | ||
297 | return err; | ||
298 | } | ||
299 | |||
300 | static __net_exit void l2tp_eth_exit_net(struct net *net) | ||
301 | { | ||
302 | struct l2tp_eth_net *pn; | ||
303 | |||
304 | pn = net_generic(net, l2tp_eth_net_id); | ||
305 | /* | ||
306 | * if someone has cached our net then | ||
307 | * further net_generic call will return NULL | ||
308 | */ | ||
309 | net_assign_generic(net, l2tp_eth_net_id, NULL); | ||
310 | kfree(pn); | ||
311 | } | 285 | } |
312 | 286 | ||
313 | static __net_initdata struct pernet_operations l2tp_eth_net_ops = { | 287 | static __net_initdata struct pernet_operations l2tp_eth_net_ops = { |
314 | .init = l2tp_eth_init_net, | 288 | .init = l2tp_eth_init_net, |
315 | .exit = l2tp_eth_exit_net, | ||
316 | .id = &l2tp_eth_net_id, | 289 | .id = &l2tp_eth_net_id, |
317 | .size = sizeof(struct l2tp_eth_net), | 290 | .size = sizeof(struct l2tp_eth_net), |
318 | }; | 291 | }; |
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 2db6a9f75913..023ba820236f 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
@@ -536,7 +536,7 @@ static int llc_ui_wait_for_disc(struct sock *sk, long timeout) | |||
536 | int rc = 0; | 536 | int rc = 0; |
537 | 537 | ||
538 | while (1) { | 538 | while (1) { |
539 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 539 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
540 | if (sk_wait_event(sk, &timeout, sk->sk_state == TCP_CLOSE)) | 540 | if (sk_wait_event(sk, &timeout, sk->sk_state == TCP_CLOSE)) |
541 | break; | 541 | break; |
542 | rc = -ERESTARTSYS; | 542 | rc = -ERESTARTSYS; |
@@ -547,7 +547,7 @@ static int llc_ui_wait_for_disc(struct sock *sk, long timeout) | |||
547 | break; | 547 | break; |
548 | rc = 0; | 548 | rc = 0; |
549 | } | 549 | } |
550 | finish_wait(sk->sk_sleep, &wait); | 550 | finish_wait(sk_sleep(sk), &wait); |
551 | return rc; | 551 | return rc; |
552 | } | 552 | } |
553 | 553 | ||
@@ -556,13 +556,13 @@ static int llc_ui_wait_for_conn(struct sock *sk, long timeout) | |||
556 | DEFINE_WAIT(wait); | 556 | DEFINE_WAIT(wait); |
557 | 557 | ||
558 | while (1) { | 558 | while (1) { |
559 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 559 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
560 | if (sk_wait_event(sk, &timeout, sk->sk_state != TCP_SYN_SENT)) | 560 | if (sk_wait_event(sk, &timeout, sk->sk_state != TCP_SYN_SENT)) |
561 | break; | 561 | break; |
562 | if (signal_pending(current) || !timeout) | 562 | if (signal_pending(current) || !timeout) |
563 | break; | 563 | break; |
564 | } | 564 | } |
565 | finish_wait(sk->sk_sleep, &wait); | 565 | finish_wait(sk_sleep(sk), &wait); |
566 | return timeout; | 566 | return timeout; |
567 | } | 567 | } |
568 | 568 | ||
@@ -573,7 +573,7 @@ static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout) | |||
573 | int rc; | 573 | int rc; |
574 | 574 | ||
575 | while (1) { | 575 | while (1) { |
576 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 576 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
577 | rc = 0; | 577 | rc = 0; |
578 | if (sk_wait_event(sk, &timeout, | 578 | if (sk_wait_event(sk, &timeout, |
579 | (sk->sk_shutdown & RCV_SHUTDOWN) || | 579 | (sk->sk_shutdown & RCV_SHUTDOWN) || |
@@ -588,7 +588,7 @@ static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout) | |||
588 | if (!timeout) | 588 | if (!timeout) |
589 | break; | 589 | break; |
590 | } | 590 | } |
591 | finish_wait(sk->sk_sleep, &wait); | 591 | finish_wait(sk_sleep(sk), &wait); |
592 | return rc; | 592 | return rc; |
593 | } | 593 | } |
594 | 594 | ||
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 9598fdb4ad01..6bb9a9a94960 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -19,8 +19,9 @@ | |||
19 | #include "ieee80211_i.h" | 19 | #include "ieee80211_i.h" |
20 | #include "driver-ops.h" | 20 | #include "driver-ops.h" |
21 | 21 | ||
22 | void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | 22 | static void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, |
23 | u16 initiator, u16 reason) | 23 | u16 initiator, u16 reason, |
24 | bool from_timer) | ||
24 | { | 25 | { |
25 | struct ieee80211_local *local = sta->local; | 26 | struct ieee80211_local *local = sta->local; |
26 | struct tid_ampdu_rx *tid_rx; | 27 | struct tid_ampdu_rx *tid_rx; |
@@ -70,10 +71,17 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
70 | 71 | ||
71 | spin_unlock_bh(&sta->lock); | 72 | spin_unlock_bh(&sta->lock); |
72 | 73 | ||
73 | del_timer_sync(&tid_rx->session_timer); | 74 | if (!from_timer) |
75 | del_timer_sync(&tid_rx->session_timer); | ||
74 | kfree(tid_rx); | 76 | kfree(tid_rx); |
75 | } | 77 | } |
76 | 78 | ||
79 | void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | ||
80 | u16 initiator, u16 reason) | ||
81 | { | ||
82 | ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason, false); | ||
83 | } | ||
84 | |||
77 | /* | 85 | /* |
78 | * After accepting the AddBA Request we activated a timer, | 86 | * After accepting the AddBA Request we activated a timer, |
79 | * resetting it after each frame that arrives from the originator. | 87 | * resetting it after each frame that arrives from the originator. |
@@ -92,8 +100,8 @@ static void sta_rx_agg_session_timer_expired(unsigned long data) | |||
92 | #ifdef CONFIG_MAC80211_HT_DEBUG | 100 | #ifdef CONFIG_MAC80211_HT_DEBUG |
93 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); | 101 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); |
94 | #endif | 102 | #endif |
95 | __ieee80211_stop_rx_ba_session(sta, *ptid, WLAN_BACK_RECIPIENT, | 103 | ___ieee80211_stop_rx_ba_session(sta, *ptid, WLAN_BACK_RECIPIENT, |
96 | WLAN_REASON_QSTA_TIMEOUT); | 104 | WLAN_REASON_QSTA_TIMEOUT, true); |
97 | } | 105 | } |
98 | 106 | ||
99 | static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid, | 107 | static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid, |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 608063f11797..c163d0a149f4 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -184,10 +184,9 @@ static void sta_addba_resp_timer_expired(unsigned long data) | |||
184 | HT_AGG_STATE_REQ_STOP_BA_MSK)) != | 184 | HT_AGG_STATE_REQ_STOP_BA_MSK)) != |
185 | HT_ADDBA_REQUESTED_MSK) { | 185 | HT_ADDBA_REQUESTED_MSK) { |
186 | spin_unlock_bh(&sta->lock); | 186 | spin_unlock_bh(&sta->lock); |
187 | *state = HT_AGG_STATE_IDLE; | ||
188 | #ifdef CONFIG_MAC80211_HT_DEBUG | 187 | #ifdef CONFIG_MAC80211_HT_DEBUG |
189 | printk(KERN_DEBUG "timer expired on tid %d but we are not " | 188 | printk(KERN_DEBUG "timer expired on tid %d but we are not " |
190 | "(or no longer) expecting addBA response there", | 189 | "(or no longer) expecting addBA response there\n", |
191 | tid); | 190 | tid); |
192 | #endif | 191 | #endif |
193 | return; | 192 | return; |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 7dd7cda75cfa..ae37270a0633 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -97,9 +97,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
97 | params->mesh_id_len, | 97 | params->mesh_id_len, |
98 | params->mesh_id); | 98 | params->mesh_id); |
99 | 99 | ||
100 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags) | ||
101 | return 0; | ||
102 | |||
103 | if (type == NL80211_IFTYPE_AP_VLAN && | 100 | if (type == NL80211_IFTYPE_AP_VLAN && |
104 | params && params->use_4addr == 0) | 101 | params && params->use_4addr == 0) |
105 | rcu_assign_pointer(sdata->u.vlan.sta, NULL); | 102 | rcu_assign_pointer(sdata->u.vlan.sta, NULL); |
@@ -107,7 +104,9 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
107 | params && params->use_4addr >= 0) | 104 | params && params->use_4addr >= 0) |
108 | sdata->u.mgd.use_4addr = params->use_4addr; | 105 | sdata->u.mgd.use_4addr = params->use_4addr; |
109 | 106 | ||
110 | sdata->u.mntr_flags = *flags; | 107 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) |
108 | sdata->u.mntr_flags = *flags; | ||
109 | |||
111 | return 0; | 110 | return 0; |
112 | } | 111 | } |
113 | 112 | ||
@@ -411,6 +410,17 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, | |||
411 | return ret; | 410 | return ret; |
412 | } | 411 | } |
413 | 412 | ||
413 | static int ieee80211_dump_survey(struct wiphy *wiphy, struct net_device *dev, | ||
414 | int idx, struct survey_info *survey) | ||
415 | { | ||
416 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
417 | |||
418 | if (!local->ops->get_survey) | ||
419 | return -EOPNOTSUPP; | ||
420 | |||
421 | return drv_get_survey(local, idx, survey); | ||
422 | } | ||
423 | |||
414 | static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, | 424 | static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, |
415 | u8 *mac, struct station_info *sinfo) | 425 | u8 *mac, struct station_info *sinfo) |
416 | { | 426 | { |
@@ -1104,6 +1114,13 @@ static int ieee80211_change_bss(struct wiphy *wiphy, | |||
1104 | changed |= BSS_CHANGED_BASIC_RATES; | 1114 | changed |= BSS_CHANGED_BASIC_RATES; |
1105 | } | 1115 | } |
1106 | 1116 | ||
1117 | if (params->ap_isolate >= 0) { | ||
1118 | if (params->ap_isolate) | ||
1119 | sdata->flags |= IEEE80211_SDATA_DONT_BRIDGE_PACKETS; | ||
1120 | else | ||
1121 | sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS; | ||
1122 | } | ||
1123 | |||
1107 | ieee80211_bss_info_change_notify(sdata, changed); | 1124 | ieee80211_bss_info_change_notify(sdata, changed); |
1108 | 1125 | ||
1109 | return 0; | 1126 | return 0; |
@@ -1388,11 +1405,11 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, | |||
1388 | return -EOPNOTSUPP; | 1405 | return -EOPNOTSUPP; |
1389 | 1406 | ||
1390 | if (enabled == sdata->u.mgd.powersave && | 1407 | if (enabled == sdata->u.mgd.powersave && |
1391 | timeout == conf->dynamic_ps_timeout) | 1408 | timeout == conf->dynamic_ps_forced_timeout) |
1392 | return 0; | 1409 | return 0; |
1393 | 1410 | ||
1394 | sdata->u.mgd.powersave = enabled; | 1411 | sdata->u.mgd.powersave = enabled; |
1395 | conf->dynamic_ps_timeout = timeout; | 1412 | conf->dynamic_ps_forced_timeout = timeout; |
1396 | 1413 | ||
1397 | /* no change, but if automatic follow powersave */ | 1414 | /* no change, but if automatic follow powersave */ |
1398 | mutex_lock(&sdata->u.mgd.mtx); | 1415 | mutex_lock(&sdata->u.mgd.mtx); |
@@ -1508,6 +1525,7 @@ struct cfg80211_ops mac80211_config_ops = { | |||
1508 | .change_station = ieee80211_change_station, | 1525 | .change_station = ieee80211_change_station, |
1509 | .get_station = ieee80211_get_station, | 1526 | .get_station = ieee80211_get_station, |
1510 | .dump_station = ieee80211_dump_station, | 1527 | .dump_station = ieee80211_dump_station, |
1528 | .dump_survey = ieee80211_dump_survey, | ||
1511 | #ifdef CONFIG_MAC80211_MESH | 1529 | #ifdef CONFIG_MAC80211_MESH |
1512 | .add_mpath = ieee80211_add_mpath, | 1530 | .add_mpath = ieee80211_add_mpath, |
1513 | .del_mpath = ieee80211_del_mpath, | 1531 | .del_mpath = ieee80211_del_mpath, |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 6bc9b07c3eda..e763f1529ddb 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -39,6 +39,13 @@ static const struct file_operations sta_ ##name## _ops = { \ | |||
39 | .open = mac80211_open_file_generic, \ | 39 | .open = mac80211_open_file_generic, \ |
40 | } | 40 | } |
41 | 41 | ||
42 | #define STA_OPS_RW(name) \ | ||
43 | static const struct file_operations sta_ ##name## _ops = { \ | ||
44 | .read = sta_##name##_read, \ | ||
45 | .write = sta_##name##_write, \ | ||
46 | .open = mac80211_open_file_generic, \ | ||
47 | } | ||
48 | |||
42 | #define STA_FILE(name, field, format) \ | 49 | #define STA_FILE(name, field, format) \ |
43 | STA_READ_##format(name, field) \ | 50 | STA_READ_##format(name, field) \ |
44 | STA_OPS(name) | 51 | STA_OPS(name) |
@@ -156,7 +163,63 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, | |||
156 | 163 | ||
157 | return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); | 164 | return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); |
158 | } | 165 | } |
159 | STA_OPS(agg_status); | 166 | |
167 | static ssize_t sta_agg_status_write(struct file *file, const char __user *userbuf, | ||
168 | size_t count, loff_t *ppos) | ||
169 | { | ||
170 | char _buf[12], *buf = _buf; | ||
171 | struct sta_info *sta = file->private_data; | ||
172 | bool start, tx; | ||
173 | unsigned long tid; | ||
174 | int ret; | ||
175 | |||
176 | if (count > sizeof(_buf)) | ||
177 | return -EINVAL; | ||
178 | |||
179 | if (copy_from_user(buf, userbuf, count)) | ||
180 | return -EFAULT; | ||
181 | |||
182 | buf[sizeof(_buf) - 1] = '\0'; | ||
183 | |||
184 | if (strncmp(buf, "tx ", 3) == 0) { | ||
185 | buf += 3; | ||
186 | tx = true; | ||
187 | } else if (strncmp(buf, "rx ", 3) == 0) { | ||
188 | buf += 3; | ||
189 | tx = false; | ||
190 | } else | ||
191 | return -EINVAL; | ||
192 | |||
193 | if (strncmp(buf, "start ", 6) == 0) { | ||
194 | buf += 6; | ||
195 | start = true; | ||
196 | if (!tx) | ||
197 | return -EINVAL; | ||
198 | } else if (strncmp(buf, "stop ", 5) == 0) { | ||
199 | buf += 5; | ||
200 | start = false; | ||
201 | } else | ||
202 | return -EINVAL; | ||
203 | |||
204 | tid = simple_strtoul(buf, NULL, 0); | ||
205 | |||
206 | if (tid >= STA_TID_NUM) | ||
207 | return -EINVAL; | ||
208 | |||
209 | if (tx) { | ||
210 | if (start) | ||
211 | ret = ieee80211_start_tx_ba_session(&sta->sta, tid); | ||
212 | else | ||
213 | ret = ieee80211_stop_tx_ba_session(&sta->sta, tid, | ||
214 | WLAN_BACK_RECIPIENT); | ||
215 | } else { | ||
216 | __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, 3); | ||
217 | ret = 0; | ||
218 | } | ||
219 | |||
220 | return ret ?: count; | ||
221 | } | ||
222 | STA_OPS_RW(agg_status); | ||
160 | 223 | ||
161 | static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf, | 224 | static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf, |
162 | size_t count, loff_t *ppos) | 225 | size_t count, loff_t *ppos) |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 9179196da264..ee8b63f92f71 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -152,14 +152,15 @@ static inline void drv_update_tkip_key(struct ieee80211_local *local, | |||
152 | } | 152 | } |
153 | 153 | ||
154 | static inline int drv_hw_scan(struct ieee80211_local *local, | 154 | static inline int drv_hw_scan(struct ieee80211_local *local, |
155 | struct ieee80211_sub_if_data *sdata, | ||
155 | struct cfg80211_scan_request *req) | 156 | struct cfg80211_scan_request *req) |
156 | { | 157 | { |
157 | int ret; | 158 | int ret; |
158 | 159 | ||
159 | might_sleep(); | 160 | might_sleep(); |
160 | 161 | ||
161 | ret = local->ops->hw_scan(&local->hw, req); | 162 | ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); |
162 | trace_drv_hw_scan(local, req, ret); | 163 | trace_drv_hw_scan(local, sdata, req, ret); |
163 | return ret; | 164 | return ret; |
164 | } | 165 | } |
165 | 166 | ||
@@ -344,6 +345,15 @@ static inline int drv_ampdu_action(struct ieee80211_local *local, | |||
344 | return ret; | 345 | return ret; |
345 | } | 346 | } |
346 | 347 | ||
348 | static inline int drv_get_survey(struct ieee80211_local *local, int idx, | ||
349 | struct survey_info *survey) | ||
350 | { | ||
351 | int ret = -EOPNOTSUPP; | ||
352 | if (local->ops->conf_tx) | ||
353 | ret = local->ops->get_survey(&local->hw, idx, survey); | ||
354 | /* trace_drv_get_survey(local, idx, survey, ret); */ | ||
355 | return ret; | ||
356 | } | ||
347 | 357 | ||
348 | static inline void drv_rfkill_poll(struct ieee80211_local *local) | 358 | static inline void drv_rfkill_poll(struct ieee80211_local *local) |
349 | { | 359 | { |
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index e209cb82ff29..ce734b58d07a 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -363,23 +363,26 @@ TRACE_EVENT(drv_update_tkip_key, | |||
363 | 363 | ||
364 | TRACE_EVENT(drv_hw_scan, | 364 | TRACE_EVENT(drv_hw_scan, |
365 | TP_PROTO(struct ieee80211_local *local, | 365 | TP_PROTO(struct ieee80211_local *local, |
366 | struct ieee80211_sub_if_data *sdata, | ||
366 | struct cfg80211_scan_request *req, int ret), | 367 | struct cfg80211_scan_request *req, int ret), |
367 | 368 | ||
368 | TP_ARGS(local, req, ret), | 369 | TP_ARGS(local, sdata, req, ret), |
369 | 370 | ||
370 | TP_STRUCT__entry( | 371 | TP_STRUCT__entry( |
371 | LOCAL_ENTRY | 372 | LOCAL_ENTRY |
373 | VIF_ENTRY | ||
372 | __field(int, ret) | 374 | __field(int, ret) |
373 | ), | 375 | ), |
374 | 376 | ||
375 | TP_fast_assign( | 377 | TP_fast_assign( |
376 | LOCAL_ASSIGN; | 378 | LOCAL_ASSIGN; |
379 | VIF_ASSIGN; | ||
377 | __entry->ret = ret; | 380 | __entry->ret = ret; |
378 | ), | 381 | ), |
379 | 382 | ||
380 | TP_printk( | 383 | TP_printk( |
381 | LOCAL_PR_FMT " ret:%d", | 384 | LOCAL_PR_FMT VIF_PR_FMT " ret:%d", |
382 | LOCAL_PR_ARG, __entry->ret | 385 | LOCAL_PR_ARG,VIF_PR_ARG, __entry->ret |
383 | ) | 386 | ) |
384 | ); | 387 | ); |
385 | 388 | ||
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index e6f3b0c7a71f..b72ee6435fa3 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -92,6 +92,12 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
92 | if (memcmp(ifibss->bssid, bssid, ETH_ALEN)) | 92 | if (memcmp(ifibss->bssid, bssid, ETH_ALEN)) |
93 | sta_info_flush(sdata->local, sdata); | 93 | sta_info_flush(sdata->local, sdata); |
94 | 94 | ||
95 | /* if merging, indicate to driver that we leave the old IBSS */ | ||
96 | if (sdata->vif.bss_conf.ibss_joined) { | ||
97 | sdata->vif.bss_conf.ibss_joined = false; | ||
98 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS); | ||
99 | } | ||
100 | |||
95 | memcpy(ifibss->bssid, bssid, ETH_ALEN); | 101 | memcpy(ifibss->bssid, bssid, ETH_ALEN); |
96 | 102 | ||
97 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; | 103 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; |
@@ -171,6 +177,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
171 | bss_change |= BSS_CHANGED_BSSID; | 177 | bss_change |= BSS_CHANGED_BSSID; |
172 | bss_change |= BSS_CHANGED_BEACON; | 178 | bss_change |= BSS_CHANGED_BEACON; |
173 | bss_change |= BSS_CHANGED_BEACON_ENABLED; | 179 | bss_change |= BSS_CHANGED_BEACON_ENABLED; |
180 | bss_change |= BSS_CHANGED_IBSS; | ||
181 | sdata->vif.bss_conf.ibss_joined = true; | ||
174 | ieee80211_bss_info_change_notify(sdata, bss_change); | 182 | ieee80211_bss_info_change_notify(sdata, bss_change); |
175 | 183 | ||
176 | ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates); | 184 | ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates); |
@@ -481,7 +489,9 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) | |||
481 | printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " | 489 | printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " |
482 | "IBSS networks with same SSID (merge)\n", sdata->name); | 490 | "IBSS networks with same SSID (merge)\n", sdata->name); |
483 | 491 | ||
484 | ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len); | 492 | ieee80211_request_internal_scan(sdata, |
493 | ifibss->ssid, ifibss->ssid_len, | ||
494 | ifibss->fixed_channel ? ifibss->channel : NULL); | ||
485 | } | 495 | } |
486 | 496 | ||
487 | static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | 497 | static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) |
@@ -588,8 +598,9 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
588 | printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " | 598 | printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " |
589 | "join\n", sdata->name); | 599 | "join\n", sdata->name); |
590 | 600 | ||
591 | ieee80211_request_internal_scan(sdata, ifibss->ssid, | 601 | ieee80211_request_internal_scan(sdata, |
592 | ifibss->ssid_len); | 602 | ifibss->ssid, ifibss->ssid_len, |
603 | ifibss->fixed_channel ? ifibss->channel : NULL); | ||
593 | } else { | 604 | } else { |
594 | int interval = IEEE80211_SCAN_INTERVAL; | 605 | int interval = IEEE80211_SCAN_INTERVAL; |
595 | 606 | ||
@@ -897,6 +908,12 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
897 | sdata->u.ibss.channel = params->channel; | 908 | sdata->u.ibss.channel = params->channel; |
898 | sdata->u.ibss.fixed_channel = params->channel_fixed; | 909 | sdata->u.ibss.fixed_channel = params->channel_fixed; |
899 | 910 | ||
911 | /* fix ourselves to that channel now already */ | ||
912 | if (params->channel_fixed) { | ||
913 | sdata->local->oper_channel = params->channel; | ||
914 | sdata->local->oper_channel_type = NL80211_CHAN_NO_HT; | ||
915 | } | ||
916 | |||
900 | if (params->ie) { | 917 | if (params->ie) { |
901 | sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len, | 918 | sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len, |
902 | GFP_KERNEL); | 919 | GFP_KERNEL); |
@@ -951,7 +968,9 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
951 | kfree(sdata->u.ibss.ie); | 968 | kfree(sdata->u.ibss.ie); |
952 | skb = sdata->u.ibss.presp; | 969 | skb = sdata->u.ibss.presp; |
953 | rcu_assign_pointer(sdata->u.ibss.presp, NULL); | 970 | rcu_assign_pointer(sdata->u.ibss.presp, NULL); |
954 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); | 971 | sdata->vif.bss_conf.ibss_joined = false; |
972 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | | ||
973 | BSS_CHANGED_IBSS); | ||
955 | synchronize_rcu(); | 974 | synchronize_rcu(); |
956 | kfree_skb(skb); | 975 | kfree_skb(skb); |
957 | 976 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c9712f35e596..cbaf4981e110 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1019,7 +1019,8 @@ void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata); | |||
1019 | /* scan/BSS handling */ | 1019 | /* scan/BSS handling */ |
1020 | void ieee80211_scan_work(struct work_struct *work); | 1020 | void ieee80211_scan_work(struct work_struct *work); |
1021 | int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, | 1021 | int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, |
1022 | const u8 *ssid, u8 ssid_len); | 1022 | const u8 *ssid, u8 ssid_len, |
1023 | struct ieee80211_channel *chan); | ||
1023 | int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, | 1024 | int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, |
1024 | struct cfg80211_scan_request *req); | 1025 | struct cfg80211_scan_request *req); |
1025 | void ieee80211_scan_cancel(struct ieee80211_local *local); | 1026 | void ieee80211_scan_cancel(struct ieee80211_local *local); |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index e8f6e3b252d8..8d4b41787dcf 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -140,6 +140,7 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
140 | struct ieee80211_sub_if_data, | 140 | struct ieee80211_sub_if_data, |
141 | u.ap); | 141 | u.ap); |
142 | 142 | ||
143 | key->conf.ap_addr = sdata->dev->dev_addr; | ||
143 | ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); | 144 | ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); |
144 | 145 | ||
145 | if (!ret) { | 146 | if (!ret) { |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 011ee85bcd57..bd632e1ee2c5 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -442,7 +442,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
442 | struct ieee80211_local *local = hw_to_local(hw); | 442 | struct ieee80211_local *local = hw_to_local(hw); |
443 | int result; | 443 | int result; |
444 | enum ieee80211_band band; | 444 | enum ieee80211_band band; |
445 | int channels, i, j, max_bitrates; | 445 | int channels, max_bitrates; |
446 | bool supp_ht; | 446 | bool supp_ht; |
447 | static const u32 cipher_suites[] = { | 447 | static const u32 cipher_suites[] = { |
448 | WLAN_CIPHER_SUITE_WEP40, | 448 | WLAN_CIPHER_SUITE_WEP40, |
@@ -572,6 +572,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
572 | 572 | ||
573 | local->hw.conf.listen_interval = local->hw.max_listen_interval; | 573 | local->hw.conf.listen_interval = local->hw.max_listen_interval; |
574 | 574 | ||
575 | local->hw.conf.dynamic_ps_forced_timeout = -1; | ||
576 | |||
575 | result = sta_info_start(local); | 577 | result = sta_info_start(local); |
576 | if (result < 0) | 578 | if (result < 0) |
577 | goto fail_sta_info; | 579 | goto fail_sta_info; |
@@ -606,21 +608,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
606 | 608 | ||
607 | ieee80211_led_init(local); | 609 | ieee80211_led_init(local); |
608 | 610 | ||
609 | /* alloc internal scan request */ | ||
610 | i = 0; | ||
611 | local->int_scan_req->ssids = &local->scan_ssid; | ||
612 | local->int_scan_req->n_ssids = 1; | ||
613 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
614 | if (!hw->wiphy->bands[band]) | ||
615 | continue; | ||
616 | for (j = 0; j < hw->wiphy->bands[band]->n_channels; j++) { | ||
617 | local->int_scan_req->channels[i] = | ||
618 | &hw->wiphy->bands[band]->channels[j]; | ||
619 | i++; | ||
620 | } | ||
621 | } | ||
622 | local->int_scan_req->n_channels = i; | ||
623 | |||
624 | local->network_latency_notifier.notifier_call = | 611 | local->network_latency_notifier.notifier_call = |
625 | ieee80211_max_network_latency; | 612 | ieee80211_max_network_latency; |
626 | result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY, | 613 | result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY, |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 35d850223a75..358226f63b81 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -175,6 +175,8 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, | |||
175 | ht_changed = conf_is_ht(&local->hw.conf) != enable_ht || | 175 | ht_changed = conf_is_ht(&local->hw.conf) != enable_ht || |
176 | channel_type != local->hw.conf.channel_type; | 176 | channel_type != local->hw.conf.channel_type; |
177 | 177 | ||
178 | if (local->tmp_channel) | ||
179 | local->tmp_channel_type = channel_type; | ||
178 | local->oper_channel_type = channel_type; | 180 | local->oper_channel_type = channel_type; |
179 | 181 | ||
180 | if (ht_changed) { | 182 | if (ht_changed) { |
@@ -476,6 +478,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) | |||
476 | { | 478 | { |
477 | struct ieee80211_sub_if_data *sdata, *found = NULL; | 479 | struct ieee80211_sub_if_data *sdata, *found = NULL; |
478 | int count = 0; | 480 | int count = 0; |
481 | int timeout; | ||
479 | 482 | ||
480 | if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) { | 483 | if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) { |
481 | local->ps_sdata = NULL; | 484 | local->ps_sdata = NULL; |
@@ -509,6 +512,26 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) | |||
509 | beaconint_us = ieee80211_tu_to_usec( | 512 | beaconint_us = ieee80211_tu_to_usec( |
510 | found->vif.bss_conf.beacon_int); | 513 | found->vif.bss_conf.beacon_int); |
511 | 514 | ||
515 | timeout = local->hw.conf.dynamic_ps_forced_timeout; | ||
516 | if (timeout < 0) { | ||
517 | /* | ||
518 | * The 2 second value is there for compatibility until | ||
519 | * the PM_QOS_NETWORK_LATENCY is configured with real | ||
520 | * values. | ||
521 | */ | ||
522 | if (latency == 2000000000) | ||
523 | timeout = 100; | ||
524 | else if (latency <= 50000) | ||
525 | timeout = 300; | ||
526 | else if (latency <= 100000) | ||
527 | timeout = 100; | ||
528 | else if (latency <= 500000) | ||
529 | timeout = 50; | ||
530 | else | ||
531 | timeout = 0; | ||
532 | } | ||
533 | local->hw.conf.dynamic_ps_timeout = timeout; | ||
534 | |||
512 | if (beaconint_us > latency) { | 535 | if (beaconint_us > latency) { |
513 | local->ps_sdata = NULL; | 536 | local->ps_sdata = NULL; |
514 | } else { | 537 | } else { |
@@ -1331,12 +1354,17 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
1331 | mutex_lock(&sdata->local->iflist_mtx); | 1354 | mutex_lock(&sdata->local->iflist_mtx); |
1332 | ieee80211_recalc_ps(sdata->local, -1); | 1355 | ieee80211_recalc_ps(sdata->local, -1); |
1333 | mutex_unlock(&sdata->local->iflist_mtx); | 1356 | mutex_unlock(&sdata->local->iflist_mtx); |
1357 | |||
1358 | if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) | ||
1359 | return; | ||
1360 | |||
1334 | /* | 1361 | /* |
1335 | * We've received a probe response, but are not sure whether | 1362 | * We've received a probe response, but are not sure whether |
1336 | * we have or will be receiving any beacons or data, so let's | 1363 | * we have or will be receiving any beacons or data, so let's |
1337 | * schedule the timers again, just in case. | 1364 | * schedule the timers again, just in case. |
1338 | */ | 1365 | */ |
1339 | mod_beacon_timer(sdata); | 1366 | mod_beacon_timer(sdata); |
1367 | |||
1340 | mod_timer(&ifmgd->conn_mon_timer, | 1368 | mod_timer(&ifmgd->conn_mon_timer, |
1341 | round_jiffies_up(jiffies + | 1369 | round_jiffies_up(jiffies + |
1342 | IEEE80211_CONNECTION_IDLE_TIME)); | 1370 | IEEE80211_CONNECTION_IDLE_TIME)); |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 72efbd87c1eb..9a08f2c446c6 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -81,8 +81,6 @@ ieee80211_rx_radiotap_len(struct ieee80211_local *local, | |||
81 | len += 8; | 81 | len += 8; |
82 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | 82 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
83 | len += 1; | 83 | len += 1; |
84 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) | ||
85 | len += 1; | ||
86 | 84 | ||
87 | if (len & 1) /* padding for RX_FLAGS if necessary */ | 85 | if (len & 1) /* padding for RX_FLAGS if necessary */ |
88 | len++; | 86 | len++; |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index e1a3defdf581..e14c44195ae9 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -85,7 +85,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
85 | { | 85 | { |
86 | struct cfg80211_bss *cbss; | 86 | struct cfg80211_bss *cbss; |
87 | struct ieee80211_bss *bss; | 87 | struct ieee80211_bss *bss; |
88 | int clen; | 88 | int clen, srlen; |
89 | s32 signal = 0; | 89 | s32 signal = 0; |
90 | 90 | ||
91 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | 91 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
@@ -114,23 +114,24 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
114 | bss->dtim_period = tim_ie->dtim_period; | 114 | bss->dtim_period = tim_ie->dtim_period; |
115 | } | 115 | } |
116 | 116 | ||
117 | bss->supp_rates_len = 0; | 117 | /* replace old supported rates if we get new values */ |
118 | srlen = 0; | ||
118 | if (elems->supp_rates) { | 119 | if (elems->supp_rates) { |
119 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; | 120 | clen = IEEE80211_MAX_SUPP_RATES; |
120 | if (clen > elems->supp_rates_len) | 121 | if (clen > elems->supp_rates_len) |
121 | clen = elems->supp_rates_len; | 122 | clen = elems->supp_rates_len; |
122 | memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates, | 123 | memcpy(bss->supp_rates, elems->supp_rates, clen); |
123 | clen); | 124 | srlen += clen; |
124 | bss->supp_rates_len += clen; | ||
125 | } | 125 | } |
126 | if (elems->ext_supp_rates) { | 126 | if (elems->ext_supp_rates) { |
127 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; | 127 | clen = IEEE80211_MAX_SUPP_RATES - srlen; |
128 | if (clen > elems->ext_supp_rates_len) | 128 | if (clen > elems->ext_supp_rates_len) |
129 | clen = elems->ext_supp_rates_len; | 129 | clen = elems->ext_supp_rates_len; |
130 | memcpy(&bss->supp_rates[bss->supp_rates_len], | 130 | memcpy(bss->supp_rates + srlen, elems->ext_supp_rates, clen); |
131 | elems->ext_supp_rates, clen); | 131 | srlen += clen; |
132 | bss->supp_rates_len += clen; | ||
133 | } | 132 | } |
133 | if (srlen) | ||
134 | bss->supp_rates_len = srlen; | ||
134 | 135 | ||
135 | bss->wmm_used = elems->wmm_param || elems->wmm_info; | 136 | bss->wmm_used = elems->wmm_param || elems->wmm_info; |
136 | bss->uapsd_supported = is_uapsd_supported(elems); | 137 | bss->uapsd_supported = is_uapsd_supported(elems); |
@@ -411,7 +412,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
411 | 412 | ||
412 | if (local->ops->hw_scan) { | 413 | if (local->ops->hw_scan) { |
413 | WARN_ON(!ieee80211_prep_hw_scan(local)); | 414 | WARN_ON(!ieee80211_prep_hw_scan(local)); |
414 | rc = drv_hw_scan(local, local->hw_scan_req); | 415 | rc = drv_hw_scan(local, sdata, local->hw_scan_req); |
415 | } else | 416 | } else |
416 | rc = ieee80211_start_sw_scan(local); | 417 | rc = ieee80211_start_sw_scan(local); |
417 | 418 | ||
@@ -655,7 +656,7 @@ void ieee80211_scan_work(struct work_struct *work) | |||
655 | } | 656 | } |
656 | 657 | ||
657 | if (local->hw_scan_req) { | 658 | if (local->hw_scan_req) { |
658 | int rc = drv_hw_scan(local, local->hw_scan_req); | 659 | int rc = drv_hw_scan(local, sdata, local->hw_scan_req); |
659 | mutex_unlock(&local->scan_mtx); | 660 | mutex_unlock(&local->scan_mtx); |
660 | if (rc) | 661 | if (rc) |
661 | ieee80211_scan_completed(&local->hw, true); | 662 | ieee80211_scan_completed(&local->hw, true); |
@@ -728,10 +729,12 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, | |||
728 | } | 729 | } |
729 | 730 | ||
730 | int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, | 731 | int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, |
731 | const u8 *ssid, u8 ssid_len) | 732 | const u8 *ssid, u8 ssid_len, |
733 | struct ieee80211_channel *chan) | ||
732 | { | 734 | { |
733 | struct ieee80211_local *local = sdata->local; | 735 | struct ieee80211_local *local = sdata->local; |
734 | int ret = -EBUSY; | 736 | int ret = -EBUSY; |
737 | enum nl80211_band band; | ||
735 | 738 | ||
736 | mutex_lock(&local->scan_mtx); | 739 | mutex_lock(&local->scan_mtx); |
737 | 740 | ||
@@ -739,6 +742,30 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, | |||
739 | if (local->scan_req) | 742 | if (local->scan_req) |
740 | goto unlock; | 743 | goto unlock; |
741 | 744 | ||
745 | /* fill internal scan request */ | ||
746 | if (!chan) { | ||
747 | int i, nchan = 0; | ||
748 | |||
749 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
750 | if (!local->hw.wiphy->bands[band]) | ||
751 | continue; | ||
752 | for (i = 0; | ||
753 | i < local->hw.wiphy->bands[band]->n_channels; | ||
754 | i++) { | ||
755 | local->int_scan_req->channels[nchan] = | ||
756 | &local->hw.wiphy->bands[band]->channels[i]; | ||
757 | nchan++; | ||
758 | } | ||
759 | } | ||
760 | |||
761 | local->int_scan_req->n_channels = nchan; | ||
762 | } else { | ||
763 | local->int_scan_req->channels[0] = chan; | ||
764 | local->int_scan_req->n_channels = 1; | ||
765 | } | ||
766 | |||
767 | local->int_scan_req->ssids = &local->scan_ssid; | ||
768 | local->int_scan_req->n_ssids = 1; | ||
742 | memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN); | 769 | memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN); |
743 | local->int_scan_req->ssids[0].ssid_len = ssid_len; | 770 | local->int_scan_req->ssids[0].ssid_len = ssid_len; |
744 | 771 | ||
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index ff0eb948917b..730197591ab5 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -575,7 +575,7 @@ static int sta_info_buffer_expired(struct sta_info *sta, | |||
575 | } | 575 | } |
576 | 576 | ||
577 | 577 | ||
578 | static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | 578 | static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, |
579 | struct sta_info *sta) | 579 | struct sta_info *sta) |
580 | { | 580 | { |
581 | unsigned long flags; | 581 | unsigned long flags; |
@@ -583,7 +583,7 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
583 | struct ieee80211_sub_if_data *sdata; | 583 | struct ieee80211_sub_if_data *sdata; |
584 | 584 | ||
585 | if (skb_queue_empty(&sta->ps_tx_buf)) | 585 | if (skb_queue_empty(&sta->ps_tx_buf)) |
586 | return; | 586 | return false; |
587 | 587 | ||
588 | for (;;) { | 588 | for (;;) { |
589 | spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); | 589 | spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); |
@@ -608,6 +608,8 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
608 | if (skb_queue_empty(&sta->ps_tx_buf)) | 608 | if (skb_queue_empty(&sta->ps_tx_buf)) |
609 | sta_info_clear_tim_bit(sta); | 609 | sta_info_clear_tim_bit(sta); |
610 | } | 610 | } |
611 | |||
612 | return true; | ||
611 | } | 613 | } |
612 | 614 | ||
613 | static int __must_check __sta_info_destroy(struct sta_info *sta) | 615 | static int __must_check __sta_info_destroy(struct sta_info *sta) |
@@ -755,15 +757,20 @@ static void sta_info_cleanup(unsigned long data) | |||
755 | { | 757 | { |
756 | struct ieee80211_local *local = (struct ieee80211_local *) data; | 758 | struct ieee80211_local *local = (struct ieee80211_local *) data; |
757 | struct sta_info *sta; | 759 | struct sta_info *sta; |
760 | bool timer_needed = false; | ||
758 | 761 | ||
759 | rcu_read_lock(); | 762 | rcu_read_lock(); |
760 | list_for_each_entry_rcu(sta, &local->sta_list, list) | 763 | list_for_each_entry_rcu(sta, &local->sta_list, list) |
761 | sta_info_cleanup_expire_buffered(local, sta); | 764 | if (sta_info_cleanup_expire_buffered(local, sta)) |
765 | timer_needed = true; | ||
762 | rcu_read_unlock(); | 766 | rcu_read_unlock(); |
763 | 767 | ||
764 | if (local->quiescing) | 768 | if (local->quiescing) |
765 | return; | 769 | return; |
766 | 770 | ||
771 | if (!timer_needed) | ||
772 | return; | ||
773 | |||
767 | local->sta_cleanup.expires = | 774 | local->sta_cleanup.expires = |
768 | round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); | 775 | round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); |
769 | add_timer(&local->sta_cleanup); | 776 | add_timer(&local->sta_cleanup); |
@@ -848,8 +855,12 @@ struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, | |||
848 | struct sta_info *sta, *nxt; | 855 | struct sta_info *sta, *nxt; |
849 | 856 | ||
850 | /* Just return a random station ... first in list ... */ | 857 | /* Just return a random station ... first in list ... */ |
851 | for_each_sta_info(hw_to_local(hw), addr, sta, nxt) | 858 | for_each_sta_info(hw_to_local(hw), addr, sta, nxt) { |
859 | if (!sta->uploaded) | ||
860 | return NULL; | ||
852 | return &sta->sta; | 861 | return &sta->sta; |
862 | } | ||
863 | |||
853 | return NULL; | 864 | return NULL; |
854 | } | 865 | } |
855 | EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); | 866 | EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); |
@@ -857,14 +868,19 @@ EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); | |||
857 | struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, | 868 | struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, |
858 | const u8 *addr) | 869 | const u8 *addr) |
859 | { | 870 | { |
860 | struct ieee80211_sub_if_data *sdata; | 871 | struct sta_info *sta; |
861 | 872 | ||
862 | if (!vif) | 873 | if (!vif) |
863 | return NULL; | 874 | return NULL; |
864 | 875 | ||
865 | sdata = vif_to_sdata(vif); | 876 | sta = sta_info_get_bss(vif_to_sdata(vif), addr); |
877 | if (!sta) | ||
878 | return NULL; | ||
879 | |||
880 | if (!sta->uploaded) | ||
881 | return NULL; | ||
866 | 882 | ||
867 | return ieee80211_find_sta_by_hw(&sdata->local->hw, addr); | 883 | return &sta->sta; |
868 | } | 884 | } |
869 | EXPORT_SYMBOL(ieee80211_find_sta); | 885 | EXPORT_SYMBOL(ieee80211_find_sta); |
870 | 886 | ||
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 11805a3a626f..94613af009f3 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -171,6 +171,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
171 | struct net_device *prev_dev = NULL; | 171 | struct net_device *prev_dev = NULL; |
172 | struct sta_info *sta, *tmp; | 172 | struct sta_info *sta, *tmp; |
173 | int retry_count = -1, i; | 173 | int retry_count = -1, i; |
174 | int rates_idx = -1; | ||
174 | bool send_to_cooked; | 175 | bool send_to_cooked; |
175 | 176 | ||
176 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | 177 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
@@ -178,6 +179,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
178 | if (i >= hw->max_rates) { | 179 | if (i >= hw->max_rates) { |
179 | info->status.rates[i].idx = -1; | 180 | info->status.rates[i].idx = -1; |
180 | info->status.rates[i].count = 0; | 181 | info->status.rates[i].count = 0; |
182 | } else if (info->status.rates[i].idx >= 0) { | ||
183 | rates_idx = i; | ||
181 | } | 184 | } |
182 | 185 | ||
183 | retry_count += info->status.rates[i].count; | 186 | retry_count += info->status.rates[i].count; |
@@ -206,6 +209,10 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
206 | return; | 209 | return; |
207 | } | 210 | } |
208 | 211 | ||
212 | if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) && | ||
213 | (rates_idx != -1)) | ||
214 | sta->last_tx_rate = info->status.rates[rates_idx]; | ||
215 | |||
209 | if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && | 216 | if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && |
210 | (ieee80211_is_data_qos(fc))) { | 217 | (ieee80211_is_data_qos(fc))) { |
211 | u16 tid, ssn; | 218 | u16 tid, ssn; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 2cb77267f733..f3841f43249e 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -429,6 +429,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
429 | struct sta_info *sta = tx->sta; | 429 | struct sta_info *sta = tx->sta; |
430 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 430 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
431 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 431 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
432 | struct ieee80211_local *local = tx->local; | ||
432 | u32 staflags; | 433 | u32 staflags; |
433 | 434 | ||
434 | if (unlikely(!sta || | 435 | if (unlikely(!sta || |
@@ -476,6 +477,12 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
476 | info->control.vif = &tx->sdata->vif; | 477 | info->control.vif = &tx->sdata->vif; |
477 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 478 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
478 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); | 479 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); |
480 | |||
481 | if (!timer_pending(&local->sta_cleanup)) | ||
482 | mod_timer(&local->sta_cleanup, | ||
483 | round_jiffies(jiffies + | ||
484 | STA_INFO_CLEANUP_INTERVAL)); | ||
485 | |||
479 | return TX_QUEUED; | 486 | return TX_QUEUED; |
480 | } | 487 | } |
481 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 488 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
@@ -586,7 +593,8 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
586 | struct ieee80211_hdr *hdr = (void *)tx->skb->data; | 593 | struct ieee80211_hdr *hdr = (void *)tx->skb->data; |
587 | struct ieee80211_supported_band *sband; | 594 | struct ieee80211_supported_band *sband; |
588 | struct ieee80211_rate *rate; | 595 | struct ieee80211_rate *rate; |
589 | int i, len; | 596 | int i; |
597 | u32 len; | ||
590 | bool inval = false, rts = false, short_preamble = false; | 598 | bool inval = false, rts = false, short_preamble = false; |
591 | struct ieee80211_tx_rate_control txrc; | 599 | struct ieee80211_tx_rate_control txrc; |
592 | u32 sta_flags; | 600 | u32 sta_flags; |
@@ -595,7 +603,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
595 | 603 | ||
596 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | 604 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; |
597 | 605 | ||
598 | len = min_t(int, tx->skb->len + FCS_LEN, | 606 | len = min_t(u32, tx->skb->len + FCS_LEN, |
599 | tx->local->hw.wiphy->frag_threshold); | 607 | tx->local->hw.wiphy->frag_threshold); |
600 | 608 | ||
601 | /* set up the tx rate control struct we give the RC algo */ | 609 | /* set up the tx rate control struct we give the RC algo */ |
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index bdb1d05b16fc..3dd07600199d 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
@@ -213,15 +213,25 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
213 | 213 | ||
214 | sband = local->hw.wiphy->bands[wk->chan->band]; | 214 | sband = local->hw.wiphy->bands[wk->chan->band]; |
215 | 215 | ||
216 | /* | 216 | if (wk->assoc.supp_rates_len) { |
217 | * Get all rates supported by the device and the AP as | 217 | /* |
218 | * some APs don't like getting a superset of their rates | 218 | * Get all rates supported by the device and the AP as |
219 | * in the association request (e.g. D-Link DAP 1353 in | 219 | * some APs don't like getting a superset of their rates |
220 | * b-only mode)... | 220 | * in the association request (e.g. D-Link DAP 1353 in |
221 | */ | 221 | * b-only mode)... |
222 | rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates, | 222 | */ |
223 | wk->assoc.supp_rates_len, | 223 | rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates, |
224 | sband, &rates); | 224 | wk->assoc.supp_rates_len, |
225 | sband, &rates); | ||
226 | } else { | ||
227 | /* | ||
228 | * In case AP not provide any supported rates information | ||
229 | * before association, we send information element(s) with | ||
230 | * all rates that we support. | ||
231 | */ | ||
232 | rates = ~0; | ||
233 | rates_len = sband->n_bitrates; | ||
234 | } | ||
225 | 235 | ||
226 | skb = alloc_skb(local->hw.extra_tx_headroom + | 236 | skb = alloc_skb(local->hw.extra_tx_headroom + |
227 | sizeof(*mgmt) + /* bit too much but doesn't matter */ | 237 | sizeof(*mgmt) + /* bit too much but doesn't matter */ |
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index 8fb0ae616761..7ba06939829f 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c +++ b/net/netfilter/ipvs/ip_vs_sync.c | |||
@@ -802,7 +802,7 @@ static int sync_thread_backup(void *data) | |||
802 | ip_vs_backup_mcast_ifn, ip_vs_backup_syncid); | 802 | ip_vs_backup_mcast_ifn, ip_vs_backup_syncid); |
803 | 803 | ||
804 | while (!kthread_should_stop()) { | 804 | while (!kthread_should_stop()) { |
805 | wait_event_interruptible(*tinfo->sock->sk->sk_sleep, | 805 | wait_event_interruptible(*sk_sleep(tinfo->sock->sk), |
806 | !skb_queue_empty(&tinfo->sock->sk->sk_receive_queue) | 806 | !skb_queue_empty(&tinfo->sock->sk->sk_receive_queue) |
807 | || kthread_should_stop()); | 807 | || kthread_should_stop()); |
808 | 808 | ||
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index fa07f044b599..06cb02796a0e 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
@@ -739,7 +739,7 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr, | |||
739 | DEFINE_WAIT(wait); | 739 | DEFINE_WAIT(wait); |
740 | 740 | ||
741 | for (;;) { | 741 | for (;;) { |
742 | prepare_to_wait(sk->sk_sleep, &wait, | 742 | prepare_to_wait(sk_sleep(sk), &wait, |
743 | TASK_INTERRUPTIBLE); | 743 | TASK_INTERRUPTIBLE); |
744 | if (sk->sk_state != TCP_SYN_SENT) | 744 | if (sk->sk_state != TCP_SYN_SENT) |
745 | break; | 745 | break; |
@@ -752,7 +752,7 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr, | |||
752 | err = -ERESTARTSYS; | 752 | err = -ERESTARTSYS; |
753 | break; | 753 | break; |
754 | } | 754 | } |
755 | finish_wait(sk->sk_sleep, &wait); | 755 | finish_wait(sk_sleep(sk), &wait); |
756 | if (err) | 756 | if (err) |
757 | goto out_release; | 757 | goto out_release; |
758 | } | 758 | } |
@@ -798,7 +798,7 @@ static int nr_accept(struct socket *sock, struct socket *newsock, int flags) | |||
798 | * hooked into the SABM we saved | 798 | * hooked into the SABM we saved |
799 | */ | 799 | */ |
800 | for (;;) { | 800 | for (;;) { |
801 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 801 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
802 | skb = skb_dequeue(&sk->sk_receive_queue); | 802 | skb = skb_dequeue(&sk->sk_receive_queue); |
803 | if (skb) | 803 | if (skb) |
804 | break; | 804 | break; |
@@ -816,7 +816,7 @@ static int nr_accept(struct socket *sock, struct socket *newsock, int flags) | |||
816 | err = -ERESTARTSYS; | 816 | err = -ERESTARTSYS; |
817 | break; | 817 | break; |
818 | } | 818 | } |
819 | finish_wait(sk->sk_sleep, &wait); | 819 | finish_wait(sk_sleep(sk), &wait); |
820 | if (err) | 820 | if (err) |
821 | goto out_release; | 821 | goto out_release; |
822 | 822 | ||
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index f162d59d8161..2078a277e06b 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -2228,8 +2228,6 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd, | |||
2228 | case SIOCGIFDSTADDR: | 2228 | case SIOCGIFDSTADDR: |
2229 | case SIOCSIFDSTADDR: | 2229 | case SIOCSIFDSTADDR: |
2230 | case SIOCSIFFLAGS: | 2230 | case SIOCSIFFLAGS: |
2231 | if (!net_eq(sock_net(sk), &init_net)) | ||
2232 | return -ENOIOCTLCMD; | ||
2233 | return inet_dgram_ops.ioctl(sock, cmd, arg); | 2231 | return inet_dgram_ops.ioctl(sock, cmd, arg); |
2234 | #endif | 2232 | #endif |
2235 | 2233 | ||
diff --git a/net/phonet/pep.c b/net/phonet/pep.c index e2a95762abd3..af4d38bc3b22 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c | |||
@@ -664,12 +664,12 @@ static int pep_wait_connreq(struct sock *sk, int noblock) | |||
664 | if (signal_pending(tsk)) | 664 | if (signal_pending(tsk)) |
665 | return sock_intr_errno(timeo); | 665 | return sock_intr_errno(timeo); |
666 | 666 | ||
667 | prepare_to_wait_exclusive(&sk->sk_socket->wait, &wait, | 667 | prepare_to_wait_exclusive(sk_sleep(sk), &wait, |
668 | TASK_INTERRUPTIBLE); | 668 | TASK_INTERRUPTIBLE); |
669 | release_sock(sk); | 669 | release_sock(sk); |
670 | timeo = schedule_timeout(timeo); | 670 | timeo = schedule_timeout(timeo); |
671 | lock_sock(sk); | 671 | lock_sock(sk); |
672 | finish_wait(&sk->sk_socket->wait, &wait); | 672 | finish_wait(sk_sleep(sk), &wait); |
673 | } | 673 | } |
674 | 674 | ||
675 | return 0; | 675 | return 0; |
@@ -910,10 +910,10 @@ disabled: | |||
910 | goto out; | 910 | goto out; |
911 | } | 911 | } |
912 | 912 | ||
913 | prepare_to_wait(&sk->sk_socket->wait, &wait, | 913 | prepare_to_wait(sk_sleep(sk), &wait, |
914 | TASK_INTERRUPTIBLE); | 914 | TASK_INTERRUPTIBLE); |
915 | done = sk_wait_event(sk, &timeo, atomic_read(&pn->tx_credits)); | 915 | done = sk_wait_event(sk, &timeo, atomic_read(&pn->tx_credits)); |
916 | finish_wait(&sk->sk_socket->wait, &wait); | 916 | finish_wait(sk_sleep(sk), &wait); |
917 | 917 | ||
918 | if (sk->sk_state != TCP_ESTABLISHED) | 918 | if (sk->sk_state != TCP_ESTABLISHED) |
919 | goto disabled; | 919 | goto disabled; |
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c index 9b4ced6e0968..c33da6576942 100644 --- a/net/phonet/pn_dev.c +++ b/net/phonet/pn_dev.c | |||
@@ -46,9 +46,16 @@ struct phonet_net { | |||
46 | 46 | ||
47 | int phonet_net_id __read_mostly; | 47 | int phonet_net_id __read_mostly; |
48 | 48 | ||
49 | static struct phonet_net *phonet_pernet(struct net *net) | ||
50 | { | ||
51 | BUG_ON(!net); | ||
52 | |||
53 | return net_generic(net, phonet_net_id); | ||
54 | } | ||
55 | |||
49 | struct phonet_device_list *phonet_device_list(struct net *net) | 56 | struct phonet_device_list *phonet_device_list(struct net *net) |
50 | { | 57 | { |
51 | struct phonet_net *pnn = net_generic(net, phonet_net_id); | 58 | struct phonet_net *pnn = phonet_pernet(net); |
52 | return &pnn->pndevs; | 59 | return &pnn->pndevs; |
53 | } | 60 | } |
54 | 61 | ||
@@ -261,7 +268,7 @@ static int phonet_device_autoconf(struct net_device *dev) | |||
261 | 268 | ||
262 | static void phonet_route_autodel(struct net_device *dev) | 269 | static void phonet_route_autodel(struct net_device *dev) |
263 | { | 270 | { |
264 | struct phonet_net *pnn = net_generic(dev_net(dev), phonet_net_id); | 271 | struct phonet_net *pnn = phonet_pernet(dev_net(dev)); |
265 | unsigned i; | 272 | unsigned i; |
266 | DECLARE_BITMAP(deleted, 64); | 273 | DECLARE_BITMAP(deleted, 64); |
267 | 274 | ||
@@ -313,7 +320,7 @@ static struct notifier_block phonet_device_notifier = { | |||
313 | /* Per-namespace Phonet devices handling */ | 320 | /* Per-namespace Phonet devices handling */ |
314 | static int __net_init phonet_init_net(struct net *net) | 321 | static int __net_init phonet_init_net(struct net *net) |
315 | { | 322 | { |
316 | struct phonet_net *pnn = net_generic(net, phonet_net_id); | 323 | struct phonet_net *pnn = phonet_pernet(net); |
317 | 324 | ||
318 | if (!proc_net_fops_create(net, "phonet", 0, &pn_sock_seq_fops)) | 325 | if (!proc_net_fops_create(net, "phonet", 0, &pn_sock_seq_fops)) |
319 | return -ENOMEM; | 326 | return -ENOMEM; |
@@ -326,7 +333,7 @@ static int __net_init phonet_init_net(struct net *net) | |||
326 | 333 | ||
327 | static void __net_exit phonet_exit_net(struct net *net) | 334 | static void __net_exit phonet_exit_net(struct net *net) |
328 | { | 335 | { |
329 | struct phonet_net *pnn = net_generic(net, phonet_net_id); | 336 | struct phonet_net *pnn = phonet_pernet(net); |
330 | struct net_device *dev; | 337 | struct net_device *dev; |
331 | unsigned i; | 338 | unsigned i; |
332 | 339 | ||
@@ -376,7 +383,7 @@ void phonet_device_exit(void) | |||
376 | 383 | ||
377 | int phonet_route_add(struct net_device *dev, u8 daddr) | 384 | int phonet_route_add(struct net_device *dev, u8 daddr) |
378 | { | 385 | { |
379 | struct phonet_net *pnn = net_generic(dev_net(dev), phonet_net_id); | 386 | struct phonet_net *pnn = phonet_pernet(dev_net(dev)); |
380 | struct phonet_routes *routes = &pnn->routes; | 387 | struct phonet_routes *routes = &pnn->routes; |
381 | int err = -EEXIST; | 388 | int err = -EEXIST; |
382 | 389 | ||
@@ -393,7 +400,7 @@ int phonet_route_add(struct net_device *dev, u8 daddr) | |||
393 | 400 | ||
394 | int phonet_route_del(struct net_device *dev, u8 daddr) | 401 | int phonet_route_del(struct net_device *dev, u8 daddr) |
395 | { | 402 | { |
396 | struct phonet_net *pnn = net_generic(dev_net(dev), phonet_net_id); | 403 | struct phonet_net *pnn = phonet_pernet(dev_net(dev)); |
397 | struct phonet_routes *routes = &pnn->routes; | 404 | struct phonet_routes *routes = &pnn->routes; |
398 | 405 | ||
399 | daddr = daddr >> 2; | 406 | daddr = daddr >> 2; |
@@ -413,7 +420,7 @@ int phonet_route_del(struct net_device *dev, u8 daddr) | |||
413 | 420 | ||
414 | struct net_device *phonet_route_get(struct net *net, u8 daddr) | 421 | struct net_device *phonet_route_get(struct net *net, u8 daddr) |
415 | { | 422 | { |
416 | struct phonet_net *pnn = net_generic(net, phonet_net_id); | 423 | struct phonet_net *pnn = phonet_pernet(net); |
417 | struct phonet_routes *routes = &pnn->routes; | 424 | struct phonet_routes *routes = &pnn->routes; |
418 | struct net_device *dev; | 425 | struct net_device *dev; |
419 | 426 | ||
@@ -428,7 +435,7 @@ struct net_device *phonet_route_get(struct net *net, u8 daddr) | |||
428 | 435 | ||
429 | struct net_device *phonet_route_output(struct net *net, u8 daddr) | 436 | struct net_device *phonet_route_output(struct net *net, u8 daddr) |
430 | { | 437 | { |
431 | struct phonet_net *pnn = net_generic(net, phonet_net_id); | 438 | struct phonet_net *pnn = phonet_pernet(net); |
432 | struct phonet_routes *routes = &pnn->routes; | 439 | struct phonet_routes *routes = &pnn->routes; |
433 | struct net_device *dev; | 440 | struct net_device *dev; |
434 | 441 | ||
diff --git a/net/phonet/socket.c b/net/phonet/socket.c index c785bfd0744f..6e9848bf0370 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c | |||
@@ -265,7 +265,7 @@ static unsigned int pn_socket_poll(struct file *file, struct socket *sock, | |||
265 | struct pep_sock *pn = pep_sk(sk); | 265 | struct pep_sock *pn = pep_sk(sk); |
266 | unsigned int mask = 0; | 266 | unsigned int mask = 0; |
267 | 267 | ||
268 | poll_wait(file, &sock->wait, wait); | 268 | poll_wait(file, sk_sleep(sk), wait); |
269 | 269 | ||
270 | switch (sk->sk_state) { | 270 | switch (sk->sk_state) { |
271 | case TCP_LISTEN: | 271 | case TCP_LISTEN: |
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index 7919a9edb8e9..aebfecbdb841 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c | |||
@@ -158,7 +158,7 @@ static unsigned int rds_poll(struct file *file, struct socket *sock, | |||
158 | unsigned int mask = 0; | 158 | unsigned int mask = 0; |
159 | unsigned long flags; | 159 | unsigned long flags; |
160 | 160 | ||
161 | poll_wait(file, sk->sk_sleep, wait); | 161 | poll_wait(file, sk_sleep(sk), wait); |
162 | 162 | ||
163 | if (rs->rs_seen_congestion) | 163 | if (rs->rs_seen_congestion) |
164 | poll_wait(file, &rds_poll_waitq, wait); | 164 | poll_wait(file, &rds_poll_waitq, wait); |
diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c index 5ea82fc47c3e..e599ba2f950d 100644 --- a/net/rds/rdma_transport.c +++ b/net/rds/rdma_transport.c | |||
@@ -133,7 +133,7 @@ static int __init rds_rdma_listen_init(void) | |||
133 | ret = PTR_ERR(cm_id); | 133 | ret = PTR_ERR(cm_id); |
134 | printk(KERN_ERR "RDS/RDMA: failed to setup listener, " | 134 | printk(KERN_ERR "RDS/RDMA: failed to setup listener, " |
135 | "rdma_create_id() returned %d\n", ret); | 135 | "rdma_create_id() returned %d\n", ret); |
136 | goto out; | 136 | return ret; |
137 | } | 137 | } |
138 | 138 | ||
139 | sin.sin_family = AF_INET, | 139 | sin.sin_family = AF_INET, |
diff --git a/net/rds/rds.h b/net/rds/rds.h index 4bec6e2ed495..c224b5bb3ba9 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h | |||
@@ -492,7 +492,7 @@ void rds_sock_put(struct rds_sock *rs); | |||
492 | void rds_wake_sk_sleep(struct rds_sock *rs); | 492 | void rds_wake_sk_sleep(struct rds_sock *rs); |
493 | static inline void __rds_wake_sk_sleep(struct sock *sk) | 493 | static inline void __rds_wake_sk_sleep(struct sock *sk) |
494 | { | 494 | { |
495 | wait_queue_head_t *waitq = sk->sk_sleep; | 495 | wait_queue_head_t *waitq = sk_sleep(sk); |
496 | 496 | ||
497 | if (!sock_flag(sk, SOCK_DEAD) && waitq) | 497 | if (!sock_flag(sk, SOCK_DEAD) && waitq) |
498 | wake_up(waitq); | 498 | wake_up(waitq); |
diff --git a/net/rds/recv.c b/net/rds/recv.c index e2a2b9344f7b..795a00b7f2cb 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c | |||
@@ -432,7 +432,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
432 | break; | 432 | break; |
433 | } | 433 | } |
434 | 434 | ||
435 | timeo = wait_event_interruptible_timeout(*sk->sk_sleep, | 435 | timeo = wait_event_interruptible_timeout(*sk_sleep(sk), |
436 | (!list_empty(&rs->rs_notify_queue) || | 436 | (!list_empty(&rs->rs_notify_queue) || |
437 | rs->rs_cong_notify || | 437 | rs->rs_cong_notify || |
438 | rds_next_incoming(rs, &inc)), timeo); | 438 | rds_next_incoming(rs, &inc)), timeo); |
diff --git a/net/rds/send.c b/net/rds/send.c index 53d6795ac9d0..9c1c6bcaa6c9 100644 --- a/net/rds/send.c +++ b/net/rds/send.c | |||
@@ -915,7 +915,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
915 | goto out; | 915 | goto out; |
916 | } | 916 | } |
917 | 917 | ||
918 | timeo = wait_event_interruptible_timeout(*sk->sk_sleep, | 918 | timeo = wait_event_interruptible_timeout(*sk_sleep(sk), |
919 | rds_send_queue_rm(rs, conn, rm, | 919 | rds_send_queue_rm(rs, conn, rm, |
920 | rs->rs_bound_port, | 920 | rs->rs_bound_port, |
921 | dport, | 921 | dport, |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 4fb711a035f4..8e45e76a95f5 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
@@ -845,7 +845,7 @@ rose_try_next_neigh: | |||
845 | DEFINE_WAIT(wait); | 845 | DEFINE_WAIT(wait); |
846 | 846 | ||
847 | for (;;) { | 847 | for (;;) { |
848 | prepare_to_wait(sk->sk_sleep, &wait, | 848 | prepare_to_wait(sk_sleep(sk), &wait, |
849 | TASK_INTERRUPTIBLE); | 849 | TASK_INTERRUPTIBLE); |
850 | if (sk->sk_state != TCP_SYN_SENT) | 850 | if (sk->sk_state != TCP_SYN_SENT) |
851 | break; | 851 | break; |
@@ -858,7 +858,7 @@ rose_try_next_neigh: | |||
858 | err = -ERESTARTSYS; | 858 | err = -ERESTARTSYS; |
859 | break; | 859 | break; |
860 | } | 860 | } |
861 | finish_wait(sk->sk_sleep, &wait); | 861 | finish_wait(sk_sleep(sk), &wait); |
862 | 862 | ||
863 | if (err) | 863 | if (err) |
864 | goto out_release; | 864 | goto out_release; |
@@ -911,7 +911,7 @@ static int rose_accept(struct socket *sock, struct socket *newsock, int flags) | |||
911 | * hooked into the SABM we saved | 911 | * hooked into the SABM we saved |
912 | */ | 912 | */ |
913 | for (;;) { | 913 | for (;;) { |
914 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 914 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
915 | 915 | ||
916 | skb = skb_dequeue(&sk->sk_receive_queue); | 916 | skb = skb_dequeue(&sk->sk_receive_queue); |
917 | if (skb) | 917 | if (skb) |
@@ -930,7 +930,7 @@ static int rose_accept(struct socket *sock, struct socket *newsock, int flags) | |||
930 | err = -ERESTARTSYS; | 930 | err = -ERESTARTSYS; |
931 | break; | 931 | break; |
932 | } | 932 | } |
933 | finish_wait(sk->sk_sleep, &wait); | 933 | finish_wait(sk_sleep(sk), &wait); |
934 | if (err) | 934 | if (err) |
935 | goto out_release; | 935 | goto out_release; |
936 | 936 | ||
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index c060095b27ce..0b9bb2085ce4 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c | |||
@@ -62,13 +62,15 @@ static inline int rxrpc_writable(struct sock *sk) | |||
62 | static void rxrpc_write_space(struct sock *sk) | 62 | static void rxrpc_write_space(struct sock *sk) |
63 | { | 63 | { |
64 | _enter("%p", sk); | 64 | _enter("%p", sk); |
65 | read_lock(&sk->sk_callback_lock); | 65 | rcu_read_lock(); |
66 | if (rxrpc_writable(sk)) { | 66 | if (rxrpc_writable(sk)) { |
67 | if (sk_has_sleeper(sk)) | 67 | struct socket_wq *wq = rcu_dereference(sk->sk_wq); |
68 | wake_up_interruptible(sk->sk_sleep); | 68 | |
69 | if (wq_has_sleeper(wq)) | ||
70 | wake_up_interruptible(&wq->wait); | ||
69 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); | 71 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); |
70 | } | 72 | } |
71 | read_unlock(&sk->sk_callback_lock); | 73 | rcu_read_unlock(); |
72 | } | 74 | } |
73 | 75 | ||
74 | /* | 76 | /* |
@@ -589,7 +591,7 @@ static unsigned int rxrpc_poll(struct file *file, struct socket *sock, | |||
589 | unsigned int mask; | 591 | unsigned int mask; |
590 | struct sock *sk = sock->sk; | 592 | struct sock *sk = sock->sk; |
591 | 593 | ||
592 | sock_poll_wait(file, sk->sk_sleep, wait); | 594 | sock_poll_wait(file, sk_sleep(sk), wait); |
593 | mask = 0; | 595 | mask = 0; |
594 | 596 | ||
595 | /* the socket is readable if there are any messages waiting on the Rx | 597 | /* the socket is readable if there are any messages waiting on the Rx |
diff --git a/net/rxrpc/ar-recvmsg.c b/net/rxrpc/ar-recvmsg.c index 60c2b94e6b54..0c65013e3bfe 100644 --- a/net/rxrpc/ar-recvmsg.c +++ b/net/rxrpc/ar-recvmsg.c | |||
@@ -91,7 +91,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
91 | 91 | ||
92 | /* wait for a message to turn up */ | 92 | /* wait for a message to turn up */ |
93 | release_sock(&rx->sk); | 93 | release_sock(&rx->sk); |
94 | prepare_to_wait_exclusive(rx->sk.sk_sleep, &wait, | 94 | prepare_to_wait_exclusive(sk_sleep(&rx->sk), &wait, |
95 | TASK_INTERRUPTIBLE); | 95 | TASK_INTERRUPTIBLE); |
96 | ret = sock_error(&rx->sk); | 96 | ret = sock_error(&rx->sk); |
97 | if (ret) | 97 | if (ret) |
@@ -102,7 +102,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
102 | goto wait_interrupted; | 102 | goto wait_interrupted; |
103 | timeo = schedule_timeout(timeo); | 103 | timeo = schedule_timeout(timeo); |
104 | } | 104 | } |
105 | finish_wait(rx->sk.sk_sleep, &wait); | 105 | finish_wait(sk_sleep(&rx->sk), &wait); |
106 | lock_sock(&rx->sk); | 106 | lock_sock(&rx->sk); |
107 | continue; | 107 | continue; |
108 | } | 108 | } |
@@ -356,7 +356,7 @@ csum_copy_error: | |||
356 | wait_interrupted: | 356 | wait_interrupted: |
357 | ret = sock_intr_errno(timeo); | 357 | ret = sock_intr_errno(timeo); |
358 | wait_error: | 358 | wait_error: |
359 | finish_wait(rx->sk.sk_sleep, &wait); | 359 | finish_wait(sk_sleep(&rx->sk), &wait); |
360 | if (continue_call) | 360 | if (continue_call) |
361 | rxrpc_put_call(continue_call); | 361 | rxrpc_put_call(continue_call); |
362 | if (copied) | 362 | if (copied) |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index aeddabfb8e4e..a969b111bd76 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -94,7 +94,7 @@ static inline int handle_dev_cpu_collision(struct sk_buff *skb, | |||
94 | * Another cpu is holding lock, requeue & delay xmits for | 94 | * Another cpu is holding lock, requeue & delay xmits for |
95 | * some time. | 95 | * some time. |
96 | */ | 96 | */ |
97 | __get_cpu_var(netdev_rx_stat).cpu_collision++; | 97 | __get_cpu_var(softnet_data).cpu_collision++; |
98 | ret = dev_requeue_skb(skb, q); | 98 | ret = dev_requeue_skb(skb, q); |
99 | } | 99 | } |
100 | 100 | ||
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index c5a9ac566007..c65762823f5e 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
@@ -123,8 +123,8 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) | |||
123 | case htons(ETH_P_IP): | 123 | case htons(ETH_P_IP): |
124 | { | 124 | { |
125 | const struct iphdr *iph = ip_hdr(skb); | 125 | const struct iphdr *iph = ip_hdr(skb); |
126 | h = iph->daddr; | 126 | h = (__force u32)iph->daddr; |
127 | h2 = iph->saddr ^ iph->protocol; | 127 | h2 = (__force u32)iph->saddr ^ iph->protocol; |
128 | if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && | 128 | if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && |
129 | (iph->protocol == IPPROTO_TCP || | 129 | (iph->protocol == IPPROTO_TCP || |
130 | iph->protocol == IPPROTO_UDP || | 130 | iph->protocol == IPPROTO_UDP || |
@@ -138,8 +138,8 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) | |||
138 | case htons(ETH_P_IPV6): | 138 | case htons(ETH_P_IPV6): |
139 | { | 139 | { |
140 | struct ipv6hdr *iph = ipv6_hdr(skb); | 140 | struct ipv6hdr *iph = ipv6_hdr(skb); |
141 | h = iph->daddr.s6_addr32[3]; | 141 | h = (__force u32)iph->daddr.s6_addr32[3]; |
142 | h2 = iph->saddr.s6_addr32[3] ^ iph->nexthdr; | 142 | h2 = (__force u32)iph->saddr.s6_addr32[3] ^ iph->nexthdr; |
143 | if (iph->nexthdr == IPPROTO_TCP || | 143 | if (iph->nexthdr == IPPROTO_TCP || |
144 | iph->nexthdr == IPPROTO_UDP || | 144 | iph->nexthdr == IPPROTO_UDP || |
145 | iph->nexthdr == IPPROTO_UDPLITE || | 145 | iph->nexthdr == IPPROTO_UDPLITE || |
@@ -150,7 +150,7 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) | |||
150 | break; | 150 | break; |
151 | } | 151 | } |
152 | default: | 152 | default: |
153 | h = (unsigned long)skb_dst(skb) ^ skb->protocol; | 153 | h = (unsigned long)skb_dst(skb) ^ (__force u32)skb->protocol; |
154 | h2 = (unsigned long)skb->sk; | 154 | h2 = (unsigned long)skb->sk; |
155 | } | 155 | } |
156 | 156 | ||
diff --git a/net/sctp/Kconfig b/net/sctp/Kconfig index 58b3e882a187..126b014eb79b 100644 --- a/net/sctp/Kconfig +++ b/net/sctp/Kconfig | |||
@@ -37,6 +37,18 @@ menuconfig IP_SCTP | |||
37 | 37 | ||
38 | if IP_SCTP | 38 | if IP_SCTP |
39 | 39 | ||
40 | config NET_SCTPPROBE | ||
41 | tristate "SCTP: Association probing" | ||
42 | depends on PROC_FS && KPROBES | ||
43 | ---help--- | ||
44 | This module allows for capturing the changes to SCTP association | ||
45 | state in response to incoming packets. It is used for debugging | ||
46 | SCTP congestion control algorithms. If you don't understand | ||
47 | what was just said, you don't need it: say N. | ||
48 | |||
49 | To compile this code as a module, choose M here: the | ||
50 | module will be called sctp_probe. | ||
51 | |||
40 | config SCTP_DBG_MSG | 52 | config SCTP_DBG_MSG |
41 | bool "SCTP: Debug messages" | 53 | bool "SCTP: Debug messages" |
42 | help | 54 | help |
diff --git a/net/sctp/Makefile b/net/sctp/Makefile index 6b794734380a..5c30b7a873df 100644 --- a/net/sctp/Makefile +++ b/net/sctp/Makefile | |||
@@ -3,6 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_IP_SCTP) += sctp.o | 5 | obj-$(CONFIG_IP_SCTP) += sctp.o |
6 | obj-$(CONFIG_NET_SCTPPROBE) += sctp_probe.o | ||
6 | 7 | ||
7 | sctp-y := sm_statetable.o sm_statefuns.o sm_sideeffect.o \ | 8 | sctp-y := sm_statetable.o sm_statefuns.o sm_sideeffect.o \ |
8 | protocol.o endpointola.o associola.o \ | 9 | protocol.o endpointola.o associola.o \ |
@@ -11,6 +12,8 @@ sctp-y := sm_statetable.o sm_statefuns.o sm_sideeffect.o \ | |||
11 | tsnmap.o bind_addr.o socket.o primitive.o \ | 12 | tsnmap.o bind_addr.o socket.o primitive.o \ |
12 | output.o input.o debug.o ssnmap.o auth.o | 13 | output.o input.o debug.o ssnmap.o auth.o |
13 | 14 | ||
15 | sctp_probe-y := probe.o | ||
16 | |||
14 | sctp-$(CONFIG_SCTP_DBG_OBJCNT) += objcnt.o | 17 | sctp-$(CONFIG_SCTP_DBG_OBJCNT) += objcnt.o |
15 | sctp-$(CONFIG_PROC_FS) += proc.o | 18 | sctp-$(CONFIG_PROC_FS) += proc.o |
16 | sctp-$(CONFIG_SYSCTL) += sysctl.o | 19 | sctp-$(CONFIG_SYSCTL) += sysctl.o |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index df5abbff63e2..3912420cedcc 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -87,9 +87,6 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
87 | /* Retrieve the SCTP per socket area. */ | 87 | /* Retrieve the SCTP per socket area. */ |
88 | sp = sctp_sk((struct sock *)sk); | 88 | sp = sctp_sk((struct sock *)sk); |
89 | 89 | ||
90 | /* Init all variables to a known value. */ | ||
91 | memset(asoc, 0, sizeof(struct sctp_association)); | ||
92 | |||
93 | /* Discarding const is appropriate here. */ | 90 | /* Discarding const is appropriate here. */ |
94 | asoc->ep = (struct sctp_endpoint *)ep; | 91 | asoc->ep = (struct sctp_endpoint *)ep; |
95 | sctp_endpoint_hold(asoc->ep); | 92 | sctp_endpoint_hold(asoc->ep); |
@@ -762,7 +759,8 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, | |||
762 | asoc->peer.retran_path = peer; | 759 | asoc->peer.retran_path = peer; |
763 | } | 760 | } |
764 | 761 | ||
765 | if (asoc->peer.active_path == asoc->peer.retran_path) { | 762 | if (asoc->peer.active_path == asoc->peer.retran_path && |
763 | peer->state != SCTP_UNCONFIRMED) { | ||
766 | asoc->peer.retran_path = peer; | 764 | asoc->peer.retran_path = peer; |
767 | } | 765 | } |
768 | 766 | ||
@@ -1194,8 +1192,10 @@ void sctp_assoc_update(struct sctp_association *asoc, | |||
1194 | /* Remove any peer addresses not present in the new association. */ | 1192 | /* Remove any peer addresses not present in the new association. */ |
1195 | list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { | 1193 | list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { |
1196 | trans = list_entry(pos, struct sctp_transport, transports); | 1194 | trans = list_entry(pos, struct sctp_transport, transports); |
1197 | if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr)) | 1195 | if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr)) { |
1198 | sctp_assoc_del_peer(asoc, &trans->ipaddr); | 1196 | sctp_assoc_rm_peer(asoc, trans); |
1197 | continue; | ||
1198 | } | ||
1199 | 1199 | ||
1200 | if (asoc->state >= SCTP_STATE_ESTABLISHED) | 1200 | if (asoc->state >= SCTP_STATE_ESTABLISHED) |
1201 | sctp_transport_reset(trans); | 1201 | sctp_transport_reset(trans); |
@@ -1318,12 +1318,13 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc) | |||
1318 | /* Keep track of the next transport in case | 1318 | /* Keep track of the next transport in case |
1319 | * we don't find any active transport. | 1319 | * we don't find any active transport. |
1320 | */ | 1320 | */ |
1321 | if (!next) | 1321 | if (t->state != SCTP_UNCONFIRMED && !next) |
1322 | next = t; | 1322 | next = t; |
1323 | } | 1323 | } |
1324 | } | 1324 | } |
1325 | 1325 | ||
1326 | asoc->peer.retran_path = t; | 1326 | if (t) |
1327 | asoc->peer.retran_path = t; | ||
1327 | 1328 | ||
1328 | SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association" | 1329 | SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association" |
1329 | " %p addr: ", | 1330 | " %p addr: ", |
@@ -1483,7 +1484,7 @@ void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned len) | |||
1483 | if (asoc->rwnd >= len) { | 1484 | if (asoc->rwnd >= len) { |
1484 | asoc->rwnd -= len; | 1485 | asoc->rwnd -= len; |
1485 | if (over) { | 1486 | if (over) { |
1486 | asoc->rwnd_press = asoc->rwnd; | 1487 | asoc->rwnd_press += asoc->rwnd; |
1487 | asoc->rwnd = 0; | 1488 | asoc->rwnd = 0; |
1488 | } | 1489 | } |
1489 | } else { | 1490 | } else { |
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 3eab6db59a37..476caaf100ed 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c | |||
@@ -58,9 +58,9 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg) | |||
58 | msg->send_failed = 0; | 58 | msg->send_failed = 0; |
59 | msg->send_error = 0; | 59 | msg->send_error = 0; |
60 | msg->can_abandon = 0; | 60 | msg->can_abandon = 0; |
61 | msg->can_delay = 1; | ||
61 | msg->expires_at = 0; | 62 | msg->expires_at = 0; |
62 | INIT_LIST_HEAD(&msg->chunks); | 63 | INIT_LIST_HEAD(&msg->chunks); |
63 | msg->msg_size = 0; | ||
64 | } | 64 | } |
65 | 65 | ||
66 | /* Allocate and initialize datamsg. */ | 66 | /* Allocate and initialize datamsg. */ |
@@ -157,7 +157,6 @@ static void sctp_datamsg_assign(struct sctp_datamsg *msg, struct sctp_chunk *chu | |||
157 | { | 157 | { |
158 | sctp_datamsg_hold(msg); | 158 | sctp_datamsg_hold(msg); |
159 | chunk->msg = msg; | 159 | chunk->msg = msg; |
160 | msg->msg_size += chunk->skb->len; | ||
161 | } | 160 | } |
162 | 161 | ||
163 | 162 | ||
@@ -247,6 +246,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, | |||
247 | if (msg_len >= first_len) { | 246 | if (msg_len >= first_len) { |
248 | msg_len -= first_len; | 247 | msg_len -= first_len; |
249 | whole = 1; | 248 | whole = 1; |
249 | msg->can_delay = 0; | ||
250 | } | 250 | } |
251 | 251 | ||
252 | /* How many full sized? How many bytes leftover? */ | 252 | /* How many full sized? How many bytes leftover? */ |
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 905fda582b92..e10acc01c75f 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
@@ -70,8 +70,6 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
70 | struct sctp_shared_key *null_key; | 70 | struct sctp_shared_key *null_key; |
71 | int err; | 71 | int err; |
72 | 72 | ||
73 | memset(ep, 0, sizeof(struct sctp_endpoint)); | ||
74 | |||
75 | ep->digest = kzalloc(SCTP_SIGNATURE_SIZE, gfp); | 73 | ep->digest = kzalloc(SCTP_SIGNATURE_SIZE, gfp); |
76 | if (!ep->digest) | 74 | if (!ep->digest) |
77 | return NULL; | 75 | return NULL; |
@@ -144,6 +142,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
144 | /* Use SCTP specific send buffer space queues. */ | 142 | /* Use SCTP specific send buffer space queues. */ |
145 | ep->sndbuf_policy = sctp_sndbuf_policy; | 143 | ep->sndbuf_policy = sctp_sndbuf_policy; |
146 | 144 | ||
145 | sk->sk_data_ready = sctp_data_ready; | ||
147 | sk->sk_write_space = sctp_write_space; | 146 | sk->sk_write_space = sctp_write_space; |
148 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); | 147 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); |
149 | 148 | ||
diff --git a/net/sctp/output.c b/net/sctp/output.c index fad261d41ec2..a646681f5acd 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -429,24 +429,17 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
429 | list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) { | 429 | list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) { |
430 | list_del_init(&chunk->list); | 430 | list_del_init(&chunk->list); |
431 | if (sctp_chunk_is_data(chunk)) { | 431 | if (sctp_chunk_is_data(chunk)) { |
432 | /* 6.3.1 C4) When data is in flight and when allowed | ||
433 | * by rule C5, a new RTT measurement MUST be made each | ||
434 | * round trip. Furthermore, new RTT measurements | ||
435 | * SHOULD be made no more than once per round-trip | ||
436 | * for a given destination transport address. | ||
437 | */ | ||
432 | 438 | ||
433 | if (!chunk->resent) { | 439 | if (!tp->rto_pending) { |
434 | 440 | chunk->rtt_in_progress = 1; | |
435 | /* 6.3.1 C4) When data is in flight and when allowed | 441 | tp->rto_pending = 1; |
436 | * by rule C5, a new RTT measurement MUST be made each | ||
437 | * round trip. Furthermore, new RTT measurements | ||
438 | * SHOULD be made no more than once per round-trip | ||
439 | * for a given destination transport address. | ||
440 | */ | ||
441 | |||
442 | if (!tp->rto_pending) { | ||
443 | chunk->rtt_in_progress = 1; | ||
444 | tp->rto_pending = 1; | ||
445 | } | ||
446 | } | 442 | } |
447 | |||
448 | chunk->resent = 1; | ||
449 | |||
450 | has_data = 1; | 443 | has_data = 1; |
451 | } | 444 | } |
452 | 445 | ||
@@ -681,7 +674,7 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, | |||
681 | * Don't delay large message writes that may have been | 674 | * Don't delay large message writes that may have been |
682 | * fragmeneted into small peices. | 675 | * fragmeneted into small peices. |
683 | */ | 676 | */ |
684 | if ((len < max) && (chunk->msg->msg_size < max)) { | 677 | if ((len < max) && chunk->msg->can_delay) { |
685 | retval = SCTP_XMIT_NAGLE_DELAY; | 678 | retval = SCTP_XMIT_NAGLE_DELAY; |
686 | goto finish; | 679 | goto finish; |
687 | } | 680 | } |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index abfc0b8dee74..5d057178ce0c 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -62,7 +62,7 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
62 | struct list_head *transmitted_queue, | 62 | struct list_head *transmitted_queue, |
63 | struct sctp_transport *transport, | 63 | struct sctp_transport *transport, |
64 | struct sctp_sackhdr *sack, | 64 | struct sctp_sackhdr *sack, |
65 | __u32 highest_new_tsn); | 65 | __u32 *highest_new_tsn); |
66 | 66 | ||
67 | static void sctp_mark_missing(struct sctp_outq *q, | 67 | static void sctp_mark_missing(struct sctp_outq *q, |
68 | struct list_head *transmitted_queue, | 68 | struct list_head *transmitted_queue, |
@@ -308,7 +308,7 @@ int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk) | |||
308 | /* If it is data, queue it up, otherwise, send it | 308 | /* If it is data, queue it up, otherwise, send it |
309 | * immediately. | 309 | * immediately. |
310 | */ | 310 | */ |
311 | if (SCTP_CID_DATA == chunk->chunk_hdr->type) { | 311 | if (sctp_chunk_is_data(chunk)) { |
312 | /* Is it OK to queue data chunks? */ | 312 | /* Is it OK to queue data chunks? */ |
313 | /* From 9. Termination of Association | 313 | /* From 9. Termination of Association |
314 | * | 314 | * |
@@ -598,11 +598,23 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, | |||
598 | if (fast_rtx && !chunk->fast_retransmit) | 598 | if (fast_rtx && !chunk->fast_retransmit) |
599 | continue; | 599 | continue; |
600 | 600 | ||
601 | redo: | ||
601 | /* Attempt to append this chunk to the packet. */ | 602 | /* Attempt to append this chunk to the packet. */ |
602 | status = sctp_packet_append_chunk(pkt, chunk); | 603 | status = sctp_packet_append_chunk(pkt, chunk); |
603 | 604 | ||
604 | switch (status) { | 605 | switch (status) { |
605 | case SCTP_XMIT_PMTU_FULL: | 606 | case SCTP_XMIT_PMTU_FULL: |
607 | if (!pkt->has_data && !pkt->has_cookie_echo) { | ||
608 | /* If this packet did not contain DATA then | ||
609 | * retransmission did not happen, so do it | ||
610 | * again. We'll ignore the error here since | ||
611 | * control chunks are already freed so there | ||
612 | * is nothing we can do. | ||
613 | */ | ||
614 | sctp_packet_transmit(pkt); | ||
615 | goto redo; | ||
616 | } | ||
617 | |||
606 | /* Send this packet. */ | 618 | /* Send this packet. */ |
607 | error = sctp_packet_transmit(pkt); | 619 | error = sctp_packet_transmit(pkt); |
608 | 620 | ||
@@ -647,14 +659,6 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, | |||
647 | if (chunk->fast_retransmit == SCTP_NEED_FRTX) | 659 | if (chunk->fast_retransmit == SCTP_NEED_FRTX) |
648 | chunk->fast_retransmit = SCTP_DONT_FRTX; | 660 | chunk->fast_retransmit = SCTP_DONT_FRTX; |
649 | 661 | ||
650 | /* Force start T3-rtx timer when fast retransmitting | ||
651 | * the earliest outstanding TSN | ||
652 | */ | ||
653 | if (!timer && fast_rtx && | ||
654 | ntohl(chunk->subh.data_hdr->tsn) == | ||
655 | asoc->ctsn_ack_point + 1) | ||
656 | timer = 2; | ||
657 | |||
658 | q->empty = 0; | 662 | q->empty = 0; |
659 | break; | 663 | break; |
660 | } | 664 | } |
@@ -854,6 +858,12 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
854 | if (status != SCTP_XMIT_OK) { | 858 | if (status != SCTP_XMIT_OK) { |
855 | /* put the chunk back */ | 859 | /* put the chunk back */ |
856 | list_add(&chunk->list, &q->control_chunk_list); | 860 | list_add(&chunk->list, &q->control_chunk_list); |
861 | } else if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN) { | ||
862 | /* PR-SCTP C5) If a FORWARD TSN is sent, the | ||
863 | * sender MUST assure that at least one T3-rtx | ||
864 | * timer is running. | ||
865 | */ | ||
866 | sctp_transport_reset_timers(transport); | ||
857 | } | 867 | } |
858 | break; | 868 | break; |
859 | 869 | ||
@@ -906,8 +916,7 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
906 | rtx_timeout, &start_timer); | 916 | rtx_timeout, &start_timer); |
907 | 917 | ||
908 | if (start_timer) | 918 | if (start_timer) |
909 | sctp_transport_reset_timers(transport, | 919 | sctp_transport_reset_timers(transport); |
910 | start_timer-1); | ||
911 | 920 | ||
912 | /* This can happen on COOKIE-ECHO resend. Only | 921 | /* This can happen on COOKIE-ECHO resend. Only |
913 | * one chunk can get bundled with a COOKIE-ECHO. | 922 | * one chunk can get bundled with a COOKIE-ECHO. |
@@ -1040,7 +1049,7 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
1040 | list_add_tail(&chunk->transmitted_list, | 1049 | list_add_tail(&chunk->transmitted_list, |
1041 | &transport->transmitted); | 1050 | &transport->transmitted); |
1042 | 1051 | ||
1043 | sctp_transport_reset_timers(transport, 0); | 1052 | sctp_transport_reset_timers(transport); |
1044 | 1053 | ||
1045 | q->empty = 0; | 1054 | q->empty = 0; |
1046 | 1055 | ||
@@ -1100,32 +1109,6 @@ static void sctp_sack_update_unack_data(struct sctp_association *assoc, | |||
1100 | assoc->unack_data = unack_data; | 1109 | assoc->unack_data = unack_data; |
1101 | } | 1110 | } |
1102 | 1111 | ||
1103 | /* Return the highest new tsn that is acknowledged by the given SACK chunk. */ | ||
1104 | static __u32 sctp_highest_new_tsn(struct sctp_sackhdr *sack, | ||
1105 | struct sctp_association *asoc) | ||
1106 | { | ||
1107 | struct sctp_transport *transport; | ||
1108 | struct sctp_chunk *chunk; | ||
1109 | __u32 highest_new_tsn, tsn; | ||
1110 | struct list_head *transport_list = &asoc->peer.transport_addr_list; | ||
1111 | |||
1112 | highest_new_tsn = ntohl(sack->cum_tsn_ack); | ||
1113 | |||
1114 | list_for_each_entry(transport, transport_list, transports) { | ||
1115 | list_for_each_entry(chunk, &transport->transmitted, | ||
1116 | transmitted_list) { | ||
1117 | tsn = ntohl(chunk->subh.data_hdr->tsn); | ||
1118 | |||
1119 | if (!chunk->tsn_gap_acked && | ||
1120 | TSN_lt(highest_new_tsn, tsn) && | ||
1121 | sctp_acked(sack, tsn)) | ||
1122 | highest_new_tsn = tsn; | ||
1123 | } | ||
1124 | } | ||
1125 | |||
1126 | return highest_new_tsn; | ||
1127 | } | ||
1128 | |||
1129 | /* This is where we REALLY process a SACK. | 1112 | /* This is where we REALLY process a SACK. |
1130 | * | 1113 | * |
1131 | * Process the SACK against the outqueue. Mostly, this just frees | 1114 | * Process the SACK against the outqueue. Mostly, this just frees |
@@ -1145,6 +1128,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) | |||
1145 | struct sctp_transport *primary = asoc->peer.primary_path; | 1128 | struct sctp_transport *primary = asoc->peer.primary_path; |
1146 | int count_of_newacks = 0; | 1129 | int count_of_newacks = 0; |
1147 | int gap_ack_blocks; | 1130 | int gap_ack_blocks; |
1131 | u8 accum_moved = 0; | ||
1148 | 1132 | ||
1149 | /* Grab the association's destination address list. */ | 1133 | /* Grab the association's destination address list. */ |
1150 | transport_list = &asoc->peer.transport_addr_list; | 1134 | transport_list = &asoc->peer.transport_addr_list; |
@@ -1193,18 +1177,15 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) | |||
1193 | if (gap_ack_blocks) | 1177 | if (gap_ack_blocks) |
1194 | highest_tsn += ntohs(frags[gap_ack_blocks - 1].gab.end); | 1178 | highest_tsn += ntohs(frags[gap_ack_blocks - 1].gab.end); |
1195 | 1179 | ||
1196 | if (TSN_lt(asoc->highest_sacked, highest_tsn)) { | 1180 | if (TSN_lt(asoc->highest_sacked, highest_tsn)) |
1197 | highest_new_tsn = highest_tsn; | ||
1198 | asoc->highest_sacked = highest_tsn; | 1181 | asoc->highest_sacked = highest_tsn; |
1199 | } else { | ||
1200 | highest_new_tsn = sctp_highest_new_tsn(sack, asoc); | ||
1201 | } | ||
1202 | 1182 | ||
1183 | highest_new_tsn = sack_ctsn; | ||
1203 | 1184 | ||
1204 | /* Run through the retransmit queue. Credit bytes received | 1185 | /* Run through the retransmit queue. Credit bytes received |
1205 | * and free those chunks that we can. | 1186 | * and free those chunks that we can. |
1206 | */ | 1187 | */ |
1207 | sctp_check_transmitted(q, &q->retransmit, NULL, sack, highest_new_tsn); | 1188 | sctp_check_transmitted(q, &q->retransmit, NULL, sack, &highest_new_tsn); |
1208 | 1189 | ||
1209 | /* Run through the transmitted queue. | 1190 | /* Run through the transmitted queue. |
1210 | * Credit bytes received and free those chunks which we can. | 1191 | * Credit bytes received and free those chunks which we can. |
@@ -1213,7 +1194,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) | |||
1213 | */ | 1194 | */ |
1214 | list_for_each_entry(transport, transport_list, transports) { | 1195 | list_for_each_entry(transport, transport_list, transports) { |
1215 | sctp_check_transmitted(q, &transport->transmitted, | 1196 | sctp_check_transmitted(q, &transport->transmitted, |
1216 | transport, sack, highest_new_tsn); | 1197 | transport, sack, &highest_new_tsn); |
1217 | /* | 1198 | /* |
1218 | * SFR-CACC algorithm: | 1199 | * SFR-CACC algorithm: |
1219 | * C) Let count_of_newacks be the number of | 1200 | * C) Let count_of_newacks be the number of |
@@ -1223,16 +1204,22 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) | |||
1223 | count_of_newacks ++; | 1204 | count_of_newacks ++; |
1224 | } | 1205 | } |
1225 | 1206 | ||
1207 | /* Move the Cumulative TSN Ack Point if appropriate. */ | ||
1208 | if (TSN_lt(asoc->ctsn_ack_point, sack_ctsn)) { | ||
1209 | asoc->ctsn_ack_point = sack_ctsn; | ||
1210 | accum_moved = 1; | ||
1211 | } | ||
1212 | |||
1226 | if (gap_ack_blocks) { | 1213 | if (gap_ack_blocks) { |
1214 | |||
1215 | if (asoc->fast_recovery && accum_moved) | ||
1216 | highest_new_tsn = highest_tsn; | ||
1217 | |||
1227 | list_for_each_entry(transport, transport_list, transports) | 1218 | list_for_each_entry(transport, transport_list, transports) |
1228 | sctp_mark_missing(q, &transport->transmitted, transport, | 1219 | sctp_mark_missing(q, &transport->transmitted, transport, |
1229 | highest_new_tsn, count_of_newacks); | 1220 | highest_new_tsn, count_of_newacks); |
1230 | } | 1221 | } |
1231 | 1222 | ||
1232 | /* Move the Cumulative TSN Ack Point if appropriate. */ | ||
1233 | if (TSN_lt(asoc->ctsn_ack_point, sack_ctsn)) | ||
1234 | asoc->ctsn_ack_point = sack_ctsn; | ||
1235 | |||
1236 | /* Update unack_data field in the assoc. */ | 1223 | /* Update unack_data field in the assoc. */ |
1237 | sctp_sack_update_unack_data(asoc, sack); | 1224 | sctp_sack_update_unack_data(asoc, sack); |
1238 | 1225 | ||
@@ -1315,7 +1302,7 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1315 | struct list_head *transmitted_queue, | 1302 | struct list_head *transmitted_queue, |
1316 | struct sctp_transport *transport, | 1303 | struct sctp_transport *transport, |
1317 | struct sctp_sackhdr *sack, | 1304 | struct sctp_sackhdr *sack, |
1318 | __u32 highest_new_tsn_in_sack) | 1305 | __u32 *highest_new_tsn_in_sack) |
1319 | { | 1306 | { |
1320 | struct list_head *lchunk; | 1307 | struct list_head *lchunk; |
1321 | struct sctp_chunk *tchunk; | 1308 | struct sctp_chunk *tchunk; |
@@ -1387,7 +1374,6 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1387 | * instance). | 1374 | * instance). |
1388 | */ | 1375 | */ |
1389 | if (!tchunk->tsn_gap_acked && | 1376 | if (!tchunk->tsn_gap_acked && |
1390 | !tchunk->resent && | ||
1391 | tchunk->rtt_in_progress) { | 1377 | tchunk->rtt_in_progress) { |
1392 | tchunk->rtt_in_progress = 0; | 1378 | tchunk->rtt_in_progress = 0; |
1393 | rtt = jiffies - tchunk->sent_at; | 1379 | rtt = jiffies - tchunk->sent_at; |
@@ -1404,6 +1390,7 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1404 | */ | 1390 | */ |
1405 | if (!tchunk->tsn_gap_acked) { | 1391 | if (!tchunk->tsn_gap_acked) { |
1406 | tchunk->tsn_gap_acked = 1; | 1392 | tchunk->tsn_gap_acked = 1; |
1393 | *highest_new_tsn_in_sack = tsn; | ||
1407 | bytes_acked += sctp_data_size(tchunk); | 1394 | bytes_acked += sctp_data_size(tchunk); |
1408 | if (!tchunk->transport) | 1395 | if (!tchunk->transport) |
1409 | migrate_bytes += sctp_data_size(tchunk); | 1396 | migrate_bytes += sctp_data_size(tchunk); |
@@ -1677,7 +1664,8 @@ static void sctp_mark_missing(struct sctp_outq *q, | |||
1677 | struct sctp_chunk *chunk; | 1664 | struct sctp_chunk *chunk; |
1678 | __u32 tsn; | 1665 | __u32 tsn; |
1679 | char do_fast_retransmit = 0; | 1666 | char do_fast_retransmit = 0; |
1680 | struct sctp_transport *primary = q->asoc->peer.primary_path; | 1667 | struct sctp_association *asoc = q->asoc; |
1668 | struct sctp_transport *primary = asoc->peer.primary_path; | ||
1681 | 1669 | ||
1682 | list_for_each_entry(chunk, transmitted_queue, transmitted_list) { | 1670 | list_for_each_entry(chunk, transmitted_queue, transmitted_list) { |
1683 | 1671 | ||
diff --git a/net/sctp/probe.c b/net/sctp/probe.c new file mode 100644 index 000000000000..db3a42b8b349 --- /dev/null +++ b/net/sctp/probe.c | |||
@@ -0,0 +1,214 @@ | |||
1 | /* | ||
2 | * sctp_probe - Observe the SCTP flow with kprobes. | ||
3 | * | ||
4 | * The idea for this came from Werner Almesberger's umlsim | ||
5 | * Copyright (C) 2004, Stephen Hemminger <shemminger@osdl.org> | ||
6 | * | ||
7 | * Modified for SCTP from Stephen Hemminger's code | ||
8 | * Copyright (C) 2010, Wei Yongjun <yjwei@cn.fujitsu.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/kprobes.h> | ||
27 | #include <linux/socket.h> | ||
28 | #include <linux/sctp.h> | ||
29 | #include <linux/proc_fs.h> | ||
30 | #include <linux/vmalloc.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/kfifo.h> | ||
33 | #include <linux/time.h> | ||
34 | #include <net/net_namespace.h> | ||
35 | |||
36 | #include <net/sctp/sctp.h> | ||
37 | #include <net/sctp/sm.h> | ||
38 | |||
39 | MODULE_AUTHOR("Wei Yongjun <yjwei@cn.fujitsu.com>"); | ||
40 | MODULE_DESCRIPTION("SCTP snooper"); | ||
41 | MODULE_LICENSE("GPL"); | ||
42 | |||
43 | static int port __read_mostly = 0; | ||
44 | MODULE_PARM_DESC(port, "Port to match (0=all)"); | ||
45 | module_param(port, int, 0); | ||
46 | |||
47 | static int bufsize __read_mostly = 64 * 1024; | ||
48 | MODULE_PARM_DESC(bufsize, "Log buffer size (default 64k)"); | ||
49 | module_param(bufsize, int, 0); | ||
50 | |||
51 | static int full __read_mostly = 1; | ||
52 | MODULE_PARM_DESC(full, "Full log (1=every ack packet received, 0=only cwnd changes)"); | ||
53 | module_param(full, int, 0); | ||
54 | |||
55 | static const char procname[] = "sctpprobe"; | ||
56 | |||
57 | static struct { | ||
58 | struct kfifo fifo; | ||
59 | spinlock_t lock; | ||
60 | wait_queue_head_t wait; | ||
61 | struct timespec tstart; | ||
62 | } sctpw; | ||
63 | |||
64 | static void printl(const char *fmt, ...) | ||
65 | { | ||
66 | va_list args; | ||
67 | int len; | ||
68 | char tbuf[256]; | ||
69 | |||
70 | va_start(args, fmt); | ||
71 | len = vscnprintf(tbuf, sizeof(tbuf), fmt, args); | ||
72 | va_end(args); | ||
73 | |||
74 | kfifo_in_locked(&sctpw.fifo, tbuf, len, &sctpw.lock); | ||
75 | wake_up(&sctpw.wait); | ||
76 | } | ||
77 | |||
78 | static int sctpprobe_open(struct inode *inode, struct file *file) | ||
79 | { | ||
80 | kfifo_reset(&sctpw.fifo); | ||
81 | getnstimeofday(&sctpw.tstart); | ||
82 | |||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | static ssize_t sctpprobe_read(struct file *file, char __user *buf, | ||
87 | size_t len, loff_t *ppos) | ||
88 | { | ||
89 | int error = 0, cnt = 0; | ||
90 | unsigned char *tbuf; | ||
91 | |||
92 | if (!buf) | ||
93 | return -EINVAL; | ||
94 | |||
95 | if (len == 0) | ||
96 | return 0; | ||
97 | |||
98 | tbuf = vmalloc(len); | ||
99 | if (!tbuf) | ||
100 | return -ENOMEM; | ||
101 | |||
102 | error = wait_event_interruptible(sctpw.wait, | ||
103 | kfifo_len(&sctpw.fifo) != 0); | ||
104 | if (error) | ||
105 | goto out_free; | ||
106 | |||
107 | cnt = kfifo_out_locked(&sctpw.fifo, tbuf, len, &sctpw.lock); | ||
108 | error = copy_to_user(buf, tbuf, cnt) ? -EFAULT : 0; | ||
109 | |||
110 | out_free: | ||
111 | vfree(tbuf); | ||
112 | |||
113 | return error ? error : cnt; | ||
114 | } | ||
115 | |||
116 | static const struct file_operations sctpprobe_fops = { | ||
117 | .owner = THIS_MODULE, | ||
118 | .open = sctpprobe_open, | ||
119 | .read = sctpprobe_read, | ||
120 | }; | ||
121 | |||
122 | sctp_disposition_t jsctp_sf_eat_sack(const struct sctp_endpoint *ep, | ||
123 | const struct sctp_association *asoc, | ||
124 | const sctp_subtype_t type, | ||
125 | void *arg, | ||
126 | sctp_cmd_seq_t *commands) | ||
127 | { | ||
128 | struct sctp_transport *sp; | ||
129 | static __u32 lcwnd = 0; | ||
130 | struct timespec now; | ||
131 | |||
132 | sp = asoc->peer.primary_path; | ||
133 | |||
134 | if ((full || sp->cwnd != lcwnd) && | ||
135 | (!port || asoc->peer.port == port || | ||
136 | ep->base.bind_addr.port == port)) { | ||
137 | lcwnd = sp->cwnd; | ||
138 | |||
139 | getnstimeofday(&now); | ||
140 | now = timespec_sub(now, sctpw.tstart); | ||
141 | |||
142 | printl("%lu.%06lu ", (unsigned long) now.tv_sec, | ||
143 | (unsigned long) now.tv_nsec / NSEC_PER_USEC); | ||
144 | |||
145 | printl("%p %5d %5d %5d %8d %5d ", asoc, | ||
146 | ep->base.bind_addr.port, asoc->peer.port, | ||
147 | asoc->pathmtu, asoc->peer.rwnd, asoc->unack_data); | ||
148 | |||
149 | list_for_each_entry(sp, &asoc->peer.transport_addr_list, | ||
150 | transports) { | ||
151 | if (sp == asoc->peer.primary_path) | ||
152 | printl("*"); | ||
153 | |||
154 | if (sp->ipaddr.sa.sa_family == AF_INET) | ||
155 | printl("%pI4 ", &sp->ipaddr.v4.sin_addr); | ||
156 | else | ||
157 | printl("%pI6 ", &sp->ipaddr.v6.sin6_addr); | ||
158 | |||
159 | printl("%2u %8u %8u %8u %8u %8u ", | ||
160 | sp->state, sp->cwnd, sp->ssthresh, | ||
161 | sp->flight_size, sp->partial_bytes_acked, | ||
162 | sp->pathmtu); | ||
163 | } | ||
164 | printl("\n"); | ||
165 | } | ||
166 | |||
167 | jprobe_return(); | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | static struct jprobe sctp_recv_probe = { | ||
172 | .kp = { | ||
173 | .symbol_name = "sctp_sf_eat_sack_6_2", | ||
174 | }, | ||
175 | .entry = jsctp_sf_eat_sack, | ||
176 | }; | ||
177 | |||
178 | static __init int sctpprobe_init(void) | ||
179 | { | ||
180 | int ret = -ENOMEM; | ||
181 | |||
182 | init_waitqueue_head(&sctpw.wait); | ||
183 | spin_lock_init(&sctpw.lock); | ||
184 | if (kfifo_alloc(&sctpw.fifo, bufsize, GFP_KERNEL)) | ||
185 | return ret; | ||
186 | |||
187 | if (!proc_net_fops_create(&init_net, procname, S_IRUSR, | ||
188 | &sctpprobe_fops)) | ||
189 | goto free_kfifo; | ||
190 | |||
191 | ret = register_jprobe(&sctp_recv_probe); | ||
192 | if (ret) | ||
193 | goto remove_proc; | ||
194 | |||
195 | pr_info("SCTP probe registered (port=%d)\n", port); | ||
196 | |||
197 | return 0; | ||
198 | |||
199 | remove_proc: | ||
200 | proc_net_remove(&init_net, procname); | ||
201 | free_kfifo: | ||
202 | kfifo_free(&sctpw.fifo); | ||
203 | return ret; | ||
204 | } | ||
205 | |||
206 | static __exit void sctpprobe_exit(void) | ||
207 | { | ||
208 | kfifo_free(&sctpw.fifo); | ||
209 | proc_net_remove(&init_net, procname); | ||
210 | unregister_jprobe(&sctp_recv_probe); | ||
211 | } | ||
212 | |||
213 | module_init(sctpprobe_init); | ||
214 | module_exit(sctpprobe_exit); | ||
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 704298f4b284..182749867c72 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -474,13 +474,17 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, | |||
474 | 474 | ||
475 | memset(&fl, 0x0, sizeof(struct flowi)); | 475 | memset(&fl, 0x0, sizeof(struct flowi)); |
476 | fl.fl4_dst = daddr->v4.sin_addr.s_addr; | 476 | fl.fl4_dst = daddr->v4.sin_addr.s_addr; |
477 | fl.fl_ip_dport = daddr->v4.sin_port; | ||
477 | fl.proto = IPPROTO_SCTP; | 478 | fl.proto = IPPROTO_SCTP; |
478 | if (asoc) { | 479 | if (asoc) { |
479 | fl.fl4_tos = RT_CONN_FLAGS(asoc->base.sk); | 480 | fl.fl4_tos = RT_CONN_FLAGS(asoc->base.sk); |
480 | fl.oif = asoc->base.sk->sk_bound_dev_if; | 481 | fl.oif = asoc->base.sk->sk_bound_dev_if; |
482 | fl.fl_ip_sport = htons(asoc->base.bind_addr.port); | ||
481 | } | 483 | } |
482 | if (saddr) | 484 | if (saddr) { |
483 | fl.fl4_src = saddr->v4.sin_addr.s_addr; | 485 | fl.fl4_src = saddr->v4.sin_addr.s_addr; |
486 | fl.fl_ip_sport = saddr->v4.sin_port; | ||
487 | } | ||
484 | 488 | ||
485 | SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ", | 489 | SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ", |
486 | __func__, &fl.fl4_dst, &fl.fl4_src); | 490 | __func__, &fl.fl4_dst, &fl.fl4_src); |
@@ -528,6 +532,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, | |||
528 | if ((laddr->state == SCTP_ADDR_SRC) && | 532 | if ((laddr->state == SCTP_ADDR_SRC) && |
529 | (AF_INET == laddr->a.sa.sa_family)) { | 533 | (AF_INET == laddr->a.sa.sa_family)) { |
530 | fl.fl4_src = laddr->a.v4.sin_addr.s_addr; | 534 | fl.fl4_src = laddr->a.v4.sin_addr.s_addr; |
535 | fl.fl_ip_sport = laddr->a.v4.sin_port; | ||
531 | if (!ip_route_output_key(&init_net, &rt, &fl)) { | 536 | if (!ip_route_output_key(&init_net, &rt, &fl)) { |
532 | dst = &rt->u.dst; | 537 | dst = &rt->u.dst; |
533 | goto out_unlock; | 538 | goto out_unlock; |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 17cb400ecd6a..d8261f3d7715 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -108,7 +108,7 @@ static const struct sctp_paramhdr prsctp_param = { | |||
108 | cpu_to_be16(sizeof(struct sctp_paramhdr)), | 108 | cpu_to_be16(sizeof(struct sctp_paramhdr)), |
109 | }; | 109 | }; |
110 | 110 | ||
111 | /* A helper to initialize to initialize an op error inside a | 111 | /* A helper to initialize an op error inside a |
112 | * provided chunk, as most cause codes will be embedded inside an | 112 | * provided chunk, as most cause codes will be embedded inside an |
113 | * abort chunk. | 113 | * abort chunk. |
114 | */ | 114 | */ |
@@ -125,6 +125,29 @@ void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code, | |||
125 | chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err); | 125 | chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err); |
126 | } | 126 | } |
127 | 127 | ||
128 | /* A helper to initialize an op error inside a | ||
129 | * provided chunk, as most cause codes will be embedded inside an | ||
130 | * abort chunk. Differs from sctp_init_cause in that it won't oops | ||
131 | * if there isn't enough space in the op error chunk | ||
132 | */ | ||
133 | int sctp_init_cause_fixed(struct sctp_chunk *chunk, __be16 cause_code, | ||
134 | size_t paylen) | ||
135 | { | ||
136 | sctp_errhdr_t err; | ||
137 | __u16 len; | ||
138 | |||
139 | /* Cause code constants are now defined in network order. */ | ||
140 | err.cause = cause_code; | ||
141 | len = sizeof(sctp_errhdr_t) + paylen; | ||
142 | err.length = htons(len); | ||
143 | |||
144 | if (skb_tailroom(chunk->skb) > len) | ||
145 | return -ENOSPC; | ||
146 | chunk->subh.err_hdr = sctp_addto_chunk_fixed(chunk, | ||
147 | sizeof(sctp_errhdr_t), | ||
148 | &err); | ||
149 | return 0; | ||
150 | } | ||
128 | /* 3.3.2 Initiation (INIT) (1) | 151 | /* 3.3.2 Initiation (INIT) (1) |
129 | * | 152 | * |
130 | * This chunk is used to initiate a SCTP association between two | 153 | * This chunk is used to initiate a SCTP association between two |
@@ -208,7 +231,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | |||
208 | sp = sctp_sk(asoc->base.sk); | 231 | sp = sctp_sk(asoc->base.sk); |
209 | num_types = sp->pf->supported_addrs(sp, types); | 232 | num_types = sp->pf->supported_addrs(sp, types); |
210 | 233 | ||
211 | chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types); | 234 | chunksize = sizeof(init) + addrs_len; |
235 | chunksize += WORD_ROUND(SCTP_SAT_LEN(num_types)); | ||
212 | chunksize += sizeof(ecap_param); | 236 | chunksize += sizeof(ecap_param); |
213 | 237 | ||
214 | if (sctp_prsctp_enable) | 238 | if (sctp_prsctp_enable) |
@@ -238,14 +262,14 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | |||
238 | /* Add HMACS parameter length if any were defined */ | 262 | /* Add HMACS parameter length if any were defined */ |
239 | auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; | 263 | auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; |
240 | if (auth_hmacs->length) | 264 | if (auth_hmacs->length) |
241 | chunksize += ntohs(auth_hmacs->length); | 265 | chunksize += WORD_ROUND(ntohs(auth_hmacs->length)); |
242 | else | 266 | else |
243 | auth_hmacs = NULL; | 267 | auth_hmacs = NULL; |
244 | 268 | ||
245 | /* Add CHUNKS parameter length */ | 269 | /* Add CHUNKS parameter length */ |
246 | auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; | 270 | auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; |
247 | if (auth_chunks->length) | 271 | if (auth_chunks->length) |
248 | chunksize += ntohs(auth_chunks->length); | 272 | chunksize += WORD_ROUND(ntohs(auth_chunks->length)); |
249 | else | 273 | else |
250 | auth_chunks = NULL; | 274 | auth_chunks = NULL; |
251 | 275 | ||
@@ -255,7 +279,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | |||
255 | 279 | ||
256 | /* If we have any extensions to report, account for that */ | 280 | /* If we have any extensions to report, account for that */ |
257 | if (num_ext) | 281 | if (num_ext) |
258 | chunksize += sizeof(sctp_supported_ext_param_t) + num_ext; | 282 | chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) + |
283 | num_ext); | ||
259 | 284 | ||
260 | /* RFC 2960 3.3.2 Initiation (INIT) (1) | 285 | /* RFC 2960 3.3.2 Initiation (INIT) (1) |
261 | * | 286 | * |
@@ -397,13 +422,13 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, | |||
397 | 422 | ||
398 | auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; | 423 | auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; |
399 | if (auth_hmacs->length) | 424 | if (auth_hmacs->length) |
400 | chunksize += ntohs(auth_hmacs->length); | 425 | chunksize += WORD_ROUND(ntohs(auth_hmacs->length)); |
401 | else | 426 | else |
402 | auth_hmacs = NULL; | 427 | auth_hmacs = NULL; |
403 | 428 | ||
404 | auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; | 429 | auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; |
405 | if (auth_chunks->length) | 430 | if (auth_chunks->length) |
406 | chunksize += ntohs(auth_chunks->length); | 431 | chunksize += WORD_ROUND(ntohs(auth_chunks->length)); |
407 | else | 432 | else |
408 | auth_chunks = NULL; | 433 | auth_chunks = NULL; |
409 | 434 | ||
@@ -412,17 +437,25 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, | |||
412 | } | 437 | } |
413 | 438 | ||
414 | if (num_ext) | 439 | if (num_ext) |
415 | chunksize += sizeof(sctp_supported_ext_param_t) + num_ext; | 440 | chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) + |
441 | num_ext); | ||
416 | 442 | ||
417 | /* Now allocate and fill out the chunk. */ | 443 | /* Now allocate and fill out the chunk. */ |
418 | retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize); | 444 | retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize); |
419 | if (!retval) | 445 | if (!retval) |
420 | goto nomem_chunk; | 446 | goto nomem_chunk; |
421 | 447 | ||
422 | /* Per the advice in RFC 2960 6.4, send this reply to | 448 | /* RFC 2960 6.4 Multi-homed SCTP Endpoints |
423 | * the source of the INIT packet. | 449 | * |
450 | * An endpoint SHOULD transmit reply chunks (e.g., SACK, | ||
451 | * HEARTBEAT ACK, * etc.) to the same destination transport | ||
452 | * address from which it received the DATA or control chunk | ||
453 | * to which it is replying. | ||
454 | * | ||
455 | * [INIT ACK back to where the INIT came from.] | ||
424 | */ | 456 | */ |
425 | retval->transport = chunk->transport; | 457 | retval->transport = chunk->transport; |
458 | |||
426 | retval->subh.init_hdr = | 459 | retval->subh.init_hdr = |
427 | sctp_addto_chunk(retval, sizeof(initack), &initack); | 460 | sctp_addto_chunk(retval, sizeof(initack), &initack); |
428 | retval->param_hdr.v = sctp_addto_chunk(retval, addrs_len, addrs.v); | 461 | retval->param_hdr.v = sctp_addto_chunk(retval, addrs_len, addrs.v); |
@@ -461,18 +494,6 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, | |||
461 | /* We need to remove the const qualifier at this point. */ | 494 | /* We need to remove the const qualifier at this point. */ |
462 | retval->asoc = (struct sctp_association *) asoc; | 495 | retval->asoc = (struct sctp_association *) asoc; |
463 | 496 | ||
464 | /* RFC 2960 6.4 Multi-homed SCTP Endpoints | ||
465 | * | ||
466 | * An endpoint SHOULD transmit reply chunks (e.g., SACK, | ||
467 | * HEARTBEAT ACK, * etc.) to the same destination transport | ||
468 | * address from which it received the DATA or control chunk | ||
469 | * to which it is replying. | ||
470 | * | ||
471 | * [INIT ACK back to where the INIT came from.] | ||
472 | */ | ||
473 | if (chunk) | ||
474 | retval->transport = chunk->transport; | ||
475 | |||
476 | nomem_chunk: | 497 | nomem_chunk: |
477 | kfree(cookie); | 498 | kfree(cookie); |
478 | nomem_cookie: | 499 | nomem_cookie: |
@@ -1129,6 +1150,24 @@ nodata: | |||
1129 | return retval; | 1150 | return retval; |
1130 | } | 1151 | } |
1131 | 1152 | ||
1153 | /* Create an Operation Error chunk of a fixed size, | ||
1154 | * specifically, max(asoc->pathmtu, SCTP_DEFAULT_MAXSEGMENT) | ||
1155 | * This is a helper function to allocate an error chunk for | ||
1156 | * for those invalid parameter codes in which we may not want | ||
1157 | * to report all the errors, if the incomming chunk is large | ||
1158 | */ | ||
1159 | static inline struct sctp_chunk *sctp_make_op_error_fixed( | ||
1160 | const struct sctp_association *asoc, | ||
1161 | const struct sctp_chunk *chunk) | ||
1162 | { | ||
1163 | size_t size = asoc ? asoc->pathmtu : 0; | ||
1164 | |||
1165 | if (!size) | ||
1166 | size = SCTP_DEFAULT_MAXSEGMENT; | ||
1167 | |||
1168 | return sctp_make_op_error_space(asoc, chunk, size); | ||
1169 | } | ||
1170 | |||
1132 | /* Create an Operation Error chunk. */ | 1171 | /* Create an Operation Error chunk. */ |
1133 | struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc, | 1172 | struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc, |
1134 | const struct sctp_chunk *chunk, | 1173 | const struct sctp_chunk *chunk, |
@@ -1210,7 +1249,6 @@ struct sctp_chunk *sctp_chunkify(struct sk_buff *skb, | |||
1210 | INIT_LIST_HEAD(&retval->list); | 1249 | INIT_LIST_HEAD(&retval->list); |
1211 | retval->skb = skb; | 1250 | retval->skb = skb; |
1212 | retval->asoc = (struct sctp_association *)asoc; | 1251 | retval->asoc = (struct sctp_association *)asoc; |
1213 | retval->resent = 0; | ||
1214 | retval->has_tsn = 0; | 1252 | retval->has_tsn = 0; |
1215 | retval->has_ssn = 0; | 1253 | retval->has_ssn = 0; |
1216 | retval->rtt_in_progress = 0; | 1254 | retval->rtt_in_progress = 0; |
@@ -1371,6 +1409,18 @@ void *sctp_addto_chunk(struct sctp_chunk *chunk, int len, const void *data) | |||
1371 | return target; | 1409 | return target; |
1372 | } | 1410 | } |
1373 | 1411 | ||
1412 | /* Append bytes to the end of a chunk. Returns NULL if there isn't sufficient | ||
1413 | * space in the chunk | ||
1414 | */ | ||
1415 | void *sctp_addto_chunk_fixed(struct sctp_chunk *chunk, | ||
1416 | int len, const void *data) | ||
1417 | { | ||
1418 | if (skb_tailroom(chunk->skb) > len) | ||
1419 | return sctp_addto_chunk(chunk, len, data); | ||
1420 | else | ||
1421 | return NULL; | ||
1422 | } | ||
1423 | |||
1374 | /* Append bytes from user space to the end of a chunk. Will panic if | 1424 | /* Append bytes from user space to the end of a chunk. Will panic if |
1375 | * chunk is not big enough. | 1425 | * chunk is not big enough. |
1376 | * Returns a kernel err value. | 1426 | * Returns a kernel err value. |
@@ -1974,13 +2024,12 @@ static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc, | |||
1974 | * returning multiple unknown parameters. | 2024 | * returning multiple unknown parameters. |
1975 | */ | 2025 | */ |
1976 | if (NULL == *errp) | 2026 | if (NULL == *errp) |
1977 | *errp = sctp_make_op_error_space(asoc, chunk, | 2027 | *errp = sctp_make_op_error_fixed(asoc, chunk); |
1978 | ntohs(chunk->chunk_hdr->length)); | ||
1979 | 2028 | ||
1980 | if (*errp) { | 2029 | if (*errp) { |
1981 | sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM, | 2030 | sctp_init_cause_fixed(*errp, SCTP_ERROR_UNKNOWN_PARAM, |
1982 | WORD_ROUND(ntohs(param.p->length))); | 2031 | WORD_ROUND(ntohs(param.p->length))); |
1983 | sctp_addto_chunk(*errp, | 2032 | sctp_addto_chunk_fixed(*errp, |
1984 | WORD_ROUND(ntohs(param.p->length)), | 2033 | WORD_ROUND(ntohs(param.p->length)), |
1985 | param.v); | 2034 | param.v); |
1986 | } else { | 2035 | } else { |
@@ -3315,21 +3364,6 @@ int sctp_process_asconf_ack(struct sctp_association *asoc, | |||
3315 | sctp_chunk_free(asconf); | 3364 | sctp_chunk_free(asconf); |
3316 | asoc->addip_last_asconf = NULL; | 3365 | asoc->addip_last_asconf = NULL; |
3317 | 3366 | ||
3318 | /* Send the next asconf chunk from the addip chunk queue. */ | ||
3319 | if (!list_empty(&asoc->addip_chunk_list)) { | ||
3320 | struct list_head *entry = asoc->addip_chunk_list.next; | ||
3321 | asconf = list_entry(entry, struct sctp_chunk, list); | ||
3322 | |||
3323 | list_del_init(entry); | ||
3324 | |||
3325 | /* Hold the chunk until an ASCONF_ACK is received. */ | ||
3326 | sctp_chunk_hold(asconf); | ||
3327 | if (sctp_primitive_ASCONF(asoc, asconf)) | ||
3328 | sctp_chunk_free(asconf); | ||
3329 | else | ||
3330 | asoc->addip_last_asconf = asconf; | ||
3331 | } | ||
3332 | |||
3333 | return retval; | 3367 | return retval; |
3334 | } | 3368 | } |
3335 | 3369 | ||
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 4c5bed9af4e3..3b7230ef77c2 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -697,11 +697,15 @@ static void sctp_cmd_setup_t2(sctp_cmd_seq_t *cmds, | |||
697 | { | 697 | { |
698 | struct sctp_transport *t; | 698 | struct sctp_transport *t; |
699 | 699 | ||
700 | t = sctp_assoc_choose_alter_transport(asoc, | 700 | if (chunk->transport) |
701 | t = chunk->transport; | ||
702 | else { | ||
703 | t = sctp_assoc_choose_alter_transport(asoc, | ||
701 | asoc->shutdown_last_sent_to); | 704 | asoc->shutdown_last_sent_to); |
705 | chunk->transport = t; | ||
706 | } | ||
702 | asoc->shutdown_last_sent_to = t; | 707 | asoc->shutdown_last_sent_to = t; |
703 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = t->rto; | 708 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = t->rto; |
704 | chunk->transport = t; | ||
705 | } | 709 | } |
706 | 710 | ||
707 | /* Helper function to change the state of an association. */ | 711 | /* Helper function to change the state of an association. */ |
@@ -962,6 +966,29 @@ static int sctp_cmd_send_msg(struct sctp_association *asoc, | |||
962 | } | 966 | } |
963 | 967 | ||
964 | 968 | ||
969 | /* Sent the next ASCONF packet currently stored in the association. | ||
970 | * This happens after the ASCONF_ACK was succeffully processed. | ||
971 | */ | ||
972 | static void sctp_cmd_send_asconf(struct sctp_association *asoc) | ||
973 | { | ||
974 | /* Send the next asconf chunk from the addip chunk | ||
975 | * queue. | ||
976 | */ | ||
977 | if (!list_empty(&asoc->addip_chunk_list)) { | ||
978 | struct list_head *entry = asoc->addip_chunk_list.next; | ||
979 | struct sctp_chunk *asconf = list_entry(entry, | ||
980 | struct sctp_chunk, list); | ||
981 | list_del_init(entry); | ||
982 | |||
983 | /* Hold the chunk until an ASCONF_ACK is received. */ | ||
984 | sctp_chunk_hold(asconf); | ||
985 | if (sctp_primitive_ASCONF(asoc, asconf)) | ||
986 | sctp_chunk_free(asconf); | ||
987 | else | ||
988 | asoc->addip_last_asconf = asconf; | ||
989 | } | ||
990 | } | ||
991 | |||
965 | 992 | ||
966 | /* These three macros allow us to pull the debugging code out of the | 993 | /* These three macros allow us to pull the debugging code out of the |
967 | * main flow of sctp_do_sm() to keep attention focused on the real | 994 | * main flow of sctp_do_sm() to keep attention focused on the real |
@@ -1617,6 +1644,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1617 | } | 1644 | } |
1618 | error = sctp_cmd_send_msg(asoc, cmd->obj.msg); | 1645 | error = sctp_cmd_send_msg(asoc, cmd->obj.msg); |
1619 | break; | 1646 | break; |
1647 | case SCTP_CMD_SEND_NEXT_ASCONF: | ||
1648 | sctp_cmd_send_asconf(asoc); | ||
1649 | break; | ||
1620 | default: | 1650 | default: |
1621 | printk(KERN_WARNING "Impossible command: %u, %p\n", | 1651 | printk(KERN_WARNING "Impossible command: %u, %p\n", |
1622 | cmd->verb, cmd->obj.ptr); | 1652 | cmd->verb, cmd->obj.ptr); |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index abf601a1b847..24b2cd555637 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -3676,8 +3676,14 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep, | |||
3676 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); | 3676 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); |
3677 | 3677 | ||
3678 | if (!sctp_process_asconf_ack((struct sctp_association *)asoc, | 3678 | if (!sctp_process_asconf_ack((struct sctp_association *)asoc, |
3679 | asconf_ack)) | 3679 | asconf_ack)) { |
3680 | /* Successfully processed ASCONF_ACK. We can | ||
3681 | * release the next asconf if we have one. | ||
3682 | */ | ||
3683 | sctp_add_cmd_sf(commands, SCTP_CMD_SEND_NEXT_ASCONF, | ||
3684 | SCTP_NULL()); | ||
3680 | return SCTP_DISPOSITION_CONSUME; | 3685 | return SCTP_DISPOSITION_CONSUME; |
3686 | } | ||
3681 | 3687 | ||
3682 | abort = sctp_make_abort(asoc, asconf_ack, | 3688 | abort = sctp_make_abort(asoc, asconf_ack, |
3683 | sizeof(sctp_errhdr_t)); | 3689 | sizeof(sctp_errhdr_t)); |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index c1941276f6e3..ba1add0b13c3 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -3719,12 +3719,9 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
3719 | sp->hmac = NULL; | 3719 | sp->hmac = NULL; |
3720 | 3720 | ||
3721 | SCTP_DBG_OBJCNT_INC(sock); | 3721 | SCTP_DBG_OBJCNT_INC(sock); |
3722 | percpu_counter_inc(&sctp_sockets_allocated); | ||
3723 | |||
3724 | /* Set socket backlog limit. */ | ||
3725 | sk->sk_backlog.limit = sysctl_sctp_rmem[1]; | ||
3726 | 3722 | ||
3727 | local_bh_disable(); | 3723 | local_bh_disable(); |
3724 | percpu_counter_inc(&sctp_sockets_allocated); | ||
3728 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); | 3725 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); |
3729 | local_bh_enable(); | 3726 | local_bh_enable(); |
3730 | 3727 | ||
@@ -3741,8 +3738,8 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk) | |||
3741 | /* Release our hold on the endpoint. */ | 3738 | /* Release our hold on the endpoint. */ |
3742 | ep = sctp_sk(sk)->ep; | 3739 | ep = sctp_sk(sk)->ep; |
3743 | sctp_endpoint_free(ep); | 3740 | sctp_endpoint_free(ep); |
3744 | percpu_counter_dec(&sctp_sockets_allocated); | ||
3745 | local_bh_disable(); | 3741 | local_bh_disable(); |
3742 | percpu_counter_dec(&sctp_sockets_allocated); | ||
3746 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); | 3743 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); |
3747 | local_bh_enable(); | 3744 | local_bh_enable(); |
3748 | } | 3745 | } |
@@ -4387,7 +4384,7 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, | |||
4387 | transports) { | 4384 | transports) { |
4388 | memcpy(&temp, &from->ipaddr, sizeof(temp)); | 4385 | memcpy(&temp, &from->ipaddr, sizeof(temp)); |
4389 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); | 4386 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); |
4390 | addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len; | 4387 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; |
4391 | if (space_left < addrlen) | 4388 | if (space_left < addrlen) |
4392 | return -ENOMEM; | 4389 | return -ENOMEM; |
4393 | if (copy_to_user(to, &temp, addrlen)) | 4390 | if (copy_to_user(to, &temp, addrlen)) |
@@ -5702,7 +5699,7 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
5702 | struct sctp_sock *sp = sctp_sk(sk); | 5699 | struct sctp_sock *sp = sctp_sk(sk); |
5703 | unsigned int mask; | 5700 | unsigned int mask; |
5704 | 5701 | ||
5705 | poll_wait(file, sk->sk_sleep, wait); | 5702 | poll_wait(file, sk_sleep(sk), wait); |
5706 | 5703 | ||
5707 | /* A TCP-style listening socket becomes readable when the accept queue | 5704 | /* A TCP-style listening socket becomes readable when the accept queue |
5708 | * is not empty. | 5705 | * is not empty. |
@@ -5943,7 +5940,7 @@ static int sctp_wait_for_packet(struct sock * sk, int *err, long *timeo_p) | |||
5943 | int error; | 5940 | int error; |
5944 | DEFINE_WAIT(wait); | 5941 | DEFINE_WAIT(wait); |
5945 | 5942 | ||
5946 | prepare_to_wait_exclusive(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 5943 | prepare_to_wait_exclusive(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
5947 | 5944 | ||
5948 | /* Socket errors? */ | 5945 | /* Socket errors? */ |
5949 | error = sock_error(sk); | 5946 | error = sock_error(sk); |
@@ -5980,14 +5977,14 @@ static int sctp_wait_for_packet(struct sock * sk, int *err, long *timeo_p) | |||
5980 | sctp_lock_sock(sk); | 5977 | sctp_lock_sock(sk); |
5981 | 5978 | ||
5982 | ready: | 5979 | ready: |
5983 | finish_wait(sk->sk_sleep, &wait); | 5980 | finish_wait(sk_sleep(sk), &wait); |
5984 | return 0; | 5981 | return 0; |
5985 | 5982 | ||
5986 | interrupted: | 5983 | interrupted: |
5987 | error = sock_intr_errno(*timeo_p); | 5984 | error = sock_intr_errno(*timeo_p); |
5988 | 5985 | ||
5989 | out: | 5986 | out: |
5990 | finish_wait(sk->sk_sleep, &wait); | 5987 | finish_wait(sk_sleep(sk), &wait); |
5991 | *err = error; | 5988 | *err = error; |
5992 | return error; | 5989 | return error; |
5993 | } | 5990 | } |
@@ -6061,14 +6058,14 @@ static void __sctp_write_space(struct sctp_association *asoc) | |||
6061 | wake_up_interruptible(&asoc->wait); | 6058 | wake_up_interruptible(&asoc->wait); |
6062 | 6059 | ||
6063 | if (sctp_writeable(sk)) { | 6060 | if (sctp_writeable(sk)) { |
6064 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 6061 | if (sk_sleep(sk) && waitqueue_active(sk_sleep(sk))) |
6065 | wake_up_interruptible(sk->sk_sleep); | 6062 | wake_up_interruptible(sk_sleep(sk)); |
6066 | 6063 | ||
6067 | /* Note that we try to include the Async I/O support | 6064 | /* Note that we try to include the Async I/O support |
6068 | * here by modeling from the current TCP/UDP code. | 6065 | * here by modeling from the current TCP/UDP code. |
6069 | * We have not tested with it yet. | 6066 | * We have not tested with it yet. |
6070 | */ | 6067 | */ |
6071 | if (sock->fasync_list && | 6068 | if (sock->wq->fasync_list && |
6072 | !(sk->sk_shutdown & SEND_SHUTDOWN)) | 6069 | !(sk->sk_shutdown & SEND_SHUTDOWN)) |
6073 | sock_wake_async(sock, | 6070 | sock_wake_async(sock, |
6074 | SOCK_WAKE_SPACE, POLL_OUT); | 6071 | SOCK_WAKE_SPACE, POLL_OUT); |
@@ -6188,6 +6185,19 @@ do_nonblock: | |||
6188 | goto out; | 6185 | goto out; |
6189 | } | 6186 | } |
6190 | 6187 | ||
6188 | void sctp_data_ready(struct sock *sk, int len) | ||
6189 | { | ||
6190 | struct socket_wq *wq; | ||
6191 | |||
6192 | rcu_read_lock(); | ||
6193 | wq = rcu_dereference(sk->sk_wq); | ||
6194 | if (wq_has_sleeper(wq)) | ||
6195 | wake_up_interruptible_sync_poll(&wq->wait, POLLIN | | ||
6196 | POLLRDNORM | POLLRDBAND); | ||
6197 | sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); | ||
6198 | rcu_read_unlock(); | ||
6199 | } | ||
6200 | |||
6191 | /* If socket sndbuf has changed, wake up all per association waiters. */ | 6201 | /* If socket sndbuf has changed, wake up all per association waiters. */ |
6192 | void sctp_write_space(struct sock *sk) | 6202 | void sctp_write_space(struct sock *sk) |
6193 | { | 6203 | { |
@@ -6296,7 +6306,7 @@ static int sctp_wait_for_accept(struct sock *sk, long timeo) | |||
6296 | 6306 | ||
6297 | 6307 | ||
6298 | for (;;) { | 6308 | for (;;) { |
6299 | prepare_to_wait_exclusive(sk->sk_sleep, &wait, | 6309 | prepare_to_wait_exclusive(sk_sleep(sk), &wait, |
6300 | TASK_INTERRUPTIBLE); | 6310 | TASK_INTERRUPTIBLE); |
6301 | 6311 | ||
6302 | if (list_empty(&ep->asocs)) { | 6312 | if (list_empty(&ep->asocs)) { |
@@ -6322,7 +6332,7 @@ static int sctp_wait_for_accept(struct sock *sk, long timeo) | |||
6322 | break; | 6332 | break; |
6323 | } | 6333 | } |
6324 | 6334 | ||
6325 | finish_wait(sk->sk_sleep, &wait); | 6335 | finish_wait(sk_sleep(sk), &wait); |
6326 | 6336 | ||
6327 | return err; | 6337 | return err; |
6328 | } | 6338 | } |
@@ -6332,7 +6342,7 @@ static void sctp_wait_for_close(struct sock *sk, long timeout) | |||
6332 | DEFINE_WAIT(wait); | 6342 | DEFINE_WAIT(wait); |
6333 | 6343 | ||
6334 | do { | 6344 | do { |
6335 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 6345 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
6336 | if (list_empty(&sctp_sk(sk)->ep->asocs)) | 6346 | if (list_empty(&sctp_sk(sk)->ep->asocs)) |
6337 | break; | 6347 | break; |
6338 | sctp_release_sock(sk); | 6348 | sctp_release_sock(sk); |
@@ -6340,7 +6350,7 @@ static void sctp_wait_for_close(struct sock *sk, long timeout) | |||
6340 | sctp_lock_sock(sk); | 6350 | sctp_lock_sock(sk); |
6341 | } while (!signal_pending(current) && timeout); | 6351 | } while (!signal_pending(current) && timeout); |
6342 | 6352 | ||
6343 | finish_wait(sk->sk_sleep, &wait); | 6353 | finish_wait(sk_sleep(sk), &wait); |
6344 | } | 6354 | } |
6345 | 6355 | ||
6346 | static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk) | 6356 | static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk) |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index be4d63d5a5cc..fccf4947aff1 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -64,9 +64,6 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | |||
64 | /* Copy in the address. */ | 64 | /* Copy in the address. */ |
65 | peer->ipaddr = *addr; | 65 | peer->ipaddr = *addr; |
66 | peer->af_specific = sctp_get_af_specific(addr->sa.sa_family); | 66 | peer->af_specific = sctp_get_af_specific(addr->sa.sa_family); |
67 | peer->asoc = NULL; | ||
68 | |||
69 | peer->dst = NULL; | ||
70 | memset(&peer->saddr, 0, sizeof(union sctp_addr)); | 67 | memset(&peer->saddr, 0, sizeof(union sctp_addr)); |
71 | 68 | ||
72 | /* From 6.3.1 RTO Calculation: | 69 | /* From 6.3.1 RTO Calculation: |
@@ -76,34 +73,21 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | |||
76 | * parameter 'RTO.Initial'. | 73 | * parameter 'RTO.Initial'. |
77 | */ | 74 | */ |
78 | peer->rto = msecs_to_jiffies(sctp_rto_initial); | 75 | peer->rto = msecs_to_jiffies(sctp_rto_initial); |
79 | peer->rtt = 0; | ||
80 | peer->rttvar = 0; | ||
81 | peer->srtt = 0; | ||
82 | peer->rto_pending = 0; | ||
83 | peer->hb_sent = 0; | ||
84 | peer->fast_recovery = 0; | ||
85 | 76 | ||
86 | peer->last_time_heard = jiffies; | 77 | peer->last_time_heard = jiffies; |
87 | peer->last_time_ecne_reduced = jiffies; | 78 | peer->last_time_ecne_reduced = jiffies; |
88 | 79 | ||
89 | peer->init_sent_count = 0; | ||
90 | |||
91 | peer->param_flags = SPP_HB_DISABLE | | 80 | peer->param_flags = SPP_HB_DISABLE | |
92 | SPP_PMTUD_ENABLE | | 81 | SPP_PMTUD_ENABLE | |
93 | SPP_SACKDELAY_ENABLE; | 82 | SPP_SACKDELAY_ENABLE; |
94 | peer->hbinterval = 0; | ||
95 | 83 | ||
96 | /* Initialize the default path max_retrans. */ | 84 | /* Initialize the default path max_retrans. */ |
97 | peer->pathmaxrxt = sctp_max_retrans_path; | 85 | peer->pathmaxrxt = sctp_max_retrans_path; |
98 | peer->error_count = 0; | ||
99 | 86 | ||
100 | INIT_LIST_HEAD(&peer->transmitted); | 87 | INIT_LIST_HEAD(&peer->transmitted); |
101 | INIT_LIST_HEAD(&peer->send_ready); | 88 | INIT_LIST_HEAD(&peer->send_ready); |
102 | INIT_LIST_HEAD(&peer->transports); | 89 | INIT_LIST_HEAD(&peer->transports); |
103 | 90 | ||
104 | peer->T3_rtx_timer.expires = 0; | ||
105 | peer->hb_timer.expires = 0; | ||
106 | |||
107 | setup_timer(&peer->T3_rtx_timer, sctp_generate_t3_rtx_event, | 91 | setup_timer(&peer->T3_rtx_timer, sctp_generate_t3_rtx_event, |
108 | (unsigned long)peer); | 92 | (unsigned long)peer); |
109 | setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event, | 93 | setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event, |
@@ -113,15 +97,6 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | |||
113 | get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce)); | 97 | get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce)); |
114 | 98 | ||
115 | atomic_set(&peer->refcnt, 1); | 99 | atomic_set(&peer->refcnt, 1); |
116 | peer->dead = 0; | ||
117 | |||
118 | peer->malloced = 0; | ||
119 | |||
120 | /* Initialize the state information for SFR-CACC */ | ||
121 | peer->cacc.changeover_active = 0; | ||
122 | peer->cacc.cycling_changeover = 0; | ||
123 | peer->cacc.next_tsn_at_change = 0; | ||
124 | peer->cacc.cacc_saw_newack = 0; | ||
125 | 100 | ||
126 | return peer; | 101 | return peer; |
127 | } | 102 | } |
@@ -195,7 +170,7 @@ static void sctp_transport_destroy(struct sctp_transport *transport) | |||
195 | /* Start T3_rtx timer if it is not already running and update the heartbeat | 170 | /* Start T3_rtx timer if it is not already running and update the heartbeat |
196 | * timer. This routine is called every time a DATA chunk is sent. | 171 | * timer. This routine is called every time a DATA chunk is sent. |
197 | */ | 172 | */ |
198 | void sctp_transport_reset_timers(struct sctp_transport *transport, int force) | 173 | void sctp_transport_reset_timers(struct sctp_transport *transport) |
199 | { | 174 | { |
200 | /* RFC 2960 6.3.2 Retransmission Timer Rules | 175 | /* RFC 2960 6.3.2 Retransmission Timer Rules |
201 | * | 176 | * |
@@ -205,7 +180,7 @@ void sctp_transport_reset_timers(struct sctp_transport *transport, int force) | |||
205 | * address. | 180 | * address. |
206 | */ | 181 | */ |
207 | 182 | ||
208 | if (force || !timer_pending(&transport->T3_rtx_timer)) | 183 | if (!timer_pending(&transport->T3_rtx_timer)) |
209 | if (!mod_timer(&transport->T3_rtx_timer, | 184 | if (!mod_timer(&transport->T3_rtx_timer, |
210 | jiffies + transport->rto)) | 185 | jiffies + transport->rto)) |
211 | sctp_transport_hold(transport); | 186 | sctp_transport_hold(transport); |
@@ -403,15 +378,16 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt) | |||
403 | void sctp_transport_raise_cwnd(struct sctp_transport *transport, | 378 | void sctp_transport_raise_cwnd(struct sctp_transport *transport, |
404 | __u32 sack_ctsn, __u32 bytes_acked) | 379 | __u32 sack_ctsn, __u32 bytes_acked) |
405 | { | 380 | { |
381 | struct sctp_association *asoc = transport->asoc; | ||
406 | __u32 cwnd, ssthresh, flight_size, pba, pmtu; | 382 | __u32 cwnd, ssthresh, flight_size, pba, pmtu; |
407 | 383 | ||
408 | cwnd = transport->cwnd; | 384 | cwnd = transport->cwnd; |
409 | flight_size = transport->flight_size; | 385 | flight_size = transport->flight_size; |
410 | 386 | ||
411 | /* See if we need to exit Fast Recovery first */ | 387 | /* See if we need to exit Fast Recovery first */ |
412 | if (transport->fast_recovery && | 388 | if (asoc->fast_recovery && |
413 | TSN_lte(transport->fast_recovery_exit, sack_ctsn)) | 389 | TSN_lte(asoc->fast_recovery_exit, sack_ctsn)) |
414 | transport->fast_recovery = 0; | 390 | asoc->fast_recovery = 0; |
415 | 391 | ||
416 | /* The appropriate cwnd increase algorithm is performed if, and only | 392 | /* The appropriate cwnd increase algorithm is performed if, and only |
417 | * if the cumulative TSN whould advanced and the congestion window is | 393 | * if the cumulative TSN whould advanced and the congestion window is |
@@ -440,7 +416,7 @@ void sctp_transport_raise_cwnd(struct sctp_transport *transport, | |||
440 | * 2) the destination's path MTU. This upper bound protects | 416 | * 2) the destination's path MTU. This upper bound protects |
441 | * against the ACK-Splitting attack outlined in [SAVAGE99]. | 417 | * against the ACK-Splitting attack outlined in [SAVAGE99]. |
442 | */ | 418 | */ |
443 | if (transport->fast_recovery) | 419 | if (asoc->fast_recovery) |
444 | return; | 420 | return; |
445 | 421 | ||
446 | if (bytes_acked > pmtu) | 422 | if (bytes_acked > pmtu) |
@@ -491,6 +467,8 @@ void sctp_transport_raise_cwnd(struct sctp_transport *transport, | |||
491 | void sctp_transport_lower_cwnd(struct sctp_transport *transport, | 467 | void sctp_transport_lower_cwnd(struct sctp_transport *transport, |
492 | sctp_lower_cwnd_t reason) | 468 | sctp_lower_cwnd_t reason) |
493 | { | 469 | { |
470 | struct sctp_association *asoc = transport->asoc; | ||
471 | |||
494 | switch (reason) { | 472 | switch (reason) { |
495 | case SCTP_LOWER_CWND_T3_RTX: | 473 | case SCTP_LOWER_CWND_T3_RTX: |
496 | /* RFC 2960 Section 7.2.3, sctpimpguide | 474 | /* RFC 2960 Section 7.2.3, sctpimpguide |
@@ -501,11 +479,11 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, | |||
501 | * partial_bytes_acked = 0 | 479 | * partial_bytes_acked = 0 |
502 | */ | 480 | */ |
503 | transport->ssthresh = max(transport->cwnd/2, | 481 | transport->ssthresh = max(transport->cwnd/2, |
504 | 4*transport->asoc->pathmtu); | 482 | 4*asoc->pathmtu); |
505 | transport->cwnd = transport->asoc->pathmtu; | 483 | transport->cwnd = asoc->pathmtu; |
506 | 484 | ||
507 | /* T3-rtx also clears fast recovery on the transport */ | 485 | /* T3-rtx also clears fast recovery */ |
508 | transport->fast_recovery = 0; | 486 | asoc->fast_recovery = 0; |
509 | break; | 487 | break; |
510 | 488 | ||
511 | case SCTP_LOWER_CWND_FAST_RTX: | 489 | case SCTP_LOWER_CWND_FAST_RTX: |
@@ -521,15 +499,15 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, | |||
521 | * cwnd = ssthresh | 499 | * cwnd = ssthresh |
522 | * partial_bytes_acked = 0 | 500 | * partial_bytes_acked = 0 |
523 | */ | 501 | */ |
524 | if (transport->fast_recovery) | 502 | if (asoc->fast_recovery) |
525 | return; | 503 | return; |
526 | 504 | ||
527 | /* Mark Fast recovery */ | 505 | /* Mark Fast recovery */ |
528 | transport->fast_recovery = 1; | 506 | asoc->fast_recovery = 1; |
529 | transport->fast_recovery_exit = transport->asoc->next_tsn - 1; | 507 | asoc->fast_recovery_exit = asoc->next_tsn - 1; |
530 | 508 | ||
531 | transport->ssthresh = max(transport->cwnd/2, | 509 | transport->ssthresh = max(transport->cwnd/2, |
532 | 4*transport->asoc->pathmtu); | 510 | 4*asoc->pathmtu); |
533 | transport->cwnd = transport->ssthresh; | 511 | transport->cwnd = transport->ssthresh; |
534 | break; | 512 | break; |
535 | 513 | ||
@@ -549,7 +527,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, | |||
549 | if (time_after(jiffies, transport->last_time_ecne_reduced + | 527 | if (time_after(jiffies, transport->last_time_ecne_reduced + |
550 | transport->rtt)) { | 528 | transport->rtt)) { |
551 | transport->ssthresh = max(transport->cwnd/2, | 529 | transport->ssthresh = max(transport->cwnd/2, |
552 | 4*transport->asoc->pathmtu); | 530 | 4*asoc->pathmtu); |
553 | transport->cwnd = transport->ssthresh; | 531 | transport->cwnd = transport->ssthresh; |
554 | transport->last_time_ecne_reduced = jiffies; | 532 | transport->last_time_ecne_reduced = jiffies; |
555 | } | 533 | } |
@@ -565,7 +543,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, | |||
565 | * interval. | 543 | * interval. |
566 | */ | 544 | */ |
567 | transport->cwnd = max(transport->cwnd/2, | 545 | transport->cwnd = max(transport->cwnd/2, |
568 | 4*transport->asoc->pathmtu); | 546 | 4*asoc->pathmtu); |
569 | break; | 547 | break; |
570 | } | 548 | } |
571 | 549 | ||
@@ -650,7 +628,6 @@ void sctp_transport_reset(struct sctp_transport *t) | |||
650 | t->error_count = 0; | 628 | t->error_count = 0; |
651 | t->rto_pending = 0; | 629 | t->rto_pending = 0; |
652 | t->hb_sent = 0; | 630 | t->hb_sent = 0; |
653 | t->fast_recovery = 0; | ||
654 | 631 | ||
655 | /* Initialize the state information for SFR-CACC */ | 632 | /* Initialize the state information for SFR-CACC */ |
656 | t->cacc.changeover_active = 0; | 633 | t->cacc.changeover_active = 0; |
diff --git a/net/socket.c b/net/socket.c index 35bc198bbf68..dae8c6b84a09 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -252,9 +252,14 @@ static struct inode *sock_alloc_inode(struct super_block *sb) | |||
252 | ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL); | 252 | ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL); |
253 | if (!ei) | 253 | if (!ei) |
254 | return NULL; | 254 | return NULL; |
255 | init_waitqueue_head(&ei->socket.wait); | 255 | ei->socket.wq = kmalloc(sizeof(struct socket_wq), GFP_KERNEL); |
256 | if (!ei->socket.wq) { | ||
257 | kmem_cache_free(sock_inode_cachep, ei); | ||
258 | return NULL; | ||
259 | } | ||
260 | init_waitqueue_head(&ei->socket.wq->wait); | ||
261 | ei->socket.wq->fasync_list = NULL; | ||
256 | 262 | ||
257 | ei->socket.fasync_list = NULL; | ||
258 | ei->socket.state = SS_UNCONNECTED; | 263 | ei->socket.state = SS_UNCONNECTED; |
259 | ei->socket.flags = 0; | 264 | ei->socket.flags = 0; |
260 | ei->socket.ops = NULL; | 265 | ei->socket.ops = NULL; |
@@ -264,10 +269,21 @@ static struct inode *sock_alloc_inode(struct super_block *sb) | |||
264 | return &ei->vfs_inode; | 269 | return &ei->vfs_inode; |
265 | } | 270 | } |
266 | 271 | ||
272 | |||
273 | static void wq_free_rcu(struct rcu_head *head) | ||
274 | { | ||
275 | struct socket_wq *wq = container_of(head, struct socket_wq, rcu); | ||
276 | |||
277 | kfree(wq); | ||
278 | } | ||
279 | |||
267 | static void sock_destroy_inode(struct inode *inode) | 280 | static void sock_destroy_inode(struct inode *inode) |
268 | { | 281 | { |
269 | kmem_cache_free(sock_inode_cachep, | 282 | struct socket_alloc *ei; |
270 | container_of(inode, struct socket_alloc, vfs_inode)); | 283 | |
284 | ei = container_of(inode, struct socket_alloc, vfs_inode); | ||
285 | call_rcu(&ei->socket.wq->rcu, wq_free_rcu); | ||
286 | kmem_cache_free(sock_inode_cachep, ei); | ||
271 | } | 287 | } |
272 | 288 | ||
273 | static void init_once(void *foo) | 289 | static void init_once(void *foo) |
@@ -513,7 +529,7 @@ void sock_release(struct socket *sock) | |||
513 | module_put(owner); | 529 | module_put(owner); |
514 | } | 530 | } |
515 | 531 | ||
516 | if (sock->fasync_list) | 532 | if (sock->wq->fasync_list) |
517 | printk(KERN_ERR "sock_release: fasync list not empty!\n"); | 533 | printk(KERN_ERR "sock_release: fasync list not empty!\n"); |
518 | 534 | ||
519 | percpu_sub(sockets_in_use, 1); | 535 | percpu_sub(sockets_in_use, 1); |
@@ -655,13 +671,13 @@ inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, struct sk_buff | |||
655 | sizeof(__u32), &skb->dropcount); | 671 | sizeof(__u32), &skb->dropcount); |
656 | } | 672 | } |
657 | 673 | ||
658 | void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, | 674 | void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, |
659 | struct sk_buff *skb) | 675 | struct sk_buff *skb) |
660 | { | 676 | { |
661 | sock_recv_timestamp(msg, sk, skb); | 677 | sock_recv_timestamp(msg, sk, skb); |
662 | sock_recv_drops(msg, sk, skb); | 678 | sock_recv_drops(msg, sk, skb); |
663 | } | 679 | } |
664 | EXPORT_SYMBOL_GPL(sock_recv_ts_and_drops); | 680 | EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops); |
665 | 681 | ||
666 | static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock, | 682 | static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock, |
667 | struct msghdr *msg, size_t size, int flags) | 683 | struct msghdr *msg, size_t size, int flags) |
@@ -1067,87 +1083,44 @@ static int sock_close(struct inode *inode, struct file *filp) | |||
1067 | * 1. fasync_list is modified only under process context socket lock | 1083 | * 1. fasync_list is modified only under process context socket lock |
1068 | * i.e. under semaphore. | 1084 | * i.e. under semaphore. |
1069 | * 2. fasync_list is used under read_lock(&sk->sk_callback_lock) | 1085 | * 2. fasync_list is used under read_lock(&sk->sk_callback_lock) |
1070 | * or under socket lock. | 1086 | * or under socket lock |
1071 | * 3. fasync_list can be used from softirq context, so that | ||
1072 | * modification under socket lock have to be enhanced with | ||
1073 | * write_lock_bh(&sk->sk_callback_lock). | ||
1074 | * --ANK (990710) | ||
1075 | */ | 1087 | */ |
1076 | 1088 | ||
1077 | static int sock_fasync(int fd, struct file *filp, int on) | 1089 | static int sock_fasync(int fd, struct file *filp, int on) |
1078 | { | 1090 | { |
1079 | struct fasync_struct *fa, *fna = NULL, **prev; | 1091 | struct socket *sock = filp->private_data; |
1080 | struct socket *sock; | 1092 | struct sock *sk = sock->sk; |
1081 | struct sock *sk; | ||
1082 | |||
1083 | if (on) { | ||
1084 | fna = kmalloc(sizeof(struct fasync_struct), GFP_KERNEL); | ||
1085 | if (fna == NULL) | ||
1086 | return -ENOMEM; | ||
1087 | } | ||
1088 | |||
1089 | sock = filp->private_data; | ||
1090 | 1093 | ||
1091 | sk = sock->sk; | 1094 | if (sk == NULL) |
1092 | if (sk == NULL) { | ||
1093 | kfree(fna); | ||
1094 | return -EINVAL; | 1095 | return -EINVAL; |
1095 | } | ||
1096 | 1096 | ||
1097 | lock_sock(sk); | 1097 | lock_sock(sk); |
1098 | 1098 | ||
1099 | spin_lock(&filp->f_lock); | 1099 | fasync_helper(fd, filp, on, &sock->wq->fasync_list); |
1100 | if (on) | ||
1101 | filp->f_flags |= FASYNC; | ||
1102 | else | ||
1103 | filp->f_flags &= ~FASYNC; | ||
1104 | spin_unlock(&filp->f_lock); | ||
1105 | |||
1106 | prev = &(sock->fasync_list); | ||
1107 | |||
1108 | for (fa = *prev; fa != NULL; prev = &fa->fa_next, fa = *prev) | ||
1109 | if (fa->fa_file == filp) | ||
1110 | break; | ||
1111 | |||
1112 | if (on) { | ||
1113 | if (fa != NULL) { | ||
1114 | write_lock_bh(&sk->sk_callback_lock); | ||
1115 | fa->fa_fd = fd; | ||
1116 | write_unlock_bh(&sk->sk_callback_lock); | ||
1117 | 1100 | ||
1118 | kfree(fna); | 1101 | if (!sock->wq->fasync_list) |
1119 | goto out; | 1102 | sock_reset_flag(sk, SOCK_FASYNC); |
1120 | } | 1103 | else |
1121 | fna->fa_file = filp; | ||
1122 | fna->fa_fd = fd; | ||
1123 | fna->magic = FASYNC_MAGIC; | ||
1124 | fna->fa_next = sock->fasync_list; | ||
1125 | write_lock_bh(&sk->sk_callback_lock); | ||
1126 | sock->fasync_list = fna; | ||
1127 | sock_set_flag(sk, SOCK_FASYNC); | 1104 | sock_set_flag(sk, SOCK_FASYNC); |
1128 | write_unlock_bh(&sk->sk_callback_lock); | ||
1129 | } else { | ||
1130 | if (fa != NULL) { | ||
1131 | write_lock_bh(&sk->sk_callback_lock); | ||
1132 | *prev = fa->fa_next; | ||
1133 | if (!sock->fasync_list) | ||
1134 | sock_reset_flag(sk, SOCK_FASYNC); | ||
1135 | write_unlock_bh(&sk->sk_callback_lock); | ||
1136 | kfree(fa); | ||
1137 | } | ||
1138 | } | ||
1139 | 1105 | ||
1140 | out: | 1106 | release_sock(sk); |
1141 | release_sock(sock->sk); | ||
1142 | return 0; | 1107 | return 0; |
1143 | } | 1108 | } |
1144 | 1109 | ||
1145 | /* This function may be called only under socket lock or callback_lock */ | 1110 | /* This function may be called only under socket lock or callback_lock or rcu_lock */ |
1146 | 1111 | ||
1147 | int sock_wake_async(struct socket *sock, int how, int band) | 1112 | int sock_wake_async(struct socket *sock, int how, int band) |
1148 | { | 1113 | { |
1149 | if (!sock || !sock->fasync_list) | 1114 | struct socket_wq *wq; |
1115 | |||
1116 | if (!sock) | ||
1150 | return -1; | 1117 | return -1; |
1118 | rcu_read_lock(); | ||
1119 | wq = rcu_dereference(sock->wq); | ||
1120 | if (!wq || !wq->fasync_list) { | ||
1121 | rcu_read_unlock(); | ||
1122 | return -1; | ||
1123 | } | ||
1151 | switch (how) { | 1124 | switch (how) { |
1152 | case SOCK_WAKE_WAITD: | 1125 | case SOCK_WAKE_WAITD: |
1153 | if (test_bit(SOCK_ASYNC_WAITDATA, &sock->flags)) | 1126 | if (test_bit(SOCK_ASYNC_WAITDATA, &sock->flags)) |
@@ -1159,11 +1132,12 @@ int sock_wake_async(struct socket *sock, int how, int band) | |||
1159 | /* fall through */ | 1132 | /* fall through */ |
1160 | case SOCK_WAKE_IO: | 1133 | case SOCK_WAKE_IO: |
1161 | call_kill: | 1134 | call_kill: |
1162 | __kill_fasync(sock->fasync_list, SIGIO, band); | 1135 | kill_fasync(&wq->fasync_list, SIGIO, band); |
1163 | break; | 1136 | break; |
1164 | case SOCK_WAKE_URG: | 1137 | case SOCK_WAKE_URG: |
1165 | __kill_fasync(sock->fasync_list, SIGURG, band); | 1138 | kill_fasync(&wq->fasync_list, SIGURG, band); |
1166 | } | 1139 | } |
1140 | rcu_read_unlock(); | ||
1167 | return 0; | 1141 | return 0; |
1168 | } | 1142 | } |
1169 | 1143 | ||
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index a29f259204e6..ce0d5b35c2ac 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -419,8 +419,8 @@ static void svc_udp_data_ready(struct sock *sk, int count) | |||
419 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); | 419 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); |
420 | svc_xprt_enqueue(&svsk->sk_xprt); | 420 | svc_xprt_enqueue(&svsk->sk_xprt); |
421 | } | 421 | } |
422 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 422 | if (sk_sleep(sk) && waitqueue_active(sk_sleep(sk))) |
423 | wake_up_interruptible(sk->sk_sleep); | 423 | wake_up_interruptible(sk_sleep(sk)); |
424 | } | 424 | } |
425 | 425 | ||
426 | /* | 426 | /* |
@@ -436,10 +436,10 @@ static void svc_write_space(struct sock *sk) | |||
436 | svc_xprt_enqueue(&svsk->sk_xprt); | 436 | svc_xprt_enqueue(&svsk->sk_xprt); |
437 | } | 437 | } |
438 | 438 | ||
439 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) { | 439 | if (sk_sleep(sk) && waitqueue_active(sk_sleep(sk))) { |
440 | dprintk("RPC svc_write_space: someone sleeping on %p\n", | 440 | dprintk("RPC svc_write_space: someone sleeping on %p\n", |
441 | svsk); | 441 | svsk); |
442 | wake_up_interruptible(sk->sk_sleep); | 442 | wake_up_interruptible(sk_sleep(sk)); |
443 | } | 443 | } |
444 | } | 444 | } |
445 | 445 | ||
@@ -757,8 +757,8 @@ static void svc_tcp_listen_data_ready(struct sock *sk, int count_unused) | |||
757 | printk("svc: socket %p: no user data\n", sk); | 757 | printk("svc: socket %p: no user data\n", sk); |
758 | } | 758 | } |
759 | 759 | ||
760 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 760 | if (sk_sleep(sk) && waitqueue_active(sk_sleep(sk))) |
761 | wake_up_interruptible_all(sk->sk_sleep); | 761 | wake_up_interruptible_all(sk_sleep(sk)); |
762 | } | 762 | } |
763 | 763 | ||
764 | /* | 764 | /* |
@@ -777,8 +777,8 @@ static void svc_tcp_state_change(struct sock *sk) | |||
777 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); | 777 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); |
778 | svc_xprt_enqueue(&svsk->sk_xprt); | 778 | svc_xprt_enqueue(&svsk->sk_xprt); |
779 | } | 779 | } |
780 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 780 | if (sk_sleep(sk) && waitqueue_active(sk_sleep(sk))) |
781 | wake_up_interruptible_all(sk->sk_sleep); | 781 | wake_up_interruptible_all(sk_sleep(sk)); |
782 | } | 782 | } |
783 | 783 | ||
784 | static void svc_tcp_data_ready(struct sock *sk, int count) | 784 | static void svc_tcp_data_ready(struct sock *sk, int count) |
@@ -791,8 +791,8 @@ static void svc_tcp_data_ready(struct sock *sk, int count) | |||
791 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); | 791 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); |
792 | svc_xprt_enqueue(&svsk->sk_xprt); | 792 | svc_xprt_enqueue(&svsk->sk_xprt); |
793 | } | 793 | } |
794 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 794 | if (sk_sleep(sk) && waitqueue_active(sk_sleep(sk))) |
795 | wake_up_interruptible(sk->sk_sleep); | 795 | wake_up_interruptible(sk_sleep(sk)); |
796 | } | 796 | } |
797 | 797 | ||
798 | /* | 798 | /* |
@@ -1494,8 +1494,8 @@ static void svc_sock_detach(struct svc_xprt *xprt) | |||
1494 | sk->sk_data_ready = svsk->sk_odata; | 1494 | sk->sk_data_ready = svsk->sk_odata; |
1495 | sk->sk_write_space = svsk->sk_owspace; | 1495 | sk->sk_write_space = svsk->sk_owspace; |
1496 | 1496 | ||
1497 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 1497 | if (sk_sleep(sk) && waitqueue_active(sk_sleep(sk))) |
1498 | wake_up_interruptible(sk->sk_sleep); | 1498 | wake_up_interruptible(sk_sleep(sk)); |
1499 | } | 1499 | } |
1500 | 1500 | ||
1501 | /* | 1501 | /* |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 42f09ade0044..699ade68aac1 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -974,7 +974,7 @@ void xprt_reserve(struct rpc_task *task) | |||
974 | 974 | ||
975 | static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt) | 975 | static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt) |
976 | { | 976 | { |
977 | return xprt->xid++; | 977 | return (__force __be32)xprt->xid++; |
978 | } | 978 | } |
979 | 979 | ||
980 | static inline void xprt_init_xid(struct rpc_xprt *xprt) | 980 | static inline void xprt_init_xid(struct rpc_xprt *xprt) |
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index fd90eb89842b..edea15a54e51 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c | |||
@@ -679,7 +679,10 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv, | |||
679 | int ret; | 679 | int ret; |
680 | 680 | ||
681 | dprintk("svcrdma: Creating RDMA socket\n"); | 681 | dprintk("svcrdma: Creating RDMA socket\n"); |
682 | 682 | if (sa->sa_family != AF_INET) { | |
683 | dprintk("svcrdma: Address family %d is not supported.\n", sa->sa_family); | ||
684 | return ERR_PTR(-EAFNOSUPPORT); | ||
685 | } | ||
683 | cma_xprt = rdma_create_xprt(serv, 1); | 686 | cma_xprt = rdma_create_xprt(serv, 1); |
684 | if (!cma_xprt) | 687 | if (!cma_xprt) |
685 | return ERR_PTR(-ENOMEM); | 688 | return ERR_PTR(-ENOMEM); |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index cfb20b80b3a1..66e889ba48fd 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -446,7 +446,7 @@ static unsigned int poll(struct file *file, struct socket *sock, | |||
446 | struct sock *sk = sock->sk; | 446 | struct sock *sk = sock->sk; |
447 | u32 mask; | 447 | u32 mask; |
448 | 448 | ||
449 | poll_wait(file, sk->sk_sleep, wait); | 449 | poll_wait(file, sk_sleep(sk), wait); |
450 | 450 | ||
451 | if (!skb_queue_empty(&sk->sk_receive_queue) || | 451 | if (!skb_queue_empty(&sk->sk_receive_queue) || |
452 | (sock->state == SS_UNCONNECTED) || | 452 | (sock->state == SS_UNCONNECTED) || |
@@ -591,7 +591,7 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, | |||
591 | break; | 591 | break; |
592 | } | 592 | } |
593 | release_sock(sk); | 593 | release_sock(sk); |
594 | res = wait_event_interruptible(*sk->sk_sleep, | 594 | res = wait_event_interruptible(*sk_sleep(sk), |
595 | !tport->congested); | 595 | !tport->congested); |
596 | lock_sock(sk); | 596 | lock_sock(sk); |
597 | if (res) | 597 | if (res) |
@@ -650,7 +650,7 @@ static int send_packet(struct kiocb *iocb, struct socket *sock, | |||
650 | break; | 650 | break; |
651 | } | 651 | } |
652 | release_sock(sk); | 652 | release_sock(sk); |
653 | res = wait_event_interruptible(*sk->sk_sleep, | 653 | res = wait_event_interruptible(*sk_sleep(sk), |
654 | (!tport->congested || !tport->connected)); | 654 | (!tport->congested || !tport->connected)); |
655 | lock_sock(sk); | 655 | lock_sock(sk); |
656 | if (res) | 656 | if (res) |
@@ -931,7 +931,7 @@ restart: | |||
931 | goto exit; | 931 | goto exit; |
932 | } | 932 | } |
933 | release_sock(sk); | 933 | release_sock(sk); |
934 | res = wait_event_interruptible(*sk->sk_sleep, | 934 | res = wait_event_interruptible(*sk_sleep(sk), |
935 | (!skb_queue_empty(&sk->sk_receive_queue) || | 935 | (!skb_queue_empty(&sk->sk_receive_queue) || |
936 | (sock->state == SS_DISCONNECTING))); | 936 | (sock->state == SS_DISCONNECTING))); |
937 | lock_sock(sk); | 937 | lock_sock(sk); |
@@ -1064,7 +1064,7 @@ restart: | |||
1064 | goto exit; | 1064 | goto exit; |
1065 | } | 1065 | } |
1066 | release_sock(sk); | 1066 | release_sock(sk); |
1067 | res = wait_event_interruptible(*sk->sk_sleep, | 1067 | res = wait_event_interruptible(*sk_sleep(sk), |
1068 | (!skb_queue_empty(&sk->sk_receive_queue) || | 1068 | (!skb_queue_empty(&sk->sk_receive_queue) || |
1069 | (sock->state == SS_DISCONNECTING))); | 1069 | (sock->state == SS_DISCONNECTING))); |
1070 | lock_sock(sk); | 1070 | lock_sock(sk); |
@@ -1271,8 +1271,8 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf) | |||
1271 | tipc_disconnect_port(tipc_sk_port(sk)); | 1271 | tipc_disconnect_port(tipc_sk_port(sk)); |
1272 | } | 1272 | } |
1273 | 1273 | ||
1274 | if (waitqueue_active(sk->sk_sleep)) | 1274 | if (waitqueue_active(sk_sleep(sk))) |
1275 | wake_up_interruptible(sk->sk_sleep); | 1275 | wake_up_interruptible(sk_sleep(sk)); |
1276 | return TIPC_OK; | 1276 | return TIPC_OK; |
1277 | } | 1277 | } |
1278 | 1278 | ||
@@ -1343,8 +1343,8 @@ static void wakeupdispatch(struct tipc_port *tport) | |||
1343 | { | 1343 | { |
1344 | struct sock *sk = (struct sock *)tport->usr_handle; | 1344 | struct sock *sk = (struct sock *)tport->usr_handle; |
1345 | 1345 | ||
1346 | if (waitqueue_active(sk->sk_sleep)) | 1346 | if (waitqueue_active(sk_sleep(sk))) |
1347 | wake_up_interruptible(sk->sk_sleep); | 1347 | wake_up_interruptible(sk_sleep(sk)); |
1348 | } | 1348 | } |
1349 | 1349 | ||
1350 | /** | 1350 | /** |
@@ -1426,7 +1426,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
1426 | /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ | 1426 | /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ |
1427 | 1427 | ||
1428 | release_sock(sk); | 1428 | release_sock(sk); |
1429 | res = wait_event_interruptible_timeout(*sk->sk_sleep, | 1429 | res = wait_event_interruptible_timeout(*sk_sleep(sk), |
1430 | (!skb_queue_empty(&sk->sk_receive_queue) || | 1430 | (!skb_queue_empty(&sk->sk_receive_queue) || |
1431 | (sock->state != SS_CONNECTING)), | 1431 | (sock->state != SS_CONNECTING)), |
1432 | sk->sk_rcvtimeo); | 1432 | sk->sk_rcvtimeo); |
@@ -1521,7 +1521,7 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
1521 | goto exit; | 1521 | goto exit; |
1522 | } | 1522 | } |
1523 | release_sock(sk); | 1523 | release_sock(sk); |
1524 | res = wait_event_interruptible(*sk->sk_sleep, | 1524 | res = wait_event_interruptible(*sk_sleep(sk), |
1525 | (!skb_queue_empty(&sk->sk_receive_queue))); | 1525 | (!skb_queue_empty(&sk->sk_receive_queue))); |
1526 | lock_sock(sk); | 1526 | lock_sock(sk); |
1527 | if (res) | 1527 | if (res) |
@@ -1632,8 +1632,8 @@ restart: | |||
1632 | /* Discard any unreceived messages; wake up sleeping tasks */ | 1632 | /* Discard any unreceived messages; wake up sleeping tasks */ |
1633 | 1633 | ||
1634 | discard_rx_queue(sk); | 1634 | discard_rx_queue(sk); |
1635 | if (waitqueue_active(sk->sk_sleep)) | 1635 | if (waitqueue_active(sk_sleep(sk))) |
1636 | wake_up_interruptible(sk->sk_sleep); | 1636 | wake_up_interruptible(sk_sleep(sk)); |
1637 | res = 0; | 1637 | res = 0; |
1638 | break; | 1638 | break; |
1639 | 1639 | ||
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 3d9122e78f41..fef2cc5e9d2b 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -313,13 +313,16 @@ static inline int unix_writable(struct sock *sk) | |||
313 | 313 | ||
314 | static void unix_write_space(struct sock *sk) | 314 | static void unix_write_space(struct sock *sk) |
315 | { | 315 | { |
316 | read_lock(&sk->sk_callback_lock); | 316 | struct socket_wq *wq; |
317 | |||
318 | rcu_read_lock(); | ||
317 | if (unix_writable(sk)) { | 319 | if (unix_writable(sk)) { |
318 | if (sk_has_sleeper(sk)) | 320 | wq = rcu_dereference(sk->sk_wq); |
319 | wake_up_interruptible_sync(sk->sk_sleep); | 321 | if (wq_has_sleeper(wq)) |
322 | wake_up_interruptible_sync(&wq->wait); | ||
320 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); | 323 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); |
321 | } | 324 | } |
322 | read_unlock(&sk->sk_callback_lock); | 325 | rcu_read_unlock(); |
323 | } | 326 | } |
324 | 327 | ||
325 | /* When dgram socket disconnects (or changes its peer), we clear its receive | 328 | /* When dgram socket disconnects (or changes its peer), we clear its receive |
@@ -406,9 +409,7 @@ static int unix_release_sock(struct sock *sk, int embrion) | |||
406 | skpair->sk_err = ECONNRESET; | 409 | skpair->sk_err = ECONNRESET; |
407 | unix_state_unlock(skpair); | 410 | unix_state_unlock(skpair); |
408 | skpair->sk_state_change(skpair); | 411 | skpair->sk_state_change(skpair); |
409 | read_lock(&skpair->sk_callback_lock); | ||
410 | sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP); | 412 | sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP); |
411 | read_unlock(&skpair->sk_callback_lock); | ||
412 | } | 413 | } |
413 | sock_put(skpair); /* It may now die */ | 414 | sock_put(skpair); /* It may now die */ |
414 | unix_peer(sk) = NULL; | 415 | unix_peer(sk) = NULL; |
@@ -1142,7 +1143,7 @@ restart: | |||
1142 | newsk->sk_peercred.pid = task_tgid_vnr(current); | 1143 | newsk->sk_peercred.pid = task_tgid_vnr(current); |
1143 | current_euid_egid(&newsk->sk_peercred.uid, &newsk->sk_peercred.gid); | 1144 | current_euid_egid(&newsk->sk_peercred.uid, &newsk->sk_peercred.gid); |
1144 | newu = unix_sk(newsk); | 1145 | newu = unix_sk(newsk); |
1145 | newsk->sk_sleep = &newu->peer_wait; | 1146 | newsk->sk_wq = &newu->peer_wq; |
1146 | otheru = unix_sk(other); | 1147 | otheru = unix_sk(other); |
1147 | 1148 | ||
1148 | /* copy address information from listening to new sock*/ | 1149 | /* copy address information from listening to new sock*/ |
@@ -1736,7 +1737,7 @@ static long unix_stream_data_wait(struct sock *sk, long timeo) | |||
1736 | unix_state_lock(sk); | 1737 | unix_state_lock(sk); |
1737 | 1738 | ||
1738 | for (;;) { | 1739 | for (;;) { |
1739 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 1740 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
1740 | 1741 | ||
1741 | if (!skb_queue_empty(&sk->sk_receive_queue) || | 1742 | if (!skb_queue_empty(&sk->sk_receive_queue) || |
1742 | sk->sk_err || | 1743 | sk->sk_err || |
@@ -1752,7 +1753,7 @@ static long unix_stream_data_wait(struct sock *sk, long timeo) | |||
1752 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 1753 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); |
1753 | } | 1754 | } |
1754 | 1755 | ||
1755 | finish_wait(sk->sk_sleep, &wait); | 1756 | finish_wait(sk_sleep(sk), &wait); |
1756 | unix_state_unlock(sk); | 1757 | unix_state_unlock(sk); |
1757 | return timeo; | 1758 | return timeo; |
1758 | } | 1759 | } |
@@ -1931,12 +1932,10 @@ static int unix_shutdown(struct socket *sock, int mode) | |||
1931 | other->sk_shutdown |= peer_mode; | 1932 | other->sk_shutdown |= peer_mode; |
1932 | unix_state_unlock(other); | 1933 | unix_state_unlock(other); |
1933 | other->sk_state_change(other); | 1934 | other->sk_state_change(other); |
1934 | read_lock(&other->sk_callback_lock); | ||
1935 | if (peer_mode == SHUTDOWN_MASK) | 1935 | if (peer_mode == SHUTDOWN_MASK) |
1936 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP); | 1936 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP); |
1937 | else if (peer_mode & RCV_SHUTDOWN) | 1937 | else if (peer_mode & RCV_SHUTDOWN) |
1938 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN); | 1938 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN); |
1939 | read_unlock(&other->sk_callback_lock); | ||
1940 | } | 1939 | } |
1941 | if (other) | 1940 | if (other) |
1942 | sock_put(other); | 1941 | sock_put(other); |
@@ -1991,7 +1990,7 @@ static unsigned int unix_poll(struct file *file, struct socket *sock, poll_table | |||
1991 | struct sock *sk = sock->sk; | 1990 | struct sock *sk = sock->sk; |
1992 | unsigned int mask; | 1991 | unsigned int mask; |
1993 | 1992 | ||
1994 | sock_poll_wait(file, sk->sk_sleep, wait); | 1993 | sock_poll_wait(file, sk_sleep(sk), wait); |
1995 | mask = 0; | 1994 | mask = 0; |
1996 | 1995 | ||
1997 | /* exceptional events? */ | 1996 | /* exceptional events? */ |
@@ -2028,7 +2027,7 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, | |||
2028 | struct sock *sk = sock->sk, *other; | 2027 | struct sock *sk = sock->sk, *other; |
2029 | unsigned int mask, writable; | 2028 | unsigned int mask, writable; |
2030 | 2029 | ||
2031 | sock_poll_wait(file, sk->sk_sleep, wait); | 2030 | sock_poll_wait(file, sk_sleep(sk), wait); |
2032 | mask = 0; | 2031 | mask = 0; |
2033 | 2032 | ||
2034 | /* exceptional events? */ | 2033 | /* exceptional events? */ |
diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 14c22c3768da..c8df6fda0b1f 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c | |||
@@ -153,15 +153,6 @@ void unix_notinflight(struct file *fp) | |||
153 | } | 153 | } |
154 | } | 154 | } |
155 | 155 | ||
156 | static inline struct sk_buff *sock_queue_head(struct sock *sk) | ||
157 | { | ||
158 | return (struct sk_buff *)&sk->sk_receive_queue; | ||
159 | } | ||
160 | |||
161 | #define receive_queue_for_each_skb(sk, next, skb) \ | ||
162 | for (skb = sock_queue_head(sk)->next, next = skb->next; \ | ||
163 | skb != sock_queue_head(sk); skb = next, next = skb->next) | ||
164 | |||
165 | static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *), | 156 | static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *), |
166 | struct sk_buff_head *hitlist) | 157 | struct sk_buff_head *hitlist) |
167 | { | 158 | { |
@@ -169,7 +160,7 @@ static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *), | |||
169 | struct sk_buff *next; | 160 | struct sk_buff *next; |
170 | 161 | ||
171 | spin_lock(&x->sk_receive_queue.lock); | 162 | spin_lock(&x->sk_receive_queue.lock); |
172 | receive_queue_for_each_skb(x, next, skb) { | 163 | skb_queue_walk_safe(&x->sk_receive_queue, skb, next) { |
173 | /* | 164 | /* |
174 | * Do we have file descriptors ? | 165 | * Do we have file descriptors ? |
175 | */ | 166 | */ |
@@ -225,7 +216,7 @@ static void scan_children(struct sock *x, void (*func)(struct unix_sock *), | |||
225 | * and perform a scan on them as well. | 216 | * and perform a scan on them as well. |
226 | */ | 217 | */ |
227 | spin_lock(&x->sk_receive_queue.lock); | 218 | spin_lock(&x->sk_receive_queue.lock); |
228 | receive_queue_for_each_skb(x, next, skb) { | 219 | skb_queue_walk_safe(&x->sk_receive_queue, skb, next) { |
229 | u = unix_sk(skb->sk); | 220 | u = unix_sk(skb->sk); |
230 | 221 | ||
231 | /* | 222 | /* |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 6ac70c101523..37d0e0ab4432 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -705,7 +705,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, | |||
705 | wdev->ps = true; | 705 | wdev->ps = true; |
706 | else | 706 | else |
707 | wdev->ps = false; | 707 | wdev->ps = false; |
708 | wdev->ps_timeout = 100; | 708 | /* allow mac80211 to determine the timeout */ |
709 | wdev->ps_timeout = -1; | ||
709 | if (rdev->ops->set_power_mgmt) | 710 | if (rdev->ops->set_power_mgmt) |
710 | if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, | 711 | if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, |
711 | wdev->ps, | 712 | wdev->ps, |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 356a84a5daee..01da83ddcff7 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -152,6 +152,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
152 | [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 }, | 152 | [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 }, |
153 | [NL80211_ATTR_CQM] = { .type = NLA_NESTED, }, | 153 | [NL80211_ATTR_CQM] = { .type = NLA_NESTED, }, |
154 | [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG }, | 154 | [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG }, |
155 | [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 }, | ||
155 | }; | 156 | }; |
156 | 157 | ||
157 | /* policy for the attributes */ | 158 | /* policy for the attributes */ |
@@ -2442,6 +2443,7 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) | |||
2442 | params.use_cts_prot = -1; | 2443 | params.use_cts_prot = -1; |
2443 | params.use_short_preamble = -1; | 2444 | params.use_short_preamble = -1; |
2444 | params.use_short_slot_time = -1; | 2445 | params.use_short_slot_time = -1; |
2446 | params.ap_isolate = -1; | ||
2445 | 2447 | ||
2446 | if (info->attrs[NL80211_ATTR_BSS_CTS_PROT]) | 2448 | if (info->attrs[NL80211_ATTR_BSS_CTS_PROT]) |
2447 | params.use_cts_prot = | 2449 | params.use_cts_prot = |
@@ -2458,6 +2460,8 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) | |||
2458 | params.basic_rates_len = | 2460 | params.basic_rates_len = |
2459 | nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); | 2461 | nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); |
2460 | } | 2462 | } |
2463 | if (info->attrs[NL80211_ATTR_AP_ISOLATE]) | ||
2464 | params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]); | ||
2461 | 2465 | ||
2462 | rtnl_lock(); | 2466 | rtnl_lock(); |
2463 | 2467 | ||
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index c2735775ec19..8ddf5ae0dd03 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -518,12 +518,16 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
518 | ev->type = EVENT_CONNECT_RESULT; | 518 | ev->type = EVENT_CONNECT_RESULT; |
519 | if (bssid) | 519 | if (bssid) |
520 | memcpy(ev->cr.bssid, bssid, ETH_ALEN); | 520 | memcpy(ev->cr.bssid, bssid, ETH_ALEN); |
521 | ev->cr.req_ie = ((u8 *)ev) + sizeof(*ev); | 521 | if (req_ie_len) { |
522 | ev->cr.req_ie_len = req_ie_len; | 522 | ev->cr.req_ie = ((u8 *)ev) + sizeof(*ev); |
523 | memcpy((void *)ev->cr.req_ie, req_ie, req_ie_len); | 523 | ev->cr.req_ie_len = req_ie_len; |
524 | ev->cr.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len; | 524 | memcpy((void *)ev->cr.req_ie, req_ie, req_ie_len); |
525 | ev->cr.resp_ie_len = resp_ie_len; | 525 | } |
526 | memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len); | 526 | if (resp_ie_len) { |
527 | ev->cr.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len; | ||
528 | ev->cr.resp_ie_len = resp_ie_len; | ||
529 | memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len); | ||
530 | } | ||
527 | ev->cr.status = status; | 531 | ev->cr.status = status; |
528 | 532 | ||
529 | spin_lock_irqsave(&wdev->event_lock, flags); | 533 | spin_lock_irqsave(&wdev->event_lock, flags); |
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index cbddd0cb83f1..296e65e01064 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
@@ -402,6 +402,7 @@ static void __x25_destroy_socket(struct sock *sk) | |||
402 | /* | 402 | /* |
403 | * Queue the unaccepted socket for death | 403 | * Queue the unaccepted socket for death |
404 | */ | 404 | */ |
405 | skb->sk->sk_state = TCP_LISTEN; | ||
405 | sock_set_flag(skb->sk, SOCK_DEAD); | 406 | sock_set_flag(skb->sk, SOCK_DEAD); |
406 | x25_start_heartbeat(skb->sk); | 407 | x25_start_heartbeat(skb->sk); |
407 | x25_sk(skb->sk)->state = X25_STATE_0; | 408 | x25_sk(skb->sk)->state = X25_STATE_0; |
@@ -718,7 +719,7 @@ static int x25_wait_for_connection_establishment(struct sock *sk) | |||
718 | DECLARE_WAITQUEUE(wait, current); | 719 | DECLARE_WAITQUEUE(wait, current); |
719 | int rc; | 720 | int rc; |
720 | 721 | ||
721 | add_wait_queue_exclusive(sk->sk_sleep, &wait); | 722 | add_wait_queue_exclusive(sk_sleep(sk), &wait); |
722 | for (;;) { | 723 | for (;;) { |
723 | __set_current_state(TASK_INTERRUPTIBLE); | 724 | __set_current_state(TASK_INTERRUPTIBLE); |
724 | rc = -ERESTARTSYS; | 725 | rc = -ERESTARTSYS; |
@@ -738,7 +739,7 @@ static int x25_wait_for_connection_establishment(struct sock *sk) | |||
738 | break; | 739 | break; |
739 | } | 740 | } |
740 | __set_current_state(TASK_RUNNING); | 741 | __set_current_state(TASK_RUNNING); |
741 | remove_wait_queue(sk->sk_sleep, &wait); | 742 | remove_wait_queue(sk_sleep(sk), &wait); |
742 | return rc; | 743 | return rc; |
743 | } | 744 | } |
744 | 745 | ||
@@ -838,7 +839,7 @@ static int x25_wait_for_data(struct sock *sk, long timeout) | |||
838 | DECLARE_WAITQUEUE(wait, current); | 839 | DECLARE_WAITQUEUE(wait, current); |
839 | int rc = 0; | 840 | int rc = 0; |
840 | 841 | ||
841 | add_wait_queue_exclusive(sk->sk_sleep, &wait); | 842 | add_wait_queue_exclusive(sk_sleep(sk), &wait); |
842 | for (;;) { | 843 | for (;;) { |
843 | __set_current_state(TASK_INTERRUPTIBLE); | 844 | __set_current_state(TASK_INTERRUPTIBLE); |
844 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 845 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
@@ -858,7 +859,7 @@ static int x25_wait_for_data(struct sock *sk, long timeout) | |||
858 | break; | 859 | break; |
859 | } | 860 | } |
860 | __set_current_state(TASK_RUNNING); | 861 | __set_current_state(TASK_RUNNING); |
861 | remove_wait_queue(sk->sk_sleep, &wait); | 862 | remove_wait_queue(sk_sleep(sk), &wait); |
862 | return rc; | 863 | return rc; |
863 | } | 864 | } |
864 | 865 | ||
diff --git a/net/x25/x25_dev.c b/net/x25/x25_dev.c index b9ef682230a0..9005f6daeab5 100644 --- a/net/x25/x25_dev.c +++ b/net/x25/x25_dev.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <net/sock.h> | 24 | #include <net/sock.h> |
25 | #include <linux/if_arp.h> | 25 | #include <linux/if_arp.h> |
26 | #include <net/x25.h> | 26 | #include <net/x25.h> |
27 | #include <net/x25device.h> | ||
27 | 28 | ||
28 | static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *nb) | 29 | static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *nb) |
29 | { | 30 | { |
@@ -115,19 +116,22 @@ int x25_lapb_receive_frame(struct sk_buff *skb, struct net_device *dev, | |||
115 | } | 116 | } |
116 | 117 | ||
117 | switch (skb->data[0]) { | 118 | switch (skb->data[0]) { |
118 | case 0x00: | 119 | |
119 | skb_pull(skb, 1); | 120 | case X25_IFACE_DATA: |
120 | if (x25_receive_data(skb, nb)) { | 121 | skb_pull(skb, 1); |
121 | x25_neigh_put(nb); | 122 | if (x25_receive_data(skb, nb)) { |
122 | goto out; | 123 | x25_neigh_put(nb); |
123 | } | 124 | goto out; |
124 | break; | 125 | } |
125 | case 0x01: | 126 | break; |
126 | x25_link_established(nb); | 127 | |
127 | break; | 128 | case X25_IFACE_CONNECT: |
128 | case 0x02: | 129 | x25_link_established(nb); |
129 | x25_link_terminated(nb); | 130 | break; |
130 | break; | 131 | |
132 | case X25_IFACE_DISCONNECT: | ||
133 | x25_link_terminated(nb); | ||
134 | break; | ||
131 | } | 135 | } |
132 | x25_neigh_put(nb); | 136 | x25_neigh_put(nb); |
133 | drop: | 137 | drop: |
@@ -148,7 +152,7 @@ void x25_establish_link(struct x25_neigh *nb) | |||
148 | return; | 152 | return; |
149 | } | 153 | } |
150 | ptr = skb_put(skb, 1); | 154 | ptr = skb_put(skb, 1); |
151 | *ptr = 0x01; | 155 | *ptr = X25_IFACE_CONNECT; |
152 | break; | 156 | break; |
153 | 157 | ||
154 | #if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE) | 158 | #if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE) |
@@ -184,7 +188,7 @@ void x25_terminate_link(struct x25_neigh *nb) | |||
184 | } | 188 | } |
185 | 189 | ||
186 | ptr = skb_put(skb, 1); | 190 | ptr = skb_put(skb, 1); |
187 | *ptr = 0x02; | 191 | *ptr = X25_IFACE_DISCONNECT; |
188 | 192 | ||
189 | skb->protocol = htons(ETH_P_X25); | 193 | skb->protocol = htons(ETH_P_X25); |
190 | skb->dev = nb->dev; | 194 | skb->dev = nb->dev; |
@@ -200,7 +204,7 @@ void x25_send_frame(struct sk_buff *skb, struct x25_neigh *nb) | |||
200 | switch (nb->dev->type) { | 204 | switch (nb->dev->type) { |
201 | case ARPHRD_X25: | 205 | case ARPHRD_X25: |
202 | dptr = skb_push(skb, 1); | 206 | dptr = skb_push(skb, 1); |
203 | *dptr = 0x00; | 207 | *dptr = X25_IFACE_DATA; |
204 | break; | 208 | break; |
205 | 209 | ||
206 | #if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE) | 210 | #if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE) |
diff --git a/net/xfrm/xfrm_hash.h b/net/xfrm/xfrm_hash.h index e5195c99f71e..1396572d2ade 100644 --- a/net/xfrm/xfrm_hash.h +++ b/net/xfrm/xfrm_hash.h | |||
@@ -16,7 +16,8 @@ static inline unsigned int __xfrm6_addr_hash(xfrm_address_t *addr) | |||
16 | 16 | ||
17 | static inline unsigned int __xfrm4_daddr_saddr_hash(xfrm_address_t *daddr, xfrm_address_t *saddr) | 17 | static inline unsigned int __xfrm4_daddr_saddr_hash(xfrm_address_t *daddr, xfrm_address_t *saddr) |
18 | { | 18 | { |
19 | return ntohl(daddr->a4 + saddr->a4); | 19 | u32 sum = (__force u32)daddr->a4 + (__force u32)saddr->a4; |
20 | return ntohl((__force __be32)sum); | ||
20 | } | 21 | } |
21 | 22 | ||
22 | static inline unsigned int __xfrm6_daddr_saddr_hash(xfrm_address_t *daddr, xfrm_address_t *saddr) | 23 | static inline unsigned int __xfrm6_daddr_saddr_hash(xfrm_address_t *daddr, xfrm_address_t *saddr) |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 7430ac26ec49..31f4ba43b48f 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1732,7 +1732,7 @@ int __xfrm_lookup(struct net *net, struct dst_entry **dst_p, struct flowi *fl, | |||
1732 | struct dst_entry *dst, *dst_orig = *dst_p, *route; | 1732 | struct dst_entry *dst, *dst_orig = *dst_p, *route; |
1733 | u16 family = dst_orig->ops->family; | 1733 | u16 family = dst_orig->ops->family; |
1734 | u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT); | 1734 | u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT); |
1735 | int i, err, num_pols, num_xfrms, drop_pols = 0; | 1735 | int i, err, num_pols, num_xfrms = 0, drop_pols = 0; |
1736 | 1736 | ||
1737 | restart: | 1737 | restart: |
1738 | dst = NULL; | 1738 | dst = NULL; |