Commit b9c887f4 authored by Jon Grimm's avatar Jon Grimm

[SCTP] Multiple causes may be embedded in an ERROR chunk (ardelle.fan)

parent eaa13e45
...@@ -457,6 +457,18 @@ for (pos.v = chunk->member;\ ...@@ -457,6 +457,18 @@ for (pos.v = chunk->member;\
pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)); \ pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)); \
pos.v += WORD_ROUND(ntohs(pos.p->length))) pos.v += WORD_ROUND(ntohs(pos.p->length)))
#define sctp_walk_errors(err, chunk_hdr)\
_sctp_walk_errors((err), (chunk_hdr), ntohs((chunk_hdr)->length))
#define _sctp_walk_errors(err, chunk_hdr, end)\
for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \
sizeof(sctp_chunkhdr_t));\
(void *)err <= (void *)chunk_hdr + end - sizeof(sctp_errhdr_t) &&\
(void *)err <= (void *)chunk_hdr + end - \
WORD_ROUND(ntohs(err->length));\
err = (sctp_errhdr_t *)((void *)err + \
WORD_ROUND(ntohs(err->length))))
/* Round an int up to the next multiple of 4. */ /* Round an int up to the next multiple of 4. */
#define WORD_ROUND(s) (((s)+3)&~3) #define WORD_ROUND(s) (((s)+3)&~3)
......
...@@ -503,10 +503,11 @@ int sctp_rcv_ootb(struct sk_buff *skb) ...@@ -503,10 +503,11 @@ int sctp_rcv_ootb(struct sk_buff *skb)
goto discard; goto discard;
if (SCTP_CID_ERROR == ch->type) { if (SCTP_CID_ERROR == ch->type) {
err = (sctp_errhdr_t *)(ch + sizeof(sctp_chunkhdr_t)); sctp_walk_errors(err, ch) {
if (SCTP_ERROR_STALE_COOKIE == err->cause) if (SCTP_ERROR_STALE_COOKIE == err->cause)
goto discard; goto discard;
} }
}
ch = (sctp_chunkhdr_t *) ch_end; ch = (sctp_chunkhdr_t *) ch_end;
} while (ch_end < skb->tail); } while (ch_end < skb->tail);
......
...@@ -1787,24 +1787,17 @@ sctp_disposition_t sctp_sf_cookie_echoed_err(const struct sctp_endpoint *ep, ...@@ -1787,24 +1787,17 @@ sctp_disposition_t sctp_sf_cookie_echoed_err(const struct sctp_endpoint *ep,
struct sctp_chunk *chunk = arg; struct sctp_chunk *chunk = arg;
sctp_errhdr_t *err; sctp_errhdr_t *err;
err = (sctp_errhdr_t *)(chunk->skb->data);
/* If we have gotten too many failures, give up. */
if (1 + asoc->counters[SCTP_COUNTER_INIT_ERROR] >
asoc->max_init_attempts) {
/* INIT_FAILED will issue an ulpevent. */
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
SCTP_U32(err->cause));
return SCTP_DISPOSITION_DELETE_TCB;
}
/* Process the error here */ /* Process the error here */
switch (err->cause) { /* FUTURE FIXME: When PR-SCTP related and other optional
case SCTP_ERROR_STALE_COOKIE: * parms are emitted, this will have to change to handle multiple
return sctp_sf_do_5_2_6_stale(ep, asoc, type, arg, commands); * errors.
default: */
return sctp_sf_pdiscard(ep, asoc, type, arg, commands); sctp_walk_errors(err, chunk->chunk_hdr) {
if (SCTP_ERROR_STALE_COOKIE == err->cause)
return sctp_sf_do_5_2_6_stale(ep, asoc, type,
arg, commands);
} }
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment