sctp: do asoc update earlier in sctp_sf_do_dupcook_b
authorXin Long <lucien.xin@gmail.com>
Fri, 30 Apr 2021 20:03:00 +0000 (04:03 +0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 30 Apr 2021 22:06:34 +0000 (15:06 -0700)
The same thing should be done for sctp_sf_do_dupcook_b().
Meanwhile, SCTP_CMD_UPDATE_ASSOC cmd can be removed.

v1->v2:
  - Fix the return value in sctp_sf_do_assoc_update().

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/sctp/command.h
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c

index e8df72e1627a1deae25eb0d68168fee2aea0df03..5e848884ff61a9ddb6d47f2f2f4c9ab8fc520842 100644 (file)
@@ -68,7 +68,6 @@ enum sctp_verb {
        SCTP_CMD_ASSOC_FAILED,   /* Handle association failure. */
        SCTP_CMD_DISCARD_PACKET, /* Discard the whole packet. */
        SCTP_CMD_GEN_SHUTDOWN,   /* Generate a SHUTDOWN chunk. */
-       SCTP_CMD_UPDATE_ASSOC,   /* Update association information. */
        SCTP_CMD_PURGE_OUTQUEUE, /* Purge all data waiting to be sent. */
        SCTP_CMD_SETUP_T2,       /* Hi-level, setup T2-shutdown parms.  */
        SCTP_CMD_RTO_PENDING,    /* Set transport's rto_pending. */
index 0948f14ce221a3c983b42f5036b7fbf6d7d4fc9c..ce15d590a615a3dd93d019011c93bd64bd413e34 100644 (file)
@@ -826,28 +826,6 @@ static void sctp_cmd_setup_t2(struct sctp_cmd_seq *cmds,
        asoc->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = t->rto;
 }
 
-static void sctp_cmd_assoc_update(struct sctp_cmd_seq *cmds,
-                                 struct sctp_association *asoc,
-                                 struct sctp_association *new)
-{
-       struct net *net = asoc->base.net;
-       struct sctp_chunk *abort;
-
-       if (!sctp_assoc_update(asoc, new))
-               return;
-
-       abort = sctp_make_abort(asoc, NULL, sizeof(struct sctp_errhdr));
-       if (abort) {
-               sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0);
-               sctp_add_cmd_sf(cmds, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
-       }
-       sctp_add_cmd_sf(cmds, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNABORTED));
-       sctp_add_cmd_sf(cmds, SCTP_CMD_ASSOC_FAILED,
-                       SCTP_PERR(SCTP_ERROR_RSRC_LOW));
-       SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
-       SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
-}
-
 /* Helper function to change the state of an association. */
 static void sctp_cmd_new_state(struct sctp_cmd_seq *cmds,
                               struct sctp_association *asoc,
@@ -1301,10 +1279,6 @@ static int sctp_cmd_interpreter(enum sctp_event_type event_type,
                        sctp_endpoint_add_asoc(ep, asoc);
                        break;
 
-               case SCTP_CMD_UPDATE_ASSOC:
-                      sctp_cmd_assoc_update(commands, asoc, cmd->obj.asoc);
-                      break;
-
                case SCTP_CMD_PURGE_OUTQUEUE:
                       sctp_outq_teardown(&asoc->outqueue);
                       break;
index e8ccc4e8b086af34769bbaabd3db63180928c429..a42844904b8181305a85874adf7a6e916628edc5 100644 (file)
@@ -1773,6 +1773,30 @@ enum sctp_disposition sctp_sf_do_5_2_3_initack(
                return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands);
 }
 
+static int sctp_sf_do_assoc_update(struct sctp_association *asoc,
+                                  struct sctp_association *new,
+                                  struct sctp_cmd_seq *cmds)
+{
+       struct net *net = asoc->base.net;
+       struct sctp_chunk *abort;
+
+       if (!sctp_assoc_update(asoc, new))
+               return 0;
+
+       abort = sctp_make_abort(asoc, NULL, sizeof(struct sctp_errhdr));
+       if (abort) {
+               sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0);
+               sctp_add_cmd_sf(cmds, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
+       }
+       sctp_add_cmd_sf(cmds, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNABORTED));
+       sctp_add_cmd_sf(cmds, SCTP_CMD_ASSOC_FAILED,
+                       SCTP_PERR(SCTP_ERROR_RSRC_LOW));
+       SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
+       SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
+
+       return -ENOMEM;
+}
+
 /* Unexpected COOKIE-ECHO handler for peer restart (Table 2, action 'A')
  *
  * Section 5.2.4
@@ -1853,21 +1877,8 @@ static enum sctp_disposition sctp_sf_do_dupcook_a(
        sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_ASCONF_QUEUE, SCTP_NULL());
 
        /* Update the content of current association. */
-       if (sctp_assoc_update((struct sctp_association *)asoc, new_asoc)) {
-               struct sctp_chunk *abort;
-
-               abort = sctp_make_abort(asoc, NULL, sizeof(struct sctp_errhdr));
-               if (abort) {
-                       sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0);
-                       sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
-               }
-               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNABORTED));
-               sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
-                               SCTP_PERR(SCTP_ERROR_RSRC_LOW));
-               SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
-               SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
+       if (sctp_sf_do_assoc_update((struct sctp_association *)asoc, new_asoc, commands))
                goto nomem;
-       }
 
        repl = sctp_make_cookie_ack(asoc, chunk);
        if (!repl)
@@ -1940,14 +1951,16 @@ static enum sctp_disposition sctp_sf_do_dupcook_b(
        if (!sctp_auth_chunk_verify(net, chunk, new_asoc))
                return SCTP_DISPOSITION_DISCARD;
 
-       /* Update the content of current association.  */
-       sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
        sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
                        SCTP_STATE(SCTP_STATE_ESTABLISHED));
        SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB);
        sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
 
-       repl = sctp_make_cookie_ack(new_asoc, chunk);
+       /* Update the content of current association.  */
+       if (sctp_sf_do_assoc_update((struct sctp_association *)asoc, new_asoc, commands))
+               goto nomem;
+
+       repl = sctp_make_cookie_ack(asoc, chunk);
        if (!repl)
                goto nomem;