sm.h 16.1 KB
Newer Older
Jon Grimm's avatar
Jon Grimm committed
1 2 3 4 5
/* SCTP kernel reference Implementation
 * Copyright (c) 1999-2000 Cisco, Inc.
 * Copyright (c) 1999-2001 Motorola, Inc.
 * Copyright (c) 2001 Intel Corp.
 * Copyright (c) 2001-2002 International Business Machines Corp.
6
 *
Jon Grimm's avatar
Jon Grimm committed
7
 * This file is part of the SCTP kernel reference Implementation
8
 *
Jon Grimm's avatar
Jon Grimm committed
9
 * These are definitions needed by the state machine.
10 11 12
 *
 * The SCTP reference implementation is free software;
 * you can redistribute it and/or modify it under the terms of
Jon Grimm's avatar
Jon Grimm committed
13 14 15
 * the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
16 17
 *
 * The SCTP reference implementation is distributed in the hope that it
Jon Grimm's avatar
Jon Grimm committed
18 19 20 21
 * 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.
22
 *
Jon Grimm's avatar
Jon Grimm committed
23 24 25
 * You should have received a copy of the GNU General Public License
 * along with GNU CC; see the file COPYING.  If not, write to
 * the Free Software Foundation, 59 Temple Place - Suite 330,
26 27
 * Boston, MA 02111-1307, USA.
 *
Jon Grimm's avatar
Jon Grimm committed
28 29 30
 * Please send any bug reports or fixes you make to the
 * email addresses:
 *    lksctp developers <lksctp-developers@lists.sourceforge.net>
31
 *
Jon Grimm's avatar
Jon Grimm committed
32 33 34
 * Or submit a bug report through the following website:
 *    http://www.sf.net/projects/lksctp
 *
35
 * Written or modified by:
Jon Grimm's avatar
Jon Grimm committed
36 37 38 39 40 41 42
 *    La Monte H.P. Yarroll <piggy@acm.org>
 *    Karl Knutson <karl@athena.chicago.il.us>
 *    Xingang Guo <xingang.guo@intel.com>
 *    Jon Grimm <jgrimm@us.ibm.com>
 *    Dajiang Zhang <dajiang.zhang@nokia.com>
 *    Sridhar Samudrala <sri@us.ibm.com>
 *    Daisy Chang <daisyc@us.ibm.com>
43
 *    Ardelle Fan <ardelle.fan@intel.com>
Jon Grimm's avatar
Jon Grimm committed
44 45 46 47 48 49 50 51 52
 *
 * Any bugs reported given to us we will try to fix... any fixes shared will
 * be incorporated into the next SCTP release.
 */

#include <linux/types.h>
#include <linux/compiler.h>
#include <linux/slab.h>
#include <linux/in.h>
53
#include <net/sctp/command.h>
Jon Grimm's avatar
Jon Grimm committed
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
#include <net/sctp/sctp.h>

#ifndef __sctp_sm_h__
#define __sctp_sm_h__

/*
 * Possible values for the disposition are:
 */
typedef enum {
	SCTP_DISPOSITION_DISCARD,	 /* No further processing.  */
	SCTP_DISPOSITION_CONSUME,	 /* Process return values normally.  */
	SCTP_DISPOSITION_NOMEM,		 /* We ran out of memory--recover.  */
	SCTP_DISPOSITION_DELETE_TCB,	 /* Close the association.  */
	SCTP_DISPOSITION_ABORT,		 /* Close the association NOW.  */
	SCTP_DISPOSITION_VIOLATION,	 /* The peer is misbehaving.  */
	SCTP_DISPOSITION_NOT_IMPL,	 /* This entry is not implemented.  */
	SCTP_DISPOSITION_ERROR,		 /* This is plain old user error.  */
	SCTP_DISPOSITION_BUG,		 /* This is a bug.  */
} sctp_disposition_t;

typedef struct {
	int name;
	int action;
} sctp_sm_command_t;

Jon Grimm's avatar
Jon Grimm committed
79 80
typedef sctp_disposition_t (sctp_state_fn_t) (const struct sctp_endpoint *,
					      const struct sctp_association *,
Jon Grimm's avatar
Jon Grimm committed
81 82 83 84 85
					      const sctp_subtype_t type,
					      void *arg,
					      sctp_cmd_seq_t *);
typedef void (sctp_timer_event_t) (unsigned long);
typedef struct {
86
	sctp_state_fn_t *fn;
87
	const char *name;
Jon Grimm's avatar
Jon Grimm committed
88 89
} sctp_sm_table_entry_t;

90
/* A naming convention of "sctp_sf_xxx" applies to all the state functions
Jon Grimm's avatar
Jon Grimm committed
91 92 93 94 95 96 97 98 99 100 101 102 103 104
 * currently in use.
 */

/* Prototypes for generic state functions. */
sctp_state_fn_t sctp_sf_not_impl;
sctp_state_fn_t sctp_sf_bug;

/* Prototypes for gener timer state functions. */
sctp_state_fn_t sctp_sf_timer_ignore;

/* Prototypes for chunk state functions. */
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_echoed_abort;
Jon Grimm's avatar
Jon Grimm committed
105 106 107
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;
Jon Grimm's avatar
Jon Grimm committed
108 109 110
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_1D_ce;
111
sctp_state_fn_t sctp_sf_do_5_1E_ca;
Jon Grimm's avatar
Jon Grimm committed
112 113 114 115 116 117 118 119
sctp_state_fn_t sctp_sf_do_4_C;
sctp_state_fn_t sctp_sf_eat_data_6_2;
sctp_state_fn_t sctp_sf_eat_data_fast_4_4;
sctp_state_fn_t sctp_sf_eat_sack_6_2;
sctp_state_fn_t sctp_sf_tabort_8_4_8;
sctp_state_fn_t sctp_sf_operr_notify;
sctp_state_fn_t sctp_sf_t1_timer_expire;
sctp_state_fn_t sctp_sf_t2_timer_expire;
Jon Grimm's avatar
Jon Grimm committed
120
sctp_state_fn_t sctp_sf_t5_timer_expire;
Jon Grimm's avatar
Jon Grimm committed
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
sctp_state_fn_t sctp_sf_sendbeat_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_do_9_2_final;
sctp_state_fn_t sctp_sf_do_9_2_shutdown;
sctp_state_fn_t sctp_sf_do_ecn_cwr;
sctp_state_fn_t sctp_sf_do_ecne;
sctp_state_fn_t sctp_sf_ootb;
sctp_state_fn_t sctp_sf_shut_8_4_5;
sctp_state_fn_t sctp_sf_pdiscard;
sctp_state_fn_t sctp_sf_violation;
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_2_dupinit;
sctp_state_fn_t sctp_sf_do_5_2_4_dupcook;
Jon Grimm's avatar
Jon Grimm committed
136
sctp_state_fn_t sctp_sf_unk_chunk;
137
sctp_state_fn_t sctp_sf_do_8_5_1_E_sa;
138 139
sctp_state_fn_t sctp_sf_cookie_echoed_err;
sctp_state_fn_t sctp_sf_do_5_2_6_stale;
Jon Grimm's avatar
Jon Grimm committed
140 141 142 143 144 145 146

/* Prototypes for primitive event state functions.  */
sctp_state_fn_t sctp_sf_do_prm_asoc;
sctp_state_fn_t sctp_sf_do_prm_send;
sctp_state_fn_t sctp_sf_do_9_2_prm_shutdown;
sctp_state_fn_t sctp_sf_cookie_wait_prm_shutdown;
sctp_state_fn_t sctp_sf_cookie_echoed_prm_shutdown;
147 148 149
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_echoed_prm_abort;
Jon Grimm's avatar
Jon Grimm committed
150 151 152
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;
Jon Grimm's avatar
Jon Grimm committed
153 154 155
sctp_state_fn_t sctp_sf_error_closed;
sctp_state_fn_t sctp_sf_error_shutdown;
sctp_state_fn_t sctp_sf_ignore_primitive;
156
sctp_state_fn_t sctp_sf_do_prm_requestheartbeat;
Jon Grimm's avatar
Jon Grimm committed
157 158 159 160 161 162 163 164 165 166 167 168

/* Prototypes for other event state functions.  */
sctp_state_fn_t sctp_sf_do_9_2_start_shutdown;
sctp_state_fn_t sctp_sf_do_9_2_shutdown_ack;
sctp_state_fn_t sctp_sf_ignore_other;

/* Prototypes for timeout event state functions.  */
sctp_state_fn_t sctp_sf_do_6_3_3_rtx;
sctp_state_fn_t sctp_sf_do_6_2_sack;
sctp_state_fn_t sctp_sf_autoclose_timer_expire;


169
/* These are state functions which are either obsolete or not in use yet.
Jon Grimm's avatar
Jon Grimm committed
170 171
 * If any of these functions needs to be revived, it should be renamed with
 * the "sctp_sf_xxx" prefix, and be moved to the above prototype groups.
172
 */
Jon Grimm's avatar
Jon Grimm committed
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191

/* Prototypes for chunk state functions.  Not in use. */
sctp_state_fn_t sctp_sf_do_9_2_reshutack;
sctp_state_fn_t sctp_sf_do_9_2_reshut;
sctp_state_fn_t sctp_sf_do_9_2_shutack;

/* Prototypes for timeout event state functions.  Not in use. */
sctp_state_fn_t sctp_do_4_2_reinit;
sctp_state_fn_t sctp_do_4_3_reecho;
sctp_state_fn_t sctp_do_9_2_reshut;
sctp_state_fn_t sctp_do_9_2_reshutack;
sctp_state_fn_t sctp_do_8_3_hb_err;
sctp_state_fn_t sctp_heartoff;

/* Prototypes for addip related state functions.  Not in use. */
sctp_state_fn_t sctp_addip_do_asconf;
sctp_state_fn_t sctp_addip_do_asconf_ack;

/* Prototypes for utility support functions.  */
192
__u8 sctp_get_chunk_type(struct sctp_chunk *chunk);
193 194 195
const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t,
					    sctp_state_t,
					    sctp_subtype_t);
196 197 198 199
int sctp_chunk_iif(const struct sctp_chunk *);
struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *,
					     struct sctp_chunk *,
					     int gfp);
200 201
__u32 sctp_generate_verification_tag(void);
void sctp_populate_tie_tags(__u8 *cookie, __u32 curTag, __u32 hisTag);
Jon Grimm's avatar
Jon Grimm committed
202 203

/* Prototypes for chunk-building functions.  */
Jon Grimm's avatar
Jon Grimm committed
204 205
struct sctp_chunk *sctp_make_init(const struct sctp_association *,
			     const struct sctp_bind_addr *,
Jon Grimm's avatar
Jon Grimm committed
206
			     int gfp, int vparam_len);
Jon Grimm's avatar
Jon Grimm committed
207 208
struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *,
				 const struct sctp_chunk *,
Jon Grimm's avatar
Jon Grimm committed
209
				 const int gfp,
210
				 const int unkparam_len);
Jon Grimm's avatar
Jon Grimm committed
211 212 213 214 215
struct sctp_chunk *sctp_make_cookie_echo(const struct sctp_association *,
				    const struct sctp_chunk *);
struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *,
				   const struct sctp_chunk *);
struct sctp_chunk *sctp_make_cwr(const struct sctp_association *,
216
				 const __u32 lowest_tsn,
Jon Grimm's avatar
Jon Grimm committed
217 218
				 const struct sctp_chunk *);
struct sctp_chunk *sctp_make_datafrag(struct sctp_association *,
Jon Grimm's avatar
Jon Grimm committed
219
				 const struct sctp_sndrcvinfo *sinfo,
220 221
				 int len, const __u8 *data,
				 __u8 flags, __u16 ssn);
Jon Grimm's avatar
Jon Grimm committed
222
struct sctp_chunk * sctp_make_datafrag_empty(struct sctp_association *,
Jon Grimm's avatar
Jon Grimm committed
223
					const struct sctp_sndrcvinfo *sinfo,
224 225
					int len, const __u8 flags,
					__u16 ssn);
Jon Grimm's avatar
Jon Grimm committed
226
struct sctp_chunk *sctp_make_data(struct sctp_association *,
Jon Grimm's avatar
Jon Grimm committed
227
			     const struct sctp_sndrcvinfo *sinfo,
228
			     int len, const __u8 *data);
