aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_statefuns.c
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2007-12-20 17:12:59 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:59:24 -0500
commit75205f478331cc64ce729ea72d3c8c1837fb59cb (patch)
tree6267006b32ff0756c142e5d4c74755d11696f6c6 /net/sctp/sm_statefuns.c
parentf57d96b2e92d209ab3991bba9a44e0d6ef7614a8 (diff)
[SCTP]: Implement ADD-IP special case processing for ABORT chunk
ADD-IP spec has a special case for processing ABORTs: 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). Check if the address we received on is in the DEL state, and if so, ignore the ABORT. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/sm_statefuns.c')
-rw-r--r--net/sctp/sm_statefuns.c52
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
146static 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
2400static 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))