|
@@ -143,6 +143,12 @@ static sctp_ierror_t sctp_sf_authenticate(const struct sctp_endpoint *ep,
|
|
|
const sctp_subtype_t type,
|
|
|
struct sctp_chunk *chunk);
|
|
|
|
|
|
+static sctp_disposition_t __sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
|
|
|
+ const struct sctp_association *asoc,
|
|
|
+ const sctp_subtype_t type,
|
|
|
+ void *arg,
|
|
|
+ sctp_cmd_seq_t *commands);
|
|
|
+
|
|
|
/* Small helper function that checks if the chunk length
|
|
|
* is of the appropriate length. The 'required_length' argument
|
|
|
* is set to be the size of a specific chunk we are testing.
|
|
@@ -2073,11 +2079,20 @@ sctp_disposition_t sctp_sf_shutdown_pending_abort(
|
|
|
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
|
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
|
|
|
|
|
+ /* ADD-IP: Special case for ABORT chunks
|
|
|
+ * F4) One special consideration is that ABORT Chunks arriving
|
|
|
+ * destined to the IP address being deleted MUST be
|
|
|
+ * ignored (see Section 5.3.1 for further details).
|
|
|
+ */
|
|
|
+ if (SCTP_ADDR_DEL ==
|
|
|
+ sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
|
|
|
+ return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
|
|
|
+
|
|
|
/* Stop the T5-shutdown guard timer. */
|
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
|
|
|
|
|
|
- return sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
|
|
|
+ return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -2109,6 +2124,15 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep,
|
|
|
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
|
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
|
|
|
|
|
+ /* ADD-IP: Special case for ABORT chunks
|
|
|
+ * F4) One special consideration is that ABORT Chunks arriving
|
|
|
+ * destined to the IP address being deleted MUST be
|
|
|
+ * ignored (see Section 5.3.1 for further details).
|
|
|
+ */
|
|
|
+ if (SCTP_ADDR_DEL ==
|
|
|
+ sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
|
|
|
+ return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
|
|
|
+
|
|
|
/* Stop the T2-shutdown timer. */
|
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
|
|
@@ -2117,7 +2141,7 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep,
|
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
|
|
|
|
|
|
- return sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
|
|
|
+ return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -2344,8 +2368,6 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
|
|
|
sctp_cmd_seq_t *commands)
|
|
|
{
|
|
|
struct sctp_chunk *chunk = arg;
|
|
|
- unsigned len;
|
|
|
- __be16 error = SCTP_ERROR_NO_ERROR;
|
|
|
|
|
|
if (!sctp_vtag_verify_either(chunk, asoc))
|
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
|
@@ -2363,6 +2385,28 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
|
|
|
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
|
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
|
|
|
|
|
+ /* ADD-IP: Special case for ABORT chunks
|
|
|
+ * F4) One special consideration is that ABORT Chunks arriving
|
|
|
+ * destined to the IP address being deleted MUST be
|
|
|
+ * ignored (see Section 5.3.1 for further details).
|
|
|
+ */
|
|
|
+ if (SCTP_ADDR_DEL ==
|
|
|
+ sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
|
|
|
+ return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
|
|
|
+
|
|
|
+ return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
|
|
|
+}
|
|
|
+
|
|
|
+static sctp_disposition_t __sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
|
|
|
+ const struct sctp_association *asoc,
|
|
|
+ const sctp_subtype_t type,
|
|
|
+ void *arg,
|
|
|
+ sctp_cmd_seq_t *commands)
|
|
|
+{
|
|
|
+ struct sctp_chunk *chunk = arg;
|
|
|
+ unsigned len;
|
|
|
+ __be16 error = SCTP_ERROR_NO_ERROR;
|
|
|
+
|
|
|
/* See if we have an error cause code in the chunk. */
|
|
|
len = ntohs(chunk->chunk_hdr->length);
|
|
|
if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
|