Revision be65e2595b4c1fbeceba336d8ee83406726b1d8d authored by Linus Torvalds on 06 September 2018, 16:06:49 UTC, committed by Linus Torvalds on 06 September 2018, 16:06:49 UTC
Pull tracing fixes from Steven Rostedt:
 "This fixes two annoying bugs:

   - The first one is a side effect caused by using SRCU for rcuidle
     tracepoints. It seems that the perf was depending on the rcuidle
     tracepoints to make RCU watch when it wasn't.

     The real fix will be to have perf use SRCU instead of depending on
     RCU watching, but that can't be done until SRCU is safe to use in
     NMI context (Paul's working on that).

   - The second bug fix is for a bug that's been periodically making my
     tests fail randomly for some time. I haven't had time to track it
     down, but finally have. It has to do with stressing NMIs (via perf)
     while enabling or disabling ftrace function handling with lockdep
     enabled.

     If an interrupt happens and just as it returns, it sets lockdep
     back to "interrupts enabled" but before it returns an NMI is
     triggered, and if this happens while printk_nmi_enter has a
     breakpoint attached to it (because ftrace is converting it to or
     from nop to call fentry), the breakpoint trap also calls into
     lockdep, and since returning from the NMI to a interrupt handler,
     interrupts were disabled when the NMI went off, lockdep keeps its
     state as interrupts disabled when it returns back from the
     interrupt handler where interrupts are enabled.

     This causes lockdep_assert_irqs_enabled() to trigger a false
     positive"

* tag 'trace-v4.19-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
  printk/tracing: Do not trace printk_nmi_enter()
  tracing: Add back in rcu_irq_enter/exit_irqson() for rcuidle tracepoints
2 parent s 5404525 + d1c392c
Raw File
sm_statetable.c
/* SCTP kernel implementation
 * (C) Copyright IBM Corp. 2001, 2004
 * Copyright (c) 1999-2000 Cisco, Inc.
 * Copyright (c) 1999-2001 Motorola, Inc.
 * Copyright (c) 2001 Intel Corp.
 * Copyright (c) 2001 Nokia, Inc.
 *
 * This file is part of the SCTP kernel implementation
 *
 * These are the state tables for the SCTP state machine.
 *
 * This SCTP implementation is free software;
 * you can redistribute it and/or modify it under the terms of
 * the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This SCTP implementation is distributed in the hope that it
 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
 *                 ************************
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU CC; see the file COPYING.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * Please send any bug reports or fixes you make to the
 * email address(es):
 *    lksctp developers <linux-sctp@vger.kernel.org>
 *
 * Written or modified by:
 *    La Monte H.P. Yarroll <piggy@acm.org>
 *    Karl Knutson          <karl@athena.chicago.il.us>
 *    Jon Grimm             <jgrimm@us.ibm.com>
 *    Hui Huang		    <hui.huang@nokia.com>
 *    Daisy Chang	    <daisyc@us.ibm.com>
 *    Ardelle Fan	    <ardelle.fan@intel.com>
 *    Sridhar Samudrala	    <sri@us.ibm.com>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/skbuff.h>
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>

static const struct sctp_sm_table_entry
primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES];
static const struct sctp_sm_table_entry
other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES];
static const struct sctp_sm_table_entry
timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES];

static const struct sctp_sm_table_entry *sctp_chunk_event_lookup(
						struct net *net,
						enum sctp_cid cid,
						enum sctp_state state);


static const struct sctp_sm_table_entry bug = {
	.fn = sctp_sf_bug,
	.name = "sctp_sf_bug"
};

#define DO_LOOKUP(_max, _type, _table)					\
({									\
	const struct sctp_sm_table_entry *rtn;				\
									\
	if ((event_subtype._type > (_max))) {				\
		pr_warn("table %p possible attack: event %d exceeds max %d\n", \
			_table, event_subtype._type, _max);		\
		rtn = &bug;						\
	} else								\
		rtn = &_table[event_subtype._type][(int)state];		\
									\
	rtn;								\
})

const struct sctp_sm_table_entry *sctp_sm_lookup_event(
					struct net *net,
					enum sctp_event event_type,
					enum sctp_state state,
					union sctp_subtype event_subtype)
{
	switch (event_type) {
	case SCTP_EVENT_T_CHUNK:
		return sctp_chunk_event_lookup(net, event_subtype.chunk, state);
	case SCTP_EVENT_T_TIMEOUT:
		return DO_LOOKUP(SCTP_EVENT_TIMEOUT_MAX, timeout,
				 timeout_event_table);
	case SCTP_EVENT_T_OTHER:
		return DO_LOOKUP(SCTP_EVENT_OTHER_MAX, other,
				 other_event_table);
	case SCTP_EVENT_T_PRIMITIVE:
		return DO_LOOKUP(SCTP_EVENT_PRIMITIVE_MAX, primitive,
				 primitive_event_table);
	default:
		/* Yikes!  We got an illegal event type.  */
		return &bug;
	}
}

