Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /* SCTP kernel Implementation
0003  * (C) Copyright IBM Corp. 2001, 2004
0004  * Copyright (C) 1999-2001 Cisco, Motorola
0005  *
0006  * This file is part of the SCTP kernel implementation
0007  *
0008  * These are the definitions needed for the command object.
0009  *
0010  * Please send any bug reports or fixes you make to the
0011  * email address(es):
0012  *    lksctp developers <linux-sctp@vger.kernel.org>
0013  *
0014  * Written or modified by:
0015  *   La Monte H.P. Yarroll <piggy@acm.org>
0016  *   Karl Knutson <karl@athena.chicago.il.us>
0017  *   Ardelle Fan <ardelle.fan@intel.com>
0018  *   Sridhar Samudrala <sri@us.ibm.com>
0019  */
0020 
0021 #ifndef __net_sctp_command_h__
0022 #define __net_sctp_command_h__
0023 
0024 #include <net/sctp/constants.h>
0025 #include <net/sctp/structs.h>
0026 
0027 
0028 enum sctp_verb {
0029     SCTP_CMD_NOP = 0,   /* Do nothing. */
0030     SCTP_CMD_NEW_ASOC,  /* Register a new association.  */
0031     SCTP_CMD_DELETE_TCB,    /* Delete the current association. */
0032     SCTP_CMD_NEW_STATE, /* Enter a new state.  */
0033     SCTP_CMD_REPORT_TSN,    /* Record the arrival of a TSN.  */
0034     SCTP_CMD_GEN_SACK,  /* Send a Selective ACK (maybe).  */
0035     SCTP_CMD_PROCESS_SACK,  /* Process an inbound SACK.  */
0036     SCTP_CMD_GEN_INIT_ACK,  /* Generate an INIT ACK chunk.  */
0037     SCTP_CMD_PEER_INIT, /* Process a INIT from the peer.  */
0038     SCTP_CMD_GEN_COOKIE_ECHO, /* Generate a COOKIE ECHO chunk. */
0039     SCTP_CMD_CHUNK_ULP, /* Send a chunk to the sockets layer.  */
0040     SCTP_CMD_EVENT_ULP, /* Send a notification to the sockets layer. */
0041     SCTP_CMD_REPLY,     /* Send a chunk to our peer.  */
0042     SCTP_CMD_SEND_PKT,  /* Send a full packet to our peer.  */
0043     SCTP_CMD_RETRAN,    /* Mark a transport for retransmission.  */
0044     SCTP_CMD_ECN_CE,        /* Do delayed CE processing.   */
0045     SCTP_CMD_ECN_ECNE,  /* Do delayed ECNE processing. */
0046     SCTP_CMD_ECN_CWR,   /* Do delayed CWR processing.  */
0047     SCTP_CMD_TIMER_START,   /* Start a timer.  */
0048     SCTP_CMD_TIMER_START_ONCE, /* Start a timer once */
0049     SCTP_CMD_TIMER_RESTART, /* Restart a timer. */
0050     SCTP_CMD_TIMER_STOP,    /* Stop a timer. */
0051     SCTP_CMD_INIT_CHOOSE_TRANSPORT, /* Choose transport for an INIT. */
0052     SCTP_CMD_INIT_COUNTER_RESET, /* Reset init counter. */
0053     SCTP_CMD_INIT_COUNTER_INC,   /* Increment init counter. */
0054     SCTP_CMD_INIT_RESTART,  /* High level, do init timer work. */
0055     SCTP_CMD_COOKIEECHO_RESTART,  /* High level, do cookie-echo timer work. */
0056     SCTP_CMD_INIT_FAILED,   /* High level, do init failure work. */
0057     SCTP_CMD_REPORT_DUP,    /* Report a duplicate TSN.  */
0058     SCTP_CMD_STRIKE,    /* Mark a strike against a transport.  */
0059     SCTP_CMD_HB_TIMERS_START,    /* Start the heartbeat timers. */
0060     SCTP_CMD_HB_TIMER_UPDATE,    /* Update a heartbeat timers.  */
0061     SCTP_CMD_HB_TIMERS_STOP,     /* Stop the heartbeat timers.  */
0062     SCTP_CMD_PROBE_TIMER_UPDATE, /* Update a probe timer.  */
0063     SCTP_CMD_TRANSPORT_HB_SENT,  /* Reset the status of a transport. */
0064     SCTP_CMD_TRANSPORT_IDLE,     /* Do manipulations on idle transport */
0065     SCTP_CMD_TRANSPORT_ON,       /* Mark the transport as active. */
0066     SCTP_CMD_REPORT_ERROR,   /* Pass this error back out of the sm. */
0067     SCTP_CMD_REPORT_BAD_TAG, /* Verification tags didn't match. */
0068     SCTP_CMD_PROCESS_CTSN,   /* Sideeffect from shutdown. */
0069     SCTP_CMD_ASSOC_FAILED,   /* Handle association failure. */
0070     SCTP_CMD_DISCARD_PACKET, /* Discard the whole packet. */
0071     SCTP_CMD_GEN_SHUTDOWN,   /* Generate a SHUTDOWN chunk. */
0072     SCTP_CMD_PURGE_OUTQUEUE, /* Purge all data waiting to be sent. */
0073     SCTP_CMD_SETUP_T2,       /* Hi-level, setup T2-shutdown parms.  */
0074     SCTP_CMD_RTO_PENDING,    /* Set transport's rto_pending. */
0075     SCTP_CMD_PART_DELIVER,   /* Partial data delivery considerations. */
0076     SCTP_CMD_RENEGE,         /* Renege data on an association. */
0077     SCTP_CMD_SETUP_T4,   /* ADDIP, setup T4 RTO timer parms. */
0078     SCTP_CMD_PROCESS_OPERR,  /* Process an ERROR chunk. */
0079     SCTP_CMD_REPORT_FWDTSN,  /* Report new cumulative TSN Ack. */
0080     SCTP_CMD_PROCESS_FWDTSN, /* Skips were reported, so process further. */
0081     SCTP_CMD_CLEAR_INIT_TAG, /* Clears association peer's inittag. */
0082     SCTP_CMD_DEL_NON_PRIMARY, /* Removes non-primary peer transports. */
0083     SCTP_CMD_T3_RTX_TIMERS_STOP, /* Stops T3-rtx pending timers */
0084     SCTP_CMD_FORCE_PRIM_RETRAN,  /* Forces retrans. over primary path. */
0085     SCTP_CMD_SET_SK_ERR,     /* Set sk_err */
0086     SCTP_CMD_ASSOC_CHANGE,   /* generate and send assoc_change event */
0087     SCTP_CMD_ADAPTATION_IND, /* generate and send adaptation event */
0088     SCTP_CMD_PEER_NO_AUTH,   /* generate and send authentication event */
0089     SCTP_CMD_ASSOC_SHKEY,    /* generate the association shared keys */
0090     SCTP_CMD_T1_RETRAN,  /* Mark for retransmission after T1 timeout  */
0091     SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */
0092     SCTP_CMD_SEND_MSG,   /* Send the whole use message */
0093     SCTP_CMD_PURGE_ASCONF_QUEUE, /* Purge all asconf queues.*/
0094     SCTP_CMD_SET_ASOC,   /* Restore association context */
0095     SCTP_CMD_LAST
0096 };
0097 
0098 /* How many commands can you put in an struct sctp_cmd_seq?
0099  * This is a rather arbitrary number, ideally derived from a careful
0100  * analysis of the state functions, but in reality just taken from
0101  * thin air in the hopes othat we don't trigger a kernel panic.
0102  */
0103 #define SCTP_MAX_NUM_COMMANDS 20
0104 
0105 union sctp_arg {
0106     void *zero_all; /* Set to NULL to clear the entire union */
0107     __s32 i32;
0108     __u32 u32;
0109     __be32 be32;
0110     __u16 u16;
0111     __u8 u8;
0112     int error;
0113     __be16 err;
0114     enum sctp_state state;
0115     enum sctp_event_timeout to;
0116     struct sctp_chunk *chunk;
0117     struct sctp_association *asoc;
0118     struct sctp_transport *transport;
0119     struct sctp_bind_addr *bp;
0120     struct sctp_init_chunk *init;
0121     struct sctp_ulpevent *ulpevent;
0122     struct sctp_packet *packet;
0123     struct sctp_sackhdr *sackh;
0124     struct sctp_datamsg *msg;
0125 };
0126 
0127 /* We are simulating ML type constructors here.
0128  *
0129  * SCTP_ARG_CONSTRUCTOR(NAME, TYPE, ELT) builds a function called
0130  * SCTP_NAME() which takes an argument of type TYPE and returns an
0131  * union sctp_arg.  It does this by inserting the sole argument into
0132  * the ELT union element of a local union sctp_arg.
0133  *
0134  * E.g., SCTP_ARG_CONSTRUCTOR(I32, __s32, i32) builds SCTP_I32(arg),
0135  * which takes an __s32 and returns a union sctp_arg containing the
0136  * __s32.  So, after foo = SCTP_I32(arg), foo.i32 == arg.
0137  */
0138 
0139 #define SCTP_ARG_CONSTRUCTOR(name, type, elt) \
0140 static inline union sctp_arg    \
0141 SCTP_## name (type arg)     \
0142 { union sctp_arg retval;\
0143   retval.zero_all = NULL;\
0144   retval.elt = arg;\
0145   return retval;\
0146 }
0147 
0148 SCTP_ARG_CONSTRUCTOR(I32,   __s32, i32)
0149 SCTP_ARG_CONSTRUCTOR(U32,   __u32, u32)
0150 SCTP_ARG_CONSTRUCTOR(BE32,  __be32, be32)
0151 SCTP_ARG_CONSTRUCTOR(U16,   __u16, u16)
0152 SCTP_ARG_CONSTRUCTOR(U8,    __u8, u8)
0153 SCTP_ARG_CONSTRUCTOR(ERROR,     int, error)
0154 SCTP_ARG_CONSTRUCTOR(PERR,      __be16, err)    /* protocol error */
0155 SCTP_ARG_CONSTRUCTOR(STATE, enum sctp_state, state)
0156 SCTP_ARG_CONSTRUCTOR(TO,    enum sctp_event_timeout, to)
0157 SCTP_ARG_CONSTRUCTOR(CHUNK, struct sctp_chunk *, chunk)
0158 SCTP_ARG_CONSTRUCTOR(ASOC,  struct sctp_association *, asoc)
0159 SCTP_ARG_CONSTRUCTOR(TRANSPORT, struct sctp_transport *, transport)
0160 SCTP_ARG_CONSTRUCTOR(BA,    struct sctp_bind_addr *, bp)
0161 SCTP_ARG_CONSTRUCTOR(PEER_INIT, struct sctp_init_chunk *, init)
0162 SCTP_ARG_CONSTRUCTOR(ULPEVENT,  struct sctp_ulpevent *, ulpevent)
0163 SCTP_ARG_CONSTRUCTOR(PACKET,    struct sctp_packet *, packet)
0164 SCTP_ARG_CONSTRUCTOR(SACKH, struct sctp_sackhdr *, sackh)
0165 SCTP_ARG_CONSTRUCTOR(DATAMSG,   struct sctp_datamsg *, msg)
0166 
0167 static inline union sctp_arg SCTP_FORCE(void)
0168 {
0169     return SCTP_I32(1);
0170 }
0171 
0172 static inline union sctp_arg SCTP_NOFORCE(void)
0173 {
0174     return SCTP_I32(0);
0175 }
0176 
0177 static inline union sctp_arg SCTP_NULL(void)
0178 {
0179     union sctp_arg retval;
0180     retval.zero_all = NULL;
0181     return retval;
0182 }
0183 
0184 struct sctp_cmd {
0185     union sctp_arg obj;
0186     enum sctp_verb verb;
0187 };
0188 
0189 struct sctp_cmd_seq {
0190     struct sctp_cmd cmds[SCTP_MAX_NUM_COMMANDS];
0191     struct sctp_cmd *last_used_slot;
0192     struct sctp_cmd *next_cmd;
0193 };
0194 
0195 
0196 /* Initialize a block of memory as a command sequence.
0197  * Return 0 if the initialization fails.
0198  */
0199 static inline int sctp_init_cmd_seq(struct sctp_cmd_seq *seq)
0200 {
0201     /* cmds[] is filled backwards to simplify the overflow BUG() check */
0202     seq->last_used_slot = seq->cmds + SCTP_MAX_NUM_COMMANDS;
0203     seq->next_cmd = seq->last_used_slot;
0204     return 1;       /* We always succeed.  */
0205 }
0206 
0207 
0208 /* Add a command to an struct sctp_cmd_seq.
0209  *
0210  * Use the SCTP_* constructors defined by SCTP_ARG_CONSTRUCTOR() above
0211  * to wrap data which goes in the obj argument.
0212  */
0213 static inline void sctp_add_cmd_sf(struct sctp_cmd_seq *seq,
0214                    enum sctp_verb verb, union sctp_arg obj)
0215 {
0216     struct sctp_cmd *cmd = seq->last_used_slot - 1;
0217 
0218     BUG_ON(cmd < seq->cmds);
0219 
0220     cmd->verb = verb;
0221     cmd->obj = obj;
0222     seq->last_used_slot = cmd;
0223 }
0224 
0225 /* Return the next command structure in an sctp_cmd_seq.
0226  * Return NULL at the end of the sequence.
0227  */
0228 static inline struct sctp_cmd *sctp_next_cmd(struct sctp_cmd_seq *seq)
0229 {
0230     if (seq->next_cmd <= seq->last_used_slot)
0231         return NULL;
0232 
0233     return --seq->next_cmd;
0234 }
0235 
0236 #endif /* __net_sctp_command_h__ */