Commit dd18325f authored by Jon Grimm's avatar Jon Grimm

Merge http://linux.bkbits.net/linux-2.5

into jgrimm.austin.ibm.com:/home/jgrimm/bk/test.merge.38
parents 5dd6a6e5 372f525b
...@@ -112,6 +112,7 @@ typedef enum { ...@@ -112,6 +112,7 @@ typedef enum {
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN, SCTP_EVENT_TIMEOUT_T2_SHUTDOWN,
SCTP_EVENT_TIMEOUT_T3_RTX, SCTP_EVENT_TIMEOUT_T3_RTX,
SCTP_EVENT_TIMEOUT_T4_RTO, SCTP_EVENT_TIMEOUT_T4_RTO,
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD,
SCTP_EVENT_TIMEOUT_HEARTBEAT, SCTP_EVENT_TIMEOUT_HEARTBEAT,
SCTP_EVENT_TIMEOUT_SACK, SCTP_EVENT_TIMEOUT_SACK,
SCTP_EVENT_TIMEOUT_AUTOCLOSE, SCTP_EVENT_TIMEOUT_AUTOCLOSE,
......
...@@ -114,7 +114,8 @@ extern sctp_protocol_t sctp_proto; ...@@ -114,7 +114,8 @@ extern sctp_protocol_t sctp_proto;
extern struct sock *sctp_get_ctl_sock(void); extern struct sock *sctp_get_ctl_sock(void);
extern int sctp_copy_local_addr_list(sctp_protocol_t *, sctp_bind_addr_t *, extern int sctp_copy_local_addr_list(sctp_protocol_t *, sctp_bind_addr_t *,
sctp_scope_t, int priority, int flags); sctp_scope_t, int priority, int flags);
extern sctp_pf_t *sctp_get_pf_specific(int family);
extern void sctp_set_pf_specific(int family, sctp_pf_t *);
/* /*
* sctp_socket.c * sctp_socket.c
......
...@@ -107,6 +107,9 @@ sctp_state_fn_t sctp_sf_timer_ignore; ...@@ -107,6 +107,9 @@ sctp_state_fn_t sctp_sf_timer_ignore;
sctp_state_fn_t sctp_sf_do_9_1_abort; sctp_state_fn_t sctp_sf_do_9_1_abort;
sctp_state_fn_t sctp_sf_cookie_wait_abort; sctp_state_fn_t sctp_sf_cookie_wait_abort;
sctp_state_fn_t sctp_sf_cookie_echoed_abort; sctp_state_fn_t sctp_sf_cookie_echoed_abort;
sctp_state_fn_t sctp_sf_shutdown_pending_abort;
sctp_state_fn_t sctp_sf_shutdown_sent_abort;
sctp_state_fn_t sctp_sf_shutdown_ack_sent_abort;
sctp_state_fn_t sctp_sf_do_5_1B_init; sctp_state_fn_t sctp_sf_do_5_1B_init;
sctp_state_fn_t sctp_sf_do_5_1C_ack; sctp_state_fn_t sctp_sf_do_5_1C_ack;
sctp_state_fn_t sctp_sf_do_5_1D_ce; sctp_state_fn_t sctp_sf_do_5_1D_ce;
...@@ -119,6 +122,7 @@ sctp_state_fn_t sctp_sf_tabort_8_4_8; ...@@ -119,6 +122,7 @@ sctp_state_fn_t sctp_sf_tabort_8_4_8;
sctp_state_fn_t sctp_sf_operr_notify; sctp_state_fn_t sctp_sf_operr_notify;
sctp_state_fn_t sctp_sf_t1_timer_expire; sctp_state_fn_t sctp_sf_t1_timer_expire;
sctp_state_fn_t sctp_sf_t2_timer_expire; sctp_state_fn_t sctp_sf_t2_timer_expire;
sctp_state_fn_t sctp_sf_t5_timer_expire;
sctp_state_fn_t sctp_sf_sendbeat_8_3; sctp_state_fn_t sctp_sf_sendbeat_8_3;
sctp_state_fn_t sctp_sf_beat_8_3; sctp_state_fn_t sctp_sf_beat_8_3;
sctp_state_fn_t sctp_sf_backbeat_8_3; sctp_state_fn_t sctp_sf_backbeat_8_3;
...@@ -134,6 +138,7 @@ sctp_state_fn_t sctp_sf_discard_chunk; ...@@ -134,6 +138,7 @@ sctp_state_fn_t sctp_sf_discard_chunk;
sctp_state_fn_t sctp_sf_do_5_2_1_siminit; sctp_state_fn_t sctp_sf_do_5_2_1_siminit;
sctp_state_fn_t sctp_sf_do_5_2_2_dupinit; sctp_state_fn_t sctp_sf_do_5_2_2_dupinit;
sctp_state_fn_t sctp_sf_do_5_2_4_dupcook; sctp_state_fn_t sctp_sf_do_5_2_4_dupcook;
sctp_state_fn_t sctp_sf_unk_chunk;
/* Prototypes for primitive event state functions. */ /* Prototypes for primitive event state functions. */
sctp_state_fn_t sctp_sf_do_prm_asoc; sctp_state_fn_t sctp_sf_do_prm_asoc;
...@@ -144,6 +149,9 @@ sctp_state_fn_t sctp_sf_cookie_echoed_prm_shutdown; ...@@ -144,6 +149,9 @@ sctp_state_fn_t sctp_sf_cookie_echoed_prm_shutdown;
sctp_state_fn_t sctp_sf_do_9_1_prm_abort; sctp_state_fn_t sctp_sf_do_9_1_prm_abort;
sctp_state_fn_t sctp_sf_cookie_wait_prm_abort; sctp_state_fn_t sctp_sf_cookie_wait_prm_abort;
sctp_state_fn_t sctp_sf_cookie_echoed_prm_abort; sctp_state_fn_t sctp_sf_cookie_echoed_prm_abort;
sctp_state_fn_t sctp_sf_shutdown_pending_prm_abort;
sctp_state_fn_t sctp_sf_shutdown_sent_prm_abort;
sctp_state_fn_t sctp_sf_shutdown_ack_sent_prm_abort;
sctp_state_fn_t sctp_sf_error_closed; sctp_state_fn_t sctp_sf_error_closed;
sctp_state_fn_t sctp_sf_error_shutdown; sctp_state_fn_t sctp_sf_error_shutdown;
sctp_state_fn_t sctp_sf_ignore_primitive; sctp_state_fn_t sctp_sf_ignore_primitive;
......
...@@ -255,6 +255,12 @@ typedef struct sctp_func { ...@@ -255,6 +255,12 @@ typedef struct sctp_func {
sctp_func_t *sctp_get_af_specific(const sockaddr_storage_t *address); sctp_func_t *sctp_get_af_specific(const sockaddr_storage_t *address);
/* Protocol family functions. */
typedef struct sctp_pf {
void (*event_msgname)(sctp_ulpevent_t *, char *, int *);
void (*skb_msgname)(struct sk_buff *, char *, int *);
} sctp_pf_t;
/* SCTP Socket type: UDP or TCP style. */ /* SCTP Socket type: UDP or TCP style. */
typedef enum { typedef enum {
SCTP_SOCKET_UDP = 0, SCTP_SOCKET_UDP = 0,
...@@ -280,6 +286,7 @@ struct sctp_opt { ...@@ -280,6 +286,7 @@ struct sctp_opt {
__u32 autoclose; __u32 autoclose;
__u8 nodelay; __u8 nodelay;
__u8 disable_fragments; __u8 disable_fragments;
sctp_pf_t *pf;
}; };
...@@ -845,6 +852,7 @@ int sctp_outqueue_set_output_handlers(sctp_outqueue_t *, ...@@ -845,6 +852,7 @@ int sctp_outqueue_set_output_handlers(sctp_outqueue_t *,
sctp_outqueue_ohandler_force_t force); sctp_outqueue_ohandler_force_t force);
void sctp_outqueue_restart(sctp_outqueue_t *); void sctp_outqueue_restart(sctp_outqueue_t *);
void sctp_retransmit(sctp_outqueue_t *, sctp_transport_t *, __u8); void sctp_retransmit(sctp_outqueue_t *, sctp_transport_t *, __u8);
void sctp_retransmit_mark(sctp_outqueue_t *, sctp_transport_t *, __u8);
/* These bind address data fields common between endpoints and associations */ /* These bind address data fields common between endpoints and associations */
...@@ -1128,6 +1136,11 @@ struct SCTP_association { ...@@ -1128,6 +1136,11 @@ struct SCTP_association {
*/ */
sctp_transport_t *primary_path; sctp_transport_t *primary_path;
/* Cache the primary path address here, when we
* need a an address for msg_name.
*/
sockaddr_storage_t primary_addr;
/* active_path /* active_path
* The path that we are currently using to * The path that we are currently using to
* transmit new data and most control chunks. * transmit new data and most control chunks.
...@@ -1183,7 +1196,7 @@ struct SCTP_association { ...@@ -1183,7 +1196,7 @@ struct SCTP_association {
int next_dup_tsn; int next_dup_tsn;
/* Do we need to sack the peer? */ /* Do we need to sack the peer? */
int sack_needed; uint8_t sack_needed;
/* These are capabilities which our peer advertised. */ /* These are capabilities which our peer advertised. */
__u8 ecn_capable; /* Can peer do ECN? */ __u8 ecn_capable; /* Can peer do ECN? */
......
...@@ -96,7 +96,7 @@ unsigned long update_adler32(unsigned long adler, ...@@ -96,7 +96,7 @@ unsigned long update_adler32(unsigned long adler,
* one subtract at the MOST, since buf[n] * one subtract at the MOST, since buf[n]
* is a max of 255. * is a max of 255.
*/ */
if(s1 >= BASE) if (s1 >= BASE)
s1 -= BASE; s1 -= BASE;
/* s2 = (s2 + s1) % BASE */ /* s2 = (s2 + s1) % BASE */
......
...@@ -66,7 +66,7 @@ static void sctp_assoc_bh_rcv(sctp_association_t *asoc); ...@@ -66,7 +66,7 @@ static void sctp_assoc_bh_rcv(sctp_association_t *asoc);
/* Allocate and initialize a new association */ /* Allocate and initialize a new association */
sctp_association_t *sctp_association_new(const sctp_endpoint_t *ep, sctp_association_t *sctp_association_new(const sctp_endpoint_t *ep,
const struct sock *sk, const struct sock *sk,
sctp_scope_t scope, int priority) sctp_scope_t scope, int priority)
{ {
sctp_association_t *asoc; sctp_association_t *asoc;
...@@ -91,7 +91,7 @@ sctp_association_t *sctp_association_new(const sctp_endpoint_t *ep, ...@@ -91,7 +91,7 @@ sctp_association_t *sctp_association_new(const sctp_endpoint_t *ep,
/* Intialize a new association from provided memory. */ /* Intialize a new association from provided memory. */
sctp_association_t *sctp_association_init(sctp_association_t *asoc, sctp_association_t *sctp_association_init(sctp_association_t *asoc,
const sctp_endpoint_t *ep, const sctp_endpoint_t *ep,
const struct sock *sk, const struct sock *sk,
sctp_scope_t scope, sctp_scope_t scope,
int priority) int priority)
...@@ -109,19 +109,19 @@ sctp_association_t *sctp_association_init(sctp_association_t *asoc, ...@@ -109,19 +109,19 @@ sctp_association_t *sctp_association_init(sctp_association_t *asoc,
asoc->ep = (sctp_endpoint_t *)ep; asoc->ep = (sctp_endpoint_t *)ep;
sctp_endpoint_hold(asoc->ep); sctp_endpoint_hold(asoc->ep);
/* Hold the sock. */ /* Hold the sock. */
asoc->base.sk = (struct sock *)sk; asoc->base.sk = (struct sock *)sk;
sock_hold(asoc->base.sk); sock_hold(asoc->base.sk);
/* Initialize the common base substructure. */ /* Initialize the common base substructure. */
asoc->base.type = SCTP_EP_TYPE_ASSOCIATION; asoc->base.type = SCTP_EP_TYPE_ASSOCIATION;
/* Initialize the object handling fields. */ /* Initialize the object handling fields. */
atomic_set(&asoc->base.refcnt, 1); atomic_set(&asoc->base.refcnt, 1);
asoc->base.dead = 0; asoc->base.dead = 0;
asoc->base.malloced = 0; asoc->base.malloced = 0;
/* Initialize the bind addr area. */ /* Initialize the bind addr area. */
sctp_bind_addr_init(&asoc->base.bind_addr, ep->base.bind_addr.port); sctp_bind_addr_init(&asoc->base.bind_addr, ep->base.bind_addr.port);
asoc->base.addr_lock = RW_LOCK_UNLOCKED; asoc->base.addr_lock = RW_LOCK_UNLOCKED;
...@@ -135,7 +135,7 @@ sctp_association_t *sctp_association_init(sctp_association_t *asoc, ...@@ -135,7 +135,7 @@ sctp_association_t *sctp_association_init(sctp_association_t *asoc,
asoc->pmtu = 0; asoc->pmtu = 0;
asoc->frag_point = 0; asoc->frag_point = 0;
/* Initialize the default association max_retrans and RTO values. */ /* Initialize the default association max_retrans and RTO values. */
asoc->max_retrans = ep->proto->max_retrans_association; asoc->max_retrans = ep->proto->max_retrans_association;
asoc->rto_initial = ep->proto->rto_initial; asoc->rto_initial = ep->proto->rto_initial;
asoc->rto_max = ep->proto->rto_max; asoc->rto_max = ep->proto->rto_max;
...@@ -288,7 +288,6 @@ sctp_association_t *sctp_association_init(sctp_association_t *asoc, ...@@ -288,7 +288,6 @@ sctp_association_t *sctp_association_init(sctp_association_t *asoc,
return NULL; return NULL;
} }
/* Free this association if possible. There may still be users, so /* Free this association if possible. There may still be users, so
* the actual deallocation may be delayed. * the actual deallocation may be delayed.
*/ */
...@@ -330,6 +329,11 @@ void sctp_association_free(sctp_association_t *asoc) ...@@ -330,6 +329,11 @@ void sctp_association_free(sctp_association_t *asoc)
sctp_association_put(asoc); sctp_association_put(asoc);
} }
/* Free peer's cached cookie. */
if (asoc->peer.cookie) {
kfree(asoc->peer.cookie);
}
/* Release the transport structures. */ /* Release the transport structures. */
list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
transport = list_entry(pos, sctp_transport_t, transports); transport = list_entry(pos, sctp_transport_t, transports);
...@@ -342,7 +346,6 @@ void sctp_association_free(sctp_association_t *asoc) ...@@ -342,7 +346,6 @@ void sctp_association_free(sctp_association_t *asoc)
sctp_association_put(asoc); sctp_association_put(asoc);
} }
/* Cleanup and free up an association. */ /* Cleanup and free up an association. */
static void sctp_association_destroy(sctp_association_t *asoc) static void sctp_association_destroy(sctp_association_t *asoc)
{ {
...@@ -383,12 +386,11 @@ sctp_transport_t *sctp_assoc_add_peer(sctp_association_t *asoc, ...@@ -383,12 +386,11 @@ sctp_transport_t *sctp_assoc_add_peer(sctp_association_t *asoc,
}; };
/* Set the port if it has not been set yet. */ /* Set the port if it has not been set yet. */
if (0 == asoc->peer.port) { if (0 == asoc->peer.port) {
asoc->peer.port = *port; asoc->peer.port = *port;
} }
SCTP_ASSERT(*port == asoc->peer.port, ":Invalid port\n", SCTP_ASSERT(*port == asoc->peer.port, ":Invalid port\n", return NULL);
return NULL);
/* Check to see if this is a duplicate. */ /* Check to see if this is a duplicate. */
peer = sctp_assoc_lookup_paddr(asoc, addr); peer = sctp_assoc_lookup_paddr(asoc, addr);
...@@ -461,11 +463,21 @@ sctp_transport_t *sctp_assoc_add_peer(sctp_association_t *asoc, ...@@ -461,11 +463,21 @@ sctp_transport_t *sctp_assoc_add_peer(sctp_association_t *asoc,
sp = sctp_sk(asoc->base.sk); sp = sctp_sk(asoc->base.sk);
peer->hb_interval = sp->paddrparam.spp_hbinterval * HZ; peer->hb_interval = sp->paddrparam.spp_hbinterval * HZ;
/* Attach the remote transport to our asoc. */ /* Attach the remote transport to our asoc. */
list_add_tail(&peer->transports, &asoc->peer.transport_addr_list); list_add_tail(&peer->transports, &asoc->peer.transport_addr_list);
/* If we do not yet have a primary path, set one. */ /* If we do not yet have a primary path, set one. */
if (NULL == asoc->peer.primary_path) { if (NULL == asoc->peer.primary_path) {
asoc->peer.primary_path = peer;
/* Set a default msg_name for events. */
memcpy(&asoc->peer.primary_addr, &peer->ipaddr,
sizeof(sockaddr_storage_t));
asoc->peer.active_path = peer;
asoc->peer.retran_path = peer;
}
/* If we do not yet have a primary path, set one. */
if (NULL == asoc->peer.primary_path) {
asoc->peer.primary_path = peer; asoc->peer.primary_path = peer;
asoc->peer.active_path = peer; asoc->peer.active_path = peer;
asoc->peer.retran_path = peer; asoc->peer.retran_path = peer;
...@@ -617,7 +629,7 @@ __u32 __sctp_association_get_next_tsn(sctp_association_t *asoc) ...@@ -617,7 +629,7 @@ __u32 __sctp_association_get_next_tsn(sctp_association_t *asoc)
asoc->next_tsn++; asoc->next_tsn++;
asoc->unack_data++; asoc->unack_data++;
return retval; return retval;
} }
/* Allocate 'num' TSNs by incrementing the association's TSN by num. */ /* Allocate 'num' TSNs by incrementing the association's TSN by num. */
...@@ -739,7 +751,7 @@ int sctp_cmp_addr_exact(const sockaddr_storage_t *ss1, ...@@ -739,7 +751,7 @@ int sctp_cmp_addr_exact(const sockaddr_storage_t *ss1,
* Note: We are sly and return a shared, prealloced chunk. * Note: We are sly and return a shared, prealloced chunk.
*/ */
sctp_chunk_t *sctp_get_ecne_prepend(sctp_association_t *asoc) sctp_chunk_t *sctp_get_ecne_prepend(sctp_association_t *asoc)
{ {
sctp_chunk_t *chunk; sctp_chunk_t *chunk;
int need_ecne; int need_ecne;
__u32 lowest_tsn; __u32 lowest_tsn;
...@@ -892,7 +904,7 @@ static void sctp_assoc_bh_rcv(sctp_association_t *asoc) ...@@ -892,7 +904,7 @@ static void sctp_assoc_bh_rcv(sctp_association_t *asoc)
/* Check to see if the association is freed in response to /* Check to see if the association is freed in response to
* the incoming chunk. If so, get out of the while loop. * the incoming chunk. If so, get out of the while loop.
*/ */
if (!sctp_id2assoc(sk, associd)) if (!sctp_id2assoc(sk, associd))
goto out; goto out;
...@@ -967,7 +979,7 @@ void sctp_assoc_update(sctp_association_t *asoc, sctp_association_t *new) ...@@ -967,7 +979,7 @@ void sctp_assoc_update(sctp_association_t *asoc, sctp_association_t *new)
* and peer's streams. * and peer's streams.
*/ */
for (i = 0; i < SCTP_MAX_STREAM; i++) { for (i = 0; i < SCTP_MAX_STREAM; i++) {
asoc->ssn[i] = 0; asoc->ssn[i] = 0;
asoc->ulpq.ssn[i] = 0; asoc->ulpq.ssn[i] = 0;
} }
} else { } else {
......
/* SCTP kernel reference Implementation /* SCTP kernel reference Implementation
* Copyright (c) Cisco 1999,2000 * Copyright (c) Cisco 1999,2000
* Copyright (c) Motorola 1999,2000,2001 * Copyright (c) Motorola 1999,2000,2001
* Copyright (c) International Business Machines Corp., 2001 * Copyright (c) International Business Machines Corp., 2001
* Copyright (c) La Monte H.P. Yarroll 2001 * Copyright (c) La Monte H.P. Yarroll 2001
* *
* This file is part of the SCTP kernel reference implementation. * This file is part of the SCTP kernel reference implementation.
* *
* A collection class to handle the storage of transport addresses. * A collection class to handle the storage of transport addresses.
* *
* The SCTP reference implementation is free software; * The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of * you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by * the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* The SCTP reference implementation is distributed in the hope that it * The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied * will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************ * ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to * along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330, * the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
* *
* Please send any bug reports or fixes you make to the * Please send any bug reports or fixes you make to the
* email address(es): * email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net> * lksctp developers <lksctp-developers@lists.sourceforge.net>
* *
* Or submit a bug report through the following website: * Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp * http://www.sf.net/projects/lksctp
* *
* Written or modified by: * Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org> * La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us> * Karl Knutson <karl@athena.chicago.il.us>
* Jon Grimm <jgrimm@us.ibm.com> * Jon Grimm <jgrimm@us.ibm.com>
* Daisy Chang <daisyc@us.ibm.com> * Daisy Chang <daisyc@us.ibm.com>
* *
* Any bugs reported given to us we will try to fix... any fixes shared will * Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release. * be incorporated into the next SCTP release.
*/ */
...@@ -83,7 +83,7 @@ int sctp_bind_addr_copy(sctp_bind_addr_t *dest, const sctp_bind_addr_t *src, ...@@ -83,7 +83,7 @@ int sctp_bind_addr_copy(sctp_bind_addr_t *dest, const sctp_bind_addr_t *src,
out: out:
if (error) if (error)
sctp_bind_addr_clean(dest); sctp_bind_addr_clean(dest);
return error; return error;
} }
...@@ -356,7 +356,7 @@ int sctp_in_scope(const sockaddr_storage_t *addr, sctp_scope_t scope) ...@@ -356,7 +356,7 @@ int sctp_in_scope(const sockaddr_storage_t *addr, sctp_scope_t scope)
case AF_INET: case AF_INET:
/* According to the SCTP IPv4 address scoping document - /* According to the SCTP IPv4 address scoping document -
* <draft-stewart-tsvwg-sctp-ipv4-00.txt>, the scope has * <draft-stewart-tsvwg-sctp-ipv4-00.txt>, the scope has
* a heirarchy of 5 levels: * a heirarchy of 5 levels:
* Level 0 - unusable SCTP addresses * Level 0 - unusable SCTP addresses
* Level 1 - loopback address * Level 1 - loopback address
* Level 2 - link-local addresses * Level 2 - link-local addresses
......
/* SCTP kernel reference Implementation Copyright (C) 1999-2001 /* SCTP kernel reference Implementation Copyright (C) 1999-2001
* Cisco, Motorola, and IBM * Cisco, Motorola, and IBM
* Copyright 2001 La Monte H.P. Yarroll * Copyright 2001 La Monte H.P. Yarroll
* *
* This file is part of the SCTP kernel reference Implementation * This file is part of the SCTP kernel reference Implementation
* *
* These functions manipulate sctp command sequences. * These functions manipulate sctp command sequences.
* *
* The SCTP reference implementation is free software; * The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of * you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by * the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* The SCTP reference implementation is distributed in the hope that it * The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied * will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************ * ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to * along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330, * the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
* *
* Please send any bug reports or fixes you make to the * Please send any bug reports or fixes you make to the
* email address(es): * email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net> * lksctp developers <lksctp-developers@lists.sourceforge.net>
* *
* Or submit a bug report through the following website: * Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp * http://www.sf.net/projects/lksctp
* *
* Written or modified by: * Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org> * La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us> * Karl Knutson <karl@athena.chicago.il.us>
* *
* Any bugs reported given to us we will try to fix... any fixes shared will * Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release. * be incorporated into the next SCTP release.
*/ */
......
...@@ -198,6 +198,7 @@ static const char *sctp_timer_tbl[] = { ...@@ -198,6 +198,7 @@ static const char *sctp_timer_tbl[] = {
"TIMEOUT_T2_SHUTDOWN", "TIMEOUT_T2_SHUTDOWN",
"TIMEOUT_T3_RTX", "TIMEOUT_T3_RTX",
"TIMEOUT_T4_RTO", "TIMEOUT_T4_RTO",
"TIMEOUT_T5_SHUTDOWN_GUARD",
"TIMEOUT_HEARTBEAT", "TIMEOUT_HEARTBEAT",
"TIMEOUT_SACK", "TIMEOUT_SACK",
"TIMEOUT_AUTOCLOSE", "TIMEOUT_AUTOCLOSE",
......
...@@ -5,46 +5,46 @@ ...@@ -5,46 +5,46 @@
* Copyright (c) 2001 Intel Corp. * Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 Nokia, Inc. * Copyright (c) 2001 Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll * Copyright (c) 2001 La Monte H.P. Yarroll
* *
* This file is part of the SCTP kernel reference Implementation * This file is part of the SCTP kernel reference Implementation
* *
* This abstraction represents an SCTP endpoint. * This abstraction represents an SCTP endpoint.
* *
* This file is part of the implementation of the add-IP extension, * This file is part of the implementation of the add-IP extension,
* based on <draft-ietf-tsvwg-addip-sctp-02.txt> June 29, 2001, * based on <draft-ietf-tsvwg-addip-sctp-02.txt> June 29, 2001,
* for the SCTP kernel reference Implementation. * for the SCTP kernel reference Implementation.
* *
* The SCTP reference implementation is free software; * The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of * you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by * the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* The SCTP reference implementation is distributed in the hope that it * The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied * will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************ * ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to * along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330, * the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
* *
* Please send any bug reports or fixes you make to the * Please send any bug reports or fixes you make to the
* email address(es): * email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net> * lksctp developers <lksctp-developers@lists.sourceforge.net>
* *
* Or submit a bug report through the following website: * Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp * http://www.sf.net/projects/lksctp
* *
* Written or modified by: * Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org> * La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us> * Karl Knutson <karl@athena.chicago.il.us>
* Jon Grimm <jgrimm@austin.ibm.com> * Jon Grimm <jgrimm@austin.ibm.com>
* Daisy Chang <daisyc@us.ibm.com> * Daisy Chang <daisyc@us.ibm.com>
* Dajiang Zhang <dajiang.zhang@nokia.com> * Dajiang Zhang <dajiang.zhang@nokia.com>
* *
* Any bugs reported given to us we will try to fix... any fixes shared will * Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release. * be incorporated into the next SCTP release.
*/ */
...@@ -92,15 +92,16 @@ sctp_endpoint_t *sctp_endpoint_new(sctp_protocol_t *proto, ...@@ -92,15 +92,16 @@ sctp_endpoint_t *sctp_endpoint_new(sctp_protocol_t *proto,
sctp_endpoint_t *sctp_endpoint_init(sctp_endpoint_t *ep, sctp_protocol_t *proto, sctp_endpoint_t *sctp_endpoint_init(sctp_endpoint_t *ep, sctp_protocol_t *proto,
struct sock *sk, int priority) struct sock *sk, int priority)
{ {
sctp_opt_t *sp = sctp_sk(sk);
memset(ep, 0, sizeof(sctp_endpoint_t)); memset(ep, 0, sizeof(sctp_endpoint_t));
/* Initialize the base structure. */ /* Initialize the base structure. */
/* What type of endpoint are we? */ /* What type of endpoint are we? */
ep->base.type = SCTP_EP_TYPE_SOCKET; ep->base.type = SCTP_EP_TYPE_SOCKET;
/* Initialize the basic object fields. */ /* Initialize the basic object fields. */
atomic_set(&ep->base.refcnt, 1); atomic_set(&ep->base.refcnt, 1);
ep->base.dead = 0; ep->base.dead = 0;
ep->base.malloced = 1; ep->base.malloced = 1;
/* Create an input queue. */ /* Create an input queue. */
...@@ -129,22 +130,30 @@ sctp_endpoint_t *sctp_endpoint_init(sctp_endpoint_t *ep, sctp_protocol_t *proto, ...@@ -129,22 +130,30 @@ sctp_endpoint_t *sctp_endpoint_init(sctp_endpoint_t *ep, sctp_protocol_t *proto,
/* Set up the base timeout information. */ /* Set up the base timeout information. */
ep->timeouts[SCTP_EVENT_TIMEOUT_NONE] = 0; ep->timeouts[SCTP_EVENT_TIMEOUT_NONE] = 0;
ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] =
= SCTP_DEFAULT_TIMEOUT_T1_COOKIE; SCTP_DEFAULT_TIMEOUT_T1_COOKIE;
ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
= SCTP_DEFAULT_TIMEOUT_T1_INIT; SCTP_DEFAULT_TIMEOUT_T1_INIT;
ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] =
= sctp_sk(sk)->rtoinfo.srto_initial; sp->rtoinfo.srto_initial;
ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0; ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0;
ep->timeouts[SCTP_EVENT_TIMEOUT_T4_RTO] = 0; ep->timeouts[SCTP_EVENT_TIMEOUT_T4_RTO] = 0;
ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT]
= SCTP_DEFAULT_TIMEOUT_HEARTBEAT; /* sctpimpguide-05 Section 2.12.2
ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] * If the 'T5-shutdown-guard' timer is used, it SHOULD be set to the
= SCTP_DEFAULT_TIMEOUT_SACK; * recommended value of 5 times 'RTO.Max'.
ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] */
= sctp_sk(sk)->autoclose * HZ; ep->timeouts[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD]
ep->timeouts[SCTP_EVENT_TIMEOUT_PMTU_RAISE] = 5 * sp->rtoinfo.srto_max;
= SCTP_DEFAULT_TIMEOUT_PMTU_RAISE;
ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] =
SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] =
SCTP_DEFAULT_TIMEOUT_SACK;
ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
sp->autoclose * HZ;
ep->timeouts[SCTP_EVENT_TIMEOUT_PMTU_RAISE] =
SCTP_DEFAULT_TIMEOUT_PMTU_RAISE;
/* Set up the default send/receive buffer space. */ /* Set up the default send/receive buffer space. */
...@@ -251,9 +260,10 @@ sctp_endpoint_t *sctp_endpoint_is_match(sctp_endpoint_t *ep, ...@@ -251,9 +260,10 @@ sctp_endpoint_t *sctp_endpoint_is_match(sctp_endpoint_t *ep,
* We do a linear search of the associations for this endpoint. * We do a linear search of the associations for this endpoint.
* We return the matching transport address too. * We return the matching transport address too.
*/ */
sctp_association_t *__sctp_endpoint_lookup_assoc(const sctp_endpoint_t *endpoint, sctp_association_t *__sctp_endpoint_lookup_assoc(
const sockaddr_storage_t *paddr, const sctp_endpoint_t *endpoint,
sctp_transport_t **transport) const sockaddr_storage_t *paddr,
sctp_transport_t **transport)
{ {
int rport; int rport;
sctp_association_t *asoc; sctp_association_t *asoc;
...@@ -310,7 +320,7 @@ static void sctp_endpoint_bh_rcv(sctp_endpoint_t *ep) ...@@ -310,7 +320,7 @@ static void sctp_endpoint_bh_rcv(sctp_endpoint_t *ep)
asoc = NULL; asoc = NULL;
inqueue = &ep->base.inqueue; inqueue = &ep->base.inqueue;
sk = ep->base.sk; sk = ep->base.sk;
while (NULL != (chunk = sctp_pop_inqueue(inqueue))) { while (NULL != (chunk = sctp_pop_inqueue(inqueue))) {
subtype.chunk = chunk->chunk_hdr->type; subtype.chunk = chunk->chunk_hdr->type;
...@@ -343,15 +353,15 @@ static void sctp_endpoint_bh_rcv(sctp_endpoint_t *ep) ...@@ -343,15 +353,15 @@ static void sctp_endpoint_bh_rcv(sctp_endpoint_t *ep)
/* FIX ME We really would rather NOT have to use /* FIX ME We really would rather NOT have to use
* GFP_ATOMIC. * GFP_ATOMIC.
*/ */
error = sctp_do_sm(SCTP_EVENT_T_CHUNK, subtype, state, error = sctp_do_sm(SCTP_EVENT_T_CHUNK, subtype, state,
ep, asoc, chunk, GFP_ATOMIC); ep, asoc, chunk, GFP_ATOMIC);
if (error != 0) if (error != 0)
goto err_out; goto err_out;
/* Check to see if the endpoint is freed in response to /* Check to see if the endpoint is freed in response to
* the incoming chunk. If so, get out of the while loop. * the incoming chunk. If so, get out of the while loop.
*/ */
if (!sctp_sk(sk)->ep) if (!sctp_sk(sk)->ep)
goto out; goto out;
} }
...@@ -360,10 +370,5 @@ static void sctp_endpoint_bh_rcv(sctp_endpoint_t *ep) ...@@ -360,10 +370,5 @@ static void sctp_endpoint_bh_rcv(sctp_endpoint_t *ep)
/* Is this the right way to pass errors up to the ULP? */ /* Is this the right way to pass errors up to the ULP? */
if (error) if (error)
ep->base.sk->err = -error; ep->base.sk->err = -error;
out: out:
} }
...@@ -5,43 +5,43 @@ ...@@ -5,43 +5,43 @@
* Copyright (c) 2001 Intel Corp. * Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 Nokia, Inc. * Copyright (c) 2001 Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll * Copyright (c) 2001 La Monte H.P. Yarroll
* *
* This file is part of the SCTP kernel reference Implementation * This file is part of the SCTP kernel reference Implementation
* *
* These functions handle all input from the IP layer into SCTP. * These functions handle all input from the IP layer into SCTP.
* *
* The SCTP reference implementation is free software; * The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of * you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by * the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* The SCTP reference implementation is distributed in the hope that it * The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied * will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************ * ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to * along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330, * the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
* *
* Please send any bug reports or fixes you make to the * Please send any bug reports or fixes you make to the
* email address(es): * email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net> * lksctp developers <lksctp-developers@lists.sourceforge.net>
* *
* Or submit a bug report through the following website: * Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp * http://www.sf.net/projects/lksctp
* *
* Written or modified by: * Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org> * La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us> * Karl Knutson <karl@athena.chicago.il.us>
* Xingang Guo <xingang.guo@intel.com> * Xingang Guo <xingang.guo@intel.com>
* Jon Grimm <jgrimm@us.ibm.com> * Jon Grimm <jgrimm@us.ibm.com>
* Hui Huang <hui.huang@nokia.com> * Hui Huang <hui.huang@nokia.com>
* Daisy Chang <daisyc@us.ibm.com> * Daisy Chang <daisyc@us.ibm.com>
* *
* Any bugs reported given to us we will try to fix... any fixes shared will * Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release. * be incorporated into the next SCTP release.
*/ */
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
#include <net/sctp/sm.h> #include <net/sctp/sm.h>
/* Forward declarations for internal helpers. */ /* Forward declarations for internal helpers. */
static int sctp_rcv_ootb(struct sk_buff *); static int sctp_rcv_ootb(struct sk_buff *);
sctp_association_t *__sctp_rcv_lookup(struct sk_buff *skb, sctp_association_t *__sctp_rcv_lookup(struct sk_buff *skb,
const sockaddr_storage_t *laddr, const sockaddr_storage_t *laddr,
const sockaddr_storage_t *paddr, const sockaddr_storage_t *paddr,
...@@ -639,7 +639,7 @@ static sctp_association_t *__sctp_rcv_initack_lookup(struct sk_buff *skb, ...@@ -639,7 +639,7 @@ static sctp_association_t *__sctp_rcv_initack_lookup(struct sk_buff *skb,
/* Lookup an association for an inbound skb. */ /* Lookup an association for an inbound skb. */
sctp_association_t *__sctp_rcv_lookup(struct sk_buff *skb, sctp_association_t *__sctp_rcv_lookup(struct sk_buff *skb,
const sockaddr_storage_t *paddr, const sockaddr_storage_t *paddr,
const sockaddr_storage_t *laddr, const sockaddr_storage_t *laddr,
sctp_transport_t **transportp) sctp_transport_t **transportp)
{ {
sctp_association_t *asoc; sctp_association_t *asoc;
......
...@@ -2,36 +2,36 @@ ...@@ -2,36 +2,36 @@
* Copyright (c) 2001 Nokia, Inc. * Copyright (c) 2001 Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll * Copyright (c) 2001 La Monte H.P. Yarroll
* Copyright (c) 2002 International Business Machines, Corp. * Copyright (c) 2002 International Business Machines, Corp.
* *
* This file is part of the SCTP kernel reference Implementation * This file is part of the SCTP kernel reference Implementation
* *
* SCTP over IPv6. * SCTP over IPv6.
* *
* The SCTP reference implementation is free software; * The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of * you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by * the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* The SCTP reference implementation is distributed in the hope that it * The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied * will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************ * ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to * along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330, * the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
* *
* Please send any bug reports or fixes you make to the * Please send any bug reports or fixes you make to the
* email address(es): * email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net> * lksctp developers <lksctp-developers@lists.sourceforge.net>
* *
* Or submit a bug report through the following website: * Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp * http://www.sf.net/projects/lksctp
* *
* Written or modified by: * Written or modified by:
* Le Yanqun <yanqun.le@nokia.com> * Le Yanqun <yanqun.le@nokia.com>
* Hui Huang <hui.huang@nokia.com> * Hui Huang <hui.huang@nokia.com>
* La Monte H.P. Yarroll <piggy@acm.org> * La Monte H.P. Yarroll <piggy@acm.org>
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
* *
* Based on: * Based on:
* linux/net/ipv6/tcp_ipv6.c * linux/net/ipv6/tcp_ipv6.c
* *
* Any bugs reported given to us we will try to fix... any fixes shared will * Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release. * be incorporated into the next SCTP release.
*/ */
...@@ -145,7 +145,7 @@ static inline int sctp_v6_xmit(struct sk_buff *skb) ...@@ -145,7 +145,7 @@ static inline int sctp_v6_xmit(struct sk_buff *skb)
IPV6_ADDR_LOOPBACK)) { IPV6_ADDR_LOOPBACK)) {
ipv6_addr_copy(&saddr, &np->daddr); ipv6_addr_copy(&saddr, &np->daddr);
} }
} }
fl.fl6_src = &saddr; fl.fl6_src = &saddr;
} else { } else {
fl.fl6_src = &np->saddr; fl.fl6_src = &np->saddr;
...@@ -177,7 +177,7 @@ int sctp_v6_get_dst_mtu(const sockaddr_storage_t *address) ...@@ -177,7 +177,7 @@ int sctp_v6_get_dst_mtu(const sockaddr_storage_t *address)
if (dst) { if (dst) {
dst_mtu = dst->pmtu; dst_mtu = dst->pmtu;
SCTP_DEBUG_PRINTK("sctp_v6_get_dst_mtu: " SCTP_DEBUG_PRINTK("sctp_v6_get_dst_mtu: "
"ip6_route_output: dev:%s pmtu:%d\n", "ip6_route_output: dev:%s pmtu:%d\n",
dst->dev->name, dst_mtu); dst->dev->name, dst_mtu);
dst_release(dst); dst_release(dst);
} else { } else {
...@@ -189,11 +189,85 @@ int sctp_v6_get_dst_mtu(const sockaddr_storage_t *address) ...@@ -189,11 +189,85 @@ int sctp_v6_get_dst_mtu(const sockaddr_storage_t *address)
return dst_mtu; return dst_mtu;
} }
/* Initialize a PF_INET6 socket msg_name. */
static void sctp_inet6_msgname(char *msgname, int *addr_len)
{
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)msgname;
sin6->sin6_family = AF_INET6;
sin6->sin6_flowinfo = 0;
sin6->sin6_scope_id = 0;
*addr_len = sizeof(struct sockaddr_in6);
}
/* Initialize a PF_INET msgname from a ulpevent. */
static void sctp_inet6_event_msgname(sctp_ulpevent_t *event, char *msgname, int *addrlen)
{
struct sockaddr_in6 *sin6, *sin6from;
if (msgname) {
sockaddr_storage_t *addr;
sctp_inet6_msgname(msgname, addrlen);
sin6 = (struct sockaddr_in6 *)msgname;
sin6->sin6_port = htons(event->asoc->peer.port);
addr = &event->asoc->peer.primary_addr;
/* Note: If we go to a common v6 format, this code
* will change.
*/
/* Map ipv4 address into v4-mapped-on-v6 address. */
if (AF_INET == addr->sa.sa_family) {
/* FIXME: Easy, but there was no way to test this
* yet.
*/
return;
}
sin6from = &event->asoc->peer.primary_addr.v6;
ipv6_addr_copy(&sin6->sin6_addr, &sin6from->sin6_addr);
}
}
/* Initialize a msg_name from an inbound skb. */
static void sctp_inet6_skb_msgname(struct sk_buff *skb, char *msgname,
int *addr_len)
{
struct sctphdr *sh;
struct sockaddr_in6 *sin6;
if (msgname) {
sctp_inet6_msgname(msgname, addr_len);
sin6 = (struct sockaddr_in6 *)msgname;
sh = (struct sctphdr *)skb->h.raw;
sin6->sin6_port = sh->source;
/* FIXME: Map ipv4 address into v4-mapped-on-v6 address. */
if (__constant_htons(ETH_P_IP) == skb->protocol) {
/* FIXME: Easy, but there was no way to test this
* yet.
*/
return;
}
/* Otherwise, just copy the v6 address. */
ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr);
if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
struct inet6_skb_parm *opt =
(struct inet6_skb_parm *) skb->cb;
sin6->sin6_scope_id = opt->iif;
}
}
}
static struct proto_ops inet6_seqpacket_ops = { static struct proto_ops inet6_seqpacket_ops = {
.family = PF_INET6, .family = PF_INET6,
.release = inet6_release, .release = inet6_release,
.bind = inet6_bind, .bind = inet6_bind,
.connect = inet_dgram_connect, .connect = inet_dgram_connect,
.socketpair = sock_no_socketpair, .socketpair = sock_no_socketpair,
.accept = inet_accept, .accept = inet_accept,
.getname = inet6_getname, .getname = inet6_getname,
...@@ -238,15 +312,22 @@ static sctp_func_t sctp_ipv6_specific = { ...@@ -238,15 +312,22 @@ static sctp_func_t sctp_ipv6_specific = {
.sa_family = AF_INET6, .sa_family = AF_INET6,
}; };
static sctp_pf_t sctp_pf_inet6_specific = {
.event_msgname = sctp_inet6_event_msgname,
.skb_msgname = sctp_inet6_skb_msgname,
};
/* Initialize IPv6 support and register with inet6 stack. */ /* Initialize IPv6 support and register with inet6 stack. */
int sctp_v6_init(void) int sctp_v6_init(void)
{ {
/* Add SCTPv6 to inetsw6 linked list. */ /* Add SCTPv6 to inetsw6 linked list. */
inet6_register_protosw(&sctpv6_protosw); inet6_register_protosw(&sctpv6_protosw);
/* Register inet6 protocol. */ /* Register inet6 protocol. */
inet6_add_protocol(&sctpv6_protocol); inet6_add_protocol(&sctpv6_protocol);
/* Register the SCTP specfic PF_INET6 functions. */
sctp_set_pf_specific(PF_INET6, &sctp_pf_inet6_specific);
/* Fill in address family info. */ /* Fill in address family info. */
INIT_LIST_HEAD(&sctp_ipv6_specific.list); INIT_LIST_HEAD(&sctp_ipv6_specific.list);
list_add_tail(&sctp_ipv6_specific.list, &sctp_proto.address_families); list_add_tail(&sctp_ipv6_specific.list, &sctp_proto.address_families);
......
...@@ -2,41 +2,41 @@ ...@@ -2,41 +2,41 @@
* Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc. * Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001 International Business Machines, Corp. * Copyright (c) 2001 International Business Machines, Corp.
* *
* This file is part of the SCTP kernel reference Implementation * This file is part of the SCTP kernel reference Implementation
* *
* These functions handle output processing. * These functions handle output processing.
* *
* The SCTP reference implementation is free software; * The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of * you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by * the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* The SCTP reference implementation is distributed in the hope that it * The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied * will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************ * ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to * along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330, * the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
* *
* Please send any bug reports or fixes you make to the * Please send any bug reports or fixes you make to the
* email address(es): * email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net> * lksctp developers <lksctp-developers@lists.sourceforge.net>
* *
* Or submit a bug report through the following website: * Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp * http://www.sf.net/projects/lksctp
* *
* Written or modified by: * Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org> * La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us> * Karl Knutson <karl@athena.chicago.il.us>
* Jon Grimm <jgrimm@austin.ibm.com> * Jon Grimm <jgrimm@austin.ibm.com>
* Sridhar Samudrala <sri@us.ibm.com> * Sridhar Samudrala <sri@us.ibm.com>
* *
* Any bugs reported given to us we will try to fix... any fixes shared will * Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release. * be incorporated into the next SCTP release.
*/ */
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/ipv6.h> #include <linux/ipv6.h>
#include <linux/init.h> #include <linux/init.h>
#include <net/inet_ecn.h> #include <net/inet_ecn.h>
#include <net/icmp.h> #include <net/icmp.h>
#ifndef TEST_FRAME #ifndef TEST_FRAME
...@@ -113,7 +113,7 @@ void sctp_packet_free(sctp_packet_t *packet) ...@@ -113,7 +113,7 @@ void sctp_packet_free(sctp_packet_t *packet)
{ {
sctp_chunk_t *chunk; sctp_chunk_t *chunk;
while (NULL != while (NULL !=
(chunk = (sctp_chunk_t *)skb_dequeue(&packet->chunks))) { (chunk = (sctp_chunk_t *)skb_dequeue(&packet->chunks))) {
sctp_free_chunk(chunk); sctp_free_chunk(chunk);
} }
...@@ -129,7 +129,8 @@ void sctp_packet_free(sctp_packet_t *packet) ...@@ -129,7 +129,8 @@ void sctp_packet_free(sctp_packet_t *packet)
* as it can fit in the packet, but any more data that does not fit in this * as it can fit in the packet, but any more data that does not fit in this
* packet can be sent only after receiving the COOKIE_ACK. * packet can be sent only after receiving the COOKIE_ACK.
*/ */
sctp_xmit_t sctp_packet_transmit_chunk(sctp_packet_t *packet, sctp_chunk_t *chunk) sctp_xmit_t sctp_packet_transmit_chunk(sctp_packet_t *packet,
sctp_chunk_t *chunk)
{ {
sctp_xmit_t retval; sctp_xmit_t retval;
int error = 0; int error = 0;
...@@ -181,8 +182,8 @@ sctp_xmit_t sctp_packet_append_chunk(sctp_packet_t *packet, sctp_chunk_t *chunk) ...@@ -181,8 +182,8 @@ sctp_xmit_t sctp_packet_append_chunk(sctp_packet_t *packet, sctp_chunk_t *chunk)
/* Both control chunks and data chunks with TSNs are /* Both control chunks and data chunks with TSNs are
* non-fragmentable. * non-fragmentable.
*/ */
int fragmentable = sctp_chunk_is_data(chunk) int fragmentable = sctp_chunk_is_data(chunk) &&
&& (!chunk->has_tsn); (!chunk->has_tsn);
if (packet_empty) { if (packet_empty) {
if (fragmentable) { if (fragmentable) {
retval = SCTP_XMIT_MUST_FRAG; retval = SCTP_XMIT_MUST_FRAG;
...@@ -221,10 +222,8 @@ sctp_xmit_t sctp_packet_append_chunk(sctp_packet_t *packet, sctp_chunk_t *chunk) ...@@ -221,10 +222,8 @@ sctp_xmit_t sctp_packet_append_chunk(sctp_packet_t *packet, sctp_chunk_t *chunk)
} }
/* It is OK to send this chunk. */ /* It is OK to send this chunk. */
skb_queue_tail(&packet->chunks, skb_queue_tail(&packet->chunks, (struct sk_buff *)chunk);
(struct sk_buff *)chunk);
packet->size += chunk_len; packet->size += chunk_len;
finish: finish:
return retval; return retval;
} }
...@@ -305,7 +304,7 @@ int sctp_packet_transmit(sctp_packet_t *packet) ...@@ -305,7 +304,7 @@ int sctp_packet_transmit(sctp_packet_t *packet)
*/ */
if ((1 == chunk->num_times_sent) && if ((1 == chunk->num_times_sent) &&
(!transport->rto_pending)) { (!transport->rto_pending)) {
chunk->rtt_in_progress = 1; chunk->rtt_in_progress = 1;
transport->rto_pending = 1; transport->rto_pending = 1;
} }
packet_has_data = 1; packet_has_data = 1;
...@@ -337,9 +336,9 @@ int sctp_packet_transmit(sctp_packet_t *packet) ...@@ -337,9 +336,9 @@ int sctp_packet_transmit(sctp_packet_t *packet)
} }
/* Build the SCTP header. */ /* Build the SCTP header. */
sh = (struct sctphdr *) skb_push(nskb, sizeof(struct sctphdr)); sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr));
sh->source = htons(packet->source_port); sh->source = htons(packet->source_port);
sh->dest = htons(packet->destination_port); sh->dest = htons(packet->destination_port);
/* From 6.8 Adler-32 Checksum Calculation: /* From 6.8 Adler-32 Checksum Calculation:
* After the packet is constructed (containing the SCTP common * After the packet is constructed (containing the SCTP common
...@@ -349,8 +348,8 @@ int sctp_packet_transmit(sctp_packet_t *packet) ...@@ -349,8 +348,8 @@ int sctp_packet_transmit(sctp_packet_t *packet)
* 1) Fill in the proper Verification Tag in the SCTP common * 1) Fill in the proper Verification Tag in the SCTP common
* header and initialize the checksum field to 0's. * header and initialize the checksum field to 0's.
*/ */
sh->vtag = htonl(packet->vtag); sh->vtag = htonl(packet->vtag);
sh->checksum = 0; sh->checksum = 0;
/* 2) Calculate the Adler-32 checksum of the whole packet, /* 2) Calculate the Adler-32 checksum of the whole packet,
* including the SCTP common header and all the * including the SCTP common header and all the
...@@ -467,7 +466,8 @@ static void sctp_packet_reset(sctp_packet_t *packet) ...@@ -467,7 +466,8 @@ static void sctp_packet_reset(sctp_packet_t *packet)
} }
/* This private function handles the specifics of appending DATA chunks. */ /* This private function handles the specifics of appending DATA chunks. */
static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet, sctp_chunk_t *chunk) static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet,
sctp_chunk_t *chunk)
{ {
sctp_xmit_t retval = SCTP_XMIT_OK; sctp_xmit_t retval = SCTP_XMIT_OK;
size_t datasize, rwnd, inflight; size_t datasize, rwnd, inflight;
...@@ -502,12 +502,13 @@ static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet, sctp_chunk_t * ...@@ -502,12 +502,13 @@ static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet, sctp_chunk_t *
} }
} }
/* sctpimpguide-05 2.14.2 D) When the time comes for the sender to /* sctpimpguide-05 2.14.2
* D) When the time comes for the sender to
* transmit new DATA chunks, the protocol parameter Max.Burst MUST * transmit new DATA chunks, the protocol parameter Max.Burst MUST
* first be applied to limit how many new DATA chunks may be sent. * first be applied to limit how many new DATA chunks may be sent.
* The limit is applied by adjusting cwnd as follows: * The limit is applied by adjusting cwnd as follows:
* if((flightsize + Max.Burst*MTU) < cwnd) * if ((flightsize + Max.Burst * MTU) < cwnd)
* cwnd = flightsize + Max.Burst*MTU * cwnd = flightsize + Max.Burst * MTU
*/ */
max_burst_bytes = transport->asoc->max_burst * transport->asoc->pmtu; max_burst_bytes = transport->asoc->max_burst * transport->asoc->pmtu;
if ((transport->flight_size + max_burst_bytes) < transport->cwnd) { if ((transport->flight_size + max_burst_bytes) < transport->cwnd) {
...@@ -516,11 +517,11 @@ static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet, sctp_chunk_t * ...@@ -516,11 +517,11 @@ static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet, sctp_chunk_t *
"transport: %p, cwnd: %d, " "transport: %p, cwnd: %d, "
"ssthresh: %d, flight_size: %d, " "ssthresh: %d, flight_size: %d, "
"pba: %d\n", "pba: %d\n",
__FUNCTION__, transport, __FUNCTION__, transport,
transport->cwnd, transport->cwnd,
transport->ssthresh, transport->ssthresh,
transport->flight_size, transport->flight_size,
transport->partial_bytes_acked); transport->partial_bytes_acked);
} }
/* RFC 2960 6.1 Transmission of DATA Chunks /* RFC 2960 6.1 Transmission of DATA Chunks
...@@ -552,7 +553,3 @@ static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet, sctp_chunk_t * ...@@ -552,7 +553,3 @@ static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet, sctp_chunk_t *
finish: finish:
return retval; return retval;
} }
...@@ -196,23 +196,14 @@ int sctp_push_outqueue(sctp_outqueue_t *q, sctp_chunk_t *chunk) ...@@ -196,23 +196,14 @@ int sctp_push_outqueue(sctp_outqueue_t *q, sctp_chunk_t *chunk)
return error; return error;
} }
/* Mark all the eligible packets on a transport for retransmission and force /* Mark all the eligible packets on a transport for retransmission. */
* one packet out. void sctp_retransmit_mark(sctp_outqueue_t *q, sctp_transport_t *transport,
*/ __u8 fast_retransmit)
void sctp_retransmit(sctp_outqueue_t *q, sctp_transport_t *transport,
__u8 fast_retransmit)
{ {
struct list_head *lchunk; struct list_head *lchunk;
sctp_chunk_t *chunk; sctp_chunk_t *chunk;
int error = 0;
struct list_head tlist; struct list_head tlist;
if (fast_retransmit) {
sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX);
} else {
sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_T3_RTX);
}
INIT_LIST_HEAD(&tlist); INIT_LIST_HEAD(&tlist);
while (!list_empty(&transport->transmitted)) { while (!list_empty(&transport->transmitted)) {
...@@ -224,7 +215,7 @@ void sctp_retransmit(sctp_outqueue_t *q, sctp_transport_t *transport, ...@@ -224,7 +215,7 @@ void sctp_retransmit(sctp_outqueue_t *q, sctp_transport_t *transport,
* should be added to the retransmit queue. If we are doing * should be added to the retransmit queue. If we are doing
* retransmission due to a timeout, only the chunks that are * retransmission due to a timeout, only the chunks that are
* not yet acked should be added to the retransmit queue. * not yet acked should be added to the retransmit queue.
*/ */
if ((fast_retransmit && !chunk->fast_retransmit) || if ((fast_retransmit && !chunk->fast_retransmit) ||
(!fast_retransmit && chunk->tsn_gap_acked)) { (!fast_retransmit && chunk->tsn_gap_acked)) {
list_add_tail(lchunk, &tlist); list_add_tail(lchunk, &tlist);
...@@ -276,7 +267,26 @@ void sctp_retransmit(sctp_outqueue_t *q, sctp_transport_t *transport, ...@@ -276,7 +267,26 @@ void sctp_retransmit(sctp_outqueue_t *q, sctp_transport_t *transport,
transport->flight_size, transport->flight_size,
transport->partial_bytes_acked); transport->partial_bytes_acked);
}
/* Mark all the eligible packets on a transport for retransmission and force
* one packet out.
*/
void sctp_retransmit(sctp_outqueue_t *q, sctp_transport_t *transport,
__u8 fast_retransmit)
{
int error = 0;
if (fast_retransmit) {
sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX);
} else {
sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_T3_RTX);
}
sctp_retransmit_mark(q, transport, fast_retransmit);
error = sctp_flush_outqueue(q, /* rtx_timeout */ 1); error = sctp_flush_outqueue(q, /* rtx_timeout */ 1);
if (error) if (error)
q->asoc->base.sk->err = -error; q->asoc->base.sk->err = -error;
} }
...@@ -327,7 +337,7 @@ static int sctp_flush_retran_queue(sctp_outqueue_t *q, sctp_packet_t *pkt, ...@@ -327,7 +337,7 @@ static int sctp_flush_retran_queue(sctp_outqueue_t *q, sctp_packet_t *pkt,
/* If a chunk has been tried for more than SCTP_DEF_MAX_SEND /* If a chunk has been tried for more than SCTP_DEF_MAX_SEND
* times, discard it, and check the empty flag of the outqueue. * times, discard it, and check the empty flag of the outqueue.
* *
* --xguo * --xguo
*/ */
if (chunk->snd_count > SCTP_DEF_MAX_SEND) { if (chunk->snd_count > SCTP_DEF_MAX_SEND) {
sctp_free_chunk(chunk); sctp_free_chunk(chunk);
...@@ -339,7 +349,7 @@ static int sctp_flush_retran_queue(sctp_outqueue_t *q, sctp_packet_t *pkt, ...@@ -339,7 +349,7 @@ static int sctp_flush_retran_queue(sctp_outqueue_t *q, sctp_packet_t *pkt,
switch (status) { switch (status) {
case SCTP_XMIT_PMTU_FULL: case SCTP_XMIT_PMTU_FULL:
/* Send this packet. */ /* Send this packet. */
if ((error = (*q->force_output)(pkt)) == 0) if ((error = (*q->force_output)(pkt)) == 0)
*start_timer = 1; *start_timer = 1;
...@@ -370,8 +380,7 @@ static int sctp_flush_retran_queue(sctp_outqueue_t *q, sctp_packet_t *pkt, ...@@ -370,8 +380,7 @@ static int sctp_flush_retran_queue(sctp_outqueue_t *q, sctp_packet_t *pkt,
/* The append was successful, so add this chunk to /* The append was successful, so add this chunk to
* the transmitted list. * the transmitted list.
*/ */
list_add_tail(lchunk, list_add_tail(lchunk, &transport->transmitted);
&transport->transmitted);
*start_timer = 1; *start_timer = 1;
q->empty = 0; q->empty = 0;
...@@ -389,8 +398,7 @@ static int sctp_flush_retran_queue(sctp_outqueue_t *q, sctp_packet_t *pkt, ...@@ -389,8 +398,7 @@ static int sctp_flush_retran_queue(sctp_outqueue_t *q, sctp_packet_t *pkt,
* chunk that is currently in the process of fragmentation. * chunk that is currently in the process of fragmentation.
*/ */
void sctp_xmit_frag(sctp_outqueue_t *q, struct sk_buff *pos, void sctp_xmit_frag(sctp_outqueue_t *q, struct sk_buff *pos,
sctp_packet_t *packet, sctp_packet_t *packet, sctp_chunk_t *frag, __u32 tsn)
sctp_chunk_t *frag, __u32 tsn)
{ {
sctp_transport_t *transport = packet->transport; sctp_transport_t *transport = packet->transport;
struct sk_buff_head *queue = &q->out; struct sk_buff_head *queue = &q->out;
...@@ -407,7 +415,7 @@ void sctp_xmit_frag(sctp_outqueue_t *q, struct sk_buff *pos, ...@@ -407,7 +415,7 @@ void sctp_xmit_frag(sctp_outqueue_t *q, struct sk_buff *pos,
if (!skb_queue_empty(queue)) { if (!skb_queue_empty(queue)) {
SCTP_DEBUG_PRINTK("sctp_xmit_frag: q not empty. " SCTP_DEBUG_PRINTK("sctp_xmit_frag: q not empty. "
"adding 0x%x to outqueue\n", "adding 0x%x to outqueue\n",
ntohl(frag->subh.data_hdr->tsn)); ntohl(frag->subh.data_hdr->tsn));
if (pos) { if (pos) {
skb_insert(pos, (struct sk_buff *) frag); skb_insert(pos, (struct sk_buff *) frag);
} else { } else {
...@@ -499,7 +507,8 @@ void sctp_xmit_fragmented_chunks(sctp_outqueue_t *q, sctp_packet_t *packet, ...@@ -499,7 +507,8 @@ void sctp_xmit_fragmented_chunks(sctp_outqueue_t *q, sctp_packet_t *packet,
* fragments. It returns the first fragment with the frag_list field holding * fragments. It returns the first fragment with the frag_list field holding
* the remaining fragments. * the remaining fragments.
*/ */
sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk, size_t max_frag_data_len) sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk,
size_t max_frag_data_len)
{ {
sctp_association_t *asoc = chunk->asoc; sctp_association_t *asoc = chunk->asoc;
void *data_ptr = chunk->subh.data_hdr; void *data_ptr = chunk->subh.data_hdr;
...@@ -519,7 +528,7 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk, size_t max_frag_data_len) ...@@ -519,7 +528,7 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk, size_t max_frag_data_len)
/* Make the first fragment. */ /* Make the first fragment. */
first_frag = sctp_make_datafrag(asoc, sinfo, max_frag_data_len, first_frag = sctp_make_datafrag(asoc, sinfo, max_frag_data_len,
data_ptr, SCTP_DATA_FIRST_FRAG, ssn); data_ptr, SCTP_DATA_FIRST_FRAG, ssn);
if (!first_frag) if (!first_frag)
goto err; goto err;
...@@ -533,11 +542,14 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk, size_t max_frag_data_len) ...@@ -533,11 +542,14 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk, size_t max_frag_data_len)
/* Make the middle fragments. */ /* Make the middle fragments. */
while (chunk_data_len > max_frag_data_len) { while (chunk_data_len > max_frag_data_len) {
frag = sctp_make_datafrag(asoc, sinfo, max_frag_data_len, frag = sctp_make_datafrag(asoc, sinfo, max_frag_data_len,
data_ptr, SCTP_DATA_MIDDLE_FRAG, ssn); data_ptr, SCTP_DATA_MIDDLE_FRAG,
ssn);
if (!frag) if (!frag)
goto err; goto err;
/* Add the middle fragment to the first fragment's frag_list. */ /* Add the middle fragment to the first fragment's
* frag_list.
*/
list_add_tail(&frag->frag_list, frag_list); list_add_tail(&frag->frag_list, frag_list);
chunk_data_len -= max_frag_data_len; chunk_data_len -= max_frag_data_len;
...@@ -641,7 +653,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout) ...@@ -641,7 +653,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
* chunk->transport, even it's inactive. * chunk->transport, even it's inactive.
*/ */
if (chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT) if (chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT)
new_transport = asoc->peer.active_path; new_transport = asoc->peer.active_path;
} }
/* Are we switching transports? /* Are we switching transports?
...@@ -674,7 +686,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout) ...@@ -674,7 +686,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
(void) (*q->build_output)(&singleton, chunk); (void) (*q->build_output)(&singleton, chunk);
error = (*q->force_output)(&singleton); error = (*q->force_output)(&singleton);
if (error < 0) if (error < 0)
return(error); return error;
break; break;
case SCTP_CID_ABORT: case SCTP_CID_ABORT:
...@@ -698,17 +710,17 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout) ...@@ -698,17 +710,17 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
default: default:
/* We built a chunk with an illegal type! */ /* We built a chunk with an illegal type! */
BUG(); BUG();
}; };
} }
/* Is it OK to send data chunks? */ /* Is it OK to send data chunks? */
switch (asoc->state) { switch (asoc->state) {
case SCTP_STATE_COOKIE_ECHOED: case SCTP_STATE_COOKIE_ECHOED:
/* Only allow bundling, if this packet has a COOKIE-ECHO /* Only allow bundling when this packet has a COOKIE-ECHO
* chunk. * chunk.
*/ */
if (packet && !packet->has_cookie_echo) if (!packet || !packet->has_cookie_echo)
break; break;
/* fallthru */ /* fallthru */
...@@ -748,6 +760,12 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout) ...@@ -748,6 +760,12 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
if (start_timer) if (start_timer)
sctp_transport_reset_timers(transport); sctp_transport_reset_timers(transport);
/* This can happen on COOKIE-ECHO resend. Only
* one chunk can get bundled with a COOKIE-ECHO.
*/
if (packet->has_cookie_echo)
goto sctp_flush_out;
} }
/* Finally, transmit new packets. */ /* Finally, transmit new packets. */
...@@ -809,12 +827,11 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout) ...@@ -809,12 +827,11 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
: "Illegal Chunk"); : "Illegal Chunk");
SCTP_DEBUG_PRINTK("TX TSN 0x%x skb->head " SCTP_DEBUG_PRINTK("TX TSN 0x%x skb->head "
"%p skb->users %d.\n", "%p skb->users %d.\n",
ntohl(chunk->subh.data_hdr->tsn), ntohl(chunk->subh.data_hdr->tsn),
chunk->skb ?chunk->skb->head : 0, chunk->skb ?chunk->skb->head : 0,
chunk->skb ? chunk->skb ?
atomic_read(&chunk->skb->users) : atomic_read(&chunk->skb->users) : -1);
-1);
/* Add the chunk to the packet. */ /* Add the chunk to the packet. */
status = (*q->build_output)(packet, chunk); status = (*q->build_output)(packet, chunk);
...@@ -826,8 +843,9 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout) ...@@ -826,8 +843,9 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
* the chunk back on the output queue. * the chunk back on the output queue.
*/ */
SCTP_DEBUG_PRINTK("sctp_flush_outqueue: could" SCTP_DEBUG_PRINTK("sctp_flush_outqueue: could"
"not transmit TSN: 0x%x, status: %d\n", "not transmit TSN: 0x%x, status: %d\n",
ntohl(chunk->subh.data_hdr->tsn), status); ntohl(chunk->subh.data_hdr->tsn),
status);
skb_queue_head(queue, (struct sk_buff *)chunk); skb_queue_head(queue, (struct sk_buff *)chunk);
goto sctp_flush_out; goto sctp_flush_out;
break; break;
...@@ -836,7 +854,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout) ...@@ -836,7 +854,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
sctp_chunk_t *frag; sctp_chunk_t *frag;
frag = sctp_fragment_chunk(chunk, frag = sctp_fragment_chunk(chunk,
packet->transport->asoc->frag_point); packet->transport->asoc->frag_point);
if (!frag) { if (!frag) {
/* We could not fragment due to out of /* We could not fragment due to out of
* memory condition. Free the original * memory condition. Free the original
...@@ -857,7 +875,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout) ...@@ -857,7 +875,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
default: default:
BUG(); BUG();
}; }
/* BUG: We assume that the (*q->force_output()) /* BUG: We assume that the (*q->force_output())
* call below will succeed all the time and add the * call below will succeed all the time and add the
...@@ -875,13 +893,19 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout) ...@@ -875,13 +893,19 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
sctp_transport_reset_timers(transport); sctp_transport_reset_timers(transport);
q->empty = 0; q->empty = 0;
/* Only let one DATA chunk get bundled with a
* COOKIE-ECHO chunk.
*/
if (packet->has_cookie_echo)
goto sctp_flush_out;
} }
break; break;
default: default:
/* Do nothing. */ /* Do nothing. */
break; break;
}; }
sctp_flush_out: sctp_flush_out:
/* Before returning, examine all the transports touched in /* Before returning, examine all the transports touched in
...@@ -901,7 +925,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout) ...@@ -901,7 +925,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
if (packet->size != SCTP_IP_OVERHEAD) if (packet->size != SCTP_IP_OVERHEAD)
error = (*q->force_output)(packet); error = (*q->force_output)(packet);
} }
return error; return error;
} }
...@@ -986,8 +1010,7 @@ int sctp_sack_outqueue(sctp_outqueue_t *q, sctp_sackhdr_t *sack) ...@@ -986,8 +1010,7 @@ int sctp_sack_outqueue(sctp_outqueue_t *q, sctp_sackhdr_t *sack)
ctsn = q->asoc->ctsn_ack_point; ctsn = q->asoc->ctsn_ack_point;
SCTP_DEBUG_PRINTK("%s: sack Cumulative TSN Ack is 0x%x.\n", SCTP_DEBUG_PRINTK("%s: sack Cumulative TSN Ack is 0x%x.\n",
__FUNCTION__, __FUNCTION__, sack_ctsn);
sack_ctsn);
SCTP_DEBUG_PRINTK("%s: Cumulative TSN Ack of association " SCTP_DEBUG_PRINTK("%s: Cumulative TSN Ack of association "
"%p is 0x%x.\n", __FUNCTION__, q->asoc, ctsn); "%p is 0x%x.\n", __FUNCTION__, q->asoc, ctsn);
...@@ -1114,8 +1137,9 @@ static void sctp_check_transmitted(sctp_outqueue_t *q, ...@@ -1114,8 +1137,9 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
* 6.3.1 C5) Karn's algorithm: RTT measurements * 6.3.1 C5) Karn's algorithm: RTT measurements
* MUST NOT be made using packets that were * MUST NOT be made using packets that were
* retransmitted (and thus for which it is * retransmitted (and thus for which it is
* ambiguous whether the reply was for the first * ambiguous whether the reply was for the
* instance of the packet or a later instance). * first instance of the packet or a later
* instance).
*/ */
if ((!tchunk->tsn_gap_acked) && if ((!tchunk->tsn_gap_acked) &&
(1 == tchunk->num_times_sent) && (1 == tchunk->num_times_sent) &&
...@@ -1150,15 +1174,15 @@ static void sctp_check_transmitted(sctp_outqueue_t *q, ...@@ -1150,15 +1174,15 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
* 'Stray DATA chunk(s)' record the highest TSN * 'Stray DATA chunk(s)' record the highest TSN
* reported as newly acknowledged, call this * reported as newly acknowledged, call this
* value 'HighestTSNinSack'. A newly * value 'HighestTSNinSack'. A newly
* acknowledged DATA chunk is one not previously * acknowledged DATA chunk is one not
* acknowledged in a SACK. * previously acknowledged in a SACK.
* *
* When the SCTP sender of data receives a SACK * When the SCTP sender of data receives a SACK
* chunk that acknowledges, for the first time, * chunk that acknowledges, for the first time,
* the receipt of a DATA chunk, all the still * the receipt of a DATA chunk, all the still
* unacknowledged DATA chunks whose TSN is older * unacknowledged DATA chunks whose TSN is
* than that newly acknowledged DATA chunk, are * older than that newly acknowledged DATA
* qualified as 'Stray DATA chunks'. * chunk, are qualified as 'Stray DATA chunks'.
*/ */
if (!tchunk->tsn_gap_acked) { if (!tchunk->tsn_gap_acked) {
tchunk->tsn_gap_acked = 1; tchunk->tsn_gap_acked = 1;
...@@ -1217,8 +1241,8 @@ static void sctp_check_transmitted(sctp_outqueue_t *q, ...@@ -1217,8 +1241,8 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
} else { } else {
if (tchunk->tsn_gap_acked) { if (tchunk->tsn_gap_acked) {
SCTP_DEBUG_PRINTK("%s: Receiver reneged on data " SCTP_DEBUG_PRINTK("%s: Receiver reneged on "
"TSN: 0x%x\n", "data TSN: 0x%x\n",
__FUNCTION__, __FUNCTION__,
tsn); tsn);
tchunk->tsn_gap_acked = 0; tchunk->tsn_gap_acked = 0;
...@@ -1227,10 +1251,11 @@ static void sctp_check_transmitted(sctp_outqueue_t *q, ...@@ -1227,10 +1251,11 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
/* RFC 2960 6.3.2 Retransmission Timer Rules /* RFC 2960 6.3.2 Retransmission Timer Rules
* *
* R4) Whenever a SACK is received missing a TSN * R4) Whenever a SACK is received missing a
* that was previously acknowledged via a Gap Ack * TSN that was previously acknowledged via a
* Block, start T3-rtx for the destination * Gap Ack Block, start T3-rtx for the
* address to which the DATA chunk was originally * destination address to which the DATA
* chunk was originally
* transmitted if it is not already running. * transmitted if it is not already running.
*/ */
restart_timer = 1; restart_timer = 1;
...@@ -1306,10 +1331,11 @@ static void sctp_check_transmitted(sctp_outqueue_t *q, ...@@ -1306,10 +1331,11 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
* active if it is not so marked. * active if it is not so marked.
*/ */
if (!transport->state.active) { if (!transport->state.active) {
sctp_assoc_control_transport(transport->asoc, sctp_assoc_control_transport(
transport, transport->asoc,
SCTP_TRANSPORT_UP, transport,
SCTP_RECEIVED_SACK); SCTP_TRANSPORT_UP,
SCTP_RECEIVED_SACK);
} }
sctp_transport_raise_cwnd(transport, sack_ctsn, sctp_transport_raise_cwnd(transport, sack_ctsn,
...@@ -1398,8 +1424,7 @@ static void sctp_check_transmitted(sctp_outqueue_t *q, ...@@ -1398,8 +1424,7 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
SCTP_DEBUG_PRINTK("%s: transport: %p, cwnd: %d, " SCTP_DEBUG_PRINTK("%s: transport: %p, cwnd: %d, "
"ssthresh: %d, flight_size: %d, pba: %d\n", "ssthresh: %d, flight_size: %d, pba: %d\n",
__FUNCTION__, __FUNCTION__, transport, transport->cwnd,
transport, transport->cwnd,
transport->ssthresh, transport->flight_size, transport->ssthresh, transport->flight_size,
transport->partial_bytes_acked); transport->partial_bytes_acked);
} }
......
/* SCTP kernel reference Implementation /* SCTP kernel reference Implementation
* Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc. * Copyright (c) 1999-2001 Motorola, Inc.
* *
* This file is part of the SCTP kernel reference Implementation * This file is part of the SCTP kernel reference Implementation
* *
* These functions implement the SCTP primitive functions from Section 10. * These functions implement the SCTP primitive functions from Section 10.
* *
* Note that the descriptions from the specification are USER level * Note that the descriptions from the specification are USER level
* functions--this file is the functions which populate the struct proto * functions--this file is the functions which populate the struct proto
* for SCTP which is the BOTTOM of the sockets interface. * for SCTP which is the BOTTOM of the sockets interface.
* *
* The SCTP reference implementation is free software; * The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of * you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by * the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* The SCTP reference implementation is distributed in the hope that it * The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied * will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************ * ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to * along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330, * the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
* *
* Please send any bug reports or fixes you make to the * Please send any bug reports or fixes you make to the
* email address(es): * email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net> * lksctp developers <lksctp-developers@lists.sourceforge.net>
* *
* Or submit a bug report through the following website: * Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp * http://www.sf.net/projects/lksctp
* *
* Written or modified by: * Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org> * La Monte H.P. Yarroll <piggy@acm.org>
* Narasimha Budihal <narasimha@refcode.org> * Narasimha Budihal <narasimha@refcode.org>
* Karl Knutson <karl@athena.chicago.il.us> * Karl Knutson <karl@athena.chicago.il.us>
* *
* Any bugs reported given to us we will try to fix... any fixes shared will * Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release. * be incorporated into the next SCTP release.
*/ */
......
...@@ -66,6 +66,9 @@ struct proc_dir_entry *proc_net_sctp; ...@@ -66,6 +66,9 @@ struct proc_dir_entry *proc_net_sctp;
*/ */
static struct socket *sctp_ctl_socket; static struct socket *sctp_ctl_socket;
static sctp_pf_t *sctp_pf_inet6_specific;
static sctp_pf_t *sctp_pf_inet_specific;
extern struct net_proto_family inet_family_ops; extern struct net_proto_family inet_family_ops;
/* Return the address of the control sock. */ /* Return the address of the control sock. */
...@@ -91,7 +94,7 @@ void sctp_proc_init(void) ...@@ -91,7 +94,7 @@ void sctp_proc_init(void)
void sctp_proc_exit(void) void sctp_proc_exit(void)
{ {
if (proc_net_sctp) { if (proc_net_sctp) {
proc_net_sctp= NULL; proc_net_sctp = NULL;
remove_proc_entry("net/sctp", 0); remove_proc_entry("net/sctp", 0);
} }
} }
...@@ -135,7 +138,8 @@ static inline void sctp_v4_get_local_addr_list(sctp_protocol_t *proto, ...@@ -135,7 +138,8 @@ static inline void sctp_v4_get_local_addr_list(sctp_protocol_t *proto,
* the protocol structure. * the protocol structure.
* FIXME: Make this an address family function. * FIXME: Make this an address family function.
*/ */
static inline void sctp_v6_get_local_addr_list(sctp_protocol_t *proto, struct net_device *dev) static inline void sctp_v6_get_local_addr_list(sctp_protocol_t *proto,
struct net_device *dev)
{ {
#ifdef SCTP_V6_SUPPORT #ifdef SCTP_V6_SUPPORT
/* FIXME: The testframe doesn't support this function. */ /* FIXME: The testframe doesn't support this function. */
...@@ -227,8 +231,8 @@ int sctp_copy_local_addr_list(sctp_protocol_t *proto, sctp_bind_addr_t *bp, ...@@ -227,8 +231,8 @@ int sctp_copy_local_addr_list(sctp_protocol_t *proto, sctp_bind_addr_t *bp,
long flags __attribute__ ((unused)); long flags __attribute__ ((unused));
sctp_spin_lock_irqsave(&proto->local_addr_lock, flags); sctp_spin_lock_irqsave(&proto->local_addr_lock, flags);
list_for_each(pos, &proto->local_addr_list) { list_for_each(pos, &proto->local_addr_list) {
addr = list_entry(pos, struct sockaddr_storage_list, list); addr = list_entry(pos, struct sockaddr_storage_list, list);
if (sctp_in_scope(&addr->a, scope)) { if (sctp_in_scope(&addr->a, scope)) {
/* Now that the address is in scope, check to see if /* Now that the address is in scope, check to see if
* the address type is really supported by the local * the address type is really supported by the local
...@@ -239,8 +243,7 @@ int sctp_copy_local_addr_list(sctp_protocol_t *proto, sctp_bind_addr_t *bp, ...@@ -239,8 +243,7 @@ int sctp_copy_local_addr_list(sctp_protocol_t *proto, sctp_bind_addr_t *bp,
(((AF_INET6 == addr->a.sa.sa_family) && (((AF_INET6 == addr->a.sa.sa_family) &&
(copy_flags & SCTP_ADDR6_ALLOWED) && (copy_flags & SCTP_ADDR6_ALLOWED) &&
(copy_flags & SCTP_ADDR6_PEERSUPP)))) { (copy_flags & SCTP_ADDR6_PEERSUPP)))) {
error = sctp_add_bind_addr(bp, error = sctp_add_bind_addr(bp, &addr->a,
&addr->a,
priority); priority);
if (error) if (error)
goto end_copy; goto end_copy;
...@@ -286,7 +289,8 @@ int sctp_v4_get_dst_mtu(const sockaddr_storage_t *address) ...@@ -286,7 +289,8 @@ int sctp_v4_get_dst_mtu(const sockaddr_storage_t *address)
/* Event handler for inet device events. /* Event handler for inet device events.
* Basically, whenever there is an event, we re-build our local address list. * Basically, whenever there is an event, we re-build our local address list.
*/ */
static int sctp_netdev_event(struct notifier_block *this, unsigned long event, void *ptr) static int sctp_netdev_event(struct notifier_block *this, unsigned long event,
void *ptr)
{ {
long flags __attribute__ ((unused)); long flags __attribute__ ((unused));
...@@ -312,8 +316,8 @@ int sctp_ctl_sock_init(void) ...@@ -312,8 +316,8 @@ int sctp_ctl_sock_init(void)
err = sock_create(family, SOCK_SEQPACKET, IPPROTO_SCTP, err = sock_create(family, SOCK_SEQPACKET, IPPROTO_SCTP,
&sctp_ctl_socket); &sctp_ctl_socket);
if (err < 0) { if (err < 0) {
printk(KERN_ERR printk(KERN_ERR
"SCTP: Failed to create the SCTP control socket.\n"); "SCTP: Failed to create the SCTP control socket.\n");
return err; return err;
} }
sctp_ctl_socket->sk->allocation = GFP_ATOMIC; sctp_ctl_socket->sk->allocation = GFP_ATOMIC;
...@@ -347,6 +351,52 @@ sctp_func_t *sctp_get_af_specific(const sockaddr_storage_t *address) ...@@ -347,6 +351,52 @@ sctp_func_t *sctp_get_af_specific(const sockaddr_storage_t *address)
return retval; return retval;
} }
/* Common code to initialize a AF_INET msg_name. */
static void sctp_inet_msgname(char *msgname, int *addr_len)
{
struct sockaddr_in *sin;
sin = (struct sockaddr_in *)msgname;
*addr_len = sizeof(struct sockaddr_in);
sin->sin_family = AF_INET;
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
}
/* Copy the primary address of the peer primary address as the msg_name. */
static void sctp_inet_event_msgname(sctp_ulpevent_t *event, char *msgname, int *addr_len)
{
struct sockaddr_in *sin, *sinfrom;
if (msgname) {
sctp_inet_msgname(msgname, addr_len);
sin = (struct sockaddr_in *)msgname;
sinfrom = &event->asoc->peer.primary_addr.v4;
sin->sin_port = htons(event->asoc->peer.port);
sin->sin_addr.s_addr = sinfrom->sin_addr.s_addr;
}
}
/* Initialize and copy out a msgname from an inbound skb. */
static void sctp_inet_skb_msgname(struct sk_buff *skb, char *msgname, int *addr_len)
{
struct sctphdr *sh;
struct sockaddr_in *sin;
if (msgname) {
sctp_inet_msgname(msgname, addr_len);
sin = (struct sockaddr_in *)msgname;
sh = (struct sctphdr *)skb->h.raw;
sin->sin_port = sh->source;
sin->sin_addr.s_addr = skb->nh.iph->saddr;
}
}
static sctp_pf_t sctp_pf_inet = {
.event_msgname = sctp_inet_event_msgname,
.skb_msgname = sctp_inet_skb_msgname,
};
/* Registration for netdev events. */ /* Registration for netdev events. */
struct notifier_block sctp_netdev_notifier = { struct notifier_block sctp_netdev_notifier = {
.notifier_call = sctp_netdev_event, .notifier_call = sctp_netdev_event,
...@@ -403,6 +453,34 @@ sctp_func_t sctp_ipv4_specific = { ...@@ -403,6 +453,34 @@ sctp_func_t sctp_ipv4_specific = {
.sa_family = AF_INET, .sa_family = AF_INET,
}; };
sctp_pf_t *sctp_get_pf_specific(int family) {
switch (family) {
case PF_INET:
return sctp_pf_inet_specific;
case PF_INET6:
return sctp_pf_inet6_specific;
default:
return NULL;
}
}
/* Set the PF specific function table. */
void sctp_set_pf_specific(int family, sctp_pf_t *pf)
{
switch (family) {
case PF_INET:
sctp_pf_inet_specific = pf;
break;
case PF_INET6:
sctp_pf_inet6_specific = pf;
break;
default:
BUG();
break;
}
}
/* Initialize the universe into something sensible. */ /* Initialize the universe into something sensible. */
int sctp_init(void) int sctp_init(void)
{ {
...@@ -421,9 +499,11 @@ int sctp_init(void) ...@@ -421,9 +499,11 @@ int sctp_init(void)
/* Initialize object count debugging. */ /* Initialize object count debugging. */
sctp_dbg_objcnt_init(); sctp_dbg_objcnt_init();
/* Initialize the SCTP specific PF functions. */
sctp_set_pf_specific(PF_INET, &sctp_pf_inet);
/* /*
* 14. Suggested SCTP Protocol Parameter Values * 14. Suggested SCTP Protocol Parameter Values
*/ */
/* The following protocol parameters are RECOMMENDED: */ /* The following protocol parameters are RECOMMENDED: */
/* RTO.Initial - 3 seconds */ /* RTO.Initial - 3 seconds */
sctp_proto.rto_initial = SCTP_RTO_INITIAL; sctp_proto.rto_initial = SCTP_RTO_INITIAL;
...@@ -468,7 +548,7 @@ int sctp_init(void) ...@@ -468,7 +548,7 @@ int sctp_init(void)
sctp_proto.assoc_hashbucket = (sctp_hashbucket_t *) sctp_proto.assoc_hashbucket = (sctp_hashbucket_t *)
kmalloc(4096 * sizeof(sctp_hashbucket_t), GFP_KERNEL); kmalloc(4096 * sizeof(sctp_hashbucket_t), GFP_KERNEL);
if (!sctp_proto.assoc_hashbucket) { if (!sctp_proto.assoc_hashbucket) {
printk (KERN_ERR "SCTP: Failed association hash alloc.\n"); printk(KERN_ERR "SCTP: Failed association hash alloc.\n");
status = -ENOMEM; status = -ENOMEM;
goto err_ahash_alloc; goto err_ahash_alloc;
} }
...@@ -482,7 +562,7 @@ int sctp_init(void) ...@@ -482,7 +562,7 @@ int sctp_init(void)
sctp_proto.ep_hashbucket = (sctp_hashbucket_t *) sctp_proto.ep_hashbucket = (sctp_hashbucket_t *)
kmalloc(64 * sizeof(sctp_hashbucket_t), GFP_KERNEL); kmalloc(64 * sizeof(sctp_hashbucket_t), GFP_KERNEL);
if (!sctp_proto.ep_hashbucket) { if (!sctp_proto.ep_hashbucket) {
printk (KERN_ERR "SCTP: Failed endpoint_hash alloc.\n"); printk(KERN_ERR "SCTP: Failed endpoint_hash alloc.\n");
status = -ENOMEM; status = -ENOMEM;
goto err_ehash_alloc; goto err_ehash_alloc;
} }
...@@ -497,7 +577,7 @@ int sctp_init(void) ...@@ -497,7 +577,7 @@ int sctp_init(void)
sctp_proto.port_hashtable = (sctp_bind_hashbucket_t *) sctp_proto.port_hashtable = (sctp_bind_hashbucket_t *)
kmalloc(4096 * sizeof(sctp_bind_hashbucket_t), GFP_KERNEL); kmalloc(4096 * sizeof(sctp_bind_hashbucket_t), GFP_KERNEL);
if (!sctp_proto.port_hashtable) { if (!sctp_proto.port_hashtable) {
printk (KERN_ERR "SCTP: Failed bind hash alloc."); printk(KERN_ERR "SCTP: Failed bind hash alloc.");
status = -ENOMEM; status = -ENOMEM;
goto err_bhash_alloc; goto err_bhash_alloc;
} }
......
...@@ -9,36 +9,36 @@ ...@@ -9,36 +9,36 @@
* This file includes part of the implementation of the add-IP extension, * This file includes part of the implementation of the add-IP extension,
* based on <draft-ietf-tsvwg-addip-sctp-02.txt> June 29, 2001, * based on <draft-ietf-tsvwg-addip-sctp-02.txt> June 29, 2001,
* for the SCTP kernel reference Implementation. * for the SCTP kernel reference Implementation.
* *
* These functions work with the state functions in sctp_sm_statefuns.c * These functions work with the state functions in sctp_sm_statefuns.c
* to implement the state operations. These functions implement the * to implement the state operations. These functions implement the
* steps which require modifying existing data structures. * steps which require modifying existing data structures.
* *
* The SCTP reference implementation is free software; * The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of * you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by * the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* The SCTP reference implementation is distributed in the hope that it * The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied * will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************ * ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to * along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330, * the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
* *
* Please send any bug reports or fixes you make to the * Please send any bug reports or fixes you make to the
* email address(es): * email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net> * lksctp developers <lksctp-developers@lists.sourceforge.net>
* *
* Or submit a bug report through the following website: * Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp * http://www.sf.net/projects/lksctp
* *
* Written or modified by: * Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org> * La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us> * Karl Knutson <karl@athena.chicago.il.us>
* C. Robin <chris@hundredacre.ac.uk> * C. Robin <chris@hundredacre.ac.uk>
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
* support any address type. * support any address type.
*/ */
static const sctp_supported_addrs_param_t sat_param = { static const sctp_supported_addrs_param_t sat_param = {
{ {
SCTP_PARAM_SUPPORTED_ADDRESS_TYPES, SCTP_PARAM_SUPPORTED_ADDRESS_TYPES,
__constant_htons(SCTP_SAT_LEN), __constant_htons(SCTP_SAT_LEN),
}, },
...@@ -204,7 +204,7 @@ sctp_chunk_t *sctp_make_init(const sctp_association_t *asoc, ...@@ -204,7 +204,7 @@ sctp_chunk_t *sctp_make_init(const sctp_association_t *asoc,
* PLEASE DO NOT FIXME [This version does not support Host Name.] * PLEASE DO NOT FIXME [This version does not support Host Name.]
*/ */
retval = sctp_make_chunk(asoc, SCTP_CID_INIT, 0, chunksize); retval = sctp_make_chunk(asoc, SCTP_CID_INIT, 0, chunksize);
if (!retval) if (!retval)
goto nodata; goto nodata;
...@@ -1204,7 +1204,7 @@ sctp_association_t *sctp_make_temp_asoc(const sctp_endpoint_t *ep, ...@@ -1204,7 +1204,7 @@ sctp_association_t *sctp_make_temp_asoc(const sctp_endpoint_t *ep,
case 6: case 6:
asoc->c.peer_addr.v6.sin6_family = AF_INET6; asoc->c.peer_addr.v6.sin6_family = AF_INET6;
asoc->c.peer_addr.v6.sin6_port asoc->c.peer_addr.v6.sin6_port
= ntohs(chunk->sctp_hdr->source); = ntohs(chunk->sctp_hdr->source);
asoc->c.peer_addr.v6.sin6_flowinfo = 0; /* BUG BUG BUG */ asoc->c.peer_addr.v6.sin6_flowinfo = 0; /* BUG BUG BUG */
asoc->c.peer_addr.v6.sin6_addr = chunk->skb->nh.ipv6h->saddr; asoc->c.peer_addr.v6.sin6_addr = chunk->skb->nh.ipv6h->saddr;
...@@ -1245,7 +1245,7 @@ sctp_cookie_param_t *sctp_pack_cookie(const sctp_endpoint_t *ep, ...@@ -1245,7 +1245,7 @@ sctp_cookie_param_t *sctp_pack_cookie(const sctp_endpoint_t *ep,
* functions simpler to write. * functions simpler to write.
*/ */
if (bodysize % SCTP_COOKIE_MULTIPLE) if (bodysize % SCTP_COOKIE_MULTIPLE)
bodysize += SCTP_COOKIE_MULTIPLE bodysize += SCTP_COOKIE_MULTIPLE
- (bodysize % SCTP_COOKIE_MULTIPLE); - (bodysize % SCTP_COOKIE_MULTIPLE);
*cookie_len = headersize + bodysize; *cookie_len = headersize + bodysize;
...@@ -1418,6 +1418,7 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid, ...@@ -1418,6 +1418,7 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
__u8 *end; __u8 *end;
sctp_transport_t *transport; sctp_transport_t *transport;
struct list_head *pos, *temp; struct list_head *pos, *temp;
char *cookie;
/* We must include the address that the INIT packet came from. /* We must include the address that the INIT packet came from.
* This is the only address that matters for an INIT packet. * This is the only address that matters for an INIT packet.
...@@ -1437,7 +1438,7 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid, ...@@ -1437,7 +1438,7 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
for (param.v = peer_init->init_hdr.params; for (param.v = peer_init->init_hdr.params;
param.v < end; param.v < end;
param.v += WORD_ROUND(ntohs(param.p->length))) { param.v += WORD_ROUND(ntohs(param.p->length))) {
if (!sctp_process_param(asoc, param, peer_addr, cid, if (!sctp_process_param(asoc, param, peer_addr, cid,
priority)) priority))
goto clean_up; goto clean_up;
} }
...@@ -1461,7 +1462,7 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid, ...@@ -1461,7 +1462,7 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
*/ */
if (asoc->c.sinit_num_ostreams > if (asoc->c.sinit_num_ostreams >
ntohs(peer_init->init_hdr.num_inbound_streams)) { ntohs(peer_init->init_hdr.num_inbound_streams)) {
asoc->c.sinit_num_ostreams = asoc->c.sinit_num_ostreams =
ntohs(peer_init->init_hdr.num_inbound_streams); ntohs(peer_init->init_hdr.num_inbound_streams);
} }
...@@ -1471,6 +1472,15 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid, ...@@ -1471,6 +1472,15 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
/* Peer Rwnd : Current calculated value of the peer's rwnd. */ /* Peer Rwnd : Current calculated value of the peer's rwnd. */
asoc->peer.rwnd = asoc->peer.i.a_rwnd; asoc->peer.rwnd = asoc->peer.i.a_rwnd;
/* Copy cookie in case we need to resend COOKIE-ECHO. */
cookie = asoc->peer.cookie;
if (cookie) {
asoc->peer.cookie = kmalloc(asoc->peer.cookie_len, priority);
if (!asoc->peer.cookie)
goto clean_up;
memcpy(asoc->peer.cookie, cookie, asoc->peer.cookie_len);
}
/* RFC 2960 7.2.1 The initial value of ssthresh MAY be arbitrarily /* RFC 2960 7.2.1 The initial value of ssthresh MAY be arbitrarily
* high (for example, implementations MAY use the size of the receiver * high (for example, implementations MAY use the size of the receiver
* advertised window). * advertised window).
...@@ -1560,7 +1570,7 @@ int sctp_process_param(sctp_association_t *asoc, sctpParam_t param, ...@@ -1560,7 +1570,7 @@ int sctp_process_param(sctp_association_t *asoc, sctpParam_t param,
break; break;
case SCTP_PARAM_HOST_NAME_ADDRESS: case SCTP_PARAM_HOST_NAME_ADDRESS:
SCTP_DEBUG_PRINTK("unimplmented SCTP_HOST_NAME_ADDRESS\n"); SCTP_DEBUG_PRINTK("unimplemented SCTP_HOST_NAME_ADDRESS\n");
break; break;
case SCTP_PARAM_SUPPORTED_ADDRESS_TYPES: case SCTP_PARAM_SUPPORTED_ADDRESS_TYPES:
...@@ -1595,13 +1605,12 @@ int sctp_process_param(sctp_association_t *asoc, sctpParam_t param, ...@@ -1595,13 +1605,12 @@ int sctp_process_param(sctp_association_t *asoc, sctpParam_t param,
case SCTP_PARAM_STATE_COOKIE: case SCTP_PARAM_STATE_COOKIE:
asoc->peer.cookie_len = asoc->peer.cookie_len =
ntohs(param.p->length) - ntohs(param.p->length) - sizeof(sctp_paramhdr_t);
sizeof(sctp_paramhdr_t);
asoc->peer.cookie = param.cookie->body; asoc->peer.cookie = param.cookie->body;
break; break;
case SCTP_PARAM_HEATBEAT_INFO: case SCTP_PARAM_HEATBEAT_INFO:
SCTP_DEBUG_PRINTK("unimplmented " SCTP_DEBUG_PRINTK("unimplemented "
"SCTP_PARAM_HEATBEAT_INFO\n"); "SCTP_PARAM_HEATBEAT_INFO\n");
break; break;
......
/* SCTP kernel reference Implementation /* SCTP kernel reference Implementation
* Copyright (c) 1999 Cisco, Inc. * Copyright (c) 1999 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc. * Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001-2002 International Business Machines Corp. * Copyright (c) 2001-2002 International Business Machines Corp.
* *
* This file is part of the SCTP kernel reference Implementation * This file is part of the SCTP kernel reference Implementation
* *
* These functions work with the state functions in sctp_sm_statefuns.c * These functions work with the state functions in sctp_sm_statefuns.c
* to implement that state operations. These functions implement the * to implement that state operations. These functions implement the
* steps which require modifying existing data structures. * steps which require modifying existing data structures.
* *
* The SCTP reference implementation is free software; * The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of * you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by * the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* The SCTP reference implementation is distributed in the hope that it * The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied * will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************ * ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to * along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330, * the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
* *
* Please send any bug reports or fixes you make to the * Please send any bug reports or fixes you make to the
* email address(es): * email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net> * lksctp developers <lksctp-developers@lists.sourceforge.net>
* *
* Or submit a bug report through the following website: * Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp * http://www.sf.net/projects/lksctp
* *
* Written or modified by: * Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org> * La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us> * Karl Knutson <karl@athena.chicago.il.us>
* Jon Grimm <jgrimm@austin.ibm.com> * Jon Grimm <jgrimm@austin.ibm.com>
...@@ -119,7 +119,7 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype, ...@@ -119,7 +119,7 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
int priority) int priority)
{ {
sctp_cmd_seq_t commands; sctp_cmd_seq_t commands;
sctp_sm_table_entry_t *state_fn; sctp_sm_table_entry_t *state_fn;
sctp_disposition_t status; sctp_disposition_t status;
int error = 0; int error = 0;
typedef const char *(printfn_t)(sctp_subtype_t); typedef const char *(printfn_t)(sctp_subtype_t);
...@@ -253,6 +253,7 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype, ...@@ -253,6 +253,7 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
sctp_chunk_t *new_obj; sctp_chunk_t *new_obj;
sctp_chunk_t *chunk; sctp_chunk_t *chunk;
sctp_packet_t *packet; sctp_packet_t *packet;
struct list_head *pos;
struct timer_list *timer; struct timer_list *timer;
unsigned long timeout; unsigned long timeout;
sctp_transport_t *t; sctp_transport_t *t;
...@@ -336,9 +337,8 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype, ...@@ -336,9 +337,8 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
case SCTP_CMD_PEER_INIT: case SCTP_CMD_PEER_INIT:
/* Process a unified INIT from the peer. */ /* Process a unified INIT from the peer. */
sctp_cmd_process_init(commands, sctp_cmd_process_init(commands, asoc, chunk,
asoc, chunk, command->obj.ptr, command->obj.ptr, priority);
priority);
break; break;
case SCTP_CMD_GEN_COOKIE_ECHO: case SCTP_CMD_GEN_COOKIE_ECHO:
...@@ -462,6 +462,7 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype, ...@@ -462,6 +462,7 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
break; break;
case SCTP_CMD_INIT_RESTART: case SCTP_CMD_INIT_RESTART:
/* Do the needed accounting and updates /* Do the needed accounting and updates
* associated with restarting an initialization * associated with restarting an initialization
* timer. * timer.
...@@ -474,6 +475,15 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype, ...@@ -474,6 +475,15 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
asoc->max_init_timeo; asoc->max_init_timeo;
} }
/* If we've sent any data bundled with
* COOKIE-ECHO we need to resend.
*/
list_for_each(pos, &asoc->peer.transport_addr_list) {
t = list_entry(pos, sctp_transport_t,
transports);
sctp_retransmit_mark(&asoc->outqueue, t, 0);
}
sctp_add_cmd_sf(commands, sctp_add_cmd_sf(commands,
SCTP_CMD_TIMER_RESTART, SCTP_CMD_TIMER_RESTART,
SCTP_TO(command->obj.to)); SCTP_TO(command->obj.to));
...@@ -602,7 +612,7 @@ static sctp_chunk_t *sctp_do_ecn_ecne_work(sctp_association_t *asoc, ...@@ -602,7 +612,7 @@ static sctp_chunk_t *sctp_do_ecn_ecne_work(sctp_association_t *asoc,
{ {
sctp_chunk_t *repl; sctp_chunk_t *repl;
sctp_transport_t *transport; sctp_transport_t *transport;
/* Our previously transmitted packet ran into some congestion /* Our previously transmitted packet ran into some congestion
* so we should take action by reducing cwnd and ssthresh * so we should take action by reducing cwnd and ssthresh
* and then ACK our peer that we we've done so by * and then ACK our peer that we we've done so by
...@@ -716,7 +726,7 @@ int sctp_gen_sack(sctp_association_t *asoc, int force, sctp_cmd_seq_t *commands) ...@@ -716,7 +726,7 @@ int sctp_gen_sack(sctp_association_t *asoc, int force, sctp_cmd_seq_t *commands)
error = sctp_push_outqueue(&asoc->outqueue, sack); error = sctp_push_outqueue(&asoc->outqueue, sack);
/* Stop the SACK timer. */ /* Stop the SACK timer. */
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
} }
...@@ -785,7 +795,7 @@ void sctp_generate_t3_rtx_event(unsigned long peer) ...@@ -785,7 +795,7 @@ void sctp_generate_t3_rtx_event(unsigned long peer)
if (!mod_timer(&transport->T3_rtx_timer, jiffies + (HZ/20))) if (!mod_timer(&transport->T3_rtx_timer, jiffies + (HZ/20)))
sctp_transport_hold(transport); sctp_transport_hold(transport);
goto out_unlock; goto out_unlock;
} }
/* Is this transport really dead and just waiting around for /* Is this transport really dead and just waiting around for
* the timer to let go of the reference? * the timer to let go of the reference?
...@@ -867,6 +877,14 @@ void sctp_generate_t2_shutdown_event(unsigned long data) ...@@ -867,6 +877,14 @@ void sctp_generate_t2_shutdown_event(unsigned long data)
sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_T2_SHUTDOWN); sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_T2_SHUTDOWN);
} }
void sctp_generate_t5_shutdown_guard_event(unsigned long data)
{
sctp_association_t *asoc = (sctp_association_t *)data;
sctp_generate_timeout_event(asoc,
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD);
} /* sctp_generate_t5_shutdown_guard_event() */
void sctp_generate_autoclose_event(unsigned long data) void sctp_generate_autoclose_event(unsigned long data)
{ {
sctp_association_t *asoc = (sctp_association_t *) data; sctp_association_t *asoc = (sctp_association_t *) data;
...@@ -890,7 +908,7 @@ void sctp_generate_heartbeat_event(unsigned long data) ...@@ -890,7 +908,7 @@ void sctp_generate_heartbeat_event(unsigned long data)
if (!mod_timer(&transport->hb_timer, jiffies + (HZ/20))) if (!mod_timer(&transport->hb_timer, jiffies + (HZ/20)))
sctp_transport_hold(transport); sctp_transport_hold(transport);
goto out_unlock; goto out_unlock;
} }
/* Is this structure just waiting around for us to actually /* Is this structure just waiting around for us to actually
* get destroyed? * get destroyed?
...@@ -932,6 +950,7 @@ sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = { ...@@ -932,6 +950,7 @@ sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = {
sctp_generate_t2_shutdown_event, sctp_generate_t2_shutdown_event,
NULL, NULL,
NULL, NULL,
sctp_generate_t5_shutdown_guard_event,
sctp_generate_heartbeat_event, sctp_generate_heartbeat_event,
sctp_generate_sack_event, sctp_generate_sack_event,
sctp_generate_autoclose_event, sctp_generate_autoclose_event,
...@@ -1023,6 +1042,9 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands, ...@@ -1023,6 +1042,9 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands,
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
SCTP_ULPEVENT(event)); SCTP_ULPEVENT(event));
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
SCTP_STATE(SCTP_STATE_CLOSED));
/* FIXME: We need to handle data that could not be sent or was not /* FIXME: We need to handle data that could not be sent or was not
* acked, if the user has enabled SEND_FAILED notifications. * acked, if the user has enabled SEND_FAILED notifications.
*/ */
......
...@@ -5,36 +5,36 @@ ...@@ -5,36 +5,36 @@
* Copyright (c) 2002 Nokia Corp. * Copyright (c) 2002 Nokia Corp.
* *
* This file is part of the SCTP kernel reference Implementation * This file is part of the SCTP kernel reference Implementation
* *
* This is part of the SCTP Linux Kernel Reference Implementation. * This is part of the SCTP Linux Kernel Reference Implementation.
* *
* These are the state functions for the state machine. * These are the state functions for the state machine.
* *
* The SCTP reference implementation is free software; * The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of * you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by * the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* The SCTP reference implementation is distributed in the hope that it * The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied * will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************ * ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to * along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330, * the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
* *
* Please send any bug reports or fixes you make to the * Please send any bug reports or fixes you make to the
* email address(es): * email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net> * lksctp developers <lksctp-developers@lists.sourceforge.net>
* *
* Or submit a bug report through the following website: * Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp * http://www.sf.net/projects/lksctp
* *
* Written or modified by: * Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org> * La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us> * Karl Knutson <karl@athena.chicago.il.us>
* Mathew Kotowsky <kotowsky@sctp.org> * Mathew Kotowsky <kotowsky@sctp.org>
...@@ -149,6 +149,9 @@ sctp_disposition_t sctp_sf_do_4_C(const sctp_endpoint_t *ep, ...@@ -149,6 +149,9 @@ sctp_disposition_t sctp_sf_do_4_C(const sctp_endpoint_t *ep,
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
SCTP_STATE(SCTP_STATE_CLOSED)); SCTP_STATE(SCTP_STATE_CLOSED));
...@@ -160,35 +163,6 @@ sctp_disposition_t sctp_sf_do_4_C(const sctp_endpoint_t *ep, ...@@ -160,35 +163,6 @@ sctp_disposition_t sctp_sf_do_4_C(const sctp_endpoint_t *ep,
return SCTP_DISPOSITION_NOMEM; return SCTP_DISPOSITION_NOMEM;
} }
/*
* Discard the whole packet.
*
* Section: 8.4 2)
*
* 2) If the OOTB packet contains an ABORT chunk, the receiver MUST
* silently discard the OOTB packet and take no further action.
* Otherwise,
*
* Verification Tag: No verification necessary
*
* Inputs
* (endpoint, asoc, chunk)
*
* Outputs
* (asoc, reply_msg, msg_up, timers, counters)
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t sctp_sf_pdiscard(const sctp_endpoint_t *ep,
const sctp_association_t *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands)
{
sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
return SCTP_DISPOSITION_CONSUME;
}
/* /*
* Respond to a normal INIT chunk. * Respond to a normal INIT chunk.
* We are the side that is being asked for an association. * We are the side that is being asked for an association.
...@@ -263,7 +237,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const sctp_endpoint_t *ep, ...@@ -263,7 +237,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const sctp_endpoint_t *ep,
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
/* /*
* Note: After sending out INIT ACK with the State Cookie parameter, * Note: After sending out INIT ACK with the State Cookie parameter,
* "Z" MUST NOT allocate any resources, nor keep any states for the * "Z" MUST NOT allocate any resources, nor keep any states for the
* new association. Otherwise, "Z" will be vulnerable to resource * new association. Otherwise, "Z" will be vulnerable to resource
* attacks. * attacks.
...@@ -324,7 +298,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const sctp_endpoint_t *ep, ...@@ -324,7 +298,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const sctp_endpoint_t *ep,
return SCTP_DISPOSITION_VIOLATION; return SCTP_DISPOSITION_VIOLATION;
/* Grab the INIT header. */ /* Grab the INIT header. */
chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data; chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
init_tag = ntohl(chunk->subh.init_hdr->init_tag); init_tag = ntohl(chunk->subh.init_hdr->init_tag);
...@@ -338,20 +312,17 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const sctp_endpoint_t *ep, ...@@ -338,20 +312,17 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const sctp_endpoint_t *ep,
if (!reply) if (!reply)
goto nomem; goto nomem;
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
SCTP_CHUNK(reply));
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
SCTP_STATE(SCTP_STATE_CLOSED)); SCTP_STATE(SCTP_STATE_CLOSED));
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
SCTP_NULL());
return SCTP_DISPOSITION_DELETE_TCB; return SCTP_DISPOSITION_DELETE_TCB;
} }
/* Tag the variable length paramters. Note that we never /* Tag the variable length paramters. Note that we never
* convert the parameters in an INIT chunk. * convert the parameters in an INIT chunk.
*/ */
chunk->param_hdr.v = chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
initchunk = (sctp_init_chunk_t *) chunk->chunk_hdr; initchunk = (sctp_init_chunk_t *) chunk->chunk_hdr;
...@@ -428,7 +399,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const sctp_endpoint_t *ep, ...@@ -428,7 +399,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const sctp_endpoint_t *ep,
* control endpoint, responding with an ABORT. * control endpoint, responding with an ABORT.
*/ */
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); return sctp_sf_ootb(ep, asoc, type, arg, commands);
/* "Decode" the chunk. We have no optional parameters so we /* "Decode" the chunk. We have no optional parameters so we
* are in good shape. * are in good shape.
...@@ -460,8 +431,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const sctp_endpoint_t *ep, ...@@ -460,8 +431,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const sctp_endpoint_t *ep,
case -SCTP_IERROR_BAD_SIG: case -SCTP_IERROR_BAD_SIG:
default: default:
return sctp_sf_pdiscard(ep, asoc, type, return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
arg, commands);
}; };
} }
...@@ -560,7 +530,7 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(const sctp_endpoint_t *ep, ...@@ -560,7 +530,7 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(const sctp_endpoint_t *ep,
SCTP_STATE(SCTP_STATE_ESTABLISHED)); SCTP_STATE(SCTP_STATE_ESTABLISHED));
sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
if (asoc->autoclose) if (asoc->autoclose)
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL()); sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
...@@ -625,8 +595,7 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const sctp_endpoint_t *ep, ...@@ -625,8 +595,7 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const sctp_endpoint_t *ep,
if (!reply) if (!reply)
goto nomem; goto nomem;
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
SCTP_CHUNK(reply));
/* Set transport error counter and association error counter /* Set transport error counter and association error counter
* when sending heartbeat. * when sending heartbeat.
...@@ -751,7 +720,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const sctp_endpoint_t *ep, ...@@ -751,7 +720,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const sctp_endpoint_t *ep,
return sctp_sf_pdiscard(ep, asoc, type, arg, commands); return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data; hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
from_addr = hbinfo->daddr; from_addr = hbinfo->daddr;
link = sctp_assoc_lookup_paddr(asoc, &from_addr); link = sctp_assoc_lookup_paddr(asoc, &from_addr);
/* This should never happen, but lets log it if so. */ /* This should never happen, but lets log it if so. */
...@@ -779,8 +748,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const sctp_endpoint_t *ep, ...@@ -779,8 +748,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const sctp_endpoint_t *ep,
* sent and mark the destination transport address as active if * sent and mark the destination transport address as active if
* it is not so marked. * it is not so marked.
*/ */
sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_ON, sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_ON, SCTP_TRANSPORT(link));
SCTP_TRANSPORT(link));
return SCTP_DISPOSITION_CONSUME; return SCTP_DISPOSITION_CONSUME;
} }
...@@ -810,7 +778,7 @@ static void sctp_tietags_populate(sctp_association_t *new_asoc, ...@@ -810,7 +778,7 @@ static void sctp_tietags_populate(sctp_association_t *new_asoc,
break; break;
/* 5.2.2 Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED, /* 5.2.2 Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED,
* COOKIE-WAIT and SHUTDOWN-ACK-SENT * COOKIE-WAIT and SHUTDOWN-ACK-SENT
*/ */
default: default:
new_asoc->c.my_ttag = asoc->c.my_vtag; new_asoc->c.my_ttag = asoc->c.my_vtag;
...@@ -843,10 +811,10 @@ static char sctp_tietags_compare(sctp_association_t *new_asoc, ...@@ -843,10 +811,10 @@ static char sctp_tietags_compare(sctp_association_t *new_asoc,
/* In this case, the peer may have restarted. */ /* In this case, the peer may have restarted. */
if ((asoc->c.my_vtag != new_asoc->c.my_vtag) && if ((asoc->c.my_vtag != new_asoc->c.my_vtag) &&
(asoc->c.peer_vtag != new_asoc->c.peer_vtag) && (asoc->c.peer_vtag != new_asoc->c.peer_vtag) &&
(asoc->c.my_vtag == new_asoc->c.my_ttag) && (asoc->c.my_vtag == new_asoc->c.my_ttag) &&
(asoc->c.peer_vtag == new_asoc->c.peer_ttag)) (asoc->c.peer_vtag == new_asoc->c.peer_ttag))
return 'A'; return 'A';
/* Collision case D. /* Collision case D.
* Note: Test case D first, otherwise it may be incorrectly * Note: Test case D first, otherwise it may be incorrectly
* identified as second case of B if the value of the Tie_tag is * identified as second case of B if the value of the Tie_tag is
...@@ -875,8 +843,10 @@ static char sctp_tietags_compare(sctp_association_t *new_asoc, ...@@ -875,8 +843,10 @@ static char sctp_tietags_compare(sctp_association_t *new_asoc,
/* Common helper routine for both duplicate and simulataneous INIT /* Common helper routine for both duplicate and simulataneous INIT
* chunk handling. * chunk handling.
*/ */
static sctp_disposition_t sctp_sf_do_unexpected_init(const sctp_endpoint_t *ep, static sctp_disposition_t sctp_sf_do_unexpected_init(
const sctp_association_t *asoc, const sctp_subtype_t type, const sctp_endpoint_t *ep,
const sctp_association_t *asoc,
const sctp_subtype_t type,
void *arg, sctp_cmd_seq_t *commands) void *arg, sctp_cmd_seq_t *commands)
{ {
sctp_chunk_t *chunk = arg; sctp_chunk_t *chunk = arg;
...@@ -894,8 +864,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(const sctp_endpoint_t *ep, ...@@ -894,8 +864,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(const sctp_endpoint_t *ep,
chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data; chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
/* Tag the variable length parameters. */ /* Tag the variable length parameters. */
chunk->param_hdr.v = chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
/* /*
* Other parameters for the endpoint SHOULD be copied from the * Other parameters for the endpoint SHOULD be copied from the
...@@ -912,10 +881,9 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(const sctp_endpoint_t *ep, ...@@ -912,10 +881,9 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(const sctp_endpoint_t *ep,
* Verification Tag and Peers Verification tag into a reserved * Verification Tag and Peers Verification tag into a reserved
* place (local tie-tag and per tie-tag) within the state cookie. * place (local tie-tag and per tie-tag) within the state cookie.
*/ */
sctp_process_init(new_asoc, chunk->chunk_hdr->type, sctp_process_init(new_asoc, chunk->chunk_hdr->type, sctp_source(chunk),
sctp_source(chunk), (sctp_init_chunk_t *)chunk->chunk_hdr, GFP_ATOMIC);
(sctp_init_chunk_t *)chunk->chunk_hdr,
GFP_ATOMIC);
sctp_tietags_populate(new_asoc, asoc); sctp_tietags_populate(new_asoc, asoc);
/* B) "Z" shall respond immediately with an INIT ACK chunk. */ /* B) "Z" shall respond immediately with an INIT ACK chunk. */
...@@ -927,7 +895,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(const sctp_endpoint_t *ep, ...@@ -927,7 +895,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(const sctp_endpoint_t *ep,
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
/* /*
* Note: After sending out INIT ACK with the State Cookie parameter, * Note: After sending out INIT ACK with the State Cookie parameter,
* "Z" MUST NOT allocate any resources for this new association. * "Z" MUST NOT allocate any resources for this new association.
* Otherwise, "Z" will be vulnerable to resource attacks. * Otherwise, "Z" will be vulnerable to resource attacks.
*/ */
...@@ -1072,7 +1040,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const sctp_endpoint_t *ep, ...@@ -1072,7 +1040,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const sctp_endpoint_t *ep,
list_for_each(pos, &new_asoc->peer.transport_addr_list) { list_for_each(pos, &new_asoc->peer.transport_addr_list) {
new_addr = list_entry(pos, sctp_transport_t, transports); new_addr = list_entry(pos, sctp_transport_t, transports);
found = 1; found = 1;
list_for_each_safe(pos2, temp, list_for_each_safe(pos2, temp,
&asoc->peer.transport_addr_list) { &asoc->peer.transport_addr_list) {
addr = list_entry(pos2, sctp_transport_t, transports); addr = list_entry(pos2, sctp_transport_t, transports);
if (!sctp_cmp_addr_exact(&new_addr->ipaddr, if (!sctp_cmp_addr_exact(&new_addr->ipaddr,
...@@ -1256,7 +1224,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(const sctp_endpoint_t *ep, ...@@ -1256,7 +1224,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(const sctp_endpoint_t *ep,
if (SCTP_STATE_ESTABLISHED != asoc->state) { if (SCTP_STATE_ESTABLISHED != asoc->state) {
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
SCTP_STATE(SCTP_STATE_ESTABLISHED)); SCTP_STATE(SCTP_STATE_ESTABLISHED));
sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START,
SCTP_NULL()); SCTP_NULL());
/* RFC 2960 5.1 Normal Establishment of an Association /* RFC 2960 5.1 Normal Establishment of an Association
...@@ -1323,10 +1291,9 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const sctp_endpoint_t *ep, ...@@ -1323,10 +1291,9 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const sctp_endpoint_t *ep,
/* "Decode" the chunk. We have no optional parameters so we /* "Decode" the chunk. We have no optional parameters so we
* are in good shape. * are in good shape.
*/ */
chunk->subh.cookie_hdr = chunk->subh.cookie_hdr = (sctp_signed_cookie_t *)chunk->skb->data;
(sctp_signed_cookie_t *) chunk->skb->data; skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t));
ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t));
/* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie /* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie
* of a duplicate COOKIE ECHO match the Verification Tags of the * of a duplicate COOKIE ECHO match the Verification Tags of the
...@@ -1335,25 +1302,24 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const sctp_endpoint_t *ep, ...@@ -1335,25 +1302,24 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const sctp_endpoint_t *ep,
*/ */
new_asoc = sctp_unpack_cookie(ep, asoc, chunk, GFP_ATOMIC, &error); new_asoc = sctp_unpack_cookie(ep, asoc, chunk, GFP_ATOMIC, &error);
/* FIXME: /* FIXME:
* If the re-build failed, what is the proper error path * If the re-build failed, what is the proper error path
* from here? * from here?
* *
* [We should abort the association. --piggy] * [We should abort the association. --piggy]
*/ */
if (!new_asoc) { if (!new_asoc) {
/* FIXME: Several errors are possible. A bad cookie should /* FIXME: Several errors are possible. A bad cookie should
* be silently discarded, but think about logging it too. * be silently discarded, but think about logging it too.
*/ */
switch (error) { switch (error) {
case -SCTP_IERROR_NOMEM: case -SCTP_IERROR_NOMEM:
goto nomem; goto nomem;
case -SCTP_IERROR_BAD_SIG: case -SCTP_IERROR_BAD_SIG:
default: default:
return sctp_sf_pdiscard(ep, asoc, type, return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
arg, commands); };
};
} }
/* Compare the tie_tag in cookie with the verification tag of /* Compare the tie_tag in cookie with the verification tag of
...@@ -1398,6 +1364,65 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const sctp_endpoint_t *ep, ...@@ -1398,6 +1364,65 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const sctp_endpoint_t *ep,
return SCTP_DISPOSITION_NOMEM; return SCTP_DISPOSITION_NOMEM;
} }
/*
* Process an ABORT. (SHUTDOWN-PENDING state)
*
* See sctp_sf_do_9_1_abort().
*/
sctp_disposition_t sctp_sf_shutdown_pending_abort(const sctp_endpoint_t *ep,
const sctp_association_t *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *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);
}
/*
* Process an ABORT. (SHUTDOWN-SENT state)
*
* See sctp_sf_do_9_1_abort().
*/
sctp_disposition_t sctp_sf_shutdown_sent_abort(const sctp_endpoint_t *ep,
const sctp_association_t *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands)
{
/* Stop the T2-shutdown timer. */
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
/* 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);
}
/*
* Process an ABORT. (SHUTDOWN-ACK-SENT state)
*
* See sctp_sf_do_9_1_abort().
*/
sctp_disposition_t sctp_sf_shutdown_ack_sent_abort(const sctp_endpoint_t *ep,
const sctp_association_t *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands)
{
/* The same T2 timer, so we should be able to use
* common function with the SHUTDOWN-SENT state.
*/
return sctp_sf_shutdown_sent_abort(ep, asoc, type, arg, commands);
}
#if 0 #if 0
/* /*
* Handle a Stale COOKIE Error * Handle a Stale COOKIE Error
...@@ -1442,7 +1467,7 @@ sctp_disposition_t do_5_2_6_stale(const sctp_endpoint_t *ep, ...@@ -1442,7 +1467,7 @@ sctp_disposition_t do_5_2_6_stale(const sctp_endpoint_t *ep,
__u8 *addrs; __u8 *addrs;
int addrs_len; int addrs_len;
time_t rtt; time_t rtt;
struct sctpCookiePreserve bht; struct sctpCookiePreserve bht;
/* If we have gotten too many failures, give up. */ /* If we have gotten too many failures, give up. */
if (1 + asoc->counters[SctpCounterInits] > asoc->max_init_attempts) { if (1 + asoc->counters[SctpCounterInits] > asoc->max_init_attempts) {
...@@ -1540,11 +1565,8 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const sctp_endpoint_t *ep, ...@@ -1540,11 +1565,8 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const sctp_endpoint_t *ep,
void *arg, void *arg,
sctp_cmd_seq_t *commands) sctp_cmd_seq_t *commands)
{ {
/* Check the verification tag. */ /* ASSOC_FAILED will DELETE_TCB. */
/* BUG: WRITE ME. */ sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
SCTP_STATE(SCTP_STATE_CLOSED));
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
/* BUG? This does not look complete... */ /* BUG? This does not look complete... */
return SCTP_DISPOSITION_ABORT; return SCTP_DISPOSITION_ABORT;
...@@ -1561,15 +1583,19 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const sctp_endpoint_t *ep, ...@@ -1561,15 +1583,19 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const sctp_endpoint_t *ep,
void *arg, void *arg,
sctp_cmd_seq_t *commands) sctp_cmd_seq_t *commands)
{ {
/* Check the verification tag. */
/* BUG: WRITE ME. */
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
SCTP_STATE(SCTP_STATE_CLOSED)); SCTP_STATE(SCTP_STATE_CLOSED));
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
/* CMD_INIT_FAILED will DELETE_TCB. */ /* CMD_INIT_FAILED will DELETE_TCB. */
sctp_add_cmd_sf(commands,SCTP_CMD_INIT_FAILED, SCTP_NULL()); sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, SCTP_NULL());
return SCTP_DISPOSITION_DELETE_TCB; /* BUG? This does not look complete... */
return SCTP_DISPOSITION_ABORT;
} }
/* /*
...@@ -1585,70 +1611,9 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const sctp_endpoint_t *ep, ...@@ -1585,70 +1611,9 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const sctp_endpoint_t *ep,
{ {
/* There is a single T1 timer, so we should be able to use /* There is a single T1 timer, so we should be able to use
* common function with the COOKIE-WAIT state. * common function with the COOKIE-WAIT state.
*/
return sctp_sf_cookie_wait_abort(ep, asoc, type, arg, commands);
}
#if 0
/*
* Handle a shutdown timeout or INIT during a shutdown phase.
*
* Section: 9.2
* If an endpoint is in SHUTDOWN-ACK-SENT state and receives an INIT chunk
* (e.g., if the SHUTDOWN COMPLETE was lost) with source and destination
* transport addresses (either in the IP addresses or in the INIT chunk)
* that belong to this association, it should discard the INIT chunk and
* retransmit the SHUTDOWN ACK chunk.
*...
* While in SHUTDOWN-SENT state ... If the timer expires, the endpoint
* must re-send the SHUTDOWN ACK.
*
* Verification Tag: Neither the INIT nor the timeout will have a
* valid verification tag, so it is safe to ignore.
*
* Inputs
* (endpoint, asoc, chunk)
*
* Outputs
* (asoc, reply_msg, msg_up, timers, counters)
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t sctp_do_9_2_reshutack(const sctp_endpoint_t *ep,
const sctp_association_t *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands)
{
sctp_chunk_t *chunk = arg;
/* If this was a timeout (not an INIT), then do the counter
* work. We might need to just dump the association.
*/ */
if (!chunk) { return sctp_sf_cookie_wait_abort(ep, asoc, type, arg, commands);
if (1 + asoc->counters[SctpCounterRetran] >
asoc->maxRetrans) {
sctp_add_cmd(commands, SCTP_CMD_DELETE_TCB,
SCTP_NULL());
return SCTP_DISPOSITION_DELETE_TCB;
}
retval->counters[0] = SCTP_COUNTER_INCR;
retval->counters[0] = SctpCounterRetran;
retval->counters[1] = 0;
retval->counters[1] = 0;
}
reply = sctp_make_shutdown_ack(asoc, chunk);
if (!reply)
goto nomem;
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
return SCTP_DISPOSITION_CONSUME;
nomem:
return SCTP_DISPOSITION_NOMEM;
} }
#endif /* 0 */
/* /*
* sctp_sf_do_9_2_shut * sctp_sf_do_9_2_shut
...@@ -1694,7 +1659,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const sctp_endpoint_t *ep, ...@@ -1694,7 +1659,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const sctp_endpoint_t *ep,
sctp_disposition_t disposition; sctp_disposition_t disposition;
/* Convert the elaborate header. */ /* Convert the elaborate header. */
sdh = (sctp_shutdownhdr_t *) chunk->skb->data; sdh = (sctp_shutdownhdr_t *)chunk->skb->data;
skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t)); skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t));
chunk->subh.shutdown_hdr = sdh; chunk->subh.shutdown_hdr = sdh;
...@@ -1718,9 +1683,8 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const sctp_endpoint_t *ep, ...@@ -1718,9 +1683,8 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const sctp_endpoint_t *ep,
disposition = SCTP_DISPOSITION_CONSUME; disposition = SCTP_DISPOSITION_CONSUME;
if (sctp_outqueue_is_empty(&asoc->outqueue)) { if (sctp_outqueue_is_empty(&asoc->outqueue)) {
disposition = disposition = sctp_sf_do_9_2_shutdown_ack(ep, asoc, type,
sctp_sf_do_9_2_shutdown_ack(ep, asoc, type, arg, commands);
arg, commands);
} }
/* - verify, by checking the Cumulative TSN Ack field of the /* - verify, by checking the Cumulative TSN Ack field of the
...@@ -1732,6 +1696,42 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const sctp_endpoint_t *ep, ...@@ -1732,6 +1696,42 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const sctp_endpoint_t *ep,
return disposition; return disposition;
} }
/* RFC 2960 9.2
* If an endpoint is in SHUTDOWN-ACK-SENT state and receives an INIT chunk
* (e.g., if the SHUTDOWN COMPLETE was lost) with source and destination
* transport addresses (either in the IP addresses or in the INIT chunk)
* that belong to this association, it should discard the INIT chunk and
* retransmit the SHUTDOWN ACK chunk.
*/
sctp_disposition_t sctp_sf_do_9_2_reshutack(const sctp_endpoint_t *ep,
const sctp_association_t *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands)
{
sctp_chunk_t *chunk = (sctp_chunk_t *) arg;
sctp_chunk_t *reply;
reply = sctp_make_shutdown_ack(asoc, chunk);
if (NULL == reply)
goto nomem;
/* Set the transport for the SHUTDOWN ACK chunk and the timeout for
* the T2-SHUTDOWN timer.
*/
sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T2, SCTP_CHUNK(reply));
/* and restart the T2-shutdown timer. */
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
return SCTP_DISPOSITION_CONSUME;
nomem:
return SCTP_DISPOSITION_NOMEM;
}
/* /*
* sctp_sf_do_ecn_cwr * sctp_sf_do_ecn_cwr
* *
...@@ -1780,7 +1780,7 @@ sctp_disposition_t sctp_sf_do_ecn_cwr(const sctp_endpoint_t *ep, ...@@ -1780,7 +1780,7 @@ sctp_disposition_t sctp_sf_do_ecn_cwr(const sctp_endpoint_t *ep,
cwr->lowest_tsn = ntohl(cwr->lowest_tsn); cwr->lowest_tsn = ntohl(cwr->lowest_tsn);
/* Does this CWR ack the last sent congestion notification? */ /* Does this CWR ack the last sent congestion notification? */
if (TSN_lte(asoc->last_ecne_tsn, cwr->lowest_tsn)) { if (TSN_lte(asoc->last_ecne_tsn, cwr->lowest_tsn)) {
/* Stop sending ECNE. */ /* Stop sending ECNE. */
sctp_add_cmd_sf(commands, sctp_add_cmd_sf(commands,
...@@ -1844,7 +1844,7 @@ sctp_disposition_t sctp_sf_do_ecne(const sctp_endpoint_t *ep, ...@@ -1844,7 +1844,7 @@ sctp_disposition_t sctp_sf_do_ecne(const sctp_endpoint_t *ep,
if (TSN_lt(asoc->last_cwr_tsn, ecne->lowest_tsn)) { if (TSN_lt(asoc->last_cwr_tsn, ecne->lowest_tsn)) {
sctp_add_cmd_sf(commands, SCTP_CMD_ECN_ECNE, sctp_add_cmd_sf(commands, SCTP_CMD_ECN_ECNE,
SCTP_U32(ecne->lowest_tsn)); SCTP_U32(ecne->lowest_tsn));
} }
return SCTP_DISPOSITION_CONSUME; return SCTP_DISPOSITION_CONSUME;
} }
...@@ -1979,13 +1979,11 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const sctp_endpoint_t *ep, ...@@ -1979,13 +1979,11 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const sctp_endpoint_t *ep,
* processing the rest of the chunks in the packet. * processing the rest of the chunks in the packet.
*/ */
sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL()); sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
SCTP_STATE(SCTP_STATE_CLOSED));
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
return SCTP_DISPOSITION_CONSUME; return SCTP_DISPOSITION_CONSUME;
} }
/* We are accepting this DATA chunk. */ /* We are accepting this DATA chunk. */
/* Record the fact that we have received this TSN. */ /* Record the fact that we have received this TSN. */
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn)); sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
...@@ -2029,7 +2027,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const sctp_endpoint_t *ep, ...@@ -2029,7 +2027,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const sctp_endpoint_t *ep,
* *
* The SCTP endpoint MUST always acknowledge the reception of * The SCTP endpoint MUST always acknowledge the reception of
* each valid DATA chunk. * each valid DATA chunk.
* *
* The guidelines on delayed acknowledgement algorithm * The guidelines on delayed acknowledgement algorithm
* specified in Section 4.2 of [RFC2581] SHOULD be followed. * specified in Section 4.2 of [RFC2581] SHOULD be followed.
* Specifically, an acknowledgement SHOULD be generated for at * Specifically, an acknowledgement SHOULD be generated for at
...@@ -2142,7 +2140,7 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(const sctp_endpoint_t *ep, ...@@ -2142,7 +2140,7 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(const sctp_endpoint_t *ep,
*/ */
if (!chunk->ecn_ce_done) { if (!chunk->ecn_ce_done) {
chunk->ecn_ce_done = 1; chunk->ecn_ce_done = 1;
if (INET_ECN_is_ce(chunk->skb->nh.iph->tos) && if (INET_ECN_is_ce(chunk->skb->nh.iph->tos) &&
asoc->peer.ecn_capable) { asoc->peer.ecn_capable) {
/* Do real work as sideffect. */ /* Do real work as sideffect. */
sctp_add_cmd_sf(commands, SCTP_CMD_ECN_CE, sctp_add_cmd_sf(commands, SCTP_CMD_ECN_CE,
...@@ -2185,9 +2183,7 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(const sctp_endpoint_t *ep, ...@@ -2185,9 +2183,7 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(const sctp_endpoint_t *ep,
* processing the rest of the chunks in the packet. * processing the rest of the chunks in the packet.
*/ */
sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL()); sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
SCTP_STATE(SCTP_STATE_CLOSED));
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
return SCTP_DISPOSITION_CONSUME; return SCTP_DISPOSITION_CONSUME;
} }
...@@ -2296,14 +2292,12 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const sctp_endpoint_t *ep, ...@@ -2296,14 +2292,12 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const sctp_endpoint_t *ep,
*/ */
if (TSN_lt(ctsn, asoc->ctsn_ack_point)) { if (TSN_lt(ctsn, asoc->ctsn_ack_point)) {
SCTP_DEBUG_PRINTK("ctsn %x\n", ctsn); SCTP_DEBUG_PRINTK("ctsn %x\n", ctsn);
SCTP_DEBUG_PRINTK("ctsn_ack_point %x\n", SCTP_DEBUG_PRINTK("ctsn_ack_point %x\n", asoc->ctsn_ack_point);
asoc->ctsn_ack_point);
return SCTP_DISPOSITION_DISCARD; return SCTP_DISPOSITION_DISCARD;
} }
/* Return this SACK for further processing. */ /* Return this SACK for further processing. */
sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, SCTP_SACKH(sackh));
SCTP_SACKH(sackh));
/* Note: We do the rest of the work on the PROCESS_SACK /* Note: We do the rest of the work on the PROCESS_SACK
* sideeffect. * sideeffect.
...@@ -2410,7 +2404,8 @@ sctp_disposition_t sctp_sf_operr_notify(const sctp_endpoint_t *ep, ...@@ -2410,7 +2404,8 @@ sctp_disposition_t sctp_sf_operr_notify(const sctp_endpoint_t *ep,
sctp_ulpevent_t *ev; sctp_ulpevent_t *ev;
while (chunk->chunk_end > chunk->skb->data) { while (chunk->chunk_end > chunk->skb->data) {
ev = sctp_ulpevent_make_remote_error(asoc,chunk,0, GFP_ATOMIC); ev = sctp_ulpevent_make_remote_error(asoc, chunk, 0,
GFP_ATOMIC);
if (!ev) if (!ev)
goto nomem; goto nomem;
...@@ -2464,6 +2459,9 @@ sctp_disposition_t sctp_sf_do_9_2_final(const sctp_endpoint_t *ep, ...@@ -2464,6 +2459,9 @@ sctp_disposition_t sctp_sf_do_9_2_final(const sctp_endpoint_t *ep,
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
/* ...send a SHUTDOWN COMPLETE chunk to its peer, */ /* ...send a SHUTDOWN COMPLETE chunk to its peer, */
reply = sctp_make_shutdown_complete(asoc, chunk); reply = sctp_make_shutdown_complete(asoc, chunk);
if (!reply) if (!reply)
...@@ -2524,7 +2522,7 @@ sctp_disposition_t sctp_sf_ootb(const sctp_endpoint_t *ep, ...@@ -2524,7 +2522,7 @@ sctp_disposition_t sctp_sf_ootb(const sctp_endpoint_t *ep,
if (ootb_shut_ack) if (ootb_shut_ack)
sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands); sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands);
else else
sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
return sctp_sf_pdiscard(ep, asoc, type, arg, commands); return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
} }
...@@ -2616,6 +2614,148 @@ sctp_disposition_t sctp_sf_shut_8_4_5(const sctp_endpoint_t *ep, ...@@ -2616,6 +2614,148 @@ sctp_disposition_t sctp_sf_shut_8_4_5(const sctp_endpoint_t *ep,
nomem: nomem:
return SCTP_DISPOSITION_NOMEM; return SCTP_DISPOSITION_NOMEM;
} }
/*
* Process an unknown chunk.
*
* Section: 3.2. Also, 2.1 in the implementor's guide.
*
* Chunk Types are encoded such that the highest-order two bits specify
* the action that must be taken if the processing endpoint does not
* recognize the Chunk Type.
*
* 00 - Stop processing this SCTP packet and discard it, do not process
* any further chunks within it.
*
* 01 - Stop processing this SCTP packet and discard it, do not process
* any further chunks within it, and report the unrecognized
* chunk in an 'Unrecognized Chunk Type'.
*
* 10 - Skip this chunk and continue processing.
*
* 11 - Skip this chunk and continue processing, but report in an ERROR
* Chunk using the 'Unrecognized Chunk Type' cause of error.
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t sctp_sf_unk_chunk(const sctp_endpoint_t *ep,
const sctp_association_t *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands)
{
sctp_chunk_t *unk_chunk = arg;
sctp_chunk_t *err_chunk;
sctp_chunkhdr_t *hdr;
SCTP_DEBUG_PRINTK("Processing the unknown chunk id %d.\n", type.chunk);
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
* that the value in the Verification Tag field of the
* received SCTP packet matches its own Tag. If the received
* Verification Tag value does not match the receiver's own
* tag value, the receiver shall silently discard the packet.
*/
if (ntohl(unk_chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
switch (type.chunk & SCTP_CID_ACTION_MASK) {
case SCTP_CID_ACTION_DISCARD:
/* Discard the packet. */
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
break;
case SCTP_CID_ACTION_DISCARD_ERR:
/* Discard the packet. */
sctp_sf_pdiscard(ep, asoc, type, arg, commands);
/* Generate an ERROR chunk as response. */
hdr = unk_chunk->chunk_hdr;
err_chunk = sctp_make_op_error(asoc, unk_chunk,
SCTP_ERROR_UNKNOWN_CHUNK, hdr,
WORD_ROUND(ntohs(hdr->length)));
if (err_chunk) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
SCTP_CHUNK(err_chunk));
}
return SCTP_DISPOSITION_CONSUME;
break;
case SCTP_CID_ACTION_SKIP:
/* Skip the chunk. */
return SCTP_DISPOSITION_DISCARD;
break;
case SCTP_CID_ACTION_SKIP_ERR:
/* Generate an ERROR chunk as response. */
hdr = unk_chunk->chunk_hdr;
err_chunk = sctp_make_op_error(asoc, unk_chunk,
SCTP_ERROR_UNKNOWN_CHUNK, hdr,
WORD_ROUND(ntohs(hdr->length)));
if (err_chunk) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
SCTP_CHUNK(err_chunk));
}
/* Skip the chunk. */
return SCTP_DISPOSITION_CONSUME;
break;
default:
break;
}
return SCTP_DISPOSITION_DISCARD;
}
/*
* Discard the chunk.
*
* Section: 0.2, 5.2.3, 5.2.5, 5.2.6, 6.0, 8.4.6, 8.5.1c, 9.2
* [Too numerous to mention...]
* Verification Tag: No verification needed.
* Inputs
* (endpoint, asoc, chunk)
*
* Outputs
* (asoc, reply_msg, msg_up, timers, counters)
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t sctp_sf_discard_chunk(const sctp_endpoint_t *ep,
const sctp_association_t *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands)
{
SCTP_DEBUG_PRINTK("Chunk %d is discarded\n", type.chunk);
return SCTP_DISPOSITION_DISCARD;
}
/*
* Discard the whole packet.
*
* Section: 8.4 2)
*
* 2) If the OOTB packet contains an ABORT chunk, the receiver MUST
* silently discard the OOTB packet and take no further action.
* Otherwise,
*
* Verification Tag: No verification necessary
*
* Inputs
* (endpoint, asoc, chunk)
*
* Outputs
* (asoc, reply_msg, msg_up, timers, counters)
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t
sctp_sf_pdiscard(const sctp_endpoint_t *ep,
const sctp_association_t *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands)
{
sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
return SCTP_DISPOSITION_CONSUME;
}
#if 0 #if 0
/* /*
...@@ -2821,7 +2961,7 @@ sctp_disposition_t sctp_sf_do_prm_asoc(const sctp_endpoint_t *ep, ...@@ -2821,7 +2961,7 @@ sctp_disposition_t sctp_sf_do_prm_asoc(const sctp_endpoint_t *ep,
* or else move the association allocation/init into this function. * or else move the association allocation/init into this function.
* The association structure is brand new before calling this * The association structure is brand new before calling this
* function, so would not be a sideeffect if the allocation * function, so would not be a sideeffect if the allocation
* moved into this function. --jgrimm * moved into this function. --jgrimm
*/ */
sctp_add_cmd_sf(commands, SCTP_CMD_SET_BIND_ADDR, (sctp_arg_t) bp); sctp_add_cmd_sf(commands, SCTP_CMD_SET_BIND_ADDR, (sctp_arg_t) bp);
...@@ -2974,13 +3114,19 @@ sctp_disposition_t sctp_sf_do_9_2_prm_shutdown(const sctp_endpoint_t *ep, ...@@ -2974,13 +3114,19 @@ sctp_disposition_t sctp_sf_do_9_2_prm_shutdown(const sctp_endpoint_t *ep,
* if necessary to fill gaps. * if necessary to fill gaps.
*/ */
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING)); SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING));
/* 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; disposition = SCTP_DISPOSITION_CONSUME;
if (sctp_outqueue_is_empty(&asoc->outqueue)) { if (sctp_outqueue_is_empty(&asoc->outqueue)) {
disposition = disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type,
sctp_sf_do_9_2_start_shutdown(ep, asoc, type, arg, commands);
arg, commands);
} }
return disposition; return disposition;
} }
...@@ -3034,7 +3180,7 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(const sctp_endpoint_t *ep, ...@@ -3034,7 +3180,7 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(const sctp_endpoint_t *ep,
/* Generate ABORT chunk to send the peer. */ /* Generate ABORT chunk to send the peer. */
abort = sctp_make_abort(asoc, NULL, 0); abort = sctp_make_abort(asoc, NULL, 0);
if (!abort) if (!abort)
retval = SCTP_DISPOSITION_NOMEM; retval = SCTP_DISPOSITION_NOMEM;
else else
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
...@@ -3042,12 +3188,8 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(const sctp_endpoint_t *ep, ...@@ -3042,12 +3188,8 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(const sctp_endpoint_t *ep,
* TCB. This is a departure from our typical NOMEM handling. * TCB. This is a departure from our typical NOMEM handling.
*/ */
/* Change to CLOSED state. */ /* Delete the established association. */
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
SCTP_STATE(SCTP_STATE_CLOSED));
/* Delete the established association. */
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
return retval; return retval;
} }
...@@ -3090,11 +3232,12 @@ sctp_disposition_t sctp_sf_error_shutdown(const sctp_endpoint_t *ep, ...@@ -3090,11 +3232,12 @@ sctp_disposition_t sctp_sf_error_shutdown(const sctp_endpoint_t *ep,
* Outputs * Outputs
* (timers) * (timers)
*/ */
sctp_disposition_t sctp_sf_cookie_wait_prm_shutdown(const sctp_endpoint_t *ep, sctp_disposition_t sctp_sf_cookie_wait_prm_shutdown(
const sctp_association_t *asoc, const sctp_endpoint_t *ep,
const sctp_subtype_t type, const sctp_association_t *asoc,
void *arg, const sctp_subtype_t type,
sctp_cmd_seq_t *commands) void *arg,
sctp_cmd_seq_t *commands)
{ {
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
...@@ -3134,7 +3277,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_prm_shutdown( ...@@ -3134,7 +3277,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_prm_shutdown(
} }
/* /*
* sctp_cookie_wait_prm_abort * sctp_sf_cookie_wait_prm_abort
* *
* Section: 4 Note: 2 * Section: 4 Note: 2
* Verification Tag: * Verification Tag:
...@@ -3148,19 +3291,41 @@ sctp_disposition_t sctp_sf_cookie_echoed_prm_shutdown( ...@@ -3148,19 +3291,41 @@ sctp_disposition_t sctp_sf_cookie_echoed_prm_shutdown(
* (timers) * (timers)
*/ */
sctp_disposition_t sctp_sf_cookie_wait_prm_abort(const sctp_endpoint_t *ep, sctp_disposition_t sctp_sf_cookie_wait_prm_abort(const sctp_endpoint_t *ep,
const sctp_association_t *asoc, const sctp_association_t *asoc,
const sctp_subtype_t type, const sctp_subtype_t type,
void *arg, void *arg,
sctp_cmd_seq_t *commands) sctp_cmd_seq_t *commands)
{ {
sctp_chunk_t *abort;
sctp_disposition_t retval;
/* Stop T1-init timer */ /* Stop T1-init timer */
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
return sctp_sf_do_9_1_prm_abort(ep, asoc, type, arg, commands); retval = SCTP_DISPOSITION_CONSUME;
/* Generate ABORT chunk to send the peer */
abort = sctp_make_abort(asoc, NULL, 0);
if (!abort)
retval = SCTP_DISPOSITION_NOMEM;
else
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
SCTP_STATE(SCTP_STATE_CLOSED));
/* Even if we can't send the ABORT due to low memory delete the
* TCB. This is a departure from our typical NOMEM handling.
*/
/* Delete the established association. */
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, SCTP_NULL());
return retval;
} }
/* /*
* sctp_cookie_echoed_prm_abort * sctp_sf_cookie_echoed_prm_abort
* *
* Section: 4 Note: 3 * Section: 4 Note: 3
* Verification Tag: * Verification Tag:
...@@ -3174,10 +3339,10 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(const sctp_endpoint_t *ep, ...@@ -3174,10 +3339,10 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(const sctp_endpoint_t *ep,
* (timers) * (timers)
*/ */
sctp_disposition_t sctp_sf_cookie_echoed_prm_abort(const sctp_endpoint_t *ep, sctp_disposition_t sctp_sf_cookie_echoed_prm_abort(const sctp_endpoint_t *ep,
const sctp_association_t *asoc, const sctp_association_t *asoc,
const sctp_subtype_t type, const sctp_subtype_t type,
void *arg, void *arg,
sctp_cmd_seq_t *commands) sctp_cmd_seq_t *commands)
{ {
/* There is a single T1 timer, so we should be able to use /* There is a single T1 timer, so we should be able to use
* common function with the COOKIE-WAIT state. * common function with the COOKIE-WAIT state.
...@@ -3185,6 +3350,87 @@ sctp_disposition_t sctp_sf_cookie_echoed_prm_abort(const sctp_endpoint_t *ep, ...@@ -3185,6 +3350,87 @@ sctp_disposition_t sctp_sf_cookie_echoed_prm_abort(const sctp_endpoint_t *ep,
return sctp_sf_cookie_wait_prm_abort(ep, asoc, type, arg, commands); return sctp_sf_cookie_wait_prm_abort(ep, asoc, type, arg, commands);
} }
/*
* sctp_sf_shutdown_pending_prm_abort
*
* Inputs
* (endpoint, asoc)
*
* The RFC does not explicitly address this issue, but is the route through the
* state table when someone issues an abort while in SHUTDOWN-PENDING state.
*
* Outputs
* (timers)
*/
sctp_disposition_t sctp_sf_shutdown_pending_prm_abort(
const sctp_endpoint_t *ep,
const sctp_association_t *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *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_prm_abort(ep, asoc, type, arg, commands);
}
/*
* sctp_sf_shutdown_sent_prm_abort
*
* Inputs
* (endpoint, asoc)
*
* The RFC does not explicitly address this issue, but is the route through the
* state table when someone issues an abort while in SHUTDOWN-SENT state.
*
* Outputs
* (timers)
*/
sctp_disposition_t sctp_sf_shutdown_sent_prm_abort(
const sctp_endpoint_t *ep,
const sctp_association_t *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands)
{
/* Stop the T2-shutdown timer. */
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
/* 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_prm_abort(ep, asoc, type, arg, commands);
}
/*
* sctp_sf_cookie_echoed_prm_abort
*
* Inputs
* (endpoint, asoc)
*
* The RFC does not explcitly address this issue, but is the route through the
* state table when someone issues an abort while in COOKIE_ECHOED state.
*
* Outputs
* (timers)
*/
sctp_disposition_t sctp_sf_shutdown_ack_sent_prm_abort(
const sctp_endpoint_t *ep,
const sctp_association_t *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands)
{
/* The same T2 timer, so we should be able to use
* common function with the SHUTDOWN-SENT state.
*/
return sctp_sf_shutdown_sent_prm_abort(ep, asoc, type, arg, commands);
}
/* /*
* Ignore the primitive event * Ignore the primitive event
* *
...@@ -3218,10 +3464,10 @@ sctp_disposition_t sctp_sf_ignore_primitive(const sctp_endpoint_t *ep, ...@@ -3218,10 +3464,10 @@ sctp_disposition_t sctp_sf_ignore_primitive(const sctp_endpoint_t *ep,
* The return value is the disposition. * The return value is the disposition.
*/ */
sctp_disposition_t sctp_sf_do_9_2_start_shutdown(const sctp_endpoint_t *ep, sctp_disposition_t sctp_sf_do_9_2_start_shutdown(const sctp_endpoint_t *ep,
const sctp_association_t *asoc, const sctp_association_t *asoc,
const sctp_subtype_t type, const sctp_subtype_t type,
void *arg, void *arg,
sctp_cmd_seq_t *commands) sctp_cmd_seq_t *commands)
{ {
sctp_chunk_t *reply; sctp_chunk_t *reply;
...@@ -3236,7 +3482,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown(const sctp_endpoint_t *ep, ...@@ -3236,7 +3482,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown(const sctp_endpoint_t *ep,
/* Set the transport for the SHUTDOWN chunk and the timeout for the /* Set the transport for the SHUTDOWN chunk and the timeout for the
* T2-shutdown timer. * T2-shutdown timer.
*/ */
sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T2, SCTP_CHUNK(reply)); sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T2, SCTP_CHUNK(reply));
/* It shall then start the T2-shutdown timer */ /* It shall then start the T2-shutdown timer */
...@@ -3322,8 +3568,7 @@ sctp_disposition_t sctp_sf_ignore_other(const sctp_endpoint_t *ep, ...@@ -3322,8 +3568,7 @@ sctp_disposition_t sctp_sf_ignore_other(const sctp_endpoint_t *ep,
void *arg, void *arg,
sctp_cmd_seq_t *commands) sctp_cmd_seq_t *commands)
{ {
SCTP_DEBUG_PRINTK("The event other type %d is ignored\n", SCTP_DEBUG_PRINTK("The event other type %d is ignored\n", type.other);
type.other);
return SCTP_DISPOSITION_DISCARD; return SCTP_DISPOSITION_DISCARD;
} }
...@@ -3413,7 +3658,7 @@ sctp_disposition_t sctp_sf_do_6_2_sack(const sctp_endpoint_t *ep, ...@@ -3413,7 +3658,7 @@ sctp_disposition_t sctp_sf_do_6_2_sack(const sctp_endpoint_t *ep,
void *arg, void *arg,
sctp_cmd_seq_t *commands) sctp_cmd_seq_t *commands)
{ {
sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE()); sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE());
return SCTP_DISPOSITION_CONSUME; return SCTP_DISPOSITION_CONSUME;
} }
...@@ -3479,11 +3724,11 @@ sctp_disposition_t sctp_sf_t1_timer_expire(const sctp_endpoint_t *ep, ...@@ -3479,11 +3724,11 @@ sctp_disposition_t sctp_sf_t1_timer_expire(const sctp_endpoint_t *ep,
if (!repl) if (!repl)
goto nomem; goto nomem;
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
/* Issue a sideeffect to do the needed accounting. */ /* Issue a sideeffect to do the needed accounting. */
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_RESTART, sctp_add_cmd_sf(commands, SCTP_CMD_INIT_RESTART,
SCTP_TO(timer)); SCTP_TO(timer));
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
} else { } else {
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, SCTP_NULL()); sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, SCTP_NULL());
return SCTP_DISPOSITION_DELETE_TCB; return SCTP_DISPOSITION_DELETE_TCB;
...@@ -3559,16 +3804,44 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const sctp_endpoint_t *ep, ...@@ -3559,16 +3804,44 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const sctp_endpoint_t *ep,
return SCTP_DISPOSITION_NOMEM; return SCTP_DISPOSITION_NOMEM;
} }
/* 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.
* At the expiration of this timer the sender SHOULD abort the association
* by sending an ABORT chunk.
*/
sctp_disposition_t sctp_sf_t5_timer_expire(const sctp_endpoint_t *ep,
const sctp_association_t *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands)
{
sctp_chunk_t *reply = NULL;
SCTP_DEBUG_PRINTK("Timer T5 expired.\n");
reply = sctp_make_abort(asoc, NULL, 0);
if (!reply)
goto nomem;
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
return SCTP_DISPOSITION_DELETE_TCB;
nomem:
return SCTP_DISPOSITION_NOMEM;
}
/* Handle expiration of AUTOCLOSE timer. When the autoclose timer expires, /* Handle expiration of AUTOCLOSE timer. When the autoclose timer expires,
* the association is automatically closed by starting the shutdown process. * the association is automatically closed by starting the shutdown process.
* The work that needs to be done is same as when SHUTDOWN is initiated by * The work that needs to be done is same as when SHUTDOWN is initiated by
* the user. So this routine looks same as sctp_sf_do_9_2_prm_shutdown(). * the user. So this routine looks same as sctp_sf_do_9_2_prm_shutdown().
*/ */
sctp_disposition_t sctp_sf_autoclose_timer_expire(const sctp_endpoint_t *ep, sctp_disposition_t sctp_sf_autoclose_timer_expire(const sctp_endpoint_t *ep,
const sctp_association_t *asoc, const sctp_association_t *asoc,
const sctp_subtype_t type, const sctp_subtype_t type,
void *arg, void *arg,
sctp_cmd_seq_t *commands) sctp_cmd_seq_t *commands)
{ {
int disposition; int disposition;
...@@ -3583,11 +3856,16 @@ sctp_disposition_t sctp_sf_autoclose_timer_expire(const sctp_endpoint_t *ep, ...@@ -3583,11 +3856,16 @@ sctp_disposition_t sctp_sf_autoclose_timer_expire(const sctp_endpoint_t *ep,
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING)); SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING));
/* 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; disposition = SCTP_DISPOSITION_CONSUME;
if (sctp_outqueue_is_empty(&asoc->outqueue)) { if (sctp_outqueue_is_empty(&asoc->outqueue)) {
disposition = disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type,
sctp_sf_do_9_2_start_shutdown(ep, asoc, type, arg, commands);
arg, commands);
} }
return disposition; return disposition;
} }
...@@ -3651,30 +3929,6 @@ sctp_disposition_t sctp_sf_timer_ignore(const sctp_endpoint_t *ep, ...@@ -3651,30 +3929,6 @@ sctp_disposition_t sctp_sf_timer_ignore(const sctp_endpoint_t *ep,
return SCTP_DISPOSITION_CONSUME; return SCTP_DISPOSITION_CONSUME;
} }
/*
* Discard the chunk.
*
* Section: 0.2, 5.2.3, 5.2.5, 5.2.6, 6.0, 8.4.6, 8.5.1c, 9.2
* [Too numerous to mention...]
* Verification Tag: No verification needed.
* Inputs
* (endpoint, asoc, chunk)
*
* Outputs
* (asoc, reply_msg, msg_up, timers, counters)
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t sctp_sf_discard_chunk(const sctp_endpoint_t *ep,
const sctp_association_t *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands)
{
SCTP_DEBUG_PRINTK("Chunk %d is discarded\n", type.chunk);
return SCTP_DISPOSITION_DISCARD;
}
/******************************************************************** /********************************************************************
* 2nd Level Abstractions * 2nd Level Abstractions
********************************************************************/ ********************************************************************/
......
...@@ -4,36 +4,36 @@ ...@@ -4,36 +4,36 @@
* Copyright (c) 2001 International Business Machines, Corp. * Copyright (c) 2001 International Business Machines, Corp.
* Copyright (c) 2001 Intel Corp. * Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 Nokia, Inc. * Copyright (c) 2001 Nokia, Inc.
* *
* This file is part of the SCTP kernel reference Implementation * This file is part of the SCTP kernel reference Implementation
* *
* These are the state tables for the SCTP state machine. * These are the state tables for the SCTP state machine.
* *
* The SCTP reference implementation is free software; * The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of * you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by * the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* The SCTP reference implementation is distributed in the hope that it * The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied * will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************ * ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to * along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330, * the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
* *
* Please send any bug reports or fixes you make to the * Please send any bug reports or fixes you make to the
* email address(es): * email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net> * lksctp developers <lksctp-developers@lists.sourceforge.net>
* *
* Or submit a bug report through the following website: * Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp * http://www.sf.net/projects/lksctp
* *
* Written or modified by: * Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org> * La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us> * Karl Knutson <karl@athena.chicago.il.us>
* Jon Grimm <jgrimm@us.ibm.com> * Jon Grimm <jgrimm@us.ibm.com>
...@@ -48,9 +48,10 @@ ...@@ -48,9 +48,10 @@
#include <net/sctp/sctp.h> #include <net/sctp/sctp.h>
#include <net/sctp/sm.h> #include <net/sctp/sm.h>
sctp_sm_table_entry_t nop = {fn: sctp_sf_discard_chunk, sctp_sm_table_entry_t bug = {
name: "sctp_sf_discard_chunk"}; .fn = sctp_sf_bug,
sctp_sm_table_entry_t bug = {fn: sctp_sf_bug, name: "sctp_sf_bug"}; .name = "sctp_sf_bug"
};
#define DO_LOOKUP(_max, _type, _table) \ #define DO_LOOKUP(_max, _type, _table) \
if ((event_subtype._type > (_max))) { \ if ((event_subtype._type > (_max))) { \
...@@ -58,9 +59,9 @@ sctp_sm_table_entry_t bug = {fn: sctp_sf_bug, name: "sctp_sf_bug"}; ...@@ -58,9 +59,9 @@ sctp_sm_table_entry_t bug = {fn: sctp_sf_bug, name: "sctp_sf_bug"};
"sctp table %p possible attack:" \ "sctp table %p possible attack:" \
" event %d exceeds max %d\n", \ " event %d exceeds max %d\n", \
_table, event_subtype._type, _max); \ _table, event_subtype._type, _max); \
return(&bug); \ return &bug; \
} \ } \
return(&_table[event_subtype._type][(int)state]); return &_table[event_subtype._type][(int)state];
sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
sctp_state_t state, sctp_state_t state,
...@@ -71,7 +72,7 @@ sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, ...@@ -71,7 +72,7 @@ sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
return sctp_chunk_event_lookup(event_subtype.chunk, state); return sctp_chunk_event_lookup(event_subtype.chunk, state);
break; break;
case SCTP_EVENT_T_TIMEOUT: case SCTP_EVENT_T_TIMEOUT:
DO_LOOKUP(SCTP_EVENT_TIMEOUT_MAX, timeout, DO_LOOKUP(SCTP_EVENT_TIMEOUT_MAX, timeout,
timeout_event_table); timeout_event_table);
break; break;
...@@ -92,320 +93,323 @@ sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, ...@@ -92,320 +93,323 @@ sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
#define TYPE_SCTP_DATA { \ #define TYPE_SCTP_DATA { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_tabort_8_4_8, name: "sctp_sf_tabort_8_4_8"}, \ {.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_eat_data_6_2, name: "sctp_sf_eat_data_6_2"}, \ {.fn = sctp_sf_eat_data_6_2, .name = "sctp_sf_eat_data_6_2"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_eat_data_6_2, name: "sctp_sf_eat_data_6_2"}, \ {.fn = sctp_sf_eat_data_6_2, .name = "sctp_sf_eat_data_6_2"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_eat_data_fast_4_4, name: "sctp_sf_eat_data_fast_4_4"}, \ {.fn = sctp_sf_eat_data_fast_4_4, .name = "sctp_sf_eat_data_fast_4_4"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
} /* TYPE_SCTP_DATA */ } /* TYPE_SCTP_DATA */
#define TYPE_SCTP_INIT { \ #define TYPE_SCTP_INIT { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_do_5_1B_init, name: "sctp_sf_do_5_1B_init"}, \ {.fn = sctp_sf_do_5_1B_init, .name = "sctp_sf_do_5_1B_init"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_do_5_2_1_siminit, name: "sctp_sf_do_5_2_1_siminit"}, \ {.fn = sctp_sf_do_5_2_1_siminit, .name = "sctp_sf_do_5_2_1_siminit"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_do_5_2_1_siminit, name: "sctp_sf_do_5_2_1_siminit"}, \ {.fn = sctp_sf_do_5_2_1_siminit, .name = "sctp_sf_do_5_2_1_siminit"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_do_5_2_2_dupinit, name: "sctp_sf_do_5_2_2_dupinit"}, \ {.fn = sctp_sf_do_5_2_2_dupinit, .name = "sctp_sf_do_5_2_2_dupinit"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_do_5_2_2_dupinit, name: "sctp_sf_do_5_2_2_dupinit"}, \ {.fn = sctp_sf_do_5_2_2_dupinit, .name = "sctp_sf_do_5_2_2_dupinit"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_do_5_2_2_dupinit, name: "sctp_sf_do_5_2_2_dupinit"}, \ {.fn = sctp_sf_do_5_2_2_dupinit, .name = "sctp_sf_do_5_2_2_dupinit"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_do_5_2_2_dupinit, name: "sctp_sf_do_5_2_2_dupinit"}, \ {.fn = sctp_sf_do_5_2_2_dupinit, .name = "sctp_sf_do_5_2_2_dupinit"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_do_9_2_reshutack, .name = "sctp_sf_do_9_2_reshutack"}, \
} /* TYPE_SCTP_INIT */ } /* TYPE_SCTP_INIT */
#define TYPE_SCTP_INIT_ACK { \ #define TYPE_SCTP_INIT_ACK { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_do_5_1C_ack, name: "sctp_sf_do_5_1C_ack"}, \ {.fn = sctp_sf_do_5_1C_ack, .name = "sctp_sf_do_5_1C_ack"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
} /* TYPE_SCTP_INIT_ACK */ } /* TYPE_SCTP_INIT_ACK */
#define TYPE_SCTP_SACK { \ #define TYPE_SCTP_SACK { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_tabort_8_4_8, name: "sctp_sf_tabort_8_4_8"}, \ {.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_eat_sack_6_2, name: "sctp_sf_eat_sack_6_2"}, \ {.fn = sctp_sf_eat_sack_6_2, .name = "sctp_sf_eat_sack_6_2"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_eat_sack_6_2, name: "sctp_sf_eat_sack_6_2"}, \ {.fn = sctp_sf_eat_sack_6_2, .name = "sctp_sf_eat_sack_6_2"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_eat_sack_6_2, name: "sctp_sf_eat_sack_6_2"}, \ {.fn = sctp_sf_eat_sack_6_2, .name = "sctp_sf_eat_sack_6_2"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_eat_sack_6_2, name: "sctp_sf_eat_sack_6_2"}, \ {.fn = sctp_sf_eat_sack_6_2, .name = "sctp_sf_eat_sack_6_2"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
} /* TYPE_SCTP_SACK */ } /* TYPE_SCTP_SACK */
#define TYPE_SCTP_HEARTBEAT { \ #define TYPE_SCTP_HEARTBEAT { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_tabort_8_4_8, name: "sctp_sf_tabort_8_4_8"}, \ {.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_beat_8_3, name: "sctp_sf_beat_8_3"}, \ {.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_beat_8_3, name: "sctp_sf_beat_8_3"}, \ {.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_beat_8_3, name: "sctp_sf_beat_8_3"}, \ {.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_beat_8_3, name: "sctp_sf_beat_8_3"}, \ {.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_beat_8_3, name: "sctp_sf_beat_8_3"}, \ {.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
/* This should not happen, but we are nice. */ \ /* This should not happen, but we are nice. */ \
{fn: sctp_sf_beat_8_3, name: "sctp_sf_beat_8_3"}, \ {.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \
} /* TYPE_SCTP_HEARTBEAT */ } /* TYPE_SCTP_HEARTBEAT */
#define TYPE_SCTP_HEARTBEAT_ACK { \ #define TYPE_SCTP_HEARTBEAT_ACK { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_tabort_8_4_8, name: "sctp_sf_tabort_8_4_8"}, \ {.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_violation, name: "sctp_sf_violation"}, \ {.fn = sctp_sf_violation, .name = "sctp_sf_violation"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_backbeat_8_3, name: "sctp_sf_backbeat_8_3"}, \ {.fn = sctp_sf_backbeat_8_3, .name = "sctp_sf_backbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_backbeat_8_3, name: "sctp_sf_backbeat_8_3"}, \ {.fn = sctp_sf_backbeat_8_3, .name = "sctp_sf_backbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_backbeat_8_3, name: "sctp_sf_backbeat_8_3"}, \ {.fn = sctp_sf_backbeat_8_3, .name = "sctp_sf_backbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_backbeat_8_3, name: "sctp_sf_backbeat_8_3"}, \ {.fn = sctp_sf_backbeat_8_3, .name = "sctp_sf_backbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} /* TYPE_SCTP_HEARTBEAT_ACK */ } /* TYPE_SCTP_HEARTBEAT_ACK */
#define TYPE_SCTP_ABORT { \ #define TYPE_SCTP_ABORT { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_pdiscard, name: "sctp_sf_pdiscard"}, \ {.fn = sctp_sf_pdiscard, .name = "sctp_sf_pdiscard"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_cookie_wait_abort, name: "sctp_sf_cookie_wait_abort"}, \ {.fn = sctp_sf_cookie_wait_abort, .name = "sctp_sf_cookie_wait_abort"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_cookie_echoed_abort, \ {.fn = sctp_sf_cookie_echoed_abort, \
name: "sctp_sf_cookie_echoed_abort"}, \ .name = "sctp_sf_cookie_echoed_abort"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_do_9_1_abort, name: "sctp_sf_do_9_1_abort"}, \ {.fn = sctp_sf_do_9_1_abort, .name = "sctp_sf_do_9_1_abort"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_do_9_1_abort, name: "sctp_sf_do_9_1_abort"}, \ {.fn = sctp_sf_shutdown_pending_abort, \
.name = "sctp_sf_shutdown_pending_abort"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_do_9_1_abort, name: "sctp_sf_do_9_1_abort"}, \ {.fn = sctp_sf_shutdown_sent_abort, \
.name = "sctp_sf_shutdown_sent_abort"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_do_9_1_abort, name: "sctp_sf_do_9_1_abort"}, \ {.fn = sctp_sf_do_9_1_abort, .name = "sctp_sf_do_9_1_abort"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_do_9_1_abort, name: "sctp_sf_do_9_1_abort"}, \ {.fn = sctp_sf_shutdown_ack_sent_abort, \
.name = "sctp_sf_shutdown_ack_sent_abort"}, \
} /* TYPE_SCTP_ABORT */ } /* TYPE_SCTP_ABORT */
#define TYPE_SCTP_SHUTDOWN { \ #define TYPE_SCTP_SHUTDOWN { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_tabort_8_4_8, name: "sctp_sf_tabort_8_4_8"}, \ {.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_do_9_2_shutdown, name: "sctp_sf_do_9_2_shutdown"}, \ {.fn = sctp_sf_do_9_2_shutdown, .name = "sctp_sf_do_9_2_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_do_9_2_shutdown_ack, \ {.fn = sctp_sf_do_9_2_shutdown_ack, \
name: "sctp_sf_do_9_2_shutdown_ack"}, \ .name = "sctp_sf_do_9_2_shutdown_ack"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
} /* TYPE_SCTP_SHUTDOWN */ } /* TYPE_SCTP_SHUTDOWN */
#define TYPE_SCTP_SHUTDOWN_ACK { \ #define TYPE_SCTP_SHUTDOWN_ACK { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_violation, name: "sctp_sf_violation"}, \ {.fn = sctp_sf_violation, .name = "sctp_sf_violation"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_violation, name: "sctp_sf_violation"}, \ {.fn = sctp_sf_violation, .name = "sctp_sf_violation"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_do_9_2_final, name: "sctp_sf_do_9_2_final"}, \ {.fn = sctp_sf_do_9_2_final, .name = "sctp_sf_do_9_2_final"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_violation, name: "sctp_sf_violation"}, \ {.fn = sctp_sf_violation, .name = "sctp_sf_violation"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_do_9_2_final, name: "sctp_sf_do_9_2_final"}, \ {.fn = sctp_sf_do_9_2_final, .name = "sctp_sf_do_9_2_final"}, \
} /* TYPE_SCTP_SHUTDOWN_ACK */ } /* TYPE_SCTP_SHUTDOWN_ACK */
#define TYPE_SCTP_ERROR { \ #define TYPE_SCTP_ERROR { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_tabort_8_4_8, name: "sctp_sf_tabort_8_4_8"}, \ {.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_operr_notify, name: "sctp_sf_operr_notify"}, \ {.fn = sctp_sf_operr_notify, .name = "sctp_sf_operr_notify"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} /* TYPE_SCTP_ERROR */ } /* TYPE_SCTP_ERROR */
#define TYPE_SCTP_COOKIE_ECHO { \ #define TYPE_SCTP_COOKIE_ECHO { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_do_5_1D_ce, name: "sctp_sf_do_5_1D_ce"}, \ {.fn = sctp_sf_do_5_1D_ce, .name = "sctp_sf_do_5_1D_ce"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_do_5_2_4_dupcook, name: "sctp_sf_do_5_2_4_dupcook"}, \ {.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_do_5_2_4_dupcook, name: "sctp_sf_do_5_2_4_dupcook"}, \ {.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_do_5_2_4_dupcook, name: "sctp_sf_do_5_2_4_dupcook"}, \ {.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_do_5_2_4_dupcook, name: "sctp_sf_do_5_2_4_dupcook"}, \ {.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_do_5_2_4_dupcook, name: "sctp_sf_do_5_2_4_dupcook"}, \ {.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_do_5_2_4_dupcook, name: "sctp_sf_do_5_2_4_dupcook"}, \ {.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_do_5_2_4_dupcook, name: "sctp_sf_do_5_2_4_dupcook"}, \ {.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \
} /* TYPE_SCTP_COOKIE_ECHO */ } /* TYPE_SCTP_COOKIE_ECHO */
#define TYPE_SCTP_COOKIE_ACK { \ #define TYPE_SCTP_COOKIE_ACK { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_do_5_1E_ca, name: "sctp_sf_do_5_1E_ca"}, \ {.fn = sctp_sf_do_5_1E_ca, .name = "sctp_sf_do_5_1E_ca"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
} /* TYPE_SCTP_COOKIE_ACK */ } /* TYPE_SCTP_COOKIE_ACK */
#define TYPE_SCTP_ECN_ECNE { \ #define TYPE_SCTP_ECN_ECNE { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_do_ecne, name: "sctp_sf_do_ecne"}, \ {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_do_ecne, name: "sctp_sf_do_ecne"}, \ {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_do_ecne, name: "sctp_sf_do_ecne"}, \ {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_do_ecne, name: "sctp_sf_do_ecne"}, \ {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_do_ecne, name: "sctp_sf_do_ecne"}, \ {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
} /* TYPE_SCTP_ECN_ECNE */ } /* TYPE_SCTP_ECN_ECNE */
#define TYPE_SCTP_ECN_CWR { \ #define TYPE_SCTP_ECN_CWR { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_do_ecn_cwr, name: "sctp_sf_do_ecn_cwr"}, \ {.fn = sctp_sf_do_ecn_cwr, .name = "sctp_sf_do_ecn_cwr"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_do_ecn_cwr, name: "sctp_sf_do_ecn_cwr"}, \ {.fn = sctp_sf_do_ecn_cwr, .name = "sctp_sf_do_ecn_cwr"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_do_ecn_cwr, name: "sctp_sf_do_ecn_cwr"}, \ {.fn = sctp_sf_do_ecn_cwr, .name = "sctp_sf_do_ecn_cwr"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
} /* TYPE_SCTP_ECN_CWR */ } /* TYPE_SCTP_ECN_CWR */
#define TYPE_SCTP_SHUTDOWN_COMPLETE { \ #define TYPE_SCTP_SHUTDOWN_COMPLETE { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_ootb, name: "sctp_sf_ootb"}, \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_do_4_C, name: "sctp_sf_do_4_C"}, \ {.fn = sctp_sf_do_4_C, .name = "sctp_sf_do_4_C"}, \
} /* TYPE_SCTP_SHUTDOWN_COMPLETE */ } /* TYPE_SCTP_SHUTDOWN_COMPLETE */
/* The primary index for this table is the chunk type. /* The primary index for this table is the chunk type.
...@@ -434,397 +438,415 @@ sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NU ...@@ -434,397 +438,415 @@ sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NU
static sctp_sm_table_entry_t static sctp_sm_table_entry_t
chunk_event_table_asconf[SCTP_STATE_NUM_STATES] = { chunk_event_table_asconf[SCTP_STATE_NUM_STATES] = {
/* SCTP_STATE_EMPTY */ /* SCTP_STATE_EMPTY */
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
/* SCTP_STATE_CLOSED */ /* SCTP_STATE_CLOSED */
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
/* SCTP_STATE_COOKIE_WAIT */ /* SCTP_STATE_COOKIE_WAIT */
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
/* SCTP_STATE_COOKIE_ECHOED */ /* SCTP_STATE_COOKIE_ECHOED */
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
/* SCTP_STATE_ESTABLISHED */ /* SCTP_STATE_ESTABLISHED */
{fn: sctp_sf_discard_chunk, {.fn = sctp_sf_discard_chunk,
name: "sctp_sf_discard_chunk (will be sctp_addip_do_asconf)"}, .name = "sctp_sf_discard_chunk (will be sctp_addip_do_asconf)"},
/* SCTP_STATE_SHUTDOWN_PENDING */ /* SCTP_STATE_SHUTDOWN_PENDING */
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
/* SCTP_STATE_SHUTDOWN_SENT */ /* SCTP_STATE_SHUTDOWN_SENT */
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
/* SCTP_STATE_SHUTDOWN_RECEIVED */ /* SCTP_STATE_SHUTDOWN_RECEIVED */
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ /* SCTP_STATE_SHUTDOWN_ACK_SENT */
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
}; /* chunk asconf */ }; /* chunk asconf */
static sctp_sm_table_entry_t static sctp_sm_table_entry_t
chunk_event_table_asconf_ack[SCTP_STATE_NUM_STATES] = { chunk_event_table_asconf_ack[SCTP_STATE_NUM_STATES] = {
/* SCTP_STATE_EMPTY */ /* SCTP_STATE_EMPTY */
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
/* SCTP_STATE_CLOSED */ /* SCTP_STATE_CLOSED */
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
/* SCTP_STATE_COOKIE_WAIT */ /* SCTP_STATE_COOKIE_WAIT */
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
/* SCTP_STATE_COOKIE_ECHOED */ /* SCTP_STATE_COOKIE_ECHOED */
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
/* SCTP_STATE_ESTABLISHED */ /* SCTP_STATE_ESTABLISHED */
{fn: sctp_sf_discard_chunk, {.fn = sctp_sf_discard_chunk,
name: "sctp_sf_discard_chunk (will be sctp_addip_do_asconf_ack)"}, .name = "sctp_sf_discard_chunk (will be sctp_addip_do_asconf_ack)"},
/* SCTP_STATE_SHUTDOWN_PENDING */ /* SCTP_STATE_SHUTDOWN_PENDING */
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
/* SCTP_STATE_SHUTDOWN_SENT */ /* SCTP_STATE_SHUTDOWN_SENT */
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
/* SCTP_STATE_SHUTDOWN_RECEIVED */ /* SCTP_STATE_SHUTDOWN_RECEIVED */
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ /* SCTP_STATE_SHUTDOWN_ACK_SENT */
{fn: sctp_sf_discard_chunk, name: "sctp_sf_discard_chunk"}, {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"},
}; /* chunk asconf_ack */ }; /* chunk asconf_ack */
static sctp_sm_table_entry_t
chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
/* SCTP_STATE_EMPTY */
{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"},
/* SCTP_STATE_CLOSED */
{.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"},
/* SCTP_STATE_COOKIE_WAIT */
{.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"},
/* SCTP_STATE_COOKIE_ECHOED */
{.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"},
/* SCTP_STATE_ESTABLISHED */
{.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"},
/* SCTP_STATE_SHUTDOWN_PENDING */
{.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"},
/* SCTP_STATE_SHUTDOWN_SENT */
{.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"},
/* SCTP_STATE_SHUTDOWN_RECEIVED */
{.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"},
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
{.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"},
}; /* chunk unknown */
#define TYPE_SCTP_PRIMITIVE_INITIALIZE { \ #define TYPE_SCTP_PRIMITIVE_INITIALIZE { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} /* TYPE_SCTP_PRIMITIVE_INITIALIZE */ } /* TYPE_SCTP_PRIMITIVE_INITIALIZE */
#define TYPE_SCTP_PRIMITIVE_ASSOCIATE { \ #define TYPE_SCTP_PRIMITIVE_ASSOCIATE { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_do_prm_asoc, name: "sctp_sf_do_prm_asoc"}, \ {.fn = sctp_sf_do_prm_asoc, .name = "sctp_sf_do_prm_asoc"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} /* TYPE_SCTP_PRIMITIVE_ASSOCIATE */ } /* TYPE_SCTP_PRIMITIVE_ASSOCIATE */
#define TYPE_SCTP_PRIMITIVE_SHUTDOWN { \ #define TYPE_SCTP_PRIMITIVE_SHUTDOWN { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_error_closed, name: "sctp_sf_error_closed"}, \ {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_cookie_wait_prm_shutdown, \ {.fn = sctp_sf_cookie_wait_prm_shutdown, \
name: "sctp_sf_cookie_wait_prm_shutdown"}, \ .name = "sctp_sf_cookie_wait_prm_shutdown"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_cookie_echoed_prm_shutdown, \ {.fn = sctp_sf_cookie_echoed_prm_shutdown, \
name:"sctp_sf_cookie_echoed_prm_shutdown"},\ name:"sctp_sf_cookie_echoed_prm_shutdown"},\
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_do_9_2_prm_shutdown, \ {.fn = sctp_sf_do_9_2_prm_shutdown, \
name: "sctp_sf_do_9_2_prm_shutdown"}, \ .name = "sctp_sf_do_9_2_prm_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_ignore_primitive, name: "sctp_sf_ignore_primitive"}, \ {.fn = sctp_sf_ignore_primitive, .name = "sctp_sf_ignore_primitive"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_ignore_primitive, name: "sctp_sf_ignore_primitive"}, \ {.fn = sctp_sf_ignore_primitive, .name = "sctp_sf_ignore_primitive"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_ignore_primitive, name: "sctp_sf_ignore_primitive"}, \ {.fn = sctp_sf_ignore_primitive, .name = "sctp_sf_ignore_primitive"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_ignore_primitive, name: "sctp_sf_ignore_primitive"}, \ {.fn = sctp_sf_ignore_primitive, .name = "sctp_sf_ignore_primitive"}, \
} /* TYPE_SCTP_PRIMITIVE_SHUTDOWN */ } /* TYPE_SCTP_PRIMITIVE_SHUTDOWN */
#define TYPE_SCTP_PRIMITIVE_ABORT { \ #define TYPE_SCTP_PRIMITIVE_ABORT { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_error_closed, name: "sctp_sf_error_closed"}, \ {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_cookie_wait_prm_abort, \ {.fn = sctp_sf_cookie_wait_prm_abort, \
name: "sctp_sf_cookie_wait_prm_abort"}, \ .name = "sctp_sf_cookie_wait_prm_abort"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_cookie_echoed_prm_abort, \ {.fn = sctp_sf_cookie_echoed_prm_abort, \
name: "sctp_sf_cookie_echoed_prm_abort"}, \ .name = "sctp_sf_cookie_echoed_prm_abort"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_do_9_1_prm_abort, \ {.fn = sctp_sf_do_9_1_prm_abort, \
name: "sctp_sf_do_9_1_prm_abort"}, \ .name = "sctp_sf_do_9_1_prm_abort"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_do_9_1_prm_abort, \ {.fn = sctp_sf_shutdown_pending_prm_abort, \
name: "sctp_sf_do_9_1_prm_abort"}, \ .name = "sctp_sf_shutdown_pending_prm_abort"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_do_9_1_prm_abort, \ {.fn = sctp_sf_shutdown_sent_prm_abort, \
name: "sctp_sf_do_9_1_prm_abort"}, \ .name = "sctp_sf_shutdown_sent_prm_abort"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_do_9_1_prm_abort, \ {.fn = sctp_sf_do_9_1_prm_abort, \
name: "sctp_sf_do_9_1_prm_abort"}, \ .name = "sctp_sf_do_9_1_prm_abort"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_do_9_1_prm_abort, \ {.fn = sctp_sf_shutdown_ack_sent_prm_abort, \
name: "sctp_sf_do_9_1_prm_abort"}, \ .name = "sctp_sf_shutdown_ack_sent_prm_abort"}, \
} /* TYPE_SCTP_PRIMITIVE_ABORT */ } /* TYPE_SCTP_PRIMITIVE_ABORT */
#define TYPE_SCTP_PRIMITIVE_SEND { \ #define TYPE_SCTP_PRIMITIVE_SEND { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_error_closed, name: "sctp_sf_error_closed"}, \ {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_do_prm_send, name: "sctp_sf_do_prm_send"}, \ {.fn = sctp_sf_do_prm_send, .name = "sctp_sf_do_prm_send"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_do_prm_send, name: "sctp_sf_do_prm_send"}, \ {.fn = sctp_sf_do_prm_send, .name = "sctp_sf_do_prm_send"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_do_prm_send, name: "sctp_sf_do_prm_send"}, \ {.fn = sctp_sf_do_prm_send, .name = "sctp_sf_do_prm_send"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_error_shutdown, name: "sctp_sf_error_shutdown"}, \ {.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_error_shutdown, name: "sctp_sf_error_shutdown"}, \ {.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_error_shutdown, name: "sctp_sf_error_shutdown"}, \ {.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_error_shutdown, name: "sctp_sf_error_shutdown"}, \ {.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \
} /* TYPE_SCTP_PRIMITIVE_SEND */ } /* TYPE_SCTP_PRIMITIVE_SEND */
#define TYPE_SCTP_PRIMITIVE_SETPRIMARY { \ #define TYPE_SCTP_PRIMITIVE_SETPRIMARY { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} /* TYPE_SCTP_PRIMITIVE_SETPRIMARY */ } /* TYPE_SCTP_PRIMITIVE_SETPRIMARY */
#define TYPE_SCTP_PRIMITIVE_RECEIVE { \ #define TYPE_SCTP_PRIMITIVE_RECEIVE { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} /* TYPE_SCTP_PRIMITIVE_RECEIVE */ } /* TYPE_SCTP_PRIMITIVE_RECEIVE */
#define TYPE_SCTP_PRIMITIVE_STATUS { \ #define TYPE_SCTP_PRIMITIVE_STATUS { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} /* TYPE_SCTP_PRIMITIVE_STATUS */ } /* TYPE_SCTP_PRIMITIVE_STATUS */
#define TYPE_SCTP_PRIMITIVE_CHANGEHEARTBEAT { \ #define TYPE_SCTP_PRIMITIVE_CHANGEHEARTBEAT { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} /* TYPE_SCTP_PRIMITIVE_CHANGEHEARTBEAT */ } /* TYPE_SCTP_PRIMITIVE_CHANGEHEARTBEAT */
#define TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT { \ #define TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */ } /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */
#define TYPE_SCTP_PRIMITIVE_GETSRTTREPORT { \ #define TYPE_SCTP_PRIMITIVE_GETSRTTREPORT { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} /* TYPE_SCTP_PRIMITIVE_GETSRTTREPORT */ } /* TYPE_SCTP_PRIMITIVE_GETSRTTREPORT */
#define TYPE_SCTP_PRIMITIVE_SETFAILURETHRESHOLD { \ #define TYPE_SCTP_PRIMITIVE_SETFAILURETHRESHOLD { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} /* TYPE_SCTP_PRIMITIVE_SETFAILURETHRESHOLD */ } /* TYPE_SCTP_PRIMITIVE_SETFAILURETHRESHOLD */
#define TYPE_SCTP_PRIMITIVE_SETPROTOPARAMETERS { \ #define TYPE_SCTP_PRIMITIVE_SETPROTOPARAMETERS { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} /* TYPE_SCTP_PRIMITIVE_SETPROTOPARAMETERS */ } /* TYPE_SCTP_PRIMITIVE_SETPROTOPARAMETERS */
#define TYPE_SCTP_PRIMITIVE_RECEIVE_UNSENT { \ #define TYPE_SCTP_PRIMITIVE_RECEIVE_UNSENT { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} /* TYPE_SCTP_PRIMITIVE_RECEIVE_UNSENT */ } /* TYPE_SCTP_PRIMITIVE_RECEIVE_UNSENT */
#define TYPE_SCTP_PRIMITIVE_RECEIVE_UNACKED { \ #define TYPE_SCTP_PRIMITIVE_RECEIVE_UNACKED { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} /* TYPE_SCTP_PRIMITIVE_RECEIVE_UNACKED */ } /* TYPE_SCTP_PRIMITIVE_RECEIVE_UNACKED */
#define TYPE_SCTP_PRIMITIVE_DESTROY { \ #define TYPE_SCTP_PRIMITIVE_DESTROY { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} /* TYPE_SCTP_PRIMITIVE_DESTROY */ } /* TYPE_SCTP_PRIMITIVE_DESTROY */
/* The primary index for this table is the primitive type. /* The primary index for this table is the primitive type.
...@@ -851,46 +873,46 @@ sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE ...@@ -851,46 +873,46 @@ sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE
#define TYPE_SCTP_OTHER_NO_PENDING_TSN { \ #define TYPE_SCTP_OTHER_NO_PENDING_TSN { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_ignore_other, name: "sctp_sf_ignore_other"}, \ {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_ignore_other, name: "sctp_sf_ignore_other"}, \ {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_ignore_other, name: "sctp_sf_ignore_other"}, \ {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_ignore_other, name: "sctp_sf_ignore_other"}, \ {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_do_9_2_start_shutdown, \ {.fn = sctp_sf_do_9_2_start_shutdown, \
name: "sctp_do_9_2_start_shutdown"}, \ .name = "sctp_do_9_2_start_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_ignore_other, name: "sctp_sf_ignore_other"}, \ {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_do_9_2_shutdown_ack, \ {.fn = sctp_sf_do_9_2_shutdown_ack, \
name: "sctp_sf_do_9_2_shutdown_ack"}, \ .name = "sctp_sf_do_9_2_shutdown_ack"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_ignore_other, name: "sctp_sf_ignore_other"}, \ {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
} }
#define TYPE_SCTP_OTHER_ICMP_UNREACHFRAG { \ #define TYPE_SCTP_OTHER_ICMP_UNREACHFRAG { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} }
sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = { sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = {
...@@ -900,213 +922,234 @@ sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STA ...@@ -900,213 +922,234 @@ sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STA
#define TYPE_SCTP_EVENT_TIMEOUT_NONE { \ #define TYPE_SCTP_EVENT_TIMEOUT_NONE { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
} }
#define TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE { \ #define TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_t1_timer_expire, name: "sctp_sf_t1_timer_expire"}, \ {.fn = sctp_sf_t1_timer_expire, .name = "sctp_sf_t1_timer_expire"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
} }
#define TYPE_SCTP_EVENT_TIMEOUT_T1_INIT { \ #define TYPE_SCTP_EVENT_TIMEOUT_T1_INIT { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_t1_timer_expire, name: "sctp_sf_t1_timer_expire"}, \ {.fn = sctp_sf_t1_timer_expire, .name = "sctp_sf_t1_timer_expire"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
} }
#define TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN { \ #define TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_t2_timer_expire, name: "sctp_sf_t2_timer_expire"}, \ {.fn = sctp_sf_t2_timer_expire, .name = "sctp_sf_t2_timer_expire"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_t2_timer_expire, name: "sctp_sf_t2_timer_expire"}, \ {.fn = sctp_sf_t2_timer_expire, .name = "sctp_sf_t2_timer_expire"}, \
} }
#define TYPE_SCTP_EVENT_TIMEOUT_T3_RTX { \ #define TYPE_SCTP_EVENT_TIMEOUT_T3_RTX { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_do_6_3_3_rtx, name: "sctp_sf_do_6_3_3_rtx"}, \ {.fn = sctp_sf_do_6_3_3_rtx, .name = "sctp_sf_do_6_3_3_rtx"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_do_6_3_3_rtx, name: "sctp_sf_do_6_3_3_rtx"}, \ {.fn = sctp_sf_do_6_3_3_rtx, .name = "sctp_sf_do_6_3_3_rtx"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_do_6_3_3_rtx, name: "sctp_sf_do_6_3_3_rtx"}, \ {.fn = sctp_sf_do_6_3_3_rtx, .name = "sctp_sf_do_6_3_3_rtx"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_do_6_3_3_rtx, name: "sctp_sf_do_6_3_3_rtx"}, \ {.fn = sctp_sf_do_6_3_3_rtx, .name = "sctp_sf_do_6_3_3_rtx"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
} }
#define TYPE_SCTP_EVENT_TIMEOUT_T4_RTO { \ #define TYPE_SCTP_EVENT_TIMEOUT_T4_RTO { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_CLOSED */ \
{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */ \
{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \
{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \
{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \
{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \
{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD { \
/* SCTP_STATE_EMPTY */ \
{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_t5_timer_expire, .name = "sctp_sf_t5_timer_expire"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
} }
#define TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT { \ #define TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_sendbeat_8_3, name: "sctp_sf_sendbeat_8_3"}, \ {.fn = sctp_sf_sendbeat_8_3, .name = "sctp_sf_sendbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_sendbeat_8_3, name: "sctp_sf_sendbeat_8_3"}, \ {.fn = sctp_sf_sendbeat_8_3, .name = "sctp_sf_sendbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} }
#define TYPE_SCTP_EVENT_TIMEOUT_SACK { \ #define TYPE_SCTP_EVENT_TIMEOUT_SACK { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_do_6_2_sack, name: "sctp_sf_do_6_2_sack"}, \ {.fn = sctp_sf_do_6_2_sack, .name = "sctp_sf_do_6_2_sack"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_do_6_2_sack, name: "sctp_sf_do_6_2_sack"}, \ {.fn = sctp_sf_do_6_2_sack, .name = "sctp_sf_do_6_2_sack"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_do_6_2_sack, name: "sctp_sf_do_6_2_sack"}, \ {.fn = sctp_sf_do_6_2_sack, .name = "sctp_sf_do_6_2_sack"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
} }
#define TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE { \ #define TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_autoclose_timer_expire, \ {.fn = sctp_sf_autoclose_timer_expire, \
name: "sctp_sf_autoclose_timer_expire"}, \ .name = "sctp_sf_autoclose_timer_expire"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_timer_ignore, name: "sctp_sf_timer_ignore"}, \ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
} }
#define TYPE_SCTP_EVENT_TIMEOUT_PMTU_RAISE { \ #define TYPE_SCTP_EVENT_TIMEOUT_PMTU_RAISE { \
/* SCTP_STATE_EMPTY */ \ /* SCTP_STATE_EMPTY */ \
{fn: sctp_sf_bug, name: "sctp_sf_bug"}, \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */ \ /* SCTP_STATE_CLOSED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */ \ /* SCTP_STATE_COOKIE_WAIT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */ \ /* SCTP_STATE_COOKIE_ECHOED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */ \ /* SCTP_STATE_ESTABLISHED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */ \ /* SCTP_STATE_SHUTDOWN_PENDING */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */ \ /* SCTP_STATE_SHUTDOWN_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */ \ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \ {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
} }
sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = { sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = {
...@@ -1116,6 +1159,7 @@ sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM ...@@ -1116,6 +1159,7 @@ sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM
TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN, TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN,
TYPE_SCTP_EVENT_TIMEOUT_T3_RTX, TYPE_SCTP_EVENT_TIMEOUT_T3_RTX,
TYPE_SCTP_EVENT_TIMEOUT_T4_RTO, TYPE_SCTP_EVENT_TIMEOUT_T4_RTO,
TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD,
TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT, TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT,
TYPE_SCTP_EVENT_TIMEOUT_SACK, TYPE_SCTP_EVENT_TIMEOUT_SACK,
TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE, TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE,
...@@ -1125,12 +1169,11 @@ sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM ...@@ -1125,12 +1169,11 @@ sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM
sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, sctp_state_t state) sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, sctp_state_t state)
{ {
if (state > SCTP_STATE_MAX) if (state > SCTP_STATE_MAX)
BUG(); return &bug;
if (cid < 0)
return &nop;
if (cid <= SCTP_CID_BASE_MAX) if (cid >= 0 && cid <= SCTP_CID_BASE_MAX) {
return &chunk_event_table[cid][state]; return &chunk_event_table[cid][state];
}
switch (cid) { switch (cid) {
case SCTP_CID_ASCONF: case SCTP_CID_ASCONF:
...@@ -1139,8 +1182,6 @@ sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, sctp_state_t stat ...@@ -1139,8 +1182,6 @@ sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, sctp_state_t stat
case SCTP_CID_ASCONF_ACK: case SCTP_CID_ASCONF_ACK:
return &chunk_event_table_asconf_ack[state]; return &chunk_event_table_asconf_ack[state];
default: default:
return &nop; return &chunk_event_table_unknown[state];
}; }
return &nop;
} }
/* Copyright (c) 1999-2000 Cisco, Inc. /* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc. * Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001 International Business Machines, Corp. * Copyright (c) 2001-2002 International Business Machines, Corp.
* Copyright (c) 2001 Intel Corp. * Copyright (c) 2001-2002 Intel Corp.
* Copyright (c) 2001 Nokia, Inc. * Copyright (c) 2001-2002 Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll * Copyright (c) 2001 La Monte H.P. Yarroll
* *
* This file is part of the SCTP kernel reference Implementation * This file is part of the SCTP kernel reference Implementation
...@@ -82,8 +82,6 @@ static void sctp_wfree(struct sk_buff *skb); ...@@ -82,8 +82,6 @@ static void sctp_wfree(struct sk_buff *skb);
static int sctp_wait_for_sndbuf(sctp_association_t *asoc, long *timeo_p, static int sctp_wait_for_sndbuf(sctp_association_t *asoc, long *timeo_p,
int msg_len); int msg_len);
static int sctp_wait_for_packet(struct sock * sk, int *err, long *timeo_p); static int sctp_wait_for_packet(struct sock * sk, int *err, long *timeo_p);
static inline void sctp_sk_memcpy_msgname(struct sock *sk, char * msgname,
int *addr_len, struct sk_buff *skb);
static inline void sctp_sk_addr_set(struct sock *, static inline void sctp_sk_addr_set(struct sock *,
const sockaddr_storage_t *newaddr, const sockaddr_storage_t *newaddr,
sockaddr_storage_t *saveaddr); sockaddr_storage_t *saveaddr);
...@@ -121,7 +119,7 @@ int sctp_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -121,7 +119,7 @@ int sctp_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
/* Disallow binding twice. */ /* Disallow binding twice. */
if (!sctp_sk(sk)->ep->base.bind_addr.port) if (!sctp_sk(sk)->ep->base.bind_addr.port)
retval = sctp_do_bind(sk, (sockaddr_storage_t *)uaddr, retval = sctp_do_bind(sk, (sockaddr_storage_t *)uaddr,
addr_len); addr_len);
else else
retval = -EINVAL; retval = -EINVAL;
...@@ -317,7 +315,7 @@ static int sctp_do_bind(struct sock *sk, sockaddr_storage_t *newaddr, int addr_l ...@@ -317,7 +315,7 @@ static int sctp_do_bind(struct sock *sk, sockaddr_storage_t *newaddr, int addr_l
/* Unprotected by locks. Call only with socket lock sk->lock held! See /* Unprotected by locks. Call only with socket lock sk->lock held! See
* sctp_bindx() for a lock-protected call. * sctp_bindx() for a lock-protected call.
*/ */
static int __sctp_bindx(struct sock *sk, struct sockaddr_storage *addrs, static int __sctp_bindx(struct sock *sk, struct sockaddr_storage *addrs,
int addrcnt, int flags) int addrcnt, int flags)
...@@ -326,11 +324,11 @@ static int __sctp_bindx(struct sock *sk, struct sockaddr_storage *addrs, ...@@ -326,11 +324,11 @@ static int __sctp_bindx(struct sock *sk, struct sockaddr_storage *addrs,
SCTP_DEBUG_PRINTK("__sctp_bindx(sk: %p, addrs: %p, addrcnt: %d, " SCTP_DEBUG_PRINTK("__sctp_bindx(sk: %p, addrs: %p, addrcnt: %d, "
"flags: %s)\n", sk, addrs, addrcnt, "flags: %s)\n", sk, addrs, addrcnt,
(BINDX_ADD_ADDR == flags)?"ADD": (BINDX_ADD_ADDR == flags) ? "ADD" :
((BINDX_REM_ADDR == flags)?"REM":"BOGUS")); ((BINDX_REM_ADDR == flags) ? "REM" : "BOGUS"));
switch (flags) { switch (flags) {
case BINDX_ADD_ADDR: case BINDX_ADD_ADDR:
retval = sctp_bindx_add(sk, addrs, addrcnt); retval = sctp_bindx_add(sk, addrs, addrcnt);
break; break;
...@@ -411,7 +409,7 @@ int sctp_bindx_add(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt) ...@@ -411,7 +409,7 @@ int sctp_bindx_add(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
sctp_bindx_rem(sk, addrs, cnt); sctp_bindx_rem(sk, addrs, cnt);
return retval; return retval;
} }
} }
/* Notify the peer(s), assuming we have (an) association(s). /* Notify the peer(s), assuming we have (an) association(s).
* FIXME: for UDP, we have a 1-1-many mapping amongst sk, ep and asoc, * FIXME: for UDP, we have a 1-1-many mapping amongst sk, ep and asoc,
...@@ -500,9 +498,8 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt) ...@@ -500,9 +498,8 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
case AF_INET: case AF_INET:
saveaddr = *((sockaddr_storage_t *) saveaddr = *((sockaddr_storage_t *)
&addrs[cnt]); &addrs[cnt]);
saveaddr.v4.sin_port = saveaddr.v4.sin_port = ntohs(saveaddr.v4.sin_port);
ntohs(saveaddr.v4.sin_port); /* Verify the port. */
/* verify the port */
if (saveaddr.v4.sin_port != bp->port) { if (saveaddr.v4.sin_port != bp->port) {
retval = -EINVAL; retval = -EINVAL;
goto err_bindx_rem; goto err_bindx_rem;
...@@ -606,7 +603,8 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt) ...@@ -606,7 +603,8 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
* *
* Returns 0 if ok, <0 errno code on error. * Returns 0 if ok, <0 errno code on error.
*/ */
static int sctp_setsockopt_bindx(struct sock* sk, struct sockaddr_storage *addrs, static int sctp_setsockopt_bindx(struct sock* sk,
struct sockaddr_storage *addrs,
int addrssize, int op) int addrssize, int op)
{ {
struct sockaddr_storage *kaddrs; struct sockaddr_storage *kaddrs;
...@@ -614,8 +612,7 @@ static int sctp_setsockopt_bindx(struct sock* sk, struct sockaddr_storage *addrs ...@@ -614,8 +612,7 @@ static int sctp_setsockopt_bindx(struct sock* sk, struct sockaddr_storage *addrs
size_t addrcnt; size_t addrcnt;
SCTP_DEBUG_PRINTK("sctp_do_setsocktopt_bindx: sk %p addrs %p" SCTP_DEBUG_PRINTK("sctp_do_setsocktopt_bindx: sk %p addrs %p"
" addrssize %d opt %d\n", sk, addrs, " addrssize %d opt %d\n", sk, addrs, addrssize, op);
addrssize, op);
/* Do we have an integer number of structs sockaddr_storage? */ /* Do we have an integer number of structs sockaddr_storage? */
if (unlikely(addrssize <= 0 || if (unlikely(addrssize <= 0 ||
...@@ -781,7 +778,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size) ...@@ -781,7 +778,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
memcpy(&to, msg->msg_name, msg->msg_namelen); memcpy(&to, msg->msg_name, msg->msg_namelen);
SCTP_DEBUG_PRINTK("Just memcpy'd. msg_name is " SCTP_DEBUG_PRINTK("Just memcpy'd. msg_name is "
"0x%x:%u.\n", "0x%x:%u.\n",
to.v4.sin_addr.s_addr, to.v4.sin_port); to.v4.sin_addr.s_addr, to.v4.sin_port);
to.v4.sin_port = ntohs(to.v4.sin_port); to.v4.sin_port = ntohs(to.v4.sin_port);
...@@ -823,14 +820,14 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size) ...@@ -823,14 +820,14 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
} else { } else {
/* For a peeled-off socket, ignore any associd specified by /* For a peeled-off socket, ignore any associd specified by
* the user with SNDRCVINFO. * the user with SNDRCVINFO.
*/ */
if (SCTP_SOCKET_UDP_HIGH_BANDWIDTH == sp->type) { if (SCTP_SOCKET_UDP_HIGH_BANDWIDTH == sp->type) {
if (list_empty(&ep->asocs)) { if (list_empty(&ep->asocs)) {
err = -EINVAL; err = -EINVAL;
goto out_unlock; goto out_unlock;
} }
asoc = list_entry(ep->asocs.next, sctp_association_t, asoc = list_entry(ep->asocs.next, sctp_association_t,
asocs); asocs);
} else if (associd) { } else if (associd) {
asoc = sctp_id2assoc(sk, associd); asoc = sctp_id2assoc(sk, associd);
} }
...@@ -851,7 +848,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size) ...@@ -851,7 +848,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
goto out_unlock; goto out_unlock;
} }
if (sinfo_flags & MSG_ABORT) { if (sinfo_flags & MSG_ABORT) {
SCTP_DEBUG_PRINTK("Aborting association: %p\n",asoc); SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc);
sctp_primitive_ABORT(asoc, NULL); sctp_primitive_ABORT(asoc, NULL);
err = 0; err = 0;
goto out_unlock; goto out_unlock;
...@@ -866,8 +863,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size) ...@@ -866,8 +863,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
* either the default or the user specified stream counts. * either the default or the user specified stream counts.
*/ */
if (sinfo) { if (sinfo) {
if (!sinit || if (!sinit || (sinit && !sinit->sinit_num_ostreams)) {
(sinit && !sinit->sinit_num_ostreams)) {
/* Check against the defaults. */ /* Check against the defaults. */
if (sinfo->sinfo_stream >= if (sinfo->sinfo_stream >=
sp->initmsg.sinit_num_ostreams) { sp->initmsg.sinit_num_ostreams) {
...@@ -988,7 +984,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size) ...@@ -988,7 +984,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
/* If the user didn't specify SNDRCVINFO, make up one with /* If the user didn't specify SNDRCVINFO, make up one with
* some defaults. * some defaults.
*/ */
default_sinfo.sinfo_stream = asoc->defaults.stream; default_sinfo.sinfo_stream = asoc->defaults.stream;
default_sinfo.sinfo_ppid = asoc->defaults.ppid; default_sinfo.sinfo_ppid = asoc->defaults.ppid;
sinfo = &default_sinfo; sinfo = &default_sinfo;
} }
...@@ -1011,7 +1007,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size) ...@@ -1011,7 +1007,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
/* FIXME: This looks wrong so I'll comment out. /* FIXME: This looks wrong so I'll comment out.
* We should be able to use this same technique for * We should be able to use this same technique for
* primary address override! --jgrimm * primary address override! --jgrimm
*/ */
/* If the user gave us an address, copy it in. */ /* If the user gave us an address, copy it in. */
if (msg->msg_name) { if (msg->msg_name) {
chunk->transport = sctp_assoc_lookup_paddr(asoc, &to); chunk->transport = sctp_assoc_lookup_paddr(asoc, &to);
...@@ -1025,7 +1021,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size) ...@@ -1025,7 +1021,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
/* Copy the message from the user. */ /* Copy the message from the user. */
err = sctp_user_addto_chunk(chunk, msg_len, msg->msg_iov); err = sctp_user_addto_chunk(chunk, msg_len, msg->msg_iov);
if (err < 0) if (err < 0)
goto out_free; goto out_free;
SCTP_DEBUG_PRINTK("Copied message to chunk: %p.\n", chunk); SCTP_DEBUG_PRINTK("Copied message to chunk: %p.\n", chunk);
...@@ -1096,12 +1092,13 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size) ...@@ -1096,12 +1092,13 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
* flags - flags sent or received with the user message, see Section * flags - flags sent or received with the user message, see Section
* 5 for complete description of the flags. * 5 for complete description of the flags.
*/ */
static struct sk_buff * sctp_skb_recv_datagram(struct sock *, int, int, int *); static struct sk_buff *sctp_skb_recv_datagram(struct sock *, int, int, int *);
static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, int len, static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, int len,
int noblock, int flags, int *addr_len) int noblock, int flags, int *addr_len)
{ {
sctp_ulpevent_t *event = NULL; sctp_ulpevent_t *event = NULL;
sctp_opt_t *sp = sctp_sk(sk);
struct sk_buff *skb; struct sk_buff *skb;
int copied; int copied;
int err = 0; int err = 0;
...@@ -1147,19 +1144,16 @@ static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, int len, ...@@ -1147,19 +1144,16 @@ static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, int len,
sock_recv_timestamp(msg, sk, skb); sock_recv_timestamp(msg, sk, skb);
if (sctp_ulpevent_is_notification(event)) { if (sctp_ulpevent_is_notification(event)) {
msg->msg_flags |= MSG_NOTIFICATION; msg->msg_flags |= MSG_NOTIFICATION;
sp->pf->event_msgname(event, msg->msg_name, addr_len);
} else { } else {
/* Copy the address. */ sp->pf->skb_msgname(skb, msg->msg_name, addr_len);
if (addr_len && msg->msg_name)
sctp_sk_memcpy_msgname(sk, msg->msg_name,
addr_len, skb);
} }
/* Check if we allow SCTP_SNDRCVINFO. */ /* Check if we allow SCTP_SNDRCVINFO. */
if (sctp_sk(sk)->subscribe.sctp_data_io_event) if (sp->subscribe.sctp_data_io_event)
sctp_ulpevent_read_sndrcvinfo(event, msg); sctp_ulpevent_read_sndrcvinfo(event, msg);
#if 0 #if 0
/* FIXME: we should be calling IP layer too. */ /* FIXME: we should be calling IP/IPv6 layers. */
if (sk->protinfo.af_inet.cmsg_flags) if (sk->protinfo.af_inet.cmsg_flags)
ip_cmsg_recv(msg, skb); ip_cmsg_recv(msg, skb);
#endif #endif
...@@ -1176,7 +1170,8 @@ static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, int len, ...@@ -1176,7 +1170,8 @@ static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, int len,
return err; return err;
} }
static inline int sctp_setsockopt_disable_fragments(struct sock *sk, char *optval, int optlen) static inline int sctp_setsockopt_disable_fragments(struct sock *sk,
char *optval, int optlen)
{ {
int val; int val;
...@@ -1191,7 +1186,8 @@ static inline int sctp_setsockopt_disable_fragments(struct sock *sk, char *optva ...@@ -1191,7 +1186,8 @@ static inline int sctp_setsockopt_disable_fragments(struct sock *sk, char *optva
return 0; return 0;
} }
static inline int sctp_setsockopt_set_events(struct sock *sk, char *optval, int optlen) static inline int sctp_setsockopt_set_events(struct sock *sk, char *optval,
int optlen)
{ {
if (optlen != sizeof(struct sctp_event_subscribe)) if (optlen != sizeof(struct sctp_event_subscribe))
return -EINVAL; return -EINVAL;
...@@ -1200,7 +1196,8 @@ static inline int sctp_setsockopt_set_events(struct sock *sk, char *optval, int ...@@ -1200,7 +1196,8 @@ static inline int sctp_setsockopt_set_events(struct sock *sk, char *optval, int
return 0; return 0;
} }
static inline int sctp_setsockopt_autoclose(struct sock *sk, char *optval, int optlen) static inline int sctp_setsockopt_autoclose(struct sock *sk, char *optval,
int optlen)
{ {
sctp_opt_t *sp = sctp_sk(sk); sctp_opt_t *sp = sctp_sk(sk);
...@@ -1236,7 +1233,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname, ...@@ -1236,7 +1233,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
char *optval, int optlen) char *optval, int optlen)
{ {
int retval = 0; int retval = 0;
char * tmp; char *tmp;
sctp_protocol_t *proto = sctp_get_protocol(); sctp_protocol_t *proto = sctp_get_protocol();
struct list_head *pos; struct list_head *pos;
sctp_func_t *af; sctp_func_t *af;
...@@ -1332,7 +1329,7 @@ static struct sock *sctp_accept(struct sock *sk, int flags, int *err) ...@@ -1332,7 +1329,7 @@ static struct sock *sctp_accept(struct sock *sk, int flags, int *err)
{ {
int error = -EOPNOTSUPP; int error = -EOPNOTSUPP;
*err = error; *err = error;
return NULL; return NULL;
} }
...@@ -1356,19 +1353,9 @@ static int sctp_init_sock(struct sock *sk) ...@@ -1356,19 +1353,9 @@ static int sctp_init_sock(struct sock *sk)
proto = sctp_get_protocol(); proto = sctp_get_protocol();
/* Create a per socket endpoint structure. Even if we
* change the data structure relationships, this may still
* be useful for storing pre-connect address information.
*/
ep = sctp_endpoint_new(proto, sk, GFP_KERNEL);
if (!ep)
return -ENOMEM;
sp = sctp_sk(sk); sp = sctp_sk(sk);
/* Initialize the SCTP per socket area. */ /* Initialize the SCTP per socket area. */
sp->ep = ep;
sp->type = SCTP_SOCKET_UDP; sp->type = SCTP_SOCKET_UDP;
/* FIXME: The next draft (04) of the SCTP Sockets Extensions /* FIXME: The next draft (04) of the SCTP Sockets Extensions
...@@ -1425,6 +1412,16 @@ static int sctp_init_sock(struct sock *sk) ...@@ -1425,6 +1412,16 @@ static int sctp_init_sock(struct sock *sk)
* for UDP-style sockets only. * for UDP-style sockets only.
*/ */
sp->autoclose = 0; sp->autoclose = 0;
sp->pf = sctp_get_pf_specific(sk->family);
/* Create a per socket endpoint structure. Even if we
* change the data structure relationships, this may still
* be useful for storing pre-connect address information.
*/
ep = sctp_endpoint_new(proto, sk, GFP_KERNEL);
if (NULL == ep)
return -ENOMEM;
sp->ep = ep;
SCTP_DBG_OBJCNT_INC(sock); SCTP_DBG_OBJCNT_INC(sock);
return 0; return 0;
...@@ -1836,8 +1833,7 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum) ...@@ -1836,8 +1833,7 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum)
case PF_INET6: case PF_INET6:
SCTP_V6(tmpaddr.v6.sin6_family = AF_INET6; SCTP_V6(tmpaddr.v6.sin6_family = AF_INET6;
tmpaddr.v6.sin6_port = snum; tmpaddr.v6.sin6_port = snum;
tmpaddr.v6.sin6_addr = tmpaddr.v6.sin6_addr = inet6_sk(sk)->rcv_saddr;
inet6_sk(sk)->rcv_saddr;
) )
break; break;
...@@ -1855,7 +1851,7 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum) ...@@ -1855,7 +1851,7 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum)
* that this port/socket (sk) combination are already * that this port/socket (sk) combination are already
* in an endpoint. * in an endpoint.
*/ */
for( ; sk2 != NULL; sk2 = sk2->bind_next) { for ( ; sk2 != NULL; sk2 = sk2->bind_next) {
sctp_endpoint_t *ep2; sctp_endpoint_t *ep2;
ep2 = sctp_sk(sk2)->ep; ep2 = sctp_sk(sk2)->ep;
...@@ -1887,7 +1883,7 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum) ...@@ -1887,7 +1883,7 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum)
* SO_REUSEADDR on this socket -sk-). * SO_REUSEADDR on this socket -sk-).
*/ */
if (pp->sk == NULL) { if (pp->sk == NULL) {
pp->fastreuse = sk->reuse? 1 : 0; pp->fastreuse = sk->reuse ? 1 : 0;
} else if (pp->fastreuse && sk->reuse == 0) { } else if (pp->fastreuse && sk->reuse == 0) {
pp->fastreuse = 0; pp->fastreuse = 0;
} }
...@@ -1974,7 +1970,7 @@ int sctp_inet_listen(struct socket *sock, int backlog) ...@@ -1974,7 +1970,7 @@ int sctp_inet_listen(struct socket *sock, int backlog)
err = -EINVAL; err = -EINVAL;
if (sock->state != SS_UNCONNECTED) if (sock->state != SS_UNCONNECTED)
goto out; goto out;
switch (sock->type) { switch (sock->type) {
case SOCK_SEQPACKET: case SOCK_SEQPACKET:
err = sctp_seqpacket_listen(sk, backlog); err = sctp_seqpacket_listen(sk, backlog);
break; break;
...@@ -2073,7 +2069,7 @@ static sctp_bind_bucket_t *sctp_bucket_create(sctp_bind_hashbucket_t *head, unsi ...@@ -2073,7 +2069,7 @@ static sctp_bind_bucket_t *sctp_bucket_create(sctp_bind_hashbucket_t *head, unsi
pp->sk = NULL; pp->sk = NULL;
if ((pp->next = head->chain) != NULL) if ((pp->next = head->chain) != NULL)
pp->next->pprev = &pp->next; pp->next->pprev = &pp->next;
head->chain= pp; head->chain = pp;
pp->pprev = &head->chain; pp->pprev = &head->chain;
} }
SCTP_DEBUG_PRINTK("sctp_bucket_create() ends, pp=%p\n", pp); SCTP_DEBUG_PRINTK("sctp_bucket_create() ends, pp=%p\n", pp);
...@@ -2127,7 +2123,7 @@ static int sctp_autobind(struct sock *sk) ...@@ -2127,7 +2123,7 @@ static int sctp_autobind(struct sock *sk)
switch (sk->family) { switch (sk->family) {
case PF_INET: case PF_INET:
autoaddr.v4.sin_family = AF_INET; autoaddr.v4.sin_family = AF_INET;
autoaddr.v4.sin_addr.s_addr = INADDR_ANY; autoaddr.v4.sin_addr.s_addr = INADDR_ANY;
autoaddr.v4.sin_port = htons(inet_sk(sk)->num); autoaddr.v4.sin_port = htons(inet_sk(sk)->num);
addr_len = sizeof(struct sockaddr_in); addr_len = sizeof(struct sockaddr_in);
break; break;
...@@ -2202,7 +2198,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs) ...@@ -2202,7 +2198,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs)
return -EINVAL; return -EINVAL;
} }
/* Should we parse this header or ignore? */ /* Should we parse this header or ignore? */
if (cmsg->cmsg_level != IPPROTO_SCTP) if (cmsg->cmsg_level != IPPROTO_SCTP)
continue; continue;
...@@ -2433,41 +2429,6 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, int no ...@@ -2433,41 +2429,6 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, int no
return NULL; return NULL;
} }
/* Copy an approriately formatted address for msg_name. */
static inline void sctp_sk_memcpy_msgname(struct sock *sk, char * msgname,
int *addr_len, struct sk_buff *skb)
{
struct sockaddr_in *sin;
struct sockaddr_in6 *sin6 __attribute__ ((unused));
struct sctphdr *sh;
/* The sockets layer handles copying this out to user space. */
switch (sk->family) {
case PF_INET:
sin = (struct sockaddr_in *)msgname;
if (addr_len)
*addr_len = sizeof(struct sockaddr_in);
sin->sin_family = AF_INET;
sh = (struct sctphdr *) skb->h.raw;
sin->sin_port = sh->source;
sin->sin_addr.s_addr = skb->nh.iph->saddr;
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
break;
case PF_INET6:
SCTP_V6(
/* FIXME: Need v6 code here. We should convert
* V4 addresses to PF_INET6 format. See ipv6/udp.c
* for an example. --jgrimm
*/
);
break;
default: /* Should not get here. */
break;
};
}
static inline int sctp_sendmsg_verify_name(struct sock *sk, struct msghdr *msg) static inline int sctp_sendmsg_verify_name(struct sock *sk, struct msghdr *msg)
{ {
sockaddr_storage_t *sa; sockaddr_storage_t *sa;
...@@ -2590,7 +2551,7 @@ static int sctp_wait_for_sndbuf(sctp_association_t *asoc, long *timeo_p, int msg ...@@ -2590,7 +2551,7 @@ static int sctp_wait_for_sndbuf(sctp_association_t *asoc, long *timeo_p, int msg
/* Let another process have a go. Since we are going /* Let another process have a go. Since we are going
* to sleep anyway. * to sleep anyway.
*/ */
sctp_release_sock(sk); sctp_release_sock(sk);
current_timeo = schedule_timeout(current_timeo); current_timeo = schedule_timeout(current_timeo);
sctp_lock_sock(sk); sctp_lock_sock(sk);
......
...@@ -4,45 +4,45 @@ ...@@ -4,45 +4,45 @@
* Copyright (c) 2001 International Business Machines Corp. * Copyright (c) 2001 International Business Machines Corp.
* Copyright (c) 2001 Intel Corp. * Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 La Monte H.P. Yarroll * Copyright (c) 2001 La Monte H.P. Yarroll
* *
* This file is part of the SCTP kernel reference Implementation * This file is part of the SCTP kernel reference Implementation
* *
* This module provides the abstraction for an SCTP tranport representing * This module provides the abstraction for an SCTP tranport representing
* a remote transport address. For local transport addresses, we just use * a remote transport address. For local transport addresses, we just use
* sockaddr_storage_t. * sockaddr_storage_t.
* *
* The SCTP reference implementation is free software; * The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of * you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by * the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* The SCTP reference implementation is distributed in the hope that it * The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied * will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************ * ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to * along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330, * the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
* *
* Please send any bug reports or fixes you make to the * Please send any bug reports or fixes you make to the
* email address(es): * email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net> * lksctp developers <lksctp-developers@lists.sourceforge.net>
* *
* Or submit a bug report through the following website: * Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp * http://www.sf.net/projects/lksctp
* *
* Written or modified by: * Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org> * La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us> * Karl Knutson <karl@athena.chicago.il.us>
* Jon Grimm <jgrimm@us.ibm.com> * Jon Grimm <jgrimm@us.ibm.com>
* Xingang Guo <xingang.guo@intel.com> * Xingang Guo <xingang.guo@intel.com>
* Hui Huang <hui.huang@nokia.com> * Hui Huang <hui.huang@nokia.com>
* Sridhar Samudrala <sri@us.ibm.com> * Sridhar Samudrala <sri@us.ibm.com>
* *
* Any bugs reported given to us we will try to fix... any fixes shared will * Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release. * be incorporated into the next SCTP release.
*/ */
...@@ -215,7 +215,7 @@ void sctp_transport_put(sctp_transport_t *transport) ...@@ -215,7 +215,7 @@ void sctp_transport_put(sctp_transport_t *transport)
sctp_transport_destroy(transport); sctp_transport_destroy(transport);
} }
/* Update transport's RTO based on the newly calculated RTT. */ /* Update transport's RTO based on the newly calculated RTT. */
void sctp_transport_update_rto(sctp_transport_t *tp, __u32 rtt) void sctp_transport_update_rto(sctp_transport_t *tp, __u32 rtt)
{ {
sctp_protocol_t *proto = sctp_get_protocol(); sctp_protocol_t *proto = sctp_get_protocol();
...@@ -263,7 +263,7 @@ void sctp_transport_update_rto(sctp_transport_t *tp, __u32 rtt) ...@@ -263,7 +263,7 @@ void sctp_transport_update_rto(sctp_transport_t *tp, __u32 rtt)
* seconds then it is rounded up to RTO.Min seconds. * seconds then it is rounded up to RTO.Min seconds.
*/ */
if (tp->rto < tp->asoc->rto_min) if (tp->rto < tp->asoc->rto_min)
tp->rto = tp->asoc->rto_min; tp->rto = tp->asoc->rto_min;
/* 6.3.1 C7) A maximum value may be placed on RTO provided it is /* 6.3.1 C7) A maximum value may be placed on RTO provided it is
* at least RTO.max seconds. * at least RTO.max seconds.
...@@ -381,13 +381,13 @@ void sctp_transport_lower_cwnd(sctp_transport_t *transport, ...@@ -381,13 +381,13 @@ void sctp_transport_lower_cwnd(sctp_transport_t *transport,
break; break;
case SCTP_LOWER_CWND_FAST_RTX: case SCTP_LOWER_CWND_FAST_RTX:
/* RFC 2960 7.2.4 Adjust the ssthresh and cwnd of the /* RFC 2960 7.2.4 Adjust the ssthresh and cwnd of the
* destination address(es) to which the missing DATA chunks * destination address(es) to which the missing DATA chunks
* were last sent, according to the formula described in * were last sent, according to the formula described in
* Section 7.2.3. * Section 7.2.3.
* *
* RFC 2960 7.2.3, sctpimpguide-05 2.9.2 Upon detection of * RFC 2960 7.2.3, sctpimpguide-05 2.9.2 Upon detection of
* packet losses from SACK (see Section 7.2.4), An endpoint * packet losses from SACK (see Section 7.2.4), An endpoint
* should do the following: * should do the following:
* ssthresh = max(cwnd/2, 2*MTU) * ssthresh = max(cwnd/2, 2*MTU)
* cwnd = ssthresh * cwnd = ssthresh
......
...@@ -46,9 +46,10 @@ ...@@ -46,9 +46,10 @@
#include <net/sctp/sctp.h> #include <net/sctp/sctp.h>
#include <net/sctp/sm.h> #include <net/sctp/sm.h>
static void sctp_rcvmsg_rfree(struct sk_buff *skb);
static void sctp_ulpevent_set_owner_r(struct sk_buff *skb, static void sctp_ulpevent_set_owner_r(struct sk_buff *skb,
sctp_association_t *asoc); sctp_association_t *asoc);
static void
sctp_ulpevent_set_owner(struct sk_buff *skb, const sctp_association_t *asoc);
/* Create a new sctp_ulpevent. */ /* Create a new sctp_ulpevent. */
sctp_ulpevent_t *sctp_ulpevent_new(int size, int msg_flags, int priority) sctp_ulpevent_t *sctp_ulpevent_new(int size, int msg_flags, int priority)
...@@ -123,14 +124,12 @@ sctp_ulpevent_t *sctp_ulpevent_make_assoc_change(const sctp_association_t *asoc, ...@@ -123,14 +124,12 @@ sctp_ulpevent_t *sctp_ulpevent_make_assoc_change(const sctp_association_t *asoc,
struct sctp_assoc_change *sac; struct sctp_assoc_change *sac;
event = sctp_ulpevent_new(sizeof(struct sctp_assoc_change), event = sctp_ulpevent_new(sizeof(struct sctp_assoc_change),
MSG_NOTIFICATION, MSG_NOTIFICATION, priority);
priority);
if (!event) if (!event)
goto fail; goto fail;
sac = (struct sctp_assoc_change *) sac = (struct sctp_assoc_change *)
skb_put(event->parent, skb_put(event->parent, sizeof(struct sctp_assoc_change));
sizeof(struct sctp_assoc_change));
/* Socket Extensions for SCTP /* Socket Extensions for SCTP
* 5.3.1.1 SCTP_ASSOC_CHANGE * 5.3.1.1 SCTP_ASSOC_CHANGE
...@@ -199,6 +198,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_assoc_change(const sctp_association_t *asoc, ...@@ -199,6 +198,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_assoc_change(const sctp_association_t *asoc,
* All notifications for a given association have the same association * All notifications for a given association have the same association
* identifier. For TCP style socket, this field is ignored. * identifier. For TCP style socket, this field is ignored.
*/ */
sctp_ulpevent_set_owner(event->parent, asoc);
sac->sac_assoc_id = sctp_assoc2id(asoc); sac->sac_assoc_id = sctp_assoc2id(asoc);
return event; return event;
...@@ -227,14 +227,12 @@ sctp_ulpevent_t *sctp_ulpevent_make_peer_addr_change( ...@@ -227,14 +227,12 @@ sctp_ulpevent_t *sctp_ulpevent_make_peer_addr_change(
struct sctp_paddr_change *spc; struct sctp_paddr_change *spc;
event = sctp_ulpevent_new(sizeof(struct sctp_paddr_change), event = sctp_ulpevent_new(sizeof(struct sctp_paddr_change),
MSG_NOTIFICATION, MSG_NOTIFICATION, priority);
priority);
if (!event) if (!event)
goto fail; goto fail;
spc = (struct sctp_paddr_change *) spc = (struct sctp_paddr_change *)
skb_put(event->parent, skb_put(event->parent, sizeof(struct sctp_paddr_change));
sizeof(struct sctp_paddr_change));
/* Sockets API Extensions for SCTP /* Sockets API Extensions for SCTP
* Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE * Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE
...@@ -287,12 +285,13 @@ sctp_ulpevent_t *sctp_ulpevent_make_peer_addr_change( ...@@ -287,12 +285,13 @@ sctp_ulpevent_t *sctp_ulpevent_make_peer_addr_change(
/* Socket Extensions for SCTP /* Socket Extensions for SCTP
* 5.3.1.1 SCTP_ASSOC_CHANGE * 5.3.1.1 SCTP_ASSOC_CHANGE
* *
* sac_assoc_id: sizeof (sctp_assoc_t) * spc_assoc_id: sizeof (sctp_assoc_t)
* *
* The association id field, holds the identifier for the association. * The association id field, holds the identifier for the association.
* All notifications for a given association have the same association * All notifications for a given association have the same association
* identifier. For TCP style socket, this field is ignored. * identifier. For TCP style socket, this field is ignored.
*/ */
sctp_ulpevent_set_owner(event->parent, asoc);
spc->spc_assoc_id = sctp_assoc2id(asoc); spc->spc_assoc_id = sctp_assoc2id(asoc);
/* Sockets API Extensions for SCTP /* Sockets API Extensions for SCTP
...@@ -360,9 +359,8 @@ sctp_ulpevent_t *sctp_ulpevent_make_remote_error(const sctp_association_t *asoc, ...@@ -360,9 +359,8 @@ sctp_ulpevent_t *sctp_ulpevent_make_remote_error(const sctp_association_t *asoc,
/* Embed the event fields inside the cloned skb. */ /* Embed the event fields inside the cloned skb. */
event = (sctp_ulpevent_t *) skb->cb; event = (sctp_ulpevent_t *) skb->cb;
event = sctp_ulpevent_init(event, event = sctp_ulpevent_init(event, skb, MSG_NOTIFICATION);
skb,
MSG_NOTIFICATION);
if (!event) if (!event)
goto fail; goto fail;
...@@ -418,6 +416,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_remote_error(const sctp_association_t *asoc, ...@@ -418,6 +416,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_remote_error(const sctp_association_t *asoc,
* All notifications for a given association have the same association * All notifications for a given association have the same association
* identifier. For TCP style socket, this field is ignored. * identifier. For TCP style socket, this field is ignored.
*/ */
sctp_ulpevent_set_owner(event->parent, asoc);
sre->sre_assoc_id = sctp_assoc2id(asoc); sre->sre_assoc_id = sctp_assoc2id(asoc);
return event; return event;
...@@ -515,9 +514,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_send_failed(const sctp_association_t *asoc, ...@@ -515,9 +514,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_send_failed(const sctp_association_t *asoc,
* The original send information associated with the undelivered * The original send information associated with the undelivered
* message. * message.
*/ */
memcpy(&ssf->ssf_info, memcpy(&ssf->ssf_info, &chunk->sinfo, sizeof(struct sctp_sndrcvinfo));
&chunk->sinfo,
sizeof(struct sctp_sndrcvinfo));
/* Socket Extensions for SCTP /* Socket Extensions for SCTP
* 5.3.1.4 SCTP_SEND_FAILED * 5.3.1.4 SCTP_SEND_FAILED
...@@ -528,8 +525,8 @@ sctp_ulpevent_t *sctp_ulpevent_make_send_failed(const sctp_association_t *asoc, ...@@ -528,8 +525,8 @@ sctp_ulpevent_t *sctp_ulpevent_make_send_failed(const sctp_association_t *asoc,
* same association identifier. For TCP style socket, this field is * same association identifier. For TCP style socket, this field is
* ignored. * ignored.
*/ */
sctp_ulpevent_set_owner(event->parent, asoc);
ssf->ssf_assoc_id = sctp_assoc2id(asoc); ssf->ssf_assoc_id = sctp_assoc2id(asoc);
return event; return event;
fail: fail:
...@@ -541,22 +538,21 @@ sctp_ulpevent_t *sctp_ulpevent_make_send_failed(const sctp_association_t *asoc, ...@@ -541,22 +538,21 @@ sctp_ulpevent_t *sctp_ulpevent_make_send_failed(const sctp_association_t *asoc,
* Socket Extensions for SCTP - draft-01 * Socket Extensions for SCTP - draft-01
* 5.3.1.5 SCTP_SHUTDOWN_EVENT * 5.3.1.5 SCTP_SHUTDOWN_EVENT
*/ */
sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(const sctp_association_t *asoc, sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(
__u16 flags, const sctp_association_t *asoc,
int priority) __u16 flags,
int priority)
{ {
sctp_ulpevent_t *event; sctp_ulpevent_t *event;
struct sctp_shutdown_event *sse; struct sctp_shutdown_event *sse;
event = sctp_ulpevent_new(sizeof(struct sctp_assoc_change), event = sctp_ulpevent_new(sizeof(struct sctp_assoc_change),
MSG_NOTIFICATION, MSG_NOTIFICATION, priority);
priority);
if (!event) if (!event)
goto fail; goto fail;
sse = (struct sctp_shutdown_event *) sse = (struct sctp_shutdown_event *)
skb_put(event->parent, skb_put(event->parent, sizeof(struct sctp_shutdown_event));
sizeof(struct sctp_shutdown_event));
/* Socket Extensions for SCTP /* Socket Extensions for SCTP
* 5.3.1.5 SCTP_SHUTDOWN_EVENT * 5.3.1.5 SCTP_SHUTDOWN_EVENT
...@@ -591,6 +587,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(const sctp_association_t *aso ...@@ -591,6 +587,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(const sctp_association_t *aso
* All notifications for a given association have the same association * All notifications for a given association have the same association
* identifier. For TCP style socket, this field is ignored. * identifier. For TCP style socket, this field is ignored.
*/ */
sctp_ulpevent_set_owner(event->parent, asoc);
sse->sse_assoc_id = sctp_assoc2id(asoc); sse->sse_assoc_id = sctp_assoc2id(asoc);
return event; return event;
...@@ -607,8 +604,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(const sctp_association_t *aso ...@@ -607,8 +604,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(const sctp_association_t *aso
* 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV) * 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
*/ */
sctp_ulpevent_t *sctp_ulpevent_make_rcvmsg(sctp_association_t *asoc, sctp_ulpevent_t *sctp_ulpevent_make_rcvmsg(sctp_association_t *asoc,
sctp_chunk_t *chunk, sctp_chunk_t *chunk, int priority)
int priority)
{ {
sctp_ulpevent_t *event; sctp_ulpevent_t *event;
struct sctp_sndrcvinfo *info; struct sctp_sndrcvinfo *info;
...@@ -619,7 +615,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_rcvmsg(sctp_association_t *asoc, ...@@ -619,7 +615,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_rcvmsg(sctp_association_t *asoc,
skb = skb_clone(chunk->skb, priority); skb = skb_clone(chunk->skb, priority);
if (!skb) if (!skb)
goto fail; goto fail;
/* First calculate the padding, so we don't inadvertently /* First calculate the padding, so we don't inadvertently
* pass up the wrong length to the user. * pass up the wrong length to the user.
* *
...@@ -645,7 +641,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_rcvmsg(sctp_association_t *asoc, ...@@ -645,7 +641,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_rcvmsg(sctp_association_t *asoc,
event = (sctp_ulpevent_t *) skb->cb; event = (sctp_ulpevent_t *) skb->cb;
/* Initialize event with flags 0. */ /* Initialize event with flags 0. */
event = sctp_ulpevent_init(event, skb, 0); event = sctp_ulpevent_init(event, skb, 0);
if (!event) if (!event)
goto fail_init; goto fail_init;
...@@ -818,23 +814,33 @@ static void sctp_ulpevent_set_owner_r(struct sk_buff *skb, sctp_association_t *a ...@@ -818,23 +814,33 @@ static void sctp_ulpevent_set_owner_r(struct sk_buff *skb, sctp_association_t *a
asoc->rwnd_over = skb->len - asoc->rwnd; asoc->rwnd_over = skb->len - asoc->rwnd;
asoc->rwnd = 0; asoc->rwnd = 0;
} }
SCTP_DEBUG_PRINTK("rwnd decreased by %d to (%u, %u)\n", SCTP_DEBUG_PRINTK("rwnd decreased by %d to (%u, %u)\n",
skb->len, asoc->rwnd, asoc->rwnd_over); skb->len, asoc->rwnd, asoc->rwnd_over);
} }
/* A simple destructor to give up the reference to the association. */
static void sctp_ulpevent_rfree(struct sk_buff *skb)
{
sctp_ulpevent_t *event;
event = (sctp_ulpevent_t *)skb->cb;
sctp_association_put(event->asoc);
}
/* Hold the association in case the msg_name needs read out of
* the association.
*/
static void sctp_ulpevent_set_owner(struct sk_buff *skb,
const sctp_association_t *asoc)
{
sctp_ulpevent_t *event;
/* Cast away the const, as we are just wanting to
* bump the reference count.
*/
sctp_association_hold((sctp_association_t *)asoc);
skb->sk = asoc->base.sk;
event = (sctp_ulpevent_t *)skb->cb;
event->asoc = (sctp_association_t *)asoc;
skb->destructor = sctp_ulpevent_rfree;
}
...@@ -5,38 +5,38 @@ ...@@ -5,38 +5,38 @@
* Copyright (c) 2001 Intel Corp. * Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 Nokia, Inc. * Copyright (c) 2001 Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll * Copyright (c) 2001 La Monte H.P. Yarroll
* *
* This abstraction carries sctp events to the ULP (sockets). * This abstraction carries sctp events to the ULP (sockets).
* *
* The SCTP reference implementation is free software; * The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of * you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by * the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* The SCTP reference implementation is distributed in the hope that it * The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied * will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************ * ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to * along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330, * the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
* *
* Please send any bug reports or fixes you make to the * Please send any bug reports or fixes you make to the
* email address(es): * email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net> * lksctp developers <lksctp-developers@lists.sourceforge.net>
* *
* Or submit a bug report through the following website: * Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp * http://www.sf.net/projects/lksctp
* *
* Written or modified by: * Written or modified by:
* Jon Grimm <jgrimm@us.ibm.com> * Jon Grimm <jgrimm@us.ibm.com>
* La Monte H.P. Yarroll <piggy@acm.org> * La Monte H.P. Yarroll <piggy@acm.org>
* Sridhar Samudrala <sri@us.ibm.com> * Sridhar Samudrala <sri@us.ibm.com>
* *
* Any bugs reported given to us we will try to fix... any fixes shared will * Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release. * be incorporated into the next SCTP release.
*/ */
...@@ -131,7 +131,7 @@ int sctp_ulpqueue_tail_data(sctp_ulpqueue_t *ulpq, sctp_chunk_t *chunk, ...@@ -131,7 +131,7 @@ int sctp_ulpqueue_tail_data(sctp_ulpqueue_t *ulpq, sctp_chunk_t *chunk,
int priority) int priority)
{ {
struct sk_buff_head temp; struct sk_buff_head temp;
sctp_data_chunk_t *hdr; sctp_data_chunk_t *hdr;
sctp_ulpevent_t *event; sctp_ulpevent_t *event;
hdr = (sctp_data_chunk_t *) chunk->chunk_hdr; hdr = (sctp_data_chunk_t *) chunk->chunk_hdr;
...@@ -157,7 +157,7 @@ int sctp_ulpqueue_tail_data(sctp_ulpqueue_t *ulpq, sctp_chunk_t *chunk, ...@@ -157,7 +157,7 @@ int sctp_ulpqueue_tail_data(sctp_ulpqueue_t *ulpq, sctp_chunk_t *chunk,
event = sctp_ulpqueue_order(ulpq, event); event = sctp_ulpqueue_order(ulpq, event);
} }
/* Send event to the ULP. */ /* Send event to the ULP. */
if (event) if (event)
sctp_ulpqueue_tail_event(ulpq, event); sctp_ulpqueue_tail_event(ulpq, event);
...@@ -449,7 +449,7 @@ static inline sctp_ulpevent_t *sctp_ulpqueue_order(sctp_ulpqueue_t *ulpq, ...@@ -449,7 +449,7 @@ static inline sctp_ulpevent_t *sctp_ulpqueue_order(sctp_ulpqueue_t *ulpq,
/* Check if this message needs ordering. */ /* Check if this message needs ordering. */
if (SCTP_DATA_UNORDERED & event->chunk_flags) if (SCTP_DATA_UNORDERED & event->chunk_flags)
return event; return event;
/* Note: The stream ID must be verified before this routine. */ /* Note: The stream ID must be verified before this routine. */
sid = event->sndrcvinfo.sinfo_stream; sid = event->sndrcvinfo.sinfo_stream;
......
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