Jon Grimm's avatar
Jon Grimm committed
229
struct sctp_chunk *sctp_make_data_empty(struct sctp_association *,
Jon Grimm's avatar
Jon Grimm committed
230
				   const struct sctp_sndrcvinfo *, int len);
Jon Grimm's avatar
Jon Grimm committed
231
struct sctp_chunk *sctp_make_ecne(const struct sctp_association *,
232
				  const __u32);
Jon Grimm's avatar
Jon Grimm committed
233 234 235 236 237 238 239 240 241
struct sctp_chunk *sctp_make_sack(const struct sctp_association *);
struct sctp_chunk *sctp_make_shutdown(const struct sctp_association *asoc);
struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc,
					  const struct sctp_chunk *);
struct sctp_chunk *sctp_make_shutdown_complete(const struct sctp_association *,
					  const struct sctp_chunk *);
void sctp_init_cause(struct sctp_chunk *, __u16 cause, const void *, size_t);
struct sctp_chunk *sctp_make_abort(const struct sctp_association *,
			      const struct sctp_chunk *,
Jon Grimm's avatar
Jon Grimm committed
242
			      const size_t hint);
Jon Grimm's avatar
Jon Grimm committed
243 244
struct sctp_chunk *sctp_make_abort_no_data(const struct sctp_association *,
				      const struct sctp_chunk *,
245
				      __u32 tsn);
Jon Grimm's avatar
Jon Grimm committed
246 247
struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *,
				   const struct sctp_chunk *,
248
				   const struct msghdr *);
Jon Grimm's avatar
Jon Grimm committed
249
struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *,
250
				  const struct sctp_transport *,
Jon Grimm's avatar
Jon Grimm committed
251 252
				  const void *payload,
				  const size_t paylen);
Jon Grimm's avatar
Jon Grimm committed
253 254
struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *,
				      const struct sctp_chunk *,
Jon Grimm's avatar
Jon Grimm committed
255 256
				      const void *payload,
				      const size_t paylen);
Jon Grimm's avatar
Jon Grimm committed
257 258
struct sctp_chunk *sctp_make_op_error(const struct sctp_association *,
				 const struct sctp_chunk *chunk,
259
				 __u16 cause_code,
Jon Grimm's avatar
Jon Grimm committed
260 261
				 const void *payload,
				 size_t paylen);
Jon Grimm's avatar
Jon Grimm committed
262 263
void sctp_chunk_assign_tsn(struct sctp_chunk *);
void sctp_chunk_assign_ssn(struct sctp_chunk *);
Jon Grimm's avatar
Jon Grimm committed
264 265 266 267 268

/* Prototypes for statetable processing. */

int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
	       sctp_state_t state,
Jon Grimm's avatar
Jon Grimm committed
269 270
               struct sctp_endpoint *,
               struct sctp_association *asoc,
Jon Grimm's avatar
Jon Grimm committed
271
               void *event_arg,
Jon Grimm's avatar
Jon Grimm committed
272
               int gfp);
Jon Grimm's avatar
Jon Grimm committed
273 274 275

int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
		      sctp_state_t state,
Jon Grimm's avatar
Jon Grimm committed
276 277
                      struct sctp_endpoint *,
                      struct sctp_association *asoc,
Jon Grimm's avatar
Jon Grimm committed
278 279 280
                      void *event_arg,
                      sctp_disposition_t status,
		      sctp_cmd_seq_t *commands,
Jon Grimm's avatar
Jon Grimm committed
281
                      int gfp);
Jon Grimm's avatar
Jon Grimm committed
282 283

/* 2nd level prototypes */
284 285 286 287
int sctp_cmd_interpreter(sctp_event_t, sctp_subtype_t, sctp_state_t,
			 struct sctp_endpoint *, struct sctp_association *,
			 void *event_arg, sctp_disposition_t,
			 sctp_cmd_seq_t *retval, int gfp);
Jon Grimm's avatar
Jon Grimm committed
288 289


Jon Grimm's avatar
Jon Grimm committed
290
int sctp_gen_sack(struct sctp_association *, int force, sctp_cmd_seq_t *);
Jon Grimm's avatar
Jon Grimm committed
291 292 293
void sctp_generate_t3_rtx_event(unsigned long peer);
void sctp_generate_heartbeat_event(unsigned long peer);

