Skip to content

Commit c5fab80

Browse files
committed
Merge branch 'sctp-chunk-fix'
Xin Long says: ==================== sctp: always send a chunk with the asoc that it belongs to Currently when processing a duplicate COOKIE-ECHO chunk, a new temp asoc would be created, then it creates the chunks with the new asoc. However, later on it uses the old asoc to send these chunks, which has caused quite a few issues. This patchset is to fix this and make sure that the COOKIE-ACK and SHUTDOWN chunks are created with the same asoc that will be used to send them out. v1->v2: - see Patch 3/3. ==================== Acked-by: Marcelo Ricardo Leitner <[email protected]> Signed-off-by: David S. Miller <[email protected]>
2 parents c5197b4 + 51eac7f commit c5fab80

File tree

3 files changed

+39
-38
lines changed

3 files changed

+39
-38
lines changed

include/net/sctp/command.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ enum sctp_verb {
6868
SCTP_CMD_ASSOC_FAILED, /* Handle association failure. */
6969
SCTP_CMD_DISCARD_PACKET, /* Discard the whole packet. */
7070
SCTP_CMD_GEN_SHUTDOWN, /* Generate a SHUTDOWN chunk. */
71-
SCTP_CMD_UPDATE_ASSOC, /* Update association information. */
7271
SCTP_CMD_PURGE_OUTQUEUE, /* Purge all data waiting to be sent. */
7372
SCTP_CMD_SETUP_T2, /* Hi-level, setup T2-shutdown parms. */
7473
SCTP_CMD_RTO_PENDING, /* Set transport's rto_pending. */

net/sctp/sm_sideeffect.c

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -826,28 +826,6 @@ static void sctp_cmd_setup_t2(struct sctp_cmd_seq *cmds,
826826
asoc->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = t->rto;
827827
}
828828

829-
static void sctp_cmd_assoc_update(struct sctp_cmd_seq *cmds,
830-
struct sctp_association *asoc,
831-
struct sctp_association *new)
832-
{
833-
struct net *net = asoc->base.net;
834-
struct sctp_chunk *abort;
835-
836-
if (!sctp_assoc_update(asoc, new))
837-
return;
838-
839-
abort = sctp_make_abort(asoc, NULL, sizeof(struct sctp_errhdr));
840-
if (abort) {
841-
sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0);
842-
sctp_add_cmd_sf(cmds, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
843-
}
844-
sctp_add_cmd_sf(cmds, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNABORTED));
845-
sctp_add_cmd_sf(cmds, SCTP_CMD_ASSOC_FAILED,
846-
SCTP_PERR(SCTP_ERROR_RSRC_LOW));
847-
SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
848-
SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
849-
}
850-
851829
/* Helper function to change the state of an association. */
852830
static void sctp_cmd_new_state(struct sctp_cmd_seq *cmds,
853831
struct sctp_association *asoc,
@@ -1301,10 +1279,6 @@ static int sctp_cmd_interpreter(enum sctp_event_type event_type,
13011279
sctp_endpoint_add_asoc(ep, asoc);
13021280
break;
13031281

1304-
case SCTP_CMD_UPDATE_ASSOC:
1305-
sctp_cmd_assoc_update(commands, asoc, cmd->obj.asoc);
1306-
break;
1307-
13081282
case SCTP_CMD_PURGE_OUTQUEUE:
13091283
sctp_outq_teardown(&asoc->outqueue);
13101284
break;

net/sctp/sm_statefuns.c

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,6 +1773,30 @@ enum sctp_disposition sctp_sf_do_5_2_3_initack(
17731773
return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands);
17741774
}
17751775

1776+
static int sctp_sf_do_assoc_update(struct sctp_association *asoc,
1777+
struct sctp_association *new,
1778+
struct sctp_cmd_seq *cmds)
1779+
{
1780+
struct net *net = asoc->base.net;
1781+
struct sctp_chunk *abort;
1782+
1783+
if (!sctp_assoc_update(asoc, new))
1784+
return 0;
1785+
1786+
abort = sctp_make_abort(asoc, NULL, sizeof(struct sctp_errhdr));
1787+
if (abort) {
1788+
sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0);
1789+
sctp_add_cmd_sf(cmds, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
1790+
}
1791+
sctp_add_cmd_sf(cmds, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNABORTED));
1792+
sctp_add_cmd_sf(cmds, SCTP_CMD_ASSOC_FAILED,
1793+
SCTP_PERR(SCTP_ERROR_RSRC_LOW));
1794+
SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
1795+
SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
1796+
1797+
return -ENOMEM;
1798+
}
1799+
17761800
/* Unexpected COOKIE-ECHO handler for peer restart (Table 2, action 'A')
17771801
*
17781802
* Section 5.2.4
@@ -1852,20 +1876,22 @@ static enum sctp_disposition sctp_sf_do_dupcook_a(
18521876
SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
18531877
sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_ASCONF_QUEUE, SCTP_NULL());
18541878

1855-
repl = sctp_make_cookie_ack(new_asoc, chunk);
1879+
/* Update the content of current association. */
1880+
if (sctp_sf_do_assoc_update((struct sctp_association *)asoc, new_asoc, commands))
1881+
goto nomem;
1882+
1883+
repl = sctp_make_cookie_ack(asoc, chunk);
18561884
if (!repl)
18571885
goto nomem;
18581886

