* notification is passed to the upper layer.
*/
ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_SHUTDOWN_COMP,
- 0, 0, 0, GFP_ATOMIC);
+ 0, 0, 0, NULL, GFP_ATOMIC);
if (ev)
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
- SCTP_ULPEVENT(ev));
+ SCTP_ULPEVENT(ev));
/* Upon reception of the SHUTDOWN COMPLETE chunk the endpoint
* will verify that it is in SHUTDOWN-ACK-SENT state, if it is
* Verification Tag field to Tag_A, and also provide its own
* Verification Tag (Tag_Z) in the Initiate Tag field.
*
- * Verification Tag: Must be 0.
+ * Verification Tag: Must be 0.
*
* Inputs
* (endpoint, asoc, chunk)
/* 6.10 Bundling
* An endpoint MUST NOT bundle INIT, INIT ACK or
* SHUTDOWN COMPLETE with any other chunks.
- *
+ *
* IG Section 2.11.2
* Furthermore, we require that the receiver of an INIT chunk MUST
* enforce these rules by silently discarding an arriving packet
return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
/* 3.1 A packet containing an INIT chunk MUST have a zero Verification
- * Tag.
+ * Tag.
*/
if (chunk->sctp_hdr->vtag != 0)
return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
}
}
- /* Grab the INIT header. */
+ /* Grab the INIT header. */
chunk->subh.init_hdr = (sctp_inithdr_t *)chunk->skb->data;
/* Tag the variable length parameters. */
/* "Decode" the chunk. We have no optional parameters so we
* are in good shape.
*/
- chunk->subh.cookie_hdr =
+ chunk->subh.cookie_hdr =
(struct sctp_signed_cookie *)chunk->skb->data;
if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
sizeof(sctp_chunkhdr_t)))
case -SCTP_IERROR_BAD_SIG:
default:
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
- };
+ }
}
ev = sctp_ulpevent_make_assoc_change(new_asoc, 0, SCTP_COMM_UP, 0,
new_asoc->c.sinit_num_ostreams,
new_asoc->c.sinit_max_instreams,
- GFP_ATOMIC);
+ NULL, GFP_ATOMIC);
if (!ev)
goto nomem_ev;
- /* Sockets API Draft Section 5.3.1.6
+ /* Sockets API Draft Section 5.3.1.6
* When a peer sends a Adaptation Layer Indication parameter , SCTP
* delivers this notification to inform the application that of the
* peers requested adaptation layer.
ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_COMM_UP,
0, asoc->c.sinit_num_ostreams,
asoc->c.sinit_max_instreams,
- GFP_ATOMIC);
+ NULL, GFP_ATOMIC);
if (!ev)
goto nomem;
sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMER_UPDATE,
SCTP_TRANSPORT(transport));
- return SCTP_DISPOSITION_CONSUME;
+ return SCTP_DISPOSITION_CONSUME;
}
/*
new_asoc->c.my_ttag = asoc->c.my_vtag;
new_asoc->c.peer_ttag = asoc->c.peer_vtag;
break;
- };
+ }
/* Other parameters for the endpoint SHOULD be copied from the
* existing parameters of the association (e.g. number of
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
/* 3.1 A packet containing an INIT chunk MUST have a zero Verification
- * Tag.
+ * Tag.
*/
if (chunk->sctp_hdr->vtag != 0)
return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
/* Per the above section, we'll discard the chunk if we have an
* endpoint. If this is an OOTB INIT-ACK, treat it as such.
*/
- if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
+ if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
return sctp_sf_ootb(ep, asoc, type, arg, commands);
else
return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_RESTART, 0,
new_asoc->c.sinit_num_ostreams,
new_asoc->c.sinit_max_instreams,
- GFP_ATOMIC);
+ NULL, GFP_ATOMIC);
if (!ev)
goto nomem_ev;
ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_COMM_UP, 0,
new_asoc->c.sinit_num_ostreams,
new_asoc->c.sinit_max_instreams,
- GFP_ATOMIC);
+ NULL, GFP_ATOMIC);
if (!ev)
goto nomem_ev;
/* Clarification from Implementor's Guide:
* D) When both local and remote tags match the endpoint should
- * enter the ESTABLISHED state, if it is in the COOKIE-ECHOED state.
- * It should stop any cookie timer that may be running and send
- * a COOKIE ACK.
+ * enter the ESTABLISHED state, if it is in the COOKIE-ECHOED state.
+ * It should stop any cookie timer that may be running and send
+ * a COOKIE ACK.
*/
/* Don't accidentally move back into established state. */
SCTP_COMM_UP, 0,
asoc->c.sinit_num_ostreams,
asoc->c.sinit_max_instreams,
- GFP_ATOMIC);
+ NULL, GFP_ATOMIC);
if (!ev)
goto nomem;
/* "Decode" the chunk. We have no optional parameters so we
* are in good shape.
*/
- chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data;
+ chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data;
if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
sizeof(sctp_chunkhdr_t)))
goto nomem;
case -SCTP_IERROR_BAD_SIG:
default:
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
- };
+ }
}
/* Compare the tie_tag in cookie with the verification tag of
default: /* Discard packet for all others. */
retval = sctp_sf_pdiscard(ep, asoc, type, arg, commands);
break;
- };
+ }
/* Delete the tempory new association. */
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
*/
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,
+ return sctp_sf_do_5_2_6_stale(ep, asoc, type,
arg, commands);
}
*/
sctp_add_cmd_sf(commands, SCTP_CMD_DEL_NON_PRIMARY, SCTP_NULL());
- /* If we've sent any data bundled with COOKIE-ECHO we will need to
- * resend
+ /* If we've sent any data bundled with COOKIE-ECHO we will need to
+ * resend
*/
- sctp_add_cmd_sf(commands, SCTP_CMD_RETRAN,
+ sctp_add_cmd_sf(commands, SCTP_CMD_RETRAN,
SCTP_TRANSPORT(asoc->peer.primary_path));
/* Cast away the const modifier, as we want to just
error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET));
- /* ASSOC_FAILED will DELETE_TCB. */
+ /* ASSOC_FAILED will DELETE_TCB. */
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_PERR(error));
SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
ev = sctp_ulpevent_make_shutdown_event(asoc, 0, GFP_ATOMIC);
if (!ev) {
disposition = SCTP_DISPOSITION_NOMEM;
- goto out;
+ goto out;
}
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_ecne_chunk_t)))
return sctp_sf_violation_chunklen(ep, asoc, type, arg,
commands);
-
+
cwr = (sctp_cwrhdr_t *) chunk->skb->data;
skb_pull(chunk->skb, sizeof(sctp_cwrhdr_t));
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
SCTP_NULL());
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
- }
+ }
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_data_chunk_t)))
return sctp_sf_violation_chunklen(ep, asoc, type, arg,
return SCTP_DISPOSITION_DISCARD;
consume:
return SCTP_DISPOSITION_CONSUME;
-
+
}
/*
/* Make an ABORT. The T bit will be set if the asoc
* is NULL.
*/
- abort = sctp_make_abort(asoc, chunk, 0);
+ abort = sctp_make_abort(asoc, chunk, 0);
if (!abort) {
sctp_ootb_pkt_free(packet);
return SCTP_DISPOSITION_NOMEM;
}
sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_OPERR,
- SCTP_CHUNK(chunk));
+ SCTP_CHUNK(chunk));
}
return SCTP_DISPOSITION_CONSUME;
* notification is passed to the upper layer.
*/
ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_SHUTDOWN_COMP,
- 0, 0, 0, GFP_ATOMIC);
+ 0, 0, 0, NULL, GFP_ATOMIC);
if (!ev)
goto nomem;
break;
ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
- if (ch_end > skb->tail)
+ if (ch_end > skb_tail_pointer(skb))
break;
if (SCTP_CID_SHUTDOWN_ACK == ch->type)
*/
if (SCTP_CID_ABORT == ch->type)
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
-
+
ch = (sctp_chunkhdr_t *) ch_end;
- } while (ch_end < skb->tail);
+ } while (ch_end < skb_tail_pointer(skb));
if (ootb_shut_ack)
sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands);
if (packet) {
/* Make an SHUTDOWN_COMPLETE.
- * The T bit will be set if the asoc is NULL.
- */
+ * The T bit will be set if the asoc is NULL.
+ */
shut = sctp_make_shutdown_complete(asoc, chunk);
if (!shut) {
sctp_ootb_pkt_free(packet);
/* ADDIP 4.2 C1) Compare the value of the serial number to the value
* the endpoint stored in a new association variable
- * 'Peer-Serial-Number'.
+ * 'Peer-Serial-Number'.
*/
if (serial == asoc->peer.addip_serial + 1) {
- /* ADDIP 4.2 C2) If the value found in the serial number is
+ /* ADDIP 4.2 C2) If the value found in the serial number is
* equal to the ('Peer-Serial-Number' + 1), the endpoint MUST
* do V1-V5.
*/
else
return SCTP_DISPOSITION_DISCARD;
} else {
- /* ADDIP 4.2 C4) Otherwise, the ASCONF Chunk is discarded since
+ /* ADDIP 4.2 C4) Otherwise, the ASCONF Chunk is discarded since
* it must be either a stale packet or from an attacker.
- */
+ */
return SCTP_DISPOSITION_DISCARD;
}
* being responded to.
*/
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(asconf_ack));
-
+
return SCTP_DISPOSITION_CONSUME;
}
*/
sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
- const sctp_subtype_t type, void *arg,
+ const sctp_subtype_t type, void *arg,
sctp_cmd_seq_t *commands)
{
struct sctp_chunk *asconf_ack = arg;
SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
- SCTP_ERROR(ECONNABORTED));
+ SCTP_ERROR(ECONNABORTED));
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
SCTP_PERR(SCTP_ERROR_ASCONF_ACK));
SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
*/
sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
- SCTP_ERROR(ECONNABORTED));
+ SCTP_ERROR(ECONNABORTED));
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
SCTP_PERR(SCTP_ERROR_ASCONF_ACK));
SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
if (len > sizeof(struct sctp_fwdtsn_hdr))
- sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
+ sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
SCTP_CHUNK(chunk));
-
+
/* Count this as receiving DATA. */
if (asoc->autoclose) {
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
}
-
+
/* FIXME: For now send a SACK, but DATA processing may
- * send another.
+ * send another.
*/
sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE());
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
if (len > sizeof(struct sctp_fwdtsn_hdr))
- sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
+ sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
SCTP_CHUNK(chunk));
-
+
/* Go a head and force a SACK, since we are shutting down. */
gen_shutdown:
/* Implementor's Guide.
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
- return SCTP_DISPOSITION_CONSUME;
+ return SCTP_DISPOSITION_CONSUME;
}
/*
* if it's length is set to be smaller then the size of sctp_sack_chunk_t.
*
* We inform the other end by sending an ABORT with a Protocol Violation
- * error code.
+ * error code.
*
* Section: Not specified
* Verification Tag: Nothing to do
SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION));
} else {
sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
- SCTP_ERROR(ECONNABORTED));
+ SCTP_ERROR(ECONNABORTED));
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION));
SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
-
+
return SCTP_DISPOSITION_ABORT;
nomem:
void *arg,
sctp_cmd_seq_t *commands)
{
- return sctp_sf_heartbeat(ep, asoc, type, (struct sctp_transport *)arg,
- commands);
+ if (SCTP_DISPOSITION_NOMEM == sctp_sf_heartbeat(ep, asoc, type,
+ (struct sctp_transport *)arg, commands))
+ return SCTP_DISPOSITION_NOMEM;
+
+ /*
+ * RFC 2960 (bis), section 8.3
+ *
+ * D) Request an on-demand HEARTBEAT on a specific destination
+ * transport address of a given association.
+ *
+ * The endpoint should increment the respective error counter of
+ * the destination transport address each time a HEARTBEAT is sent
+ * to that address and not acknowledged within one RTO.
+ *
+ */
+ sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_RESET,
+ SCTP_TRANSPORT(arg));
+ return SCTP_DISPOSITION_CONSUME;
}
/*
/* sctp-implguide 2.10 Issues with Heartbeating and failover
*
* HEARTBEAT ... is discontinued after sending either SHUTDOWN
- * or SHUTDOWN-ACK.
+ * or SHUTDOWN-ACK.
*/
sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_STOP, SCTP_NULL());
/* sctp-implguide 2.10 Issues with Heartbeating and failover
*
* HEARTBEAT ... is discontinued after sending either SHUTDOWN
- * or SHUTDOWN-ACK.
+ * or SHUTDOWN-ACK.
*/
sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_STOP, SCTP_NULL());
* sent as soon as cwnd allows (normally when a SACK arrives).
*/
- /* NB: Rules E4 and F1 are implicit in R1. */
- sctp_add_cmd_sf(commands, SCTP_CMD_RETRAN, SCTP_TRANSPORT(transport));
-
/* Do some failure management (Section 8.2). */
sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE, SCTP_TRANSPORT(transport));
+ /* NB: Rules E4 and F1 are implicit in R1. */
+ sctp_add_cmd_sf(commands, SCTP_CMD_RETRAN, SCTP_TRANSPORT(transport));
+
return SCTP_DISPOSITION_CONSUME;
}
default:
BUG();
break;
- };
+ }
if (!reply)
goto nomem;
/* ADDIP 4.1 B4) Re-transmit the ASCONF Chunk last sent and if possible
* choose an alternate destination address (please refer to RFC2960
* [5] section 6.4.1). An endpoint MUST NOT add new parameters to this
- * chunk, it MUST be the same (including its serial number) as the last
+ * chunk, it MUST be the same (including its serial number) as the last
* ASCONF sent.
*/
sctp_chunk_hold(asoc->addip_last_asconf);
/* sctpimpguide-05 Section 2.12.2
* The sender of the SHUTDOWN MAY also start an overall guard timer
* 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
- */
+ */
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
disposition = SCTP_DISPOSITION_CONSUME;
vtag = ntohl(init->init_hdr.init_tag);
break;
}
- default:
+ default:
vtag = ntohl(chunk->sctp_hdr->vtag);
break;
}
/* Override the OOTB vtag from the cookie. */
cookie = chunk->subh.cookie_hdr;
packet->vtag = cookie->c.peer_vtag;
-
+
/* Set the skb to the belonging sock for accounting. */
err_chunk->skb->sk = ep->base.sk;
sctp_packet_append_chunk(packet, err_chunk);
chunk->ecn_ce_done = 1;
af = sctp_get_af_specific(
- ipver2af(chunk->skb->nh.iph->version));
+ ipver2af(ip_hdr(chunk->skb)->version));
if (af && af->is_ce(chunk->skb) && asoc->peer.ecn_capable) {
/* Do real work as sideffect. */
sctp_add_cmd_sf(commands, SCTP_CMD_PART_DELIVER, SCTP_NULL());
}
- /* Spill over rwnd a little bit. Note: While allowed, this spill over
+ /* Spill over rwnd a little bit. Note: While allowed, this spill over
* seems a bit troublesome in that frag_point varies based on
* PMTU. In cases, such as loopback, this might be a rather
* large spill over.