aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladislav Yasevich <vladislav.yasevich@hp.com>2006-08-22 03:19:51 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 17:55:17 -0400
commitdf7deeb5402087ea0387173aaf067d37a264a8f0 (patch)
tree3001b220fe38b48a0bf2d7a4f4590fd2c8ed87e3
parentac0b04627269ff16c3c7ab854a65fe6780c6e3e5 (diff)
[SCTP]: Cleanup nomem handling in the state functions.
This patch cleans up the "nomem" conditions that may occur during the processing by the state machine functions. In most cases we delay adding side-effect commands until all memory allocations are done. Signed-off-by: Vladislav Yasevich <vladislav.yasevich@hp.com> Signed-off-by: Sridhar Samudrala <sri@us.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/sctp/sm_statefuns.c159
1 files changed, 86 insertions, 73 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 32f57f42af9e..1c42fe983a5b 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -187,10 +187,9 @@ sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep,
187 */ 187 */
188 ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_SHUTDOWN_COMP, 188 ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_SHUTDOWN_COMP,
189 0, 0, 0, GFP_ATOMIC); 189 0, 0, 0, GFP_ATOMIC);
190 if (!ev) 190 if (ev)
191 goto nomem; 191 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
192 192 SCTP_ULPEVENT(ev));
193 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
194 193
195 /* Upon reception of the SHUTDOWN COMPLETE chunk the endpoint 194 /* Upon reception of the SHUTDOWN COMPLETE chunk the endpoint
196 * will verify that it is in SHUTDOWN-ACK-SENT state, if it is 195 * will verify that it is in SHUTDOWN-ACK-SENT state, if it is
@@ -215,9 +214,6 @@ sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep,
215 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); 214 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
216 215
217 return SCTP_DISPOSITION_DELETE_TCB; 216 return SCTP_DISPOSITION_DELETE_TCB;
218
219nomem:
220 return SCTP_DISPOSITION_NOMEM;
221} 217}
222 218
223/* 219/*
@@ -347,8 +343,6 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
347 GFP_ATOMIC)) 343 GFP_ATOMIC))
348 goto nomem_init; 344 goto nomem_init;
349 345
350 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
351
352 /* B) "Z" shall respond immediately with an INIT ACK chunk. */ 346 /* B) "Z" shall respond immediately with an INIT ACK chunk. */
353 347
354 /* If there are errors need to be reported for unknown parameters, 348 /* If there are errors need to be reported for unknown parameters,
@@ -360,11 +354,11 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
360 sizeof(sctp_chunkhdr_t); 354 sizeof(sctp_chunkhdr_t);
361 355
362 if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0) 356 if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0)
363 goto nomem_ack; 357 goto nomem_init;
364 358
365 repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); 359 repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
366 if (!repl) 360 if (!repl)
367 goto nomem_ack; 361 goto nomem_init;
368 362
369 /* If there are errors need to be reported for unknown parameters, 363 /* If there are errors need to be reported for unknown parameters,
370 * include them in the outgoing INIT ACK as "Unrecognized parameter" 364 * include them in the outgoing INIT ACK as "Unrecognized parameter"
@@ -388,6 +382,8 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
388 sctp_chunk_free(err_chunk); 382 sctp_chunk_free(err_chunk);
389 } 383 }
390 384
385 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
386
391 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); 387 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
392 388
393 /* 389 /*
@@ -400,12 +396,11 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
400 396
401 return SCTP_DISPOSITION_DELETE_TCB; 397 return SCTP_DISPOSITION_DELETE_TCB;
402 398
403nomem_ack:
404 if (err_chunk)
405 sctp_chunk_free(err_chunk);
406nomem_init: 399nomem_init:
407 sctp_association_free(new_asoc); 400 sctp_association_free(new_asoc);
408nomem: 401nomem:
402 if (err_chunk)
403 sctp_chunk_free(err_chunk);
409 return SCTP_DISPOSITION_NOMEM; 404 return SCTP_DISPOSITION_NOMEM;
410} 405}
411 406
@@ -600,7 +595,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
600 struct sctp_association *new_asoc; 595 struct sctp_association *new_asoc;
601 sctp_init_chunk_t *peer_init; 596 sctp_init_chunk_t *peer_init;
602 struct sctp_chunk *repl; 597 struct sctp_chunk *repl;
603 struct sctp_ulpevent *ev; 598 struct sctp_ulpevent *ev, *ai_ev = NULL;
604 int error = 0; 599 int error = 0;
605 struct sctp_chunk *err_chk_p; 600 struct sctp_chunk *err_chk_p;
606 601
@@ -659,20 +654,10 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
659 }; 654 };
660 } 655 }
661 656
662 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
663 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
664 SCTP_STATE(SCTP_STATE_ESTABLISHED));
665 SCTP_INC_STATS(SCTP_MIB_CURRESTAB);
666 SCTP_INC_STATS(SCTP_MIB_PASSIVEESTABS);
667 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
668 657
669 if (new_asoc->autoclose) 658 /* Delay state machine commands until later.
670 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, 659 *
671 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); 660 * Re-build the bind address for the association is done in
672
673 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
674
675 /* Re-build the bind address for the association is done in
676 * the sctp_unpack_cookie() already. 661 * the sctp_unpack_cookie() already.
677 */ 662 */
678 /* This is a brand-new association, so these are not yet side 663 /* This is a brand-new association, so these are not yet side
@@ -687,9 +672,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
687 672
688 repl = sctp_make_cookie_ack(new_asoc, chunk); 673 repl = sctp_make_cookie_ack(new_asoc, chunk);
689 if (!repl) 674 if (!repl)
690 goto nomem_repl; 675 goto nomem_init;
691
692 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
693 676
694 /* RFC 2960 5.1 Normal Establishment of an Association 677 /* RFC 2960 5.1 Normal Establishment of an Association
695 * 678 *
@@ -704,28 +687,53 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
704 if (!ev) 687 if (!ev)
705 goto nomem_ev; 688 goto nomem_ev;
706 689
707 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
708
709 /* Sockets API Draft Section 5.3.1.6 690 /* Sockets API Draft Section 5.3.1.6
710 * When a peer sends a Adaption Layer Indication parameter , SCTP 691 * When a peer sends a Adaption Layer Indication parameter , SCTP
711 * delivers this notification to inform the application that of the 692 * delivers this notification to inform the application that of the
712 * peers requested adaption layer. 693 * peers requested adaption layer.
713 */ 694 */
714 if (new_asoc->peer.adaption_ind) { 695 if (new_asoc->peer.adaption_ind) {
715 ev = sctp_ulpevent_make_adaption_indication(new_asoc, 696 ai_ev = sctp_ulpevent_make_adaption_indication(new_asoc,
716 GFP_ATOMIC); 697 GFP_ATOMIC);
717 if (!ev) 698 if (!ai_ev)
718 goto nomem_ev; 699 goto nomem_aiev;
700 }
701
702 /* Add all the state machine commands now since we've created
703 * everything. This way we don't introduce memory corruptions
704 * during side-effect processing and correclty count established
705 * associations.
706 */
707 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
708 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
709 SCTP_STATE(SCTP_STATE_ESTABLISHED));
710 SCTP_INC_STATS(SCTP_MIB_CURRESTAB);
711 SCTP_INC_STATS(SCTP_MIB_PASSIVEESTABS);
712 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
713
714 if (new_asoc->autoclose)
715 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
716 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
717
718 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
719 719
720 /* This will send the COOKIE ACK */
721 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
722
723 /* Queue the ASSOC_CHANGE event */
724 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
725
726 /* Send up the Adaptation Layer Indication event */
727 if (ai_ev)
720 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, 728 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
721 SCTP_ULPEVENT(ev)); 729 SCTP_ULPEVENT(ai_ev));
722 }
723 730
724 return SCTP_DISPOSITION_CONSUME; 731 return SCTP_DISPOSITION_CONSUME;
725 732
733nomem_aiev:
734 sctp_ulpevent_free(ev);
726nomem_ev: 735nomem_ev:
727 sctp_chunk_free(repl); 736 sctp_chunk_free(repl);
728nomem_repl:
729nomem_init: 737nomem_init:
730 sctp_association_free(new_asoc); 738 sctp_association_free(new_asoc);
731nomem: 739nomem:
@@ -1360,10 +1368,8 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
1360 if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, 1368 if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
1361 sctp_source(chunk), 1369 sctp_source(chunk),
1362 (sctp_init_chunk_t *)chunk->chunk_hdr, 1370 (sctp_init_chunk_t *)chunk->chunk_hdr,
1363 GFP_ATOMIC)) { 1371 GFP_ATOMIC))
1364 retval = SCTP_DISPOSITION_NOMEM; 1372 goto nomem;
1365 goto nomem_init;
1366 }
1367 1373
1368 /* Make sure no new addresses are being added during the 1374 /* Make sure no new addresses are being added during the
1369 * restart. Do not do this check for COOKIE-WAIT state, 1375 * restart. Do not do this check for COOKIE-WAIT state,
@@ -1374,7 +1380,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
1374 if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk, 1380 if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk,
1375 commands)) { 1381 commands)) {
1376 retval = SCTP_DISPOSITION_CONSUME; 1382 retval = SCTP_DISPOSITION_CONSUME;
1377 goto cleanup_asoc; 1383 goto nomem_retval;
1378 } 1384 }
1379 } 1385 }
1380 1386
@@ -1430,17 +1436,17 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
1430 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); 1436 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
1431 retval = SCTP_DISPOSITION_CONSUME; 1437 retval = SCTP_DISPOSITION_CONSUME;
1432 1438
1439 return retval;
1440
1441nomem:
1442 retval = SCTP_DISPOSITION_NOMEM;
1443nomem_retval:
1444 if (new_asoc)
1445 sctp_association_free(new_asoc);
1433cleanup: 1446cleanup:
1434 if (err_chunk) 1447 if (err_chunk)
1435 sctp_chunk_free(err_chunk); 1448 sctp_chunk_free(err_chunk);
1436 return retval; 1449 return retval;
1437nomem:
1438 retval = SCTP_DISPOSITION_NOMEM;
1439 goto cleanup;
1440nomem_init:
1441cleanup_asoc:
1442 sctp_association_free(new_asoc);
1443 goto cleanup;
1444} 1450}
1445 1451
1446/* 1452/*
@@ -1611,15 +1617,10 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
1611 */ 1617 */
1612 sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL()); 1618 sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL());
1613 1619
1614 /* Update the content of current association. */
1615 sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
1616
1617 repl = sctp_make_cookie_ack(new_asoc, chunk); 1620 repl = sctp_make_cookie_ack(new_asoc, chunk);
1618 if (!repl) 1621 if (!repl)
1619 goto nomem; 1622 goto nomem;
1620 1623
1621 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
1622
1623 /* Report association restart to upper layer. */ 1624 /* Report association restart to upper layer. */
1624 ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_RESTART, 0, 1625 ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_RESTART, 0,
1625 new_asoc->c.sinit_num_ostreams, 1626 new_asoc->c.sinit_num_ostreams,
@@ -1628,6 +1629,9 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
1628 if (!ev) 1629 if (!ev)
1629 goto nomem_ev; 1630 goto nomem_ev;
1630 1631
1632 /* Update the content of current association. */
1633 sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
1634 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
1631 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); 1635 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
1632 return SCTP_DISPOSITION_CONSUME; 1636 return SCTP_DISPOSITION_CONSUME;
1633 1637
@@ -1751,7 +1755,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(const struct sctp_endpoint *ep,
1751 sctp_cmd_seq_t *commands, 1755 sctp_cmd_seq_t *commands,
1752 struct sctp_association *new_asoc) 1756 struct sctp_association *new_asoc)
1753{ 1757{
1754 struct sctp_ulpevent *ev = NULL; 1758 struct sctp_ulpevent *ev = NULL, *ai_ev = NULL;
1755 struct sctp_chunk *repl; 1759 struct sctp_chunk *repl;
1756 1760
1757 /* Clarification from Implementor's Guide: 1761 /* Clarification from Implementor's Guide:
@@ -1778,29 +1782,25 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(const struct sctp_endpoint *ep,
1778 * SCTP user upon reception of a valid COOKIE 1782 * SCTP user upon reception of a valid COOKIE
1779 * ECHO chunk. 1783 * ECHO chunk.
1780 */ 1784 */
1781 ev = sctp_ulpevent_make_assoc_change(new_asoc, 0, 1785 ev = sctp_ulpevent_make_assoc_change(asoc, 0,
1782 SCTP_COMM_UP, 0, 1786 SCTP_COMM_UP, 0,
1783 new_asoc->c.sinit_num_ostreams, 1787 asoc->c.sinit_num_ostreams,
1784 new_asoc->c.sinit_max_instreams, 1788 asoc->c.sinit_max_instreams,
1785 GFP_ATOMIC); 1789 GFP_ATOMIC);
1786 if (!ev) 1790 if (!ev)
1787 goto nomem; 1791 goto nomem;
1788 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
1789 SCTP_ULPEVENT(ev));
1790 1792
1791 /* Sockets API Draft Section 5.3.1.6 1793 /* Sockets API Draft Section 5.3.1.6
1792 * When a peer sends a Adaption Layer Indication parameter, 1794 * When a peer sends a Adaption Layer Indication parameter,
1793 * SCTP delivers this notification to inform the application 1795 * SCTP delivers this notification to inform the application
1794 * that of the peers requested adaption layer. 1796 * that of the peers requested adaption layer.
1795 */ 1797 */
1796 if (new_asoc->peer.adaption_ind) { 1798 if (asoc->peer.adaption_ind) {
1797 ev = sctp_ulpevent_make_adaption_indication(new_asoc, 1799 ai_ev = sctp_ulpevent_make_adaption_indication(asoc,
1798 GFP_ATOMIC); 1800 GFP_ATOMIC);
1799 if (!ev) 1801 if (!ai_ev)
1800 goto nomem; 1802 goto nomem;
1801 1803
1802 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
1803 SCTP_ULPEVENT(ev));
1804 } 1804 }
1805 } 1805 }
1806 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL()); 1806 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
@@ -1809,12 +1809,21 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(const struct sctp_endpoint *ep,
1809 if (!repl) 1809 if (!repl)
1810 goto nomem; 1810 goto nomem;
1811 1811
1812 if (ev)
1813 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
1814 SCTP_ULPEVENT(ev));
1815 if (ai_ev)
1816 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
1817 SCTP_ULPEVENT(ai_ev));
1818
1812 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); 1819 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
1813 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL()); 1820 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
1814 1821
1815 return SCTP_DISPOSITION_CONSUME; 1822 return SCTP_DISPOSITION_CONSUME;
1816 1823
1817nomem: 1824nomem:
1825 if (ai_ev)
1826 sctp_ulpevent_free(ai_ev);
1818 if (ev) 1827 if (ev)
1819 sctp_ulpevent_free(ev); 1828 sctp_ulpevent_free(ev);
1820 return SCTP_DISPOSITION_NOMEM; 1829 return SCTP_DISPOSITION_NOMEM;
@@ -3019,7 +3028,6 @@ sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep,
3019 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t))) 3028 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
3020 return sctp_sf_violation_chunklen(ep, asoc, type, arg, 3029 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3021 commands); 3030 commands);
3022
3023 /* 10.2 H) SHUTDOWN COMPLETE notification 3031 /* 10.2 H) SHUTDOWN COMPLETE notification
3024 * 3032 *
3025 * When SCTP completes the shutdown procedures (section 9.2) this 3033 * When SCTP completes the shutdown procedures (section 9.2) this
@@ -3030,6 +3038,14 @@ sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep,
3030 if (!ev) 3038 if (!ev)
3031 goto nomem; 3039 goto nomem;
3032 3040
3041 /* ...send a SHUTDOWN COMPLETE chunk to its peer, */
3042 reply = sctp_make_shutdown_complete(asoc, chunk);
3043 if (!reply)
3044 goto nomem_chunk;
3045
3046 /* Do all the commands now (after allocation), so that we
3047 * have consistent state if memory allocation failes
3048 */
3033 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); 3049 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
3034 3050
3035 /* Upon the receipt of the SHUTDOWN ACK, the SHUTDOWN sender shall 3051 /* Upon the receipt of the SHUTDOWN ACK, the SHUTDOWN sender shall
@@ -3041,11 +3057,6 @@ sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep,
3041 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, 3057 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
3042 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); 3058 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
3043 3059
3044 /* ...send a SHUTDOWN COMPLETE chunk to its peer, */
3045 reply = sctp_make_shutdown_complete(asoc, chunk);
3046 if (!reply)
3047 goto nomem;
3048
3049 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, 3060 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
3050 SCTP_STATE(SCTP_STATE_CLOSED)); 3061 SCTP_STATE(SCTP_STATE_CLOSED));
3051 SCTP_INC_STATS(SCTP_MIB_SHUTDOWNS); 3062 SCTP_INC_STATS(SCTP_MIB_SHUTDOWNS);
@@ -3056,6 +3067,8 @@ sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep,
3056 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); 3067 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
3057 return SCTP_DISPOSITION_DELETE_TCB; 3068 return SCTP_DISPOSITION_DELETE_TCB;
3058 3069
3070nomem_chunk:
3071 sctp_ulpevent_free(ev);
3059nomem: 3072nomem:
3060 return SCTP_DISPOSITION_NOMEM; 3073 return SCTP_DISPOSITION_NOMEM;
3061} 3074}