18591887
/* Report association restart to upper layer. */
18601888
ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_RESTART, 0,
1861-
new_asoc->c.sinit_num_ostreams,
1862-
new_asoc->c.sinit_max_instreams,
1889+
asoc->c.sinit_num_ostreams,
1890+
asoc->c.sinit_max_instreams,
18631891
NULL, GFP_ATOMIC);
18641892
if (!ev)
18651893
goto nomem_ev;
18661894

1867-
/* Update the content of current association. */
1868-
sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
18691895
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
18701896
if ((sctp_state(asoc, SHUTDOWN_PENDING) ||
18711897
sctp_state(asoc, SHUTDOWN_SENT)) &&
@@ -1877,7 +1903,7 @@ static enum sctp_disposition sctp_sf_do_dupcook_a(
18771903
*/
18781904
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
18791905
return sctp_sf_do_9_2_start_shutdown(net, ep, asoc,
1880-
SCTP_ST_CHUNK(0), repl,
1906+
SCTP_ST_CHUNK(0), NULL,
18811907
commands);
18821908
} else {
18831909
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
@@ -1925,14 +1951,16 @@ static enum sctp_disposition sctp_sf_do_dupcook_b(
19251951
if (!sctp_auth_chunk_verify(net, chunk, new_asoc))
19261952
return SCTP_DISPOSITION_DISCARD;
19271953

1928-
/* Update the content of current association. */
1929-
sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
19301954
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
19311955
SCTP_STATE(SCTP_STATE_ESTABLISHED));
19321956
SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB);
19331957
sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
19341958

1935-
repl = sctp_make_cookie_ack(new_asoc, chunk);
1959+
/* Update the content of current association. */
1960+
if (sctp_sf_do_assoc_update((struct sctp_association *)asoc, new_asoc, commands))
1961+
goto nomem;
1962+
1963+
repl = sctp_make_cookie_ack(asoc, chunk);
19361964
if (!repl)
19371965
goto nomem;
19381966

@@ -5521,7 +5549,7 @@ enum sctp_disposition sctp_sf_do_9_2_start_shutdown(
55215549
* in the Cumulative TSN Ack field the last sequential TSN it
55225550
* has received from the peer.
55235551
*/
5524-
reply = sctp_make_shutdown(asoc, arg);
5552+
reply = sctp_make_shutdown(asoc, NULL);
55255553
if (!reply)
55265554
goto nomem;
55275555

@@ -6119,7 +6147,7 @@ enum sctp_disposition sctp_sf_autoclose_timer_expire(
61196147
disposition = SCTP_DISPOSITION_CONSUME;
61206148
if (sctp_outq_is_empty(&asoc->outqueue)) {
61216149
disposition = sctp_sf_do_9_2_start_shutdown(net, ep, asoc, type,
6122-
NULL, commands);
6150+
arg, commands);
61236151
}
61246152

61256153
return disposition;

0 commit comments

Comments
 (0)