diff options
Diffstat (limited to 'net/sctp/sm_statefuns.c')
-rw-r--r-- | net/sctp/sm_statefuns.c | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index a1be9d93f1a8..0c9f37eb7d8d 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -143,6 +143,12 @@ static sctp_ierror_t sctp_sf_authenticate(const struct sctp_endpoint *ep, | |||
143 | const sctp_subtype_t type, | 143 | const sctp_subtype_t type, |
144 | struct sctp_chunk *chunk); | 144 | struct sctp_chunk *chunk); |
145 | 145 | ||
146 | static sctp_disposition_t __sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep, | ||
147 | const struct sctp_association *asoc, | ||
148 | const sctp_subtype_t type, | ||
149 | void *arg, | ||
150 | sctp_cmd_seq_t *commands); | ||
151 | |||
146 | /* Small helper function that checks if the chunk length | 152 | /* Small helper function that checks if the chunk length |
147 | * is of the appropriate length. The 'required_length' argument | 153 | * is of the appropriate length. The 'required_length' argument |
148 | * is set to be the size of a specific chunk we are testing. | 154 | * 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( | |||
2073 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t))) | 2079 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t))) |
2074 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | 2080 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); |
2075 | 2081 | ||
2082 | /* ADD-IP: Special case for ABORT chunks | ||
2083 | * F4) One special consideration is that ABORT Chunks arriving | ||
2084 | * destined to the IP address being deleted MUST be | ||
2085 | * ignored (see Section 5.3.1 for further details). | ||
2086 | */ | ||
2087 | if (SCTP_ADDR_DEL == | ||
2088 | sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) | ||
2089 | return sctp_sf_discard_chunk(ep, asoc, type, arg, commands); | ||
2090 | |||
2076 | /* Stop the T5-shutdown guard timer. */ | 2091 | /* Stop the T5-shutdown guard timer. */ |
2077 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 2092 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
2078 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); | 2093 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); |
2079 | 2094 | ||
2080 | return sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands); | 2095 | return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands); |
2081 | } | 2096 | } |
2082 | 2097 | ||
2083 | /* | 2098 | /* |
@@ -2109,6 +2124,15 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep, | |||
2109 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t))) | 2124 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t))) |
2110 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | 2125 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); |
2111 | 2126 | ||
2127 | /* ADD-IP: Special case for ABORT chunks | ||
2128 | * F4) One special consideration is that ABORT Chunks arriving | ||
2129 | * destined to the IP address being deleted MUST be | ||
2130 | * ignored (see Section 5.3.1 for further details). | ||
2131 | */ | ||
2132 | if (SCTP_ADDR_DEL == | ||
2133 | sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) | ||
2134 | return sctp_sf_discard_chunk(ep, asoc, type, arg, commands); | ||
2135 | |||
2112 | /* Stop the T2-shutdown timer. */ | 2136 | /* Stop the T2-shutdown timer. */ |
2113 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 2137 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
2114 | SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); | 2138 | SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); |
@@ -2117,7 +2141,7 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep, | |||
2117 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 2141 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
2118 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); | 2142 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); |
2119 | 2143 | ||
2120 | return sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands); | 2144 | return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands); |
2121 | } | 2145 | } |
2122 | 2146 | ||
2123 | /* | 2147 | /* |
@@ -2344,8 +2368,6 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep, | |||
2344 | sctp_cmd_seq_t *commands) | 2368 | sctp_cmd_seq_t *commands) |
2345 | { | 2369 | { |
2346 | struct sctp_chunk *chunk = arg; | 2370 | struct sctp_chunk *chunk = arg; |
2347 | unsigned len; | ||
2348 | __be16 error = SCTP_ERROR_NO_ERROR; | ||
2349 | 2371 | ||
2350 | if (!sctp_vtag_verify_either(chunk, asoc)) | 2372 | if (!sctp_vtag_verify_either(chunk, asoc)) |
2351 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | 2373 | 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, | |||
2363 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t))) | 2385 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t))) |
2364 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | 2386 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); |
2365 | 2387 | ||
2388 | /* ADD-IP: Special case for ABORT chunks | ||
2389 | * F4) One special consideration is that ABORT Chunks arriving | ||
2390 | * destined to the IP address being deleted MUST be | ||
2391 | * ignored (see Section 5.3.1 for further details). | ||
2392 | */ | ||
2393 | if (SCTP_ADDR_DEL == | ||
2394 | sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) | ||
2395 | return sctp_sf_discard_chunk(ep, asoc, type, arg, commands); | ||
2396 | |||
2397 | return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands); | ||
2398 | } | ||
2399 | |||
2400 | static sctp_disposition_t __sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep, | ||
2401 | const struct sctp_association *asoc, | ||
2402 | const sctp_subtype_t type, | ||
2403 | void *arg, | ||
2404 | sctp_cmd_seq_t *commands) | ||
2405 | { | ||
2406 | struct sctp_chunk *chunk = arg; | ||
2407 | unsigned len; | ||
2408 | __be16 error = SCTP_ERROR_NO_ERROR; | ||
2409 | |||
2366 | /* See if we have an error cause code in the chunk. */ | 2410 | /* See if we have an error cause code in the chunk. */ |
2367 | len = ntohs(chunk->chunk_hdr->length); | 2411 | len = ntohs(chunk->chunk_hdr->length); |
2368 | if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) | 2412 | if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) |