Jon Grimm's avatar
Jon Grimm committed
294
sctp_sackhdr_t *sctp_sm_pull_sack(struct sctp_chunk *);
295 296 297 298 299 300 301 302
struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *,
				       const struct sctp_association *,
				       struct sctp_chunk *chunk,
				       const void *payload,
				       size_t paylen);
struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *,
				      const struct sctp_chunk *);
void sctp_ootb_pkt_free(struct sctp_packet *);
Jon Grimm's avatar
Jon Grimm committed
303

304
struct sctp_cookie_param *
305 306
sctp_pack_cookie(const struct sctp_endpoint *, const struct sctp_association *,
		 const struct sctp_chunk *, int *cookie_len,
307
		 const __u8 *, int addrs_len);
Jon Grimm's avatar
Jon Grimm committed
308 309
struct sctp_association *sctp_unpack_cookie(const struct sctp_endpoint *,
				       const struct sctp_association *,
Jon Grimm's avatar
Jon Grimm committed
310 311
				       struct sctp_chunk *, int gfp, int *err,
				       struct sctp_chunk **err_chk_p);
Jon Grimm's avatar
Jon Grimm committed
312
int sctp_addip_addr_config(struct sctp_association *, sctp_param_t,
Jon Grimm's avatar
Jon Grimm committed
313
			   struct sockaddr_storage*, int);
Jon Grimm's avatar
Jon Grimm committed
314 315
void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
				const struct sctp_association *asoc,
Jon Grimm's avatar
Jon Grimm committed
316
				const struct sctp_chunk *chunk,
317
				sctp_cmd_seq_t *commands,
Jon Grimm's avatar
Jon Grimm committed
318
				struct sctp_chunk *err_chunk);
Jon Grimm's avatar
Jon Grimm committed
319 320

/* 3rd level prototypes */
Jon Grimm's avatar
Jon Grimm committed
321 322
__u32 sctp_generate_tag(const struct sctp_endpoint *);
__u32 sctp_generate_tsn(const struct sctp_endpoint *);
Jon Grimm's avatar
Jon Grimm committed
323 324

/* 4th level prototypes */
325
void sctp_param2sockaddr(union sctp_addr *addr, union sctp_addr_param *,
326
			 __u16 port, int iif);
Jon Grimm's avatar
Jon Grimm committed
327
int sctp_addr2sockaddr(const union sctp_params, union sctp_addr *);
328
int sockaddr2sctp_addr(const union sctp_addr *, union sctp_addr_param *);
Jon Grimm's avatar
Jon Grimm committed
329 330

/* Extern declarations for major data structures.  */
331 332
const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t, sctp_state_t);
extern const sctp_sm_table_entry_t
Jon Grimm's avatar
Jon Grimm committed
333
primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES];
334
extern const sctp_sm_table_entry_t
Jon Grimm's avatar
Jon Grimm committed
335
other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES];
336
extern const sctp_sm_table_entry_t
Jon Grimm's avatar
Jon Grimm committed
337 338 339 340 341 342 343
timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES];
extern sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES];

/* These are some handy utility macros... */


/* Get the size of a DATA chunk payload. */
Jon Grimm's avatar
Jon Grimm committed
344
static inline __u16 sctp_data_size(struct sctp_chunk *chunk)
Jon Grimm's avatar
Jon Grimm committed
345
{
346
	__u16 size;
Jon Grimm's avatar
Jon Grimm committed
347 348 349 350

	size = ntohs(chunk->chunk_hdr->length);
	size -= sizeof(sctp_data_chunk_t);

351 352
	return size;
}
Jon Grimm's avatar
Jon Grimm committed
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371

/* Compare two TSNs */

/* RFC 1982 - Serial Number Arithmetic
 *
 * 2. Comparison
 *  Then, s1 is said to be equal to s2 if and only if i1 is equal to i2,
 *  in all other cases, s1 is not equal to s2.
 *
 * s1 is said to be less than s2 if, and only if, s1 is not equal to s2,
 * and
 *
 *      (i1 < i2 and i2 - i1 < 2^(SERIAL_BITS - 1)) or
 *      (i1 > i2 and i1 - i2 > 2^(SERIAL_BITS - 1))
 *
 * s1 is said to be greater than s2 if, and only if, s1 is not equal to
 * s2, and
 *
 *      (i1 < i2 and i2 - i1 > 2^(SERIAL_BITS - 1)) or
372
 *      (i1 > i2 and i1 - i2 < 2^(SERIAL_BITS - 1))
Jon Grimm's avatar
Jon Grimm committed
373 374 375 376
 */