#define TYPE_SCTP_FUNC(func) {.fn = func, .name = #func}

#define TYPE_SCTP_DATA { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_ootb), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_eat_data_6_2), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_eat_data_6_2), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_eat_data_fast_4_4), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
} /* TYPE_SCTP_DATA */

#define TYPE_SCTP_INIT { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_1B_init), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_2_1_siminit), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_2_1_siminit), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_2_2_dupinit), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_2_2_dupinit), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_2_2_dupinit), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_2_2_dupinit), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_9_2_reshutack), \
} /* TYPE_SCTP_INIT */

#define TYPE_SCTP_INIT_ACK { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_2_3_initack), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_1C_ack), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
} /* TYPE_SCTP_INIT_ACK */

#define TYPE_SCTP_SACK { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_ootb), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_eat_sack_6_2), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_eat_sack_6_2), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_eat_sack_6_2), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_eat_sack_6_2), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
} /* TYPE_SCTP_SACK */

#define TYPE_SCTP_HEARTBEAT { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_ootb), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_beat_8_3), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_beat_8_3), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_beat_8_3), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_beat_8_3), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_beat_8_3), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	/* This should not happen, but we are nice.  */ \
	TYPE_SCTP_FUNC(sctp_sf_beat_8_3), \
} /* TYPE_SCTP_HEARTBEAT */

#define TYPE_SCTP_HEARTBEAT_ACK { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_ootb), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_violation), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_backbeat_8_3), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_backbeat_8_3), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_backbeat_8_3), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_backbeat_8_3), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
} /* TYPE_SCTP_HEARTBEAT_ACK */

#define TYPE_SCTP_ABORT { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_pdiscard), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_cookie_wait_abort), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_cookie_echoed_abort), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_9_1_abort), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_shutdown_pending_abort), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_shutdown_sent_abort), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_9_1_abort), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_shutdown_ack_sent_abort), \
} /* TYPE_SCTP_ABORT */

#define TYPE_SCTP_SHUTDOWN { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_ootb), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_9_2_shutdown), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_do_9_2_shutdown), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_9_2_shutdown_ack), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_9_2_shut_ctsn), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
} /* TYPE_SCTP_SHUTDOWN */

#define TYPE_SCTP_SHUTDOWN_ACK { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_ootb), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_8_5_1_E_sa), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_8_5_1_E_sa), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_violation), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_violation), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_9_2_final), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_violation), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_9_2_final), \
} /* TYPE_SCTP_SHUTDOWN_ACK */

#define TYPE_SCTP_ERROR { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_ootb), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_cookie_echoed_err), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_operr_notify), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_operr_notify), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_operr_notify), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
} /* TYPE_SCTP_ERROR */

