aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/sctp/command.h1
-rw-r--r--include/net/sctp/sctp.h6
-rw-r--r--net/sctp/input.c144
-rw-r--r--net/sctp/sm_sideeffect.c16
-rw-r--r--net/sctp/sm_statefuns.c81
-rw-r--r--net/sctp/socket.c29
6 files changed, 168 insertions, 109 deletions
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
index 34a1a09e5aef..807d6f1ef4b5 100644
--- a/include/net/sctp/command.h
+++ b/include/net/sctp/command.h
@@ -99,6 +99,7 @@ typedef enum {
99 SCTP_CMD_DEL_NON_PRIMARY, /* Removes non-primary peer transports. */ 99 SCTP_CMD_DEL_NON_PRIMARY, /* Removes non-primary peer transports. */
100 SCTP_CMD_T3_RTX_TIMERS_STOP, /* Stops T3-rtx pending timers */ 100 SCTP_CMD_T3_RTX_TIMERS_STOP, /* Stops T3-rtx pending timers */
101 SCTP_CMD_FORCE_PRIM_RETRAN, /* Forces retrans. over primary path. */ 101 SCTP_CMD_FORCE_PRIM_RETRAN, /* Forces retrans. over primary path. */
102 SCTP_CMD_SET_SK_ERR, /* Set sk_err */
102 SCTP_CMD_LAST 103 SCTP_CMD_LAST
103} sctp_verb_t; 104} sctp_verb_t;
104 105
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index e673b2c984e9..aa6033ca7cd8 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -461,12 +461,12 @@ static inline int sctp_frag_point(const struct sctp_sock *sp, int pmtu)
461 * there is room for a param header too. 461 * there is room for a param header too.
462 */ 462 */
463#define sctp_walk_params(pos, chunk, member)\ 463#define sctp_walk_params(pos, chunk, member)\
464_sctp_walk_params((pos), (chunk), WORD_ROUND(ntohs((chunk)->chunk_hdr.length)), member) 464_sctp_walk_params((pos), (chunk), ntohs((chunk)->chunk_hdr.length), member)
465 465
466#define _sctp_walk_params(pos, chunk, end, member)\ 466#define _sctp_walk_params(pos, chunk, end, member)\
467for (pos.v = chunk->member;\ 467for (pos.v = chunk->member;\
468 pos.v <= (void *)chunk + end - sizeof(sctp_paramhdr_t) &&\ 468 pos.v <= (void *)chunk + end - sizeof(sctp_paramhdr_t) &&\
469 pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)) &&\ 469 pos.v <= (void *)chunk + end - ntohs(pos.p->length) &&\
470 ntohs(pos.p->length) >= sizeof(sctp_paramhdr_t);\ 470 ntohs(pos.p->length) >= sizeof(sctp_paramhdr_t);\
471 pos.v += WORD_ROUND(ntohs(pos.p->length))) 471 pos.v += WORD_ROUND(ntohs(pos.p->length)))
472 472
@@ -477,7 +477,7 @@ _sctp_walk_errors((err), (chunk_hdr), ntohs((chunk_hdr)->length))
477for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \ 477for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \
478 sizeof(sctp_chunkhdr_t));\ 478 sizeof(sctp_chunkhdr_t));\
479 (void *)err <= (void *)chunk_hdr + end - sizeof(sctp_errhdr_t) &&\ 479 (void *)err <= (void *)chunk_hdr + end - sizeof(sctp_errhdr_t) &&\
480 (void *)err <= (void *)chunk_hdr + end - WORD_ROUND(ntohs(err->length)) &&\ 480 (void *)err <= (void *)chunk_hdr + end - ntohs(err->length) &&\
481 ntohs(err->length) >= sizeof(sctp_errhdr_t); \ 481 ntohs(err->length) >= sizeof(sctp_errhdr_t); \
482 err = (sctp_errhdr_t *)((void *)err + WORD_ROUND(ntohs(err->length)))) 482 err = (sctp_errhdr_t *)((void *)err + WORD_ROUND(ntohs(err->length))))
483 483
diff --git a/net/sctp/input.c b/net/sctp/input.c
index d117ebc75cf8..1662f9cc869e 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -73,6 +73,8 @@ static struct sctp_association *__sctp_lookup_association(
73 const union sctp_addr *peer, 73 const union sctp_addr *peer,
74 struct sctp_transport **pt); 74 struct sctp_transport **pt);
75 75
76static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb);
77
76 78
77/* Calculate the SCTP checksum of an SCTP packet. */ 79/* Calculate the SCTP checksum of an SCTP packet. */
78static inline int sctp_rcv_checksum(struct sk_buff *skb) 80static inline int sctp_rcv_checksum(struct sk_buff *skb)
@@ -186,7 +188,6 @@ int sctp_rcv(struct sk_buff *skb)
186 */ 188 */
187 if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb))) 189 if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb)))
188 { 190 {
189 sock_put(sk);
190 if (asoc) { 191 if (asoc) {
191 sctp_association_put(asoc); 192 sctp_association_put(asoc);
192 asoc = NULL; 193 asoc = NULL;
@@ -197,7 +198,6 @@ int sctp_rcv(struct sk_buff *skb)
197 sk = sctp_get_ctl_sock(); 198 sk = sctp_get_ctl_sock();
198 ep = sctp_sk(sk)->ep; 199 ep = sctp_sk(sk)->ep;
199 sctp_endpoint_hold(ep); 200 sctp_endpoint_hold(ep);
200 sock_hold(sk);
201 rcvr = &ep->base; 201 rcvr = &ep->base;
202 } 202 }
203 203
@@ -253,25 +253,18 @@ int sctp_rcv(struct sk_buff *skb)
253 */ 253 */
254 sctp_bh_lock_sock(sk); 254 sctp_bh_lock_sock(sk);
255 255
256 /* It is possible that the association could have moved to a different
257 * socket if it is peeled off. If so, update the sk.
258 */
259 if (sk != rcvr->sk) {
260 sctp_bh_lock_sock(rcvr->sk);
261 sctp_bh_unlock_sock(sk);
262 sk = rcvr->sk;
263 }
264
265 if (sock_owned_by_user(sk)) 256 if (sock_owned_by_user(sk))
266 sk_add_backlog(sk, skb); 257 sctp_add_backlog(sk, skb);
267 else 258 else
268 sctp_backlog_rcv(sk, skb); 259 sctp_inq_push(&chunk->rcvr->inqueue, chunk);
269 260
270 /* Release the sock and the sock ref we took in the lookup calls.
271 * The asoc/ep ref will be released in sctp_backlog_rcv.
272 */
273 sctp_bh_unlock_sock(sk); 261 sctp_bh_unlock_sock(sk);
274 sock_put(sk); 262
263 /* Release the asoc/ep ref we took in the lookup calls. */
264 if (asoc)
265 sctp_association_put(asoc);
266 else
267 sctp_endpoint_put(ep);
275 268
276 return 0; 269 return 0;
277 270
@@ -280,8 +273,7 @@ discard_it:
280 return 0; 273 return 0;
281 274
282discard_release: 275discard_release:
283 /* Release any structures we may be holding. */ 276 /* Release the asoc/ep ref we took in the lookup calls. */
284 sock_put(sk);
285 if (asoc) 277 if (asoc)
286 sctp_association_put(asoc); 278 sctp_association_put(asoc);
287 else 279 else
@@ -290,56 +282,87 @@ discard_release:
290 goto discard_it; 282 goto discard_it;
291} 283}
292 284
293/* Handle second half of inbound skb processing. If the sock was busy, 285/* Process the backlog queue of the socket. Every skb on
294 * we may have need to delay processing until later when the sock is 286 * the backlog holds a ref on an association or endpoint.
295 * released (on the backlog). If not busy, we call this routine 287 * We hold this ref throughout the state machine to make
296 * directly from the bottom half. 288 * sure that the structure we need is still around.
297 */ 289 */
298int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) 290int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
299{ 291{
300 struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; 292 struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk;
301 struct sctp_inq *inqueue = NULL; 293 struct sctp_inq *inqueue = &chunk->rcvr->inqueue;
302 struct sctp_ep_common *rcvr = NULL; 294 struct sctp_ep_common *rcvr = NULL;
295 int backloged = 0;
303 296
304 rcvr = chunk->rcvr; 297 rcvr = chunk->rcvr;
305 298
306 BUG_TRAP(rcvr->sk == sk); 299 /* If the rcvr is dead then the association or endpoint
307 300 * has been deleted and we can safely drop the chunk
308 if (rcvr->dead) { 301 * and refs that we are holding.
309 sctp_chunk_free(chunk); 302 */
310 } else { 303 if (rcvr->dead) {
311 inqueue = &chunk->rcvr->inqueue; 304 sctp_chunk_free(chunk);
312 sctp_inq_push(inqueue, chunk); 305 goto done;
313 } 306 }
314 307
315 /* Release the asoc/ep ref we took in the lookup calls in sctp_rcv. */ 308 if (unlikely(rcvr->sk != sk)) {
316 if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type) 309 /* In this case, the association moved from one socket to
317 sctp_association_put(sctp_assoc(rcvr)); 310 * another. We are currently sitting on the backlog of the
318 else 311 * old socket, so we need to move.
319 sctp_endpoint_put(sctp_ep(rcvr)); 312 * However, since we are here in the process context we
320 313 * need to take make sure that the user doesn't own
314 * the new socket when we process the packet.
315 * If the new socket is user-owned, queue the chunk to the
316 * backlog of the new socket without dropping any refs.
317 * Otherwise, we can safely push the chunk on the inqueue.
318 */
319
320 sk = rcvr->sk;
321 sctp_bh_lock_sock(sk);
322
323 if (sock_owned_by_user(sk)) {
324 sk_add_backlog(sk, skb);
325 backloged = 1;
326 } else
327 sctp_inq_push(inqueue, chunk);
328
329 sctp_bh_unlock_sock(sk);
330
331 /* If the chunk was backloged again, don't drop refs */
332 if (backloged)
333 return 0;
334 } else {
335 sctp_inq_push(inqueue, chunk);
336 }
337
338done:
339 /* Release the refs we took in sctp_add_backlog */
340 if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type)
341 sctp_association_put(sctp_assoc(rcvr));
342 else if (SCTP_EP_TYPE_SOCKET == rcvr->type)
343 sctp_endpoint_put(sctp_ep(rcvr));
344 else
345 BUG();
346
321 return 0; 347 return 0;
322} 348}
323 349
324void sctp_backlog_migrate(struct sctp_association *assoc, 350static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb)
325 struct sock *oldsk, struct sock *newsk)
326{ 351{
327 struct sk_buff *skb; 352 struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk;
328 struct sctp_chunk *chunk; 353 struct sctp_ep_common *rcvr = chunk->rcvr;
329 354
330 skb = oldsk->sk_backlog.head; 355 /* Hold the assoc/ep while hanging on the backlog queue.
331 oldsk->sk_backlog.head = oldsk->sk_backlog.tail = NULL; 356 * This way, we know structures we need will not disappear from us
332 while (skb != NULL) { 357 */
333 struct sk_buff *next = skb->next; 358 if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type)
334 359 sctp_association_hold(sctp_assoc(rcvr));
335 chunk = SCTP_INPUT_CB(skb)->chunk; 360 else if (SCTP_EP_TYPE_SOCKET == rcvr->type)
336 skb->next = NULL; 361 sctp_endpoint_hold(sctp_ep(rcvr));
337 if (&assoc->base == chunk->rcvr) 362 else
338 sk_add_backlog(newsk, skb); 363 BUG();
339 else 364
340 sk_add_backlog(oldsk, skb); 365 sk_add_backlog(sk, skb);
341 skb = next;
342 }
343} 366}
344 367
345/* Handle icmp frag needed error. */ 368/* Handle icmp frag needed error. */
@@ -412,7 +435,7 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
412 union sctp_addr daddr; 435 union sctp_addr daddr;
413 struct sctp_af *af; 436 struct sctp_af *af;
414 struct sock *sk = NULL; 437 struct sock *sk = NULL;
415 struct sctp_association *asoc = NULL; 438 struct sctp_association *asoc;
416 struct sctp_transport *transport = NULL; 439 struct sctp_transport *transport = NULL;
417 440
418 *app = NULL; *tpp = NULL; 441 *app = NULL; *tpp = NULL;
@@ -453,7 +476,6 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
453 return sk; 476 return sk;
454 477
455out: 478out:
456 sock_put(sk);
457 if (asoc) 479 if (asoc)
458 sctp_association_put(asoc); 480 sctp_association_put(asoc);
459 return NULL; 481 return NULL;
@@ -463,7 +485,6 @@ out:
463void sctp_err_finish(struct sock *sk, struct sctp_association *asoc) 485void sctp_err_finish(struct sock *sk, struct sctp_association *asoc)
464{ 486{
465 sctp_bh_unlock_sock(sk); 487 sctp_bh_unlock_sock(sk);
466 sock_put(sk);
467 if (asoc) 488 if (asoc)
468 sctp_association_put(asoc); 489 sctp_association_put(asoc);
469} 490}
@@ -490,7 +511,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
490 int type = skb->h.icmph->type; 511 int type = skb->h.icmph->type;
491 int code = skb->h.icmph->code; 512 int code = skb->h.icmph->code;
492 struct sock *sk; 513 struct sock *sk;
493 struct sctp_association *asoc; 514 struct sctp_association *asoc = NULL;
494 struct sctp_transport *transport; 515 struct sctp_transport *transport;
495 struct inet_sock *inet; 516 struct inet_sock *inet;
496 char *saveip, *savesctp; 517 char *saveip, *savesctp;
@@ -716,7 +737,6 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *l
716 737
717hit: 738hit:
718 sctp_endpoint_hold(ep); 739 sctp_endpoint_hold(ep);
719 sock_hold(epb->sk);
720 read_unlock(&head->lock); 740 read_unlock(&head->lock);
721 return ep; 741 return ep;
722} 742}
@@ -818,7 +838,6 @@ static struct sctp_association *__sctp_lookup_association(
818hit: 838hit:
819 *pt = transport; 839 *pt = transport;
820 sctp_association_hold(asoc); 840 sctp_association_hold(asoc);
821 sock_hold(epb->sk);
822 read_unlock(&head->lock); 841 read_unlock(&head->lock);
823 return asoc; 842 return asoc;
824} 843}
@@ -846,7 +865,6 @@ int sctp_has_association(const union sctp_addr *laddr,
846 struct sctp_transport *transport; 865 struct sctp_transport *transport;
847 866
848 if ((asoc = sctp_lookup_association(laddr, paddr, &transport))) { 867 if ((asoc = sctp_lookup_association(laddr, paddr, &transport))) {
849 sock_put(asoc->base.sk);
850 sctp_association_put(asoc); 868 sctp_association_put(asoc);
851 return 1; 869 return 1;
852 } 870 }
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 8d1dc24bab4c..c5beb2ad7ef7 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -498,10 +498,6 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands,
498 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, 498 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
499 SCTP_STATE(SCTP_STATE_CLOSED)); 499 SCTP_STATE(SCTP_STATE_CLOSED));
500 500
501 /* Set sk_err to ECONNRESET on a 1-1 style socket. */
502 if (!sctp_style(asoc->base.sk, UDP))
503 asoc->base.sk->sk_err = ECONNRESET;
504
505 /* SEND_FAILED sent later when cleaning up the association. */ 501 /* SEND_FAILED sent later when cleaning up the association. */
506 asoc->outqueue.error = error; 502 asoc->outqueue.error = error;
507 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); 503 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
@@ -838,6 +834,15 @@ static void sctp_cmd_del_non_primary(struct sctp_association *asoc)
838 return; 834 return;
839} 835}
840 836
837/* Helper function to set sk_err on a 1-1 style socket. */
838static void sctp_cmd_set_sk_err(struct sctp_association *asoc, int error)
839{
840 struct sock *sk = asoc->base.sk;
841
842 if (!sctp_style(sk, UDP))
843 sk->sk_err = error;
844}
845
841/* These three macros allow us to pull the debugging code out of the 846/* These three macros allow us to pull the debugging code out of the
842 * main flow of sctp_do_sm() to keep attention focused on the real 847 * main flow of sctp_do_sm() to keep attention focused on the real
843 * functionality there. 848 * functionality there.
@@ -1458,6 +1463,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1458 local_cork = 0; 1463 local_cork = 0;
1459 asoc->peer.retran_path = t; 1464 asoc->peer.retran_path = t;
1460 break; 1465 break;
1466 case SCTP_CMD_SET_SK_ERR:
1467 sctp_cmd_set_sk_err(asoc, cmd->obj.error);
1468 break;
1461 default: 1469 default:
1462 printk(KERN_WARNING "Impossible command: %u, %p\n", 1470 printk(KERN_WARNING "Impossible command: %u, %p\n",
1463 cmd->verb, cmd->obj.ptr); 1471 cmd->verb, cmd->obj.ptr);
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 8cdba51ec076..8bc279219a72 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -93,7 +93,7 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
93static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk); 93static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk);
94 94
95static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, 95static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
96 __u16 error, 96 __u16 error, int sk_err,
97 const struct sctp_association *asoc, 97 const struct sctp_association *asoc,
98 struct sctp_transport *transport); 98 struct sctp_transport *transport);
99 99
@@ -448,7 +448,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
448 __u32 init_tag; 448 __u32 init_tag;
449 struct sctp_chunk *err_chunk; 449 struct sctp_chunk *err_chunk;
450 struct sctp_packet *packet; 450 struct sctp_packet *packet;
451 sctp_disposition_t ret; 451 __u16 error;
452 452
453 if (!sctp_vtag_verify(chunk, asoc)) 453 if (!sctp_vtag_verify(chunk, asoc))
454 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); 454 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -480,11 +480,9 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
480 goto nomem; 480 goto nomem;
481 481
482 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply)); 482 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
483 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, 483 return sctp_stop_t1_and_abort(commands, SCTP_ERROR_INV_PARAM,
484 SCTP_STATE(SCTP_STATE_CLOSED)); 484 ECONNREFUSED, asoc,
485 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 485 chunk->transport);
486 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
487 return SCTP_DISPOSITION_DELETE_TCB;
488 } 486 }
489 487
490 /* Verify the INIT chunk before processing it. */ 488 /* Verify the INIT chunk before processing it. */
@@ -511,27 +509,16 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
511 sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT, 509 sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
512 SCTP_PACKET(packet)); 510 SCTP_PACKET(packet));
513 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); 511 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
514 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, 512 error = SCTP_ERROR_INV_PARAM;
515 SCTP_STATE(SCTP_STATE_CLOSED));
516 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,
517 SCTP_NULL());
518 return SCTP_DISPOSITION_CONSUME;
519 } else { 513 } else {
520 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, 514 error = SCTP_ERROR_NO_RESOURCE;
521 SCTP_STATE(SCTP_STATE_CLOSED));
522 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,
523 SCTP_NULL());
524 return SCTP_DISPOSITION_NOMEM;
525 } 515 }
526 } else { 516 } else {
527 ret = sctp_sf_tabort_8_4_8(ep, asoc, type, arg, 517 sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
528 commands); 518 error = SCTP_ERROR_INV_PARAM;
529 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
530 SCTP_STATE(SCTP_STATE_CLOSED));
531 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,
532 SCTP_NULL());
533 return ret;
534 } 519 }
520 return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED,
521 asoc, chunk->transport);
535 } 522 }
536 523
537 /* Tag the variable length parameters. Note that we never 524 /* Tag the variable length parameters. Note that we never
@@ -886,6 +873,8 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,
886 struct sctp_transport *transport = (struct sctp_transport *) arg; 873 struct sctp_transport *transport = (struct sctp_transport *) arg;
887 874
888 if (asoc->overall_error_count >= asoc->max_retrans) { 875 if (asoc->overall_error_count >= asoc->max_retrans) {
876 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
877 SCTP_ERROR(ETIMEDOUT));
889 /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ 878 /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
890 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 879 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
891 SCTP_U32(SCTP_ERROR_NO_ERROR)); 880 SCTP_U32(SCTP_ERROR_NO_ERROR));
@@ -1030,6 +1019,12 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
1030 commands); 1019 commands);
1031 1020
1032 hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data; 1021 hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
1022 /* Make sure that the length of the parameter is what we expect */
1023 if (ntohs(hbinfo->param_hdr.length) !=
1024 sizeof(sctp_sender_hb_info_t)) {
1025 return SCTP_DISPOSITION_DISCARD;
1026 }
1027
1033 from_addr = hbinfo->daddr; 1028 from_addr = hbinfo->daddr;
1034 link = sctp_assoc_lookup_paddr(asoc, &from_addr); 1029 link = sctp_assoc_lookup_paddr(asoc, &from_addr);
1035 1030
@@ -2126,6 +2121,8 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
2126 int attempts = asoc->init_err_counter + 1; 2121 int attempts = asoc->init_err_counter + 1;
2127 2122
2128 if (attempts > asoc->max_init_attempts) { 2123 if (attempts > asoc->max_init_attempts) {
2124 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
2125 SCTP_ERROR(ETIMEDOUT));
2129 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, 2126 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
2130 SCTP_U32(SCTP_ERROR_STALE_COOKIE)); 2127 SCTP_U32(SCTP_ERROR_STALE_COOKIE));
2131 return SCTP_DISPOSITION_DELETE_TCB; 2128 return SCTP_DISPOSITION_DELETE_TCB;
@@ -2262,6 +2259,7 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
2262 if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) 2259 if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
2263 error = ((sctp_errhdr_t *)chunk->skb->data)->cause; 2260 error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
2264 2261
2262 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET));
2265 /* ASSOC_FAILED will DELETE_TCB. */ 2263 /* ASSOC_FAILED will DELETE_TCB. */
2266 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(error)); 2264 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(error));
2267 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 2265 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -2306,7 +2304,8 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep,
2306 if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) 2304 if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
2307 error = ((sctp_errhdr_t *)chunk->skb->data)->cause; 2305 error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
2308 2306
2309 return sctp_stop_t1_and_abort(commands, error, asoc, chunk->transport); 2307 return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED, asoc,
2308 chunk->transport);
2310} 2309}
2311 2310
2312/* 2311/*
@@ -2318,7 +2317,8 @@ sctp_disposition_t sctp_sf_cookie_wait_icmp_abort(const struct sctp_endpoint *ep
2318 void *arg, 2317 void *arg,
2319 sctp_cmd_seq_t *commands) 2318 sctp_cmd_seq_t *commands)
2320{ 2319{
2321 return sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR, asoc, 2320 return sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR,
2321 ENOPROTOOPT, asoc,
2322 (struct sctp_transport *)arg); 2322 (struct sctp_transport *)arg);
2323} 2323}
2324 2324
@@ -2343,7 +2343,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep,
2343 * This is common code called by several sctp_sf_*_abort() functions above. 2343 * This is common code called by several sctp_sf_*_abort() functions above.
2344 */ 2344 */
2345static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, 2345static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
2346 __u16 error, 2346 __u16 error, int sk_err,
2347 const struct sctp_association *asoc, 2347 const struct sctp_association *asoc,
2348 struct sctp_transport *transport) 2348 struct sctp_transport *transport)
2349{ 2349{
@@ -2353,6 +2353,7 @@ static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
2353 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 2353 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
2354 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, 2354 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
2355 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); 2355 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
2356 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(sk_err));
2356 /* CMD_INIT_FAILED will DELETE_TCB. */ 2357 /* CMD_INIT_FAILED will DELETE_TCB. */
2357 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, 2358 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
2358 SCTP_U32(error)); 2359 SCTP_U32(error));
@@ -3336,6 +3337,8 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
3336 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, 3337 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
3337 SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); 3338 SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
3338 sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL()); 3339 sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
3340 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
3341 SCTP_ERROR(ECONNABORTED));
3339 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 3342 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
3340 SCTP_U32(SCTP_ERROR_ASCONF_ACK)); 3343 SCTP_U32(SCTP_ERROR_ASCONF_ACK));
3341 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 3344 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -3362,6 +3365,8 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
3362 * processing the rest of the chunks in the packet. 3365 * processing the rest of the chunks in the packet.
3363 */ 3366 */
3364 sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL()); 3367 sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
3368 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
3369 SCTP_ERROR(ECONNABORTED));
3365 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 3370 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
3366 SCTP_U32(SCTP_ERROR_ASCONF_ACK)); 3371 SCTP_U32(SCTP_ERROR_ASCONF_ACK));
3367 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 3372 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -3714,9 +3719,13 @@ static sctp_disposition_t sctp_sf_violation_chunklen(
3714 if (asoc->state <= SCTP_STATE_COOKIE_ECHOED) { 3719 if (asoc->state <= SCTP_STATE_COOKIE_ECHOED) {
3715 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, 3720 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
3716 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); 3721 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
3722 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
3723 SCTP_ERROR(ECONNREFUSED));
3717 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, 3724 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
3718 SCTP_U32(SCTP_ERROR_PROTO_VIOLATION)); 3725 SCTP_U32(SCTP_ERROR_PROTO_VIOLATION));
3719 } else { 3726 } else {
3727 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
3728 SCTP_ERROR(ECONNABORTED));
3720 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 3729 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
3721 SCTP_U32(SCTP_ERROR_PROTO_VIOLATION)); 3730 SCTP_U32(SCTP_ERROR_PROTO_VIOLATION));
3722 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); 3731 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
@@ -4034,6 +4043,8 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(
4034 * TCB. This is a departure from our typical NOMEM handling. 4043 * TCB. This is a departure from our typical NOMEM handling.
4035 */ 4044 */
4036 4045
4046 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
4047 SCTP_ERROR(ECONNABORTED));
4037 /* Delete the established association. */ 4048 /* Delete the established association. */
4038 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 4049 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
4039 SCTP_U32(SCTP_ERROR_USER_ABORT)); 4050 SCTP_U32(SCTP_ERROR_USER_ABORT));
@@ -4175,6 +4186,8 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(
4175 * TCB. This is a departure from our typical NOMEM handling. 4186 * TCB. This is a departure from our typical NOMEM handling.
4176 */ 4187 */
4177 4188
4189 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
4190 SCTP_ERROR(ECONNREFUSED));
4178 /* Delete the established association. */ 4191 /* Delete the established association. */
4179 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, 4192 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
4180 SCTP_U32(SCTP_ERROR_USER_ABORT)); 4193 SCTP_U32(SCTP_ERROR_USER_ABORT));
@@ -4543,6 +4556,8 @@ sctp_disposition_t sctp_sf_do_6_3_3_rtx(const struct sctp_endpoint *ep,
4543 struct sctp_transport *transport = arg; 4556 struct sctp_transport *transport = arg;
4544 4557
4545 if (asoc->overall_error_count >= asoc->max_retrans) { 4558 if (asoc->overall_error_count >= asoc->max_retrans) {
4559 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
4560 SCTP_ERROR(ETIMEDOUT));
4546 /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ 4561 /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
4547 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 4562 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
4548 SCTP_U32(SCTP_ERROR_NO_ERROR)); 4563 SCTP_U32(SCTP_ERROR_NO_ERROR));
@@ -4662,6 +4677,8 @@ sctp_disposition_t sctp_sf_t1_init_timer_expire(const struct sctp_endpoint *ep,
4662 SCTP_DEBUG_PRINTK("Giving up on INIT, attempts: %d" 4677 SCTP_DEBUG_PRINTK("Giving up on INIT, attempts: %d"
4663 " max_init_attempts: %d\n", 4678 " max_init_attempts: %d\n",
4664 attempts, asoc->max_init_attempts); 4679 attempts, asoc->max_init_attempts);
4680 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
4681 SCTP_ERROR(ETIMEDOUT));
4665 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, 4682 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
4666 SCTP_U32(SCTP_ERROR_NO_ERROR)); 4683 SCTP_U32(SCTP_ERROR_NO_ERROR));
4667 return SCTP_DISPOSITION_DELETE_TCB; 4684 return SCTP_DISPOSITION_DELETE_TCB;
@@ -4711,6 +4728,8 @@ sctp_disposition_t sctp_sf_t1_cookie_timer_expire(const struct sctp_endpoint *ep
4711 4728
4712 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); 4729 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
4713 } else { 4730 } else {
4731 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
4732 SCTP_ERROR(ETIMEDOUT));
4714 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, 4733 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
4715 SCTP_U32(SCTP_ERROR_NO_ERROR)); 4734 SCTP_U32(SCTP_ERROR_NO_ERROR));
4716 return SCTP_DISPOSITION_DELETE_TCB; 4735 return SCTP_DISPOSITION_DELETE_TCB;
@@ -4742,6 +4761,8 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep,
4742 4761
4743 SCTP_DEBUG_PRINTK("Timer T2 expired.\n"); 4762 SCTP_DEBUG_PRINTK("Timer T2 expired.\n");
4744 if (asoc->overall_error_count >= asoc->max_retrans) { 4763 if (asoc->overall_error_count >= asoc->max_retrans) {
4764 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
4765 SCTP_ERROR(ETIMEDOUT));
4745 /* Note: CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ 4766 /* Note: CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
4746 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 4767 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
4747 SCTP_U32(SCTP_ERROR_NO_ERROR)); 4768 SCTP_U32(SCTP_ERROR_NO_ERROR));
@@ -4817,6 +4838,8 @@ sctp_disposition_t sctp_sf_t4_timer_expire(
4817 if (asoc->overall_error_count >= asoc->max_retrans) { 4838 if (asoc->overall_error_count >= asoc->max_retrans) {
4818 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, 4839 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
4819 SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); 4840 SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
4841 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
4842 SCTP_ERROR(ETIMEDOUT));
4820 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 4843 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
4821 SCTP_U32(SCTP_ERROR_NO_ERROR)); 4844 SCTP_U32(SCTP_ERROR_NO_ERROR));
4822 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 4845 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -4870,6 +4893,8 @@ sctp_disposition_t sctp_sf_t5_timer_expire(const struct sctp_endpoint *ep,
4870 goto nomem; 4893 goto nomem;
4871 4894
4872 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply)); 4895 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
4896 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
4897 SCTP_ERROR(ETIMEDOUT));
4873 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 4898 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
4874 SCTP_U32(SCTP_ERROR_NO_ERROR)); 4899 SCTP_U32(SCTP_ERROR_NO_ERROR));
4875 4900
@@ -5309,6 +5334,8 @@ static int sctp_eat_data(const struct sctp_association *asoc,
5309 * processing the rest of the chunks in the packet. 5334 * processing the rest of the chunks in the packet.
5310 */ 5335 */
5311 sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL()); 5336 sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
5337 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
5338 SCTP_ERROR(ECONNABORTED));
5312 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 5339 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
5313 SCTP_U32(SCTP_ERROR_NO_DATA)); 5340 SCTP_U32(SCTP_ERROR_NO_DATA));
5314 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 5341 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index b6e4b89539b3..174d4d35e951 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1057,6 +1057,7 @@ static int __sctp_connect(struct sock* sk,
1057 inet_sk(sk)->dport = htons(asoc->peer.port); 1057 inet_sk(sk)->dport = htons(asoc->peer.port);
1058 af = sctp_get_af_specific(to.sa.sa_family); 1058 af = sctp_get_af_specific(to.sa.sa_family);
1059 af->to_sk_daddr(&to, sk); 1059 af->to_sk_daddr(&to, sk);
1060 sk->sk_err = 0;
1060 1061
1061 timeo = sock_sndtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK); 1062 timeo = sock_sndtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK);
1062 err = sctp_wait_for_connect(asoc, &timeo); 1063 err = sctp_wait_for_connect(asoc, &timeo);
@@ -1228,7 +1229,7 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
1228 1229
1229 ep = sctp_sk(sk)->ep; 1230 ep = sctp_sk(sk)->ep;
1230 1231
1231 /* Walk all associations on a socket, not on an endpoint. */ 1232 /* Walk all associations on an endpoint. */
1232 list_for_each_safe(pos, temp, &ep->asocs) { 1233 list_for_each_safe(pos, temp, &ep->asocs) {
1233 asoc = list_entry(pos, struct sctp_association, asocs); 1234 asoc = list_entry(pos, struct sctp_association, asocs);
1234 1235
@@ -1241,13 +1242,13 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
1241 if (sctp_state(asoc, CLOSED)) { 1242 if (sctp_state(asoc, CLOSED)) {
1242 sctp_unhash_established(asoc); 1243 sctp_unhash_established(asoc);
1243 sctp_association_free(asoc); 1244 sctp_association_free(asoc);
1245 continue;
1246 }
1247 }
1244 1248
1245 } else if (sock_flag(sk, SOCK_LINGER) && 1249 if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime)
1246 !sk->sk_lingertime) 1250 sctp_primitive_ABORT(asoc, NULL);
1247 sctp_primitive_ABORT(asoc, NULL); 1251 else
1248 else
1249 sctp_primitive_SHUTDOWN(asoc, NULL);
1250 } else
1251 sctp_primitive_SHUTDOWN(asoc, NULL); 1252 sctp_primitive_SHUTDOWN(asoc, NULL);
1252 } 1253 }
1253 1254
@@ -5317,6 +5318,7 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p,
5317 */ 5318 */
5318 sctp_release_sock(sk); 5319 sctp_release_sock(sk);
5319 current_timeo = schedule_timeout(current_timeo); 5320 current_timeo = schedule_timeout(current_timeo);
5321 BUG_ON(sk != asoc->base.sk);
5320 sctp_lock_sock(sk); 5322 sctp_lock_sock(sk);
5321 5323
5322 *timeo_p = current_timeo; 5324 *timeo_p = current_timeo;
@@ -5604,12 +5606,14 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
5604 */ 5606 */
5605 newsp->type = type; 5607 newsp->type = type;
5606 5608
5607 spin_lock_bh(&oldsk->sk_lock.slock); 5609 /* Mark the new socket "in-use" by the user so that any packets
5608 /* Migrate the backlog from oldsk to newsk. */ 5610 * that may arrive on the association after we've moved it are
5609 sctp_backlog_migrate(assoc, oldsk, newsk); 5611 * queued to the backlog. This prevents a potential race between
5610 /* Migrate the association to the new socket. */ 5612 * backlog processing on the old socket and new-packet processing
5613 * on the new socket.
5614 */
5615 sctp_lock_sock(newsk);
5611 sctp_assoc_migrate(assoc, newsk); 5616 sctp_assoc_migrate(assoc, newsk);
5612 spin_unlock_bh(&oldsk->sk_lock.slock);
5613 5617
5614 /* If the association on the newsk is already closed before accept() 5618 /* If the association on the newsk is already closed before accept()
5615 * is called, set RCV_SHUTDOWN flag. 5619 * is called, set RCV_SHUTDOWN flag.
@@ -5618,6 +5622,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
5618 newsk->sk_shutdown |= RCV_SHUTDOWN; 5622 newsk->sk_shutdown |= RCV_SHUTDOWN;
5619 5623
5620 newsk->sk_state = SCTP_SS_ESTABLISHED; 5624 newsk->sk_state = SCTP_SS_ESTABLISHED;
5625 sctp_release_sock(newsk);
5621} 5626}
5622 5627
5623/* This proto struct describes the ULP interface for SCTP. */ 5628/* This proto struct describes the ULP interface for SCTP. */