/*
 * RFC 2960
377
 *  1.6 Serial Number Arithmetic
Jon Grimm's avatar
Jon Grimm committed
378 379 380 381 382 383 384 385 386
 *
 * Comparisons and arithmetic on TSNs in this document SHOULD use Serial
 * Number Arithmetic as defined in [RFC1982] where SERIAL_BITS = 32.
 */

enum {
	TSN_SIGN_BIT = (1<<31)
};

387
static inline int TSN_lt(__u32 s, __u32 t)
Jon Grimm's avatar
Jon Grimm committed
388 389 390 391
{
	return (((s) - (t)) & TSN_SIGN_BIT);
}

392
static inline int TSN_lte(__u32 s, __u32 t)
Jon Grimm's avatar
Jon Grimm committed
393 394 395 396 397 398 399 400
{
	return (((s) == (t)) || (((s) - (t)) & TSN_SIGN_BIT));
}

/* Compare two SSNs */

/*
 * RFC 2960
401
 *  1.6 Serial Number Arithmetic
Jon Grimm's avatar
Jon Grimm committed
402
 *
403 404
 * Comparisons and arithmetic on Stream Sequence Numbers in this document
 * SHOULD use Serial Number Arithmetic as defined in [RFC1982] where
Jon Grimm's avatar
Jon Grimm committed
405 406 407 408 409 410
 * SERIAL_BITS = 16.
 */
enum {
	SSN_SIGN_BIT = (1<<15)
};

411
static inline int SSN_lt(__u16 s, __u16 t)
Jon Grimm's avatar
Jon Grimm committed
412 413 414 415
{
	return (((s) - (t)) & SSN_SIGN_BIT);
}

416
static inline int SSN_lte(__u16 s, __u16 t)
Jon Grimm's avatar
Jon Grimm committed
417 418 419 420 421
{
	return (((s) == (t)) || (((s) - (t)) & SSN_SIGN_BIT));
}

/* Run sctp_add_cmd() generating a BUG() if there is a failure.  */
422
static inline void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_arg_t obj)
Jon Grimm's avatar
Jon Grimm committed
423
{
424
	if (unlikely(!sctp_add_cmd(seq, verb, obj)))
Jon Grimm's avatar
Jon Grimm committed
425
		BUG();
426
}
Jon Grimm's avatar
Jon Grimm committed
427

428 429 430 431
/* Check VTAG of the packet matches the sender's own tag OR its peer's
 * tag and the T bit is set in the Chunk Flags.
 */
static inline int
Jon Grimm's avatar
Jon Grimm committed
432
sctp_vtag_verify_either(const struct sctp_chunk *chunk,
Jon Grimm's avatar
Jon Grimm committed
433
			const struct sctp_association *asoc)
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459
{
        /* RFC 2960 Section 8.5.1, sctpimpguide-06 Section 2.13.2
	 *
	 * B) The receiver of a ABORT shall accept the packet if the
	 * Verification Tag field of the packet matches its own tag OR it
	 * is set to its peer's tag and the T bit is set in the Chunk
	 * Flags. Otherwise, the receiver MUST silently discard the packet
	 * and take no further action.
	 *
	 * (C) The receiver of a SHUTDOWN COMPLETE shall accept the
	 * packet if the Verification Tag field of the packet
	 * matches its own tag OR it is set to its peer's tag and
	 * the T bit is set in the Chunk Flags.  Otherwise, the
	 * receiver MUST silently discard the packet and take no
	 * further action....
	 *
	 */
        if ((ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag) ||
	    (sctp_test_T_bit(chunk) && (ntohl(chunk->sctp_hdr->vtag)
	    == asoc->c.peer_vtag))) {
                return 1;
	}

	return 0;
}

Jon Grimm's avatar
Jon Grimm committed
460
#endif /* __sctp_sm_h__ */