#define TYPE_SCTP_COOKIE_ECHO { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_1D_ce), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_2_4_dupcook), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_2_4_dupcook), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_2_4_dupcook), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_2_4_dupcook), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_2_4_dupcook), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_2_4_dupcook), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_2_4_dupcook), \
} /* TYPE_SCTP_COOKIE_ECHO */

#define TYPE_SCTP_COOKIE_ACK { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_5_1E_ca), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
} /* TYPE_SCTP_COOKIE_ACK */

#define TYPE_SCTP_ECN_ECNE { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_ecne), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_ecne), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_do_ecne), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_ecne), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_ecne), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
} /* TYPE_SCTP_ECN_ECNE */

#define TYPE_SCTP_ECN_CWR { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_ecn_cwr), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_do_ecn_cwr), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_ecn_cwr), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
} /* TYPE_SCTP_ECN_CWR */

#define TYPE_SCTP_SHUTDOWN_COMPLETE { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_4_C), \
} /* TYPE_SCTP_SHUTDOWN_COMPLETE */

/* The primary index for this table is the chunk type.
 * The secondary index for this table is the state.
 *
 * For base protocol (RFC 2960).
 */
static const struct sctp_sm_table_entry
chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
	TYPE_SCTP_DATA,
	TYPE_SCTP_INIT,
	TYPE_SCTP_INIT_ACK,
	TYPE_SCTP_SACK,
	TYPE_SCTP_HEARTBEAT,
	TYPE_SCTP_HEARTBEAT_ACK,
	TYPE_SCTP_ABORT,
	TYPE_SCTP_SHUTDOWN,
	TYPE_SCTP_SHUTDOWN_ACK,
	TYPE_SCTP_ERROR,
	TYPE_SCTP_COOKIE_ECHO,
	TYPE_SCTP_COOKIE_ACK,
	TYPE_SCTP_ECN_ECNE,
	TYPE_SCTP_ECN_CWR,
	TYPE_SCTP_SHUTDOWN_COMPLETE,
}; /* state_fn_t chunk_event_table[][] */

#define TYPE_SCTP_ASCONF { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_asconf), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_do_asconf), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_asconf), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_asconf), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
} /* TYPE_SCTP_ASCONF */

#define TYPE_SCTP_ASCONF_ACK { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_asconf_ack), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_do_asconf_ack), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_asconf_ack), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_asconf_ack), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
} /* TYPE_SCTP_ASCONF_ACK */

/* The primary index for this table is the chunk type.
 * The secondary index for this table is the state.
 */
static const struct sctp_sm_table_entry
addip_chunk_event_table[SCTP_NUM_ADDIP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
	TYPE_SCTP_ASCONF,
	TYPE_SCTP_ASCONF_ACK,
}; /*state_fn_t addip_chunk_event_table[][] */

#define TYPE_SCTP_FWD_TSN { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_ootb), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_eat_fwd_tsn), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_eat_fwd_tsn), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_eat_fwd_tsn_fast), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
} /* TYPE_SCTP_FWD_TSN */

/* The primary index for this table is the chunk type.
 * The secondary index for this table is the state.
 */
static const struct sctp_sm_table_entry
prsctp_chunk_event_table[SCTP_NUM_PRSCTP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
	TYPE_SCTP_FWD_TSN,
}; /*state_fn_t prsctp_chunk_event_table[][] */

#define TYPE_SCTP_RECONF { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_reconf), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_do_reconf), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
} /* TYPE_SCTP_RECONF */

/* The primary index for this table is the chunk type.
 * The secondary index for this table is the state.
 */
static const struct sctp_sm_table_entry
reconf_chunk_event_table[SCTP_NUM_RECONF_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
	TYPE_SCTP_RECONF,
}; /*state_fn_t reconf_chunk_event_table[][] */

#define TYPE_SCTP_AUTH { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_ootb), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_eat_auth), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_eat_auth), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_eat_auth), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_eat_auth), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_eat_auth), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_eat_auth), \
} /* TYPE_SCTP_AUTH */

/* The primary index for this table is the chunk type.
 * The secondary index for this table is the state.
 */
static const struct sctp_sm_table_entry
auth_chunk_event_table[SCTP_NUM_AUTH_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
	TYPE_SCTP_AUTH,
}; /*state_fn_t auth_chunk_event_table[][] */

static const struct sctp_sm_table_entry
chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
	/* SCTP_STATE_CLOSED */
	TYPE_SCTP_FUNC(sctp_sf_ootb),
	/* SCTP_STATE_COOKIE_WAIT */
	TYPE_SCTP_FUNC(sctp_sf_unk_chunk),
	/* SCTP_STATE_COOKIE_ECHOED */
	TYPE_SCTP_FUNC(sctp_sf_unk_chunk),
	/* SCTP_STATE_ESTABLISHED */
	TYPE_SCTP_FUNC(sctp_sf_unk_chunk),
	/* SCTP_STATE_SHUTDOWN_PENDING */
	TYPE_SCTP_FUNC(sctp_sf_unk_chunk),
	/* SCTP_STATE_SHUTDOWN_SENT */
	TYPE_SCTP_FUNC(sctp_sf_unk_chunk),
	/* SCTP_STATE_SHUTDOWN_RECEIVED */
	TYPE_SCTP_FUNC(sctp_sf_unk_chunk),
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */
	TYPE_SCTP_FUNC(sctp_sf_unk_chunk),
};	/* chunk unknown */


#define TYPE_SCTP_PRIMITIVE_ASSOCIATE  { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_asoc), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_not_impl), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_not_impl), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_not_impl), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_not_impl), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_not_impl), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_not_impl), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_not_impl), \
} /* TYPE_SCTP_PRIMITIVE_ASSOCIATE */

#define TYPE_SCTP_PRIMITIVE_SHUTDOWN  { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_error_closed), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_cookie_wait_prm_shutdown), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_cookie_echoed_prm_shutdown),\
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_9_2_prm_shutdown), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_ignore_primitive), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_ignore_primitive), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_ignore_primitive), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_ignore_primitive), \
} /* TYPE_SCTP_PRIMITIVE_SHUTDOWN */

#define TYPE_SCTP_PRIMITIVE_ABORT  { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_error_closed), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_cookie_wait_prm_abort), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_cookie_echoed_prm_abort), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_9_1_prm_abort), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_shutdown_pending_prm_abort), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_shutdown_sent_prm_abort), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_9_1_prm_abort), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_shutdown_ack_sent_prm_abort), \
} /* TYPE_SCTP_PRIMITIVE_ABORT */

#define TYPE_SCTP_PRIMITIVE_SEND  { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_error_closed), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_send), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_send), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_send), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
} /* TYPE_SCTP_PRIMITIVE_SEND */

#define TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT  { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_error_closed), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_requestheartbeat),          \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_requestheartbeat),          \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_requestheartbeat),          \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_requestheartbeat),          \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_requestheartbeat),          \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_requestheartbeat),          \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_requestheartbeat),          \
} /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */

#define TYPE_SCTP_PRIMITIVE_ASCONF { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_error_closed), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_error_closed), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_error_closed), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_asconf), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_asconf), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_asconf), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_asconf), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
} /* TYPE_SCTP_PRIMITIVE_ASCONF */

#define TYPE_SCTP_PRIMITIVE_RECONF { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_error_closed), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_error_closed), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_error_closed), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_reconf), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_reconf), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_reconf), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_prm_reconf), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
} /* TYPE_SCTP_PRIMITIVE_RECONF */

/* The primary index for this table is the primitive type.
 * The secondary index for this table is the state.
 */
static const struct sctp_sm_table_entry
primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES] = {
	TYPE_SCTP_PRIMITIVE_ASSOCIATE,
	TYPE_SCTP_PRIMITIVE_SHUTDOWN,
	TYPE_SCTP_PRIMITIVE_ABORT,
	TYPE_SCTP_PRIMITIVE_SEND,
	TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT,
	TYPE_SCTP_PRIMITIVE_ASCONF,
	TYPE_SCTP_PRIMITIVE_RECONF,
};

#define TYPE_SCTP_OTHER_NO_PENDING_TSN  { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_no_pending_tsn), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_do_9_2_start_shutdown), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_9_2_shutdown_ack), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
}

#define TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH  { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_cookie_wait_icmp_abort), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
}

static const struct sctp_sm_table_entry
other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = {
	TYPE_SCTP_OTHER_NO_PENDING_TSN,
	TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH,
};

#define TYPE_SCTP_EVENT_TIMEOUT_NONE { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_bug), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_bug), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_bug), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_bug), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_bug), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_bug), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_bug), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_bug), \
}

#define TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_bug), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_t1_cookie_timer_expire), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
}

#define TYPE_SCTP_EVENT_TIMEOUT_T1_INIT { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_t1_init_timer_expire), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
}

#define TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_t2_timer_expire), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_t2_timer_expire), \
}

#define TYPE_SCTP_EVENT_TIMEOUT_T3_RTX { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_6_3_3_rtx), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_6_3_3_rtx), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_do_6_3_3_rtx), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_6_3_3_rtx), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
}

#define TYPE_SCTP_EVENT_TIMEOUT_T4_RTO { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_t4_timer_expire), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
}

#define TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_t5_timer_expire), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_t5_timer_expire), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
}

#define TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_sendbeat_8_3), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_sendbeat_8_3), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_sendbeat_8_3), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
}

#define TYPE_SCTP_EVENT_TIMEOUT_SACK { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_do_6_2_sack), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_do_6_2_sack), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_do_6_2_sack), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
}

#define TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_autoclose_timer_expire), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
}

#define TYPE_SCTP_EVENT_TIMEOUT_RECONF { \
	/* SCTP_STATE_CLOSED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_WAIT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_COOKIE_ECHOED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_ESTABLISHED */ \
	TYPE_SCTP_FUNC(sctp_sf_send_reconf), \
	/* SCTP_STATE_SHUTDOWN_PENDING */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
}

static const struct sctp_sm_table_entry
timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = {
	TYPE_SCTP_EVENT_TIMEOUT_NONE,
	TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE,
	TYPE_SCTP_EVENT_TIMEOUT_T1_INIT,
	TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN,
	TYPE_SCTP_EVENT_TIMEOUT_T3_RTX,
	TYPE_SCTP_EVENT_TIMEOUT_T4_RTO,
	TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD,
	TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT,
	TYPE_SCTP_EVENT_TIMEOUT_RECONF,
	TYPE_SCTP_EVENT_TIMEOUT_SACK,
	TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE,
};

static const struct sctp_sm_table_entry *sctp_chunk_event_lookup(
						struct net *net,
						enum sctp_cid cid,
						enum sctp_state state)
{
	if (state > SCTP_STATE_MAX)
		return &bug;

	if (cid == SCTP_CID_I_DATA)
		cid = SCTP_CID_DATA;

	if (cid <= SCTP_CID_BASE_MAX)
		return &chunk_event_table[cid][state];

	if (net->sctp.prsctp_enable) {
		if (cid == SCTP_CID_FWD_TSN || cid == SCTP_CID_I_FWD_TSN)
			return &prsctp_chunk_event_table[0][state];
	}

	if (net->sctp.addip_enable) {
		if (cid == SCTP_CID_ASCONF)
			return &addip_chunk_event_table[0][state];

		if (cid == SCTP_CID_ASCONF_ACK)
			return &addip_chunk_event_table[1][state];
	}

	if (net->sctp.reconf_enable)
		if (cid == SCTP_CID_RECONF)
			return &reconf_chunk_event_table[0][state];

	if (net->sctp.auth_enable) {
		if (cid == SCTP_CID_AUTH)
			return &auth_chunk_event_table[0][state];
	}

	return &chunk_event_table_unknown[state];
}
back to top