mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-08 01:08:03 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
120
include/net/sctp/auth.h
Normal file
120
include/net/sctp/auth.h
Normal file
|
@ -0,0 +1,120 @@
|
|||
/* SCTP kernel implementation
|
||||
* (C) Copyright 2007 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* This file is part of the SCTP kernel implementation
|
||||
*
|
||||
* 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:
|
||||
* Vlad Yasevich <vladislav.yasevich@hp.com>
|
||||
*/
|
||||
|
||||
#ifndef __sctp_auth_h__
|
||||
#define __sctp_auth_h__
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/crypto.h>
|
||||
|
||||
struct sctp_endpoint;
|
||||
struct sctp_association;
|
||||
struct sctp_authkey;
|
||||
struct sctp_hmacalgo;
|
||||
|
||||
/*
|
||||
* Define a generic struct that will hold all the info
|
||||
* necessary for an HMAC transform
|
||||
*/
|
||||
struct sctp_hmac {
|
||||
__u16 hmac_id; /* one of the above ids */
|
||||
char *hmac_name; /* name for loading */
|
||||
__u16 hmac_len; /* length of the signature */
|
||||
};
|
||||
|
||||
/* This is generic structure that containst authentication bytes used
|
||||
* as keying material. It's a what is referred to as byte-vector all
|
||||
* over SCTP-AUTH
|
||||
*/
|
||||
struct sctp_auth_bytes {
|
||||
atomic_t refcnt;
|
||||
__u32 len;
|
||||
__u8 data[];
|
||||
};
|
||||
|
||||
/* Definition for a shared key, weather endpoint or association */
|
||||
struct sctp_shared_key {
|
||||
struct list_head key_list;
|
||||
__u16 key_id;
|
||||
struct sctp_auth_bytes *key;
|
||||
};
|
||||
|
||||
#define key_for_each(__key, __list_head) \
|
||||
list_for_each_entry(__key, __list_head, key_list)
|
||||
|
||||
#define key_for_each_safe(__key, __tmp, __list_head) \
|
||||
list_for_each_entry_safe(__key, __tmp, __list_head, key_list)
|
||||
|
||||
static inline void sctp_auth_key_hold(struct sctp_auth_bytes *key)
|
||||
{
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
atomic_inc(&key->refcnt);
|
||||
}
|
||||
|
||||
void sctp_auth_key_put(struct sctp_auth_bytes *key);
|
||||
struct sctp_shared_key *sctp_auth_shkey_create(__u16 key_id, gfp_t gfp);
|
||||
void sctp_auth_destroy_keys(struct list_head *keys);
|
||||
int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp);
|
||||
struct sctp_shared_key *sctp_auth_get_shkey(
|
||||
const struct sctp_association *asoc,
|
||||
__u16 key_id);
|
||||
int sctp_auth_asoc_copy_shkeys(const struct sctp_endpoint *ep,
|
||||
struct sctp_association *asoc,
|
||||
gfp_t gfp);
|
||||
int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp);
|
||||
void sctp_auth_destroy_hmacs(struct crypto_hash *auth_hmacs[]);
|
||||
struct sctp_hmac *sctp_auth_get_hmac(__u16 hmac_id);
|
||||
struct sctp_hmac *sctp_auth_asoc_get_hmac(const struct sctp_association *asoc);
|
||||
void sctp_auth_asoc_set_default_hmac(struct sctp_association *asoc,
|
||||
struct sctp_hmac_algo_param *hmacs);
|
||||
int sctp_auth_asoc_verify_hmac_id(const struct sctp_association *asoc,
|
||||
__be16 hmac_id);
|
||||
int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc);
|
||||
int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc);
|
||||
void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
|
||||
struct sk_buff *skb,
|
||||
struct sctp_auth_chunk *auth, gfp_t gfp);
|
||||
|
||||
/* API Helpers */
|
||||
int sctp_auth_ep_add_chunkid(struct sctp_endpoint *ep, __u8 chunk_id);
|
||||
int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep,
|
||||
struct sctp_hmacalgo *hmacs);
|
||||
int sctp_auth_set_key(struct sctp_endpoint *ep,
|
||||
struct sctp_association *asoc,
|
||||
struct sctp_authkey *auth_key);
|
||||
int sctp_auth_set_active_key(struct sctp_endpoint *ep,
|
||||
struct sctp_association *asoc,
|
||||
__u16 key_id);
|
||||
int sctp_auth_del_key_id(struct sctp_endpoint *ep,
|
||||
struct sctp_association *asoc,
|
||||
__u16 key_id);
|
||||
|
||||
#endif
|
78
include/net/sctp/checksum.h
Normal file
78
include/net/sctp/checksum.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
/* SCTP kernel reference Implementation
|
||||
* Copyright (c) 1999-2001 Motorola, Inc.
|
||||
* Copyright (c) 2001-2003 International Business Machines, Corp.
|
||||
*
|
||||
* This file is part of the SCTP kernel reference Implementation
|
||||
*
|
||||
* SCTP Checksum functions
|
||||
*
|
||||
* The SCTP reference 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.
|
||||
*
|
||||
* The SCTP reference 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:
|
||||
* Dinakaran Joseph
|
||||
* Jon Grimm <jgrimm@us.ibm.com>
|
||||
* Sridhar Samudrala <sri@us.ibm.com>
|
||||
*
|
||||
* Rewritten to use libcrc32c by:
|
||||
* Vlad Yasevich <vladislav.yasevich@hp.com>
|
||||
*/
|
||||
|
||||
#ifndef __sctp_checksum_h__
|
||||
#define __sctp_checksum_h__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <net/sctp/sctp.h>
|
||||
#include <linux/crc32c.h>
|
||||
#include <linux/crc32.h>
|
||||
|
||||
static inline __wsum sctp_csum_update(const void *buff, int len, __wsum sum)
|
||||
{
|
||||
/* This uses the crypto implementation of crc32c, which is either
|
||||
* implemented w/ hardware support or resolves to __crc32c_le().
|
||||
*/
|
||||
return crc32c(sum, buff, len);
|
||||
}
|
||||
|
||||
static inline __wsum sctp_csum_combine(__wsum csum, __wsum csum2,
|
||||
int offset, int len)
|
||||
{
|
||||
return __crc32c_le_combine(csum, csum2, len);
|
||||
}
|
||||
|
||||
static inline __le32 sctp_compute_cksum(const struct sk_buff *skb,
|
||||
unsigned int offset)
|
||||
{
|
||||
struct sctphdr *sh = sctp_hdr(skb);
|
||||
__le32 ret, old = sh->checksum;
|
||||
const struct skb_checksum_ops ops = {
|
||||
.update = sctp_csum_update,
|
||||
.combine = sctp_csum_combine,
|
||||
};
|
||||
|
||||
sh->checksum = 0;
|
||||
ret = cpu_to_le32(~__skb_checksum(skb, offset, skb->len - offset,
|
||||
~(__u32)0, &ops));
|
||||
sh->checksum = old;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* __sctp_checksum_h__ */
|
251
include/net/sctp/command.h
Normal file
251
include/net/sctp/command.h
Normal file
|
@ -0,0 +1,251 @@
|
|||
/* SCTP kernel Implementation
|
||||
* (C) Copyright IBM Corp. 2001, 2004
|
||||
* Copyright (C) 1999-2001 Cisco, Motorola
|
||||
*
|
||||
* This file is part of the SCTP kernel implementation
|
||||
*
|
||||
* These are the definitions needed for the command object.
|
||||
*
|
||||
* 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>
|
||||
* Ardelle Fan <ardelle.fan@intel.com>
|
||||
* Sridhar Samudrala <sri@us.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef __net_sctp_command_h__
|
||||
#define __net_sctp_command_h__
|
||||
|
||||
#include <net/sctp/constants.h>
|
||||
#include <net/sctp/structs.h>
|
||||
|
||||
|
||||
typedef enum {
|
||||
SCTP_CMD_NOP = 0, /* Do nothing. */
|
||||
SCTP_CMD_NEW_ASOC, /* Register a new association. */
|
||||
SCTP_CMD_DELETE_TCB, /* Delete the current association. */
|
||||
SCTP_CMD_NEW_STATE, /* Enter a new state. */
|
||||
SCTP_CMD_REPORT_TSN, /* Record the arrival of a TSN. */
|
||||
SCTP_CMD_GEN_SACK, /* Send a Selective ACK (maybe). */
|
||||
SCTP_CMD_PROCESS_SACK, /* Process an inbound SACK. */
|
||||
SCTP_CMD_GEN_INIT_ACK, /* Generate an INIT ACK chunk. */
|
||||
SCTP_CMD_PEER_INIT, /* Process a INIT from the peer. */
|
||||
SCTP_CMD_GEN_COOKIE_ECHO, /* Generate a COOKIE ECHO chunk. */
|
||||
SCTP_CMD_CHUNK_ULP, /* Send a chunk to the sockets layer. */
|
||||
SCTP_CMD_EVENT_ULP, /* Send a notification to the sockets layer. */
|
||||
SCTP_CMD_REPLY, /* Send a chunk to our peer. */
|
||||
SCTP_CMD_SEND_PKT, /* Send a full packet to our peer. */
|
||||
SCTP_CMD_RETRAN, /* Mark a transport for retransmission. */
|
||||
SCTP_CMD_ECN_CE, /* Do delayed CE processing. */
|
||||
SCTP_CMD_ECN_ECNE, /* Do delayed ECNE processing. */
|
||||
SCTP_CMD_ECN_CWR, /* Do delayed CWR processing. */
|
||||
SCTP_CMD_TIMER_START, /* Start a timer. */
|
||||
SCTP_CMD_TIMER_START_ONCE, /* Start a timer once */
|
||||
SCTP_CMD_TIMER_RESTART, /* Restart a timer. */
|
||||
SCTP_CMD_TIMER_STOP, /* Stop a timer. */
|
||||
SCTP_CMD_INIT_CHOOSE_TRANSPORT, /* Choose transport for an INIT. */
|
||||
SCTP_CMD_INIT_COUNTER_RESET, /* Reset init counter. */
|
||||
SCTP_CMD_INIT_COUNTER_INC, /* Increment init counter. */
|
||||
SCTP_CMD_INIT_RESTART, /* High level, do init timer work. */
|
||||
SCTP_CMD_COOKIEECHO_RESTART, /* High level, do cookie-echo timer work. */
|
||||
SCTP_CMD_INIT_FAILED, /* High level, do init failure work. */
|
||||
SCTP_CMD_REPORT_DUP, /* Report a duplicate TSN. */
|
||||
SCTP_CMD_STRIKE, /* Mark a strike against a transport. */
|
||||
SCTP_CMD_HB_TIMERS_START, /* Start the heartbeat timers. */
|
||||
SCTP_CMD_HB_TIMER_UPDATE, /* Update a heartbeat timers. */
|
||||
SCTP_CMD_HB_TIMERS_STOP, /* Stop the heartbeat timers. */
|
||||
SCTP_CMD_TRANSPORT_HB_SENT, /* Reset the status of a transport. */
|
||||
SCTP_CMD_TRANSPORT_IDLE, /* Do manipulations on idle transport */
|
||||
SCTP_CMD_TRANSPORT_ON, /* Mark the transport as active. */
|
||||
SCTP_CMD_REPORT_ERROR, /* Pass this error back out of the sm. */
|
||||
SCTP_CMD_REPORT_BAD_TAG, /* Verification tags didn't match. */
|
||||
SCTP_CMD_PROCESS_CTSN, /* Sideeffect from shutdown. */
|
||||
SCTP_CMD_ASSOC_FAILED, /* Handle association failure. */
|
||||
SCTP_CMD_DISCARD_PACKET, /* Discard the whole packet. */
|
||||
SCTP_CMD_GEN_SHUTDOWN, /* Generate a SHUTDOWN chunk. */
|
||||
SCTP_CMD_UPDATE_ASSOC, /* Update association information. */
|
||||
SCTP_CMD_PURGE_OUTQUEUE, /* Purge all data waiting to be sent. */
|
||||
SCTP_CMD_SETUP_T2, /* Hi-level, setup T2-shutdown parms. */
|
||||
SCTP_CMD_RTO_PENDING, /* Set transport's rto_pending. */
|
||||
SCTP_CMD_PART_DELIVER, /* Partial data delivery considerations. */
|
||||
SCTP_CMD_RENEGE, /* Renege data on an association. */
|
||||
SCTP_CMD_SETUP_T4, /* ADDIP, setup T4 RTO timer parms. */
|
||||
SCTP_CMD_PROCESS_OPERR, /* Process an ERROR chunk. */
|
||||
SCTP_CMD_REPORT_FWDTSN, /* Report new cumulative TSN Ack. */
|
||||
SCTP_CMD_PROCESS_FWDTSN, /* Skips were reported, so process further. */
|
||||
SCTP_CMD_CLEAR_INIT_TAG, /* Clears association peer's inittag. */
|
||||
SCTP_CMD_DEL_NON_PRIMARY, /* Removes non-primary peer transports. */
|
||||
SCTP_CMD_T3_RTX_TIMERS_STOP, /* Stops T3-rtx pending timers */
|
||||
SCTP_CMD_FORCE_PRIM_RETRAN, /* Forces retrans. over primary path. */
|
||||
SCTP_CMD_SET_SK_ERR, /* Set sk_err */
|
||||
SCTP_CMD_ASSOC_CHANGE, /* generate and send assoc_change event */
|
||||
SCTP_CMD_ADAPTATION_IND, /* generate and send adaptation event */
|
||||
SCTP_CMD_ASSOC_SHKEY, /* generate the association shared keys */
|
||||
SCTP_CMD_T1_RETRAN, /* Mark for retransmission after T1 timeout */
|
||||
SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */
|
||||
SCTP_CMD_SEND_MSG, /* Send the whole use message */
|
||||
SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */
|
||||
SCTP_CMD_PURGE_ASCONF_QUEUE, /* Purge all asconf queues.*/
|
||||
SCTP_CMD_SET_ASOC, /* Restore association context */
|
||||
SCTP_CMD_LAST
|
||||
} sctp_verb_t;
|
||||
|
||||
/* How many commands can you put in an sctp_cmd_seq_t?
|
||||
* This is a rather arbitrary number, ideally derived from a careful
|
||||
* analysis of the state functions, but in reality just taken from
|
||||
* thin air in the hopes othat we don't trigger a kernel panic.
|
||||
*/
|
||||
#define SCTP_MAX_NUM_COMMANDS 20
|
||||
|
||||
typedef union {
|
||||
void *zero_all; /* Set to NULL to clear the entire union */
|
||||
__s32 i32;
|
||||
__u32 u32;
|
||||
__be32 be32;
|
||||
__u16 u16;
|
||||
__u8 u8;
|
||||
int error;
|
||||
__be16 err;
|
||||
sctp_state_t state;
|
||||
sctp_event_timeout_t to;
|
||||
struct sctp_chunk *chunk;
|
||||
struct sctp_association *asoc;
|
||||
struct sctp_transport *transport;
|
||||
struct sctp_bind_addr *bp;
|
||||
sctp_init_chunk_t *init;
|
||||
struct sctp_ulpevent *ulpevent;
|
||||
struct sctp_packet *packet;
|
||||
sctp_sackhdr_t *sackh;
|
||||
struct sctp_datamsg *msg;
|
||||
} sctp_arg_t;
|
||||
|
||||
/* We are simulating ML type constructors here.
|
||||
*
|
||||
* SCTP_ARG_CONSTRUCTOR(NAME, TYPE, ELT) builds a function called
|
||||
* SCTP_NAME() which takes an argument of type TYPE and returns an
|
||||
* sctp_arg_t. It does this by inserting the sole argument into the
|
||||
* ELT union element of a local sctp_arg_t.
|
||||
*
|
||||
* E.g., SCTP_ARG_CONSTRUCTOR(I32, __s32, i32) builds SCTP_I32(arg),
|
||||
* which takes an __s32 and returns a sctp_arg_t containing the
|
||||
* __s32. So, after foo = SCTP_I32(arg), foo.i32 == arg.
|
||||
*/
|
||||
|
||||
#define SCTP_ARG_CONSTRUCTOR(name, type, elt) \
|
||||
static inline sctp_arg_t \
|
||||
SCTP_## name (type arg) \
|
||||
{ sctp_arg_t retval;\
|
||||
retval.zero_all = NULL;\
|
||||
retval.elt = arg;\
|
||||
return retval;\
|
||||
}
|
||||
|
||||
SCTP_ARG_CONSTRUCTOR(I32, __s32, i32)
|
||||
SCTP_ARG_CONSTRUCTOR(U32, __u32, u32)
|
||||
SCTP_ARG_CONSTRUCTOR(BE32, __be32, be32)
|
||||
SCTP_ARG_CONSTRUCTOR(U16, __u16, u16)
|
||||
SCTP_ARG_CONSTRUCTOR(U8, __u8, u8)
|
||||
SCTP_ARG_CONSTRUCTOR(ERROR, int, error)
|
||||
SCTP_ARG_CONSTRUCTOR(PERR, __be16, err) /* protocol error */
|
||||
SCTP_ARG_CONSTRUCTOR(STATE, sctp_state_t, state)
|
||||
SCTP_ARG_CONSTRUCTOR(TO, sctp_event_timeout_t, to)
|
||||
SCTP_ARG_CONSTRUCTOR(CHUNK, struct sctp_chunk *, chunk)
|
||||
SCTP_ARG_CONSTRUCTOR(ASOC, struct sctp_association *, asoc)
|
||||
SCTP_ARG_CONSTRUCTOR(TRANSPORT, struct sctp_transport *, transport)
|
||||
SCTP_ARG_CONSTRUCTOR(BA, struct sctp_bind_addr *, bp)
|
||||
SCTP_ARG_CONSTRUCTOR(PEER_INIT, sctp_init_chunk_t *, init)
|
||||
SCTP_ARG_CONSTRUCTOR(ULPEVENT, struct sctp_ulpevent *, ulpevent)
|
||||
SCTP_ARG_CONSTRUCTOR(PACKET, struct sctp_packet *, packet)
|
||||
SCTP_ARG_CONSTRUCTOR(SACKH, sctp_sackhdr_t *, sackh)
|
||||
SCTP_ARG_CONSTRUCTOR(DATAMSG, struct sctp_datamsg *, msg)
|
||||
|
||||
static inline sctp_arg_t SCTP_FORCE(void)
|
||||
{
|
||||
return SCTP_I32(1);
|
||||
}
|
||||
|
||||
static inline sctp_arg_t SCTP_NOFORCE(void)
|
||||
{
|
||||
return SCTP_I32(0);
|
||||
}
|
||||
|
||||
static inline sctp_arg_t SCTP_NULL(void)
|
||||
{
|
||||
sctp_arg_t retval;
|
||||
retval.zero_all = NULL;
|
||||
return retval;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
sctp_arg_t obj;
|
||||
sctp_verb_t verb;
|
||||
} sctp_cmd_t;
|
||||
|
||||
typedef struct {
|
||||
sctp_cmd_t cmds[SCTP_MAX_NUM_COMMANDS];
|
||||
sctp_cmd_t *last_used_slot;
|
||||
sctp_cmd_t *next_cmd;
|
||||
} sctp_cmd_seq_t;
|
||||
|
||||
|
||||
/* Initialize a block of memory as a command sequence.
|
||||
* Return 0 if the initialization fails.
|
||||
*/
|
||||
static inline int sctp_init_cmd_seq(sctp_cmd_seq_t *seq)
|
||||
{
|
||||
/* cmds[] is filled backwards to simplify the overflow BUG() check */
|
||||
seq->last_used_slot = seq->cmds + SCTP_MAX_NUM_COMMANDS;
|
||||
seq->next_cmd = seq->last_used_slot;
|
||||
return 1; /* We always succeed. */
|
||||
}
|
||||
|
||||
|
||||
/* Add a command to an sctp_cmd_seq_t.
|
||||
*
|
||||
* Use the SCTP_* constructors defined by SCTP_ARG_CONSTRUCTOR() above
|
||||
* to wrap data which goes in the obj argument.
|
||||
*/
|
||||
static inline void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb,
|
||||
sctp_arg_t obj)
|
||||
{
|
||||
sctp_cmd_t *cmd = seq->last_used_slot - 1;
|
||||
|
||||
BUG_ON(cmd < seq->cmds);
|
||||
|
||||
cmd->verb = verb;
|
||||
cmd->obj = obj;
|
||||
seq->last_used_slot = cmd;
|
||||
}
|
||||
|
||||
/* Return the next command structure in an sctp_cmd_seq.
|
||||
* Return NULL at the end of the sequence.
|
||||
*/
|
||||
static inline sctp_cmd_t *sctp_next_cmd(sctp_cmd_seq_t *seq)
|
||||
{
|
||||
if (seq->next_cmd <= seq->last_used_slot)
|
||||
return NULL;
|
||||
|
||||
return --seq->next_cmd;
|
||||
}
|
||||
|
||||
#endif /* __net_sctp_command_h__ */
|
427
include/net/sctp/constants.h
Normal file
427
include/net/sctp/constants.h
Normal file
|
@ -0,0 +1,427 @@
|
|||
/* 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.
|
||||
*
|
||||
* This file is part of the SCTP kernel implementation
|
||||
*
|
||||
* 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>
|
||||
* Randall Stewart <randall@stewart.chicago.il.us>
|
||||
* Ken Morneau <kmorneau@cisco.com>
|
||||
* Qiaobing Xie <qxie1@motorola.com>
|
||||
* Xingang Guo <xingang.guo@intel.com>
|
||||
* Sridhar Samudrala <samudrala@us.ibm.com>
|
||||
* Daisy Chang <daisyc@us.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef __sctp_constants_h__
|
||||
#define __sctp_constants_h__
|
||||
|
||||
#include <linux/sctp.h>
|
||||
#include <linux/ipv6.h> /* For ipv6hdr. */
|
||||
#include <net/tcp_states.h> /* For TCP states used in sctp_sock_state_t */
|
||||
|
||||
/* Value used for stream negotiation. */
|
||||
enum { SCTP_MAX_STREAM = 0xffff };
|
||||
enum { SCTP_DEFAULT_OUTSTREAMS = 10 };
|
||||
enum { SCTP_DEFAULT_INSTREAMS = SCTP_MAX_STREAM };
|
||||
|
||||
/* Since CIDs are sparse, we need all four of the following
|
||||
* symbols. CIDs are dense through SCTP_CID_BASE_MAX.
|
||||
*/
|
||||
#define SCTP_CID_BASE_MAX SCTP_CID_SHUTDOWN_COMPLETE
|
||||
|
||||
#define SCTP_NUM_BASE_CHUNK_TYPES (SCTP_CID_BASE_MAX + 1)
|
||||
|
||||
#define SCTP_NUM_ADDIP_CHUNK_TYPES 2
|
||||
|
||||
#define SCTP_NUM_PRSCTP_CHUNK_TYPES 1
|
||||
|
||||
#define SCTP_NUM_AUTH_CHUNK_TYPES 1
|
||||
|
||||
#define SCTP_NUM_CHUNK_TYPES (SCTP_NUM_BASE_CHUNK_TYPES + \
|
||||
SCTP_NUM_ADDIP_CHUNK_TYPES +\
|
||||
SCTP_NUM_PRSCTP_CHUNK_TYPES +\
|
||||
SCTP_NUM_AUTH_CHUNK_TYPES)
|
||||
|
||||
/* These are the different flavours of event. */
|
||||
typedef enum {
|
||||
|
||||
SCTP_EVENT_T_CHUNK = 1,
|
||||
SCTP_EVENT_T_TIMEOUT,
|
||||
SCTP_EVENT_T_OTHER,
|
||||
SCTP_EVENT_T_PRIMITIVE
|
||||
|
||||
} sctp_event_t;
|
||||
|
||||
/* As a convenience for the state machine, we append SCTP_EVENT_* and
|
||||
* SCTP_ULP_* to the list of possible chunks.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
SCTP_EVENT_TIMEOUT_NONE = 0,
|
||||
SCTP_EVENT_TIMEOUT_T1_COOKIE,
|
||||
SCTP_EVENT_TIMEOUT_T1_INIT,
|
||||
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN,
|
||||
SCTP_EVENT_TIMEOUT_T3_RTX,
|
||||
SCTP_EVENT_TIMEOUT_T4_RTO,
|
||||
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD,
|
||||
SCTP_EVENT_TIMEOUT_HEARTBEAT,
|
||||
SCTP_EVENT_TIMEOUT_SACK,
|
||||
SCTP_EVENT_TIMEOUT_AUTOCLOSE,
|
||||
} sctp_event_timeout_t;
|
||||
|
||||
#define SCTP_EVENT_TIMEOUT_MAX SCTP_EVENT_TIMEOUT_AUTOCLOSE
|
||||
#define SCTP_NUM_TIMEOUT_TYPES (SCTP_EVENT_TIMEOUT_MAX + 1)
|
||||
|
||||
typedef enum {
|
||||
SCTP_EVENT_NO_PENDING_TSN = 0,
|
||||
SCTP_EVENT_ICMP_PROTO_UNREACH,
|
||||
} sctp_event_other_t;
|
||||
|
||||
#define SCTP_EVENT_OTHER_MAX SCTP_EVENT_ICMP_PROTO_UNREACH
|
||||
#define SCTP_NUM_OTHER_TYPES (SCTP_EVENT_OTHER_MAX + 1)
|
||||
|
||||
/* These are primitive requests from the ULP. */
|
||||
typedef enum {
|
||||
SCTP_PRIMITIVE_ASSOCIATE = 0,
|
||||
SCTP_PRIMITIVE_SHUTDOWN,
|
||||
SCTP_PRIMITIVE_ABORT,
|
||||
SCTP_PRIMITIVE_SEND,
|
||||
SCTP_PRIMITIVE_REQUESTHEARTBEAT,
|
||||
SCTP_PRIMITIVE_ASCONF,
|
||||
} sctp_event_primitive_t;
|
||||
|
||||
#define SCTP_EVENT_PRIMITIVE_MAX SCTP_PRIMITIVE_ASCONF
|
||||
#define SCTP_NUM_PRIMITIVE_TYPES (SCTP_EVENT_PRIMITIVE_MAX + 1)
|
||||
|
||||
/* We define here a utility type for manipulating subtypes.
|
||||
* The subtype constructors all work like this:
|
||||
*
|
||||
* sctp_subtype_t foo = SCTP_ST_CHUNK(SCTP_CID_INIT);
|
||||
*/
|
||||
|
||||
typedef union {
|
||||
sctp_cid_t chunk;
|
||||
sctp_event_timeout_t timeout;
|
||||
sctp_event_other_t other;
|
||||
sctp_event_primitive_t primitive;
|
||||
} sctp_subtype_t;
|
||||
|
||||
#define SCTP_SUBTYPE_CONSTRUCTOR(_name, _type, _elt) \
|
||||
static inline sctp_subtype_t \
|
||||
SCTP_ST_## _name (_type _arg) \
|
||||
{ sctp_subtype_t _retval; _retval._elt = _arg; return _retval; }
|
||||
|
||||
SCTP_SUBTYPE_CONSTRUCTOR(CHUNK, sctp_cid_t, chunk)
|
||||
SCTP_SUBTYPE_CONSTRUCTOR(TIMEOUT, sctp_event_timeout_t, timeout)
|
||||
SCTP_SUBTYPE_CONSTRUCTOR(OTHER, sctp_event_other_t, other)
|
||||
SCTP_SUBTYPE_CONSTRUCTOR(PRIMITIVE, sctp_event_primitive_t, primitive)
|
||||
|
||||
|
||||
#define sctp_chunk_is_data(a) (a->chunk_hdr->type == SCTP_CID_DATA)
|
||||
|
||||
/* Calculate the actual data size in a data chunk */
|
||||
#define SCTP_DATA_SNDSIZE(c) ((int)((unsigned long)(c->chunk_end)\
|
||||
- (unsigned long)(c->chunk_hdr)\
|
||||
- sizeof(sctp_data_chunk_t)))
|
||||
|
||||
/* Internal error codes */
|
||||
typedef enum {
|
||||
|
||||
SCTP_IERROR_NO_ERROR = 0,
|
||||
SCTP_IERROR_BASE = 1000,
|
||||
SCTP_IERROR_NO_COOKIE,
|
||||
SCTP_IERROR_BAD_SIG,
|
||||
SCTP_IERROR_STALE_COOKIE,
|
||||
SCTP_IERROR_NOMEM,
|
||||
SCTP_IERROR_MALFORMED,
|
||||
SCTP_IERROR_BAD_TAG,
|
||||
SCTP_IERROR_BIG_GAP,
|
||||
SCTP_IERROR_DUP_TSN,
|
||||
SCTP_IERROR_HIGH_TSN,
|
||||
SCTP_IERROR_IGNORE_TSN,
|
||||
SCTP_IERROR_NO_DATA,
|
||||
SCTP_IERROR_BAD_STREAM,
|
||||
SCTP_IERROR_BAD_PORTS,
|
||||
SCTP_IERROR_AUTH_BAD_HMAC,
|
||||
SCTP_IERROR_AUTH_BAD_KEYID,
|
||||
SCTP_IERROR_PROTO_VIOLATION,
|
||||
SCTP_IERROR_ERROR,
|
||||
SCTP_IERROR_ABORT,
|
||||
} sctp_ierror_t;
|
||||
|
||||
|
||||
|
||||
/* SCTP state defines for internal state machine */
|
||||
typedef enum {
|
||||
|
||||
SCTP_STATE_CLOSED = 0,
|
||||
SCTP_STATE_COOKIE_WAIT = 1,
|
||||
SCTP_STATE_COOKIE_ECHOED = 2,
|
||||
SCTP_STATE_ESTABLISHED = 3,
|
||||
SCTP_STATE_SHUTDOWN_PENDING = 4,
|
||||
SCTP_STATE_SHUTDOWN_SENT = 5,
|
||||
SCTP_STATE_SHUTDOWN_RECEIVED = 6,
|
||||
SCTP_STATE_SHUTDOWN_ACK_SENT = 7,
|
||||
|
||||
} sctp_state_t;
|
||||
|
||||
#define SCTP_STATE_MAX SCTP_STATE_SHUTDOWN_ACK_SENT
|
||||
#define SCTP_STATE_NUM_STATES (SCTP_STATE_MAX + 1)
|
||||
|
||||
/* These are values for sk->state.
|
||||
* For a UDP-style SCTP socket, the states are defined as follows
|
||||
* - A socket in SCTP_SS_CLOSED state indicates that it is not willing to
|
||||
* accept new associations, but it can initiate the creation of new ones.
|
||||
* - A socket in SCTP_SS_LISTENING state indicates that it is willing to
|
||||
* accept new associations and can initiate the creation of new ones.
|
||||
* - A socket in SCTP_SS_ESTABLISHED state indicates that it is a peeled off
|
||||
* socket with one association.
|
||||
* For a TCP-style SCTP socket, the states are defined as follows
|
||||
* - A socket in SCTP_SS_CLOSED state indicates that it is not willing to
|
||||
* accept new associations, but it can initiate the creation of new ones.
|
||||
* - A socket in SCTP_SS_LISTENING state indicates that it is willing to
|
||||
* accept new associations, but cannot initiate the creation of new ones.
|
||||
* - A socket in SCTP_SS_ESTABLISHED state indicates that it has a single
|
||||
* association.
|
||||
*/
|
||||
typedef enum {
|
||||
SCTP_SS_CLOSED = TCP_CLOSE,
|
||||
SCTP_SS_LISTENING = TCP_LISTEN,
|
||||
SCTP_SS_ESTABLISHING = TCP_SYN_SENT,
|
||||
SCTP_SS_ESTABLISHED = TCP_ESTABLISHED,
|
||||
SCTP_SS_CLOSING = TCP_CLOSING,
|
||||
} sctp_sock_state_t;
|
||||
|
||||
/* These functions map various type to printable names. */
|
||||
const char *sctp_cname(const sctp_subtype_t); /* chunk types */
|
||||
const char *sctp_oname(const sctp_subtype_t); /* other events */
|
||||
const char *sctp_tname(const sctp_subtype_t); /* timeouts */
|
||||
const char *sctp_pname(const sctp_subtype_t); /* primitives */
|
||||
|
||||
/* This is a table of printable names of sctp_state_t's. */
|
||||
extern const char *const sctp_state_tbl[];
|
||||
extern const char *const sctp_evttype_tbl[];
|
||||
extern const char *const sctp_status_tbl[];
|
||||
|
||||
/* Maximum chunk length considering padding requirements. */
|
||||
enum { SCTP_MAX_CHUNK_LEN = ((1<<16) - sizeof(__u32)) };
|
||||
|
||||
/* Encourage Cookie-Echo bundling by pre-fragmenting chunks a little
|
||||
* harder (until reaching ESTABLISHED state).
|
||||
*/
|
||||
enum { SCTP_ARBITRARY_COOKIE_ECHO_LEN = 200 };
|
||||
|
||||
/* Guess at how big to make the TSN mapping array.
|
||||
* We guarantee that we can handle at least this big a gap between the
|
||||
* cumulative ACK and the highest TSN. In practice, we can often
|
||||
* handle up to twice this value.
|
||||
*
|
||||
* NEVER make this more than 32767 (2^15-1). The Gap Ack Blocks in a
|
||||
* SACK (see section 3.3.4) are only 16 bits, so 2*SCTP_TSN_MAP_SIZE
|
||||
* must be less than 65535 (2^16 - 1), or we will have overflow
|
||||
* problems creating SACK's.
|
||||
*/
|
||||
#define SCTP_TSN_MAP_INITIAL BITS_PER_LONG
|
||||
#define SCTP_TSN_MAP_INCREMENT SCTP_TSN_MAP_INITIAL
|
||||
#define SCTP_TSN_MAP_SIZE 4096
|
||||
|
||||
/* We will not record more than this many duplicate TSNs between two
|
||||
* SACKs. The minimum PMTU is 576. Remove all the headers and there
|
||||
* is enough room for 131 duplicate reports. Round down to the
|
||||
* nearest power of 2.
|
||||
*/
|
||||
enum { SCTP_MIN_PMTU = 576 };
|
||||
enum { SCTP_MAX_DUP_TSNS = 16 };
|
||||
enum { SCTP_MAX_GABS = 16 };
|
||||
|
||||
/* Heartbeat interval - 30 secs */
|
||||
#define SCTP_DEFAULT_TIMEOUT_HEARTBEAT (30*1000)
|
||||
|
||||
/* Delayed sack timer - 200ms */
|
||||
#define SCTP_DEFAULT_TIMEOUT_SACK (200)
|
||||
|
||||
/* RTO.Initial - 3 seconds
|
||||
* RTO.Min - 1 second
|
||||
* RTO.Max - 60 seconds
|
||||
* RTO.Alpha - 1/8
|
||||
* RTO.Beta - 1/4
|
||||
*/
|
||||
#define SCTP_RTO_INITIAL (3 * 1000)
|
||||
#define SCTP_RTO_MIN (1 * 1000)
|
||||
#define SCTP_RTO_MAX (60 * 1000)
|
||||
|
||||
#define SCTP_RTO_ALPHA 3 /* 1/8 when converted to right shifts. */
|
||||
#define SCTP_RTO_BETA 2 /* 1/4 when converted to right shifts. */
|
||||
|
||||
/* Maximum number of new data packets that can be sent in a burst. */
|
||||
#define SCTP_DEFAULT_MAX_BURST 4
|
||||
|
||||
#define SCTP_CLOCK_GRANULARITY 1 /* 1 jiffy */
|
||||
|
||||
#define SCTP_DEFAULT_COOKIE_LIFE (60 * 1000) /* 60 seconds */
|
||||
|
||||
#define SCTP_DEFAULT_MINWINDOW 1500 /* default minimum rwnd size */
|
||||
#define SCTP_DEFAULT_MAXWINDOW 65535 /* default rwnd size */
|
||||
#define SCTP_DEFAULT_RWND_SHIFT 4 /* by default, update on 1/16 of
|
||||
* rcvbuf, which is 1/8 of initial
|
||||
* window
|
||||
*/
|
||||
#define SCTP_DEFAULT_MAXSEGMENT 1500 /* MTU size, this is the limit
|
||||
* to which we will raise the P-MTU.
|
||||
*/
|
||||
#define SCTP_DEFAULT_MINSEGMENT 512 /* MTU size ... if no mtu disc */
|
||||
|
||||
#define SCTP_SECRET_SIZE 32 /* Number of octets in a 256 bits. */
|
||||
|
||||
#define SCTP_SIGNATURE_SIZE 20 /* size of a SLA-1 signature */
|
||||
|
||||
#define SCTP_COOKIE_MULTIPLE 32 /* Pad out our cookie to make our hash
|
||||
* functions simpler to write.
|
||||
*/
|
||||
|
||||
/* These return values describe the success or failure of a number of
|
||||
* routines which form the lower interface to SCTP_outqueue.
|
||||
*/
|
||||
typedef enum {
|
||||
SCTP_XMIT_OK,
|
||||
SCTP_XMIT_PMTU_FULL,
|
||||
SCTP_XMIT_RWND_FULL,
|
||||
SCTP_XMIT_DELAY,
|
||||
} sctp_xmit_t;
|
||||
|
||||
/* These are the commands for manipulating transports. */
|
||||
typedef enum {
|
||||
SCTP_TRANSPORT_UP,
|
||||
SCTP_TRANSPORT_DOWN,
|
||||
SCTP_TRANSPORT_PF,
|
||||
} sctp_transport_cmd_t;
|
||||
|
||||
/* These are the address scopes defined mainly for IPv4 addresses
|
||||
* based on draft of SCTP IPv4 scoping <draft-stewart-tsvwg-sctp-ipv4-00.txt>.
|
||||
* These scopes are hopefully generic enough to be used on scoping both
|
||||
* IPv4 and IPv6 addresses in SCTP.
|
||||
* At this point, the IPv6 scopes will be mapped to these internal scopes
|
||||
* as much as possible.
|
||||
*/
|
||||
typedef enum {
|
||||
SCTP_SCOPE_GLOBAL, /* IPv4 global addresses */
|
||||
SCTP_SCOPE_PRIVATE, /* IPv4 private addresses */
|
||||
SCTP_SCOPE_LINK, /* IPv4 link local address */
|
||||
SCTP_SCOPE_LOOPBACK, /* IPv4 loopback address */
|
||||
SCTP_SCOPE_UNUSABLE, /* IPv4 unusable addresses */
|
||||
} sctp_scope_t;
|
||||
|
||||
typedef enum {
|
||||
SCTP_SCOPE_POLICY_DISABLE, /* Disable IPv4 address scoping */
|
||||
SCTP_SCOPE_POLICY_ENABLE, /* Enable IPv4 address scoping */
|
||||
SCTP_SCOPE_POLICY_PRIVATE, /* Follow draft but allow IPv4 private addresses */
|
||||
SCTP_SCOPE_POLICY_LINK, /* Follow draft but allow IPv4 link local addresses */
|
||||
} sctp_scope_policy_t;
|
||||
|
||||
/* Based on IPv4 scoping <draft-stewart-tsvwg-sctp-ipv4-00.txt>,
|
||||
* SCTP IPv4 unusable addresses: 0.0.0.0/8, 224.0.0.0/4, 198.18.0.0/24,
|
||||
* 192.88.99.0/24.
|
||||
* Also, RFC 8.4, non-unicast addresses are not considered valid SCTP
|
||||
* addresses.
|
||||
*/
|
||||
#define IS_IPV4_UNUSABLE_ADDRESS(a) \
|
||||
((htonl(INADDR_BROADCAST) == a) || \
|
||||
ipv4_is_multicast(a) || \
|
||||
ipv4_is_zeronet(a) || \
|
||||
ipv4_is_test_198(a) || \
|
||||
ipv4_is_anycast_6to4(a))
|
||||
|
||||
/* Flags used for the bind address copy functions. */
|
||||
#define SCTP_ADDR6_ALLOWED 0x00000001 /* IPv6 address is allowed by
|
||||
local sock family */
|
||||
#define SCTP_ADDR4_PEERSUPP 0x00000002 /* IPv4 address is supported by
|
||||
peer */
|
||||
#define SCTP_ADDR6_PEERSUPP 0x00000004 /* IPv6 address is supported by
|
||||
peer */
|
||||
|
||||
/* Reasons to retransmit. */
|
||||
typedef enum {
|
||||
SCTP_RTXR_T3_RTX,
|
||||
SCTP_RTXR_FAST_RTX,
|
||||
SCTP_RTXR_PMTUD,
|
||||
SCTP_RTXR_T1_RTX,
|
||||
} sctp_retransmit_reason_t;
|
||||
|
||||
/* Reasons to lower cwnd. */
|
||||
typedef enum {
|
||||
SCTP_LOWER_CWND_T3_RTX,
|
||||
SCTP_LOWER_CWND_FAST_RTX,
|
||||
SCTP_LOWER_CWND_ECNE,
|
||||
SCTP_LOWER_CWND_INACTIVE,
|
||||
} sctp_lower_cwnd_t;
|
||||
|
||||
|
||||
/* SCTP-AUTH Necessary constants */
|
||||
|
||||
/* SCTP-AUTH, Section 3.3
|
||||
*
|
||||
* The following Table 2 shows the currently defined values for HMAC
|
||||
* identifiers.
|
||||
*
|
||||
* +-----------------+--------------------------+
|
||||
* | HMAC Identifier | Message Digest Algorithm |
|
||||
* +-----------------+--------------------------+
|
||||
* | 0 | Reserved |
|
||||
* | 1 | SHA-1 defined in [8] |
|
||||
* | 2 | Reserved |
|
||||
* | 3 | SHA-256 defined in [8] |
|
||||
* +-----------------+--------------------------+
|
||||
*/
|
||||
enum {
|
||||
SCTP_AUTH_HMAC_ID_RESERVED_0,
|
||||
SCTP_AUTH_HMAC_ID_SHA1,
|
||||
SCTP_AUTH_HMAC_ID_RESERVED_2,
|
||||
#if defined (CONFIG_CRYPTO_SHA256) || defined (CONFIG_CRYPTO_SHA256_MODULE)
|
||||
SCTP_AUTH_HMAC_ID_SHA256,
|
||||
#endif
|
||||
__SCTP_AUTH_HMAC_MAX
|
||||
};
|
||||
|
||||
#define SCTP_AUTH_HMAC_ID_MAX __SCTP_AUTH_HMAC_MAX - 1
|
||||
#define SCTP_AUTH_NUM_HMACS __SCTP_AUTH_HMAC_MAX
|
||||
#define SCTP_SHA1_SIG_SIZE 20
|
||||
#define SCTP_SHA256_SIG_SIZE 32
|
||||
|
||||
/* SCTP-AUTH, Section 3.2
|
||||
* The chunk types for INIT, INIT-ACK, SHUTDOWN-COMPLETE and AUTH chunks
|
||||
* MUST NOT be listed in the CHUNKS parameter
|
||||
*/
|
||||
#define SCTP_NUM_NOAUTH_CHUNKS 4
|
||||
#define SCTP_AUTH_MAX_CHUNKS (SCTP_NUM_CHUNK_TYPES - SCTP_NUM_NOAUTH_CHUNKS)
|
||||
|
||||
/* SCTP-AUTH Section 6.1
|
||||
* The RANDOM parameter MUST contain a 32 byte random number.
|
||||
*/
|
||||
#define SCTP_AUTH_RANDOM_LENGTH 32
|
||||
|
||||
#endif /* __sctp_constants_h__ */
|
597
include/net/sctp/sctp.h
Normal file
597
include/net/sctp/sctp.h
Normal file
|
@ -0,0 +1,597 @@
|
|||
/* SCTP kernel implementation
|
||||
* (C) Copyright IBM Corp. 2001, 2004
|
||||
* Copyright (c) 1999-2000 Cisco, Inc.
|
||||
* Copyright (c) 1999-2001 Motorola, Inc.
|
||||
* Copyright (c) 2001-2003 Intel Corp.
|
||||
*
|
||||
* This file is part of the SCTP kernel implementation
|
||||
*
|
||||
* The base lksctp header.
|
||||
*
|
||||
* 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>
|
||||
* Xingang Guo <xingang.guo@intel.com>
|
||||
* Jon Grimm <jgrimm@us.ibm.com>
|
||||
* Daisy Chang <daisyc@us.ibm.com>
|
||||
* Sridhar Samudrala <sri@us.ibm.com>
|
||||
* Ardelle Fan <ardelle.fan@intel.com>
|
||||
* Ryan Layer <rmlayer@us.ibm.com>
|
||||
* Kevin Gao <kevin.gao@intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __net_sctp_h__
|
||||
#define __net_sctp_h__
|
||||
|
||||
/* Header Strategy.
|
||||
* Start getting some control over the header file depencies:
|
||||
* includes
|
||||
* constants
|
||||
* structs
|
||||
* prototypes
|
||||
* macros, externs, and inlines
|
||||
*
|
||||
* Move test_frame specific items out of the kernel headers
|
||||
* and into the test frame headers. This is not perfect in any sense
|
||||
* and will continue to evolve.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/idr.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
#include <net/ipv6.h>
|
||||
#include <net/ip6_route.h>
|
||||
#endif
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/page.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/snmp.h>
|
||||
#include <net/sctp/structs.h>
|
||||
#include <net/sctp/constants.h>
|
||||
|
||||
#ifdef CONFIG_IP_SCTP_MODULE
|
||||
#define SCTP_PROTOSW_FLAG 0
|
||||
#else /* static! */
|
||||
#define SCTP_PROTOSW_FLAG INET_PROTOSW_PERMANENT
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Function declarations.
|
||||
*/
|
||||
|
||||
/*
|
||||
* sctp/protocol.c
|
||||
*/
|
||||
int sctp_copy_local_addr_list(struct net *, struct sctp_bind_addr *,
|
||||
sctp_scope_t, gfp_t gfp, int flags);
|
||||
struct sctp_pf *sctp_get_pf_specific(sa_family_t family);
|
||||
int sctp_register_pf(struct sctp_pf *, sa_family_t);
|
||||
void sctp_addr_wq_mgmt(struct net *, struct sctp_sockaddr_entry *, int);
|
||||
|
||||
/*
|
||||
* sctp/socket.c
|
||||
*/
|
||||
int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb);
|
||||
int sctp_inet_listen(struct socket *sock, int backlog);
|
||||
void sctp_write_space(struct sock *sk);
|
||||
void sctp_data_ready(struct sock *sk);
|
||||
unsigned int sctp_poll(struct file *file, struct socket *sock,
|
||||
poll_table *wait);
|
||||
void sctp_sock_rfree(struct sk_buff *skb);
|
||||
void sctp_copy_sock(struct sock *newsk, struct sock *sk,
|
||||
struct sctp_association *asoc);
|
||||
extern struct percpu_counter sctp_sockets_allocated;
|
||||
int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *);
|
||||
struct sk_buff *sctp_skb_recv_datagram(struct sock *, int, int, int *);
|
||||
|
||||
/*
|
||||
* sctp/primitive.c
|
||||
*/
|
||||
int sctp_primitive_ASSOCIATE(struct net *, struct sctp_association *, void *arg);
|
||||
int sctp_primitive_SHUTDOWN(struct net *, struct sctp_association *, void *arg);
|
||||
int sctp_primitive_ABORT(struct net *, struct sctp_association *, void *arg);
|
||||
int sctp_primitive_SEND(struct net *, struct sctp_association *, void *arg);
|
||||
int sctp_primitive_REQUESTHEARTBEAT(struct net *, struct sctp_association *, void *arg);
|
||||
int sctp_primitive_ASCONF(struct net *, struct sctp_association *, void *arg);
|
||||
|
||||
/*
|
||||
* sctp/input.c
|
||||
*/
|
||||
int sctp_rcv(struct sk_buff *skb);
|
||||
void sctp_v4_err(struct sk_buff *skb, u32 info);
|
||||
void sctp_hash_established(struct sctp_association *);
|
||||
void sctp_unhash_established(struct sctp_association *);
|
||||
void sctp_hash_endpoint(struct sctp_endpoint *);
|
||||
void sctp_unhash_endpoint(struct sctp_endpoint *);
|
||||
struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *,
|
||||
struct sctphdr *, struct sctp_association **,
|
||||
struct sctp_transport **);
|
||||
void sctp_err_finish(struct sock *, struct sctp_association *);
|
||||
void sctp_icmp_frag_needed(struct sock *, struct sctp_association *,
|
||||
struct sctp_transport *t, __u32 pmtu);
|
||||
void sctp_icmp_redirect(struct sock *, struct sctp_transport *,
|
||||
struct sk_buff *);
|
||||
void sctp_icmp_proto_unreachable(struct sock *sk,
|
||||
struct sctp_association *asoc,
|
||||
struct sctp_transport *t);
|
||||
void sctp_backlog_migrate(struct sctp_association *assoc,
|
||||
struct sock *oldsk, struct sock *newsk);
|
||||
|
||||
/*
|
||||
* sctp/proc.c
|
||||
*/
|
||||
int sctp_snmp_proc_init(struct net *net);
|
||||
void sctp_snmp_proc_exit(struct net *net);
|
||||
int sctp_eps_proc_init(struct net *net);
|
||||
void sctp_eps_proc_exit(struct net *net);
|
||||
int sctp_assocs_proc_init(struct net *net);
|
||||
void sctp_assocs_proc_exit(struct net *net);
|
||||
int sctp_remaddr_proc_init(struct net *net);
|
||||
void sctp_remaddr_proc_exit(struct net *net);
|
||||
|
||||
|
||||
/*
|
||||
* Module global variables
|
||||
*/
|
||||
|
||||
/*
|
||||
* sctp/protocol.c
|
||||
*/
|
||||
extern struct kmem_cache *sctp_chunk_cachep __read_mostly;
|
||||
extern struct kmem_cache *sctp_bucket_cachep __read_mostly;
|
||||
|
||||
/*
|
||||
* Section: Macros, externs, and inlines
|
||||
*/
|
||||
|
||||
/* SCTP SNMP MIB stats handlers */
|
||||
#define SCTP_INC_STATS(net, field) SNMP_INC_STATS((net)->sctp.sctp_statistics, field)
|
||||
#define SCTP_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->sctp.sctp_statistics, field)
|
||||
#define SCTP_INC_STATS_USER(net, field) SNMP_INC_STATS_USER((net)->sctp.sctp_statistics, field)
|
||||
#define SCTP_DEC_STATS(net, field) SNMP_DEC_STATS((net)->sctp.sctp_statistics, field)
|
||||
|
||||
/* sctp mib definitions */
|
||||
enum {
|
||||
SCTP_MIB_NUM = 0,
|
||||
SCTP_MIB_CURRESTAB, /* CurrEstab */
|
||||
SCTP_MIB_ACTIVEESTABS, /* ActiveEstabs */
|
||||
SCTP_MIB_PASSIVEESTABS, /* PassiveEstabs */
|
||||
SCTP_MIB_ABORTEDS, /* Aborteds */
|
||||
SCTP_MIB_SHUTDOWNS, /* Shutdowns */
|
||||
SCTP_MIB_OUTOFBLUES, /* OutOfBlues */
|
||||
SCTP_MIB_CHECKSUMERRORS, /* ChecksumErrors */
|
||||
SCTP_MIB_OUTCTRLCHUNKS, /* OutCtrlChunks */
|
||||
SCTP_MIB_OUTORDERCHUNKS, /* OutOrderChunks */
|
||||
SCTP_MIB_OUTUNORDERCHUNKS, /* OutUnorderChunks */
|
||||
SCTP_MIB_INCTRLCHUNKS, /* InCtrlChunks */
|
||||
SCTP_MIB_INORDERCHUNKS, /* InOrderChunks */
|
||||
SCTP_MIB_INUNORDERCHUNKS, /* InUnorderChunks */
|
||||
SCTP_MIB_FRAGUSRMSGS, /* FragUsrMsgs */
|
||||
SCTP_MIB_REASMUSRMSGS, /* ReasmUsrMsgs */
|
||||
SCTP_MIB_OUTSCTPPACKS, /* OutSCTPPacks */
|
||||
SCTP_MIB_INSCTPPACKS, /* InSCTPPacks */
|
||||
SCTP_MIB_T1_INIT_EXPIREDS,
|
||||
SCTP_MIB_T1_COOKIE_EXPIREDS,
|
||||
SCTP_MIB_T2_SHUTDOWN_EXPIREDS,
|
||||
SCTP_MIB_T3_RTX_EXPIREDS,
|
||||
SCTP_MIB_T4_RTO_EXPIREDS,
|
||||
SCTP_MIB_T5_SHUTDOWN_GUARD_EXPIREDS,
|
||||
SCTP_MIB_DELAY_SACK_EXPIREDS,
|
||||
SCTP_MIB_AUTOCLOSE_EXPIREDS,
|
||||
SCTP_MIB_T1_RETRANSMITS,
|
||||
SCTP_MIB_T3_RETRANSMITS,
|
||||
SCTP_MIB_PMTUD_RETRANSMITS,
|
||||
SCTP_MIB_FAST_RETRANSMITS,
|
||||
SCTP_MIB_IN_PKT_SOFTIRQ,
|
||||
SCTP_MIB_IN_PKT_BACKLOG,
|
||||
SCTP_MIB_IN_PKT_DISCARDS,
|
||||
SCTP_MIB_IN_DATA_CHUNK_DISCARDS,
|
||||
__SCTP_MIB_MAX
|
||||
};
|
||||
|
||||
#define SCTP_MIB_MAX __SCTP_MIB_MAX
|
||||
struct sctp_mib {
|
||||
unsigned long mibs[SCTP_MIB_MAX];
|
||||
};
|
||||
|
||||
/* helper function to track stats about max rto and related transport */
|
||||
static inline void sctp_max_rto(struct sctp_association *asoc,
|
||||
struct sctp_transport *trans)
|
||||
{
|
||||
if (asoc->stats.max_obs_rto < (__u64)trans->rto) {
|
||||
asoc->stats.max_obs_rto = trans->rto;
|
||||
memset(&asoc->stats.obs_rto_ipaddr, 0,
|
||||
sizeof(struct sockaddr_storage));
|
||||
memcpy(&asoc->stats.obs_rto_ipaddr, &trans->ipaddr,
|
||||
trans->af_specific->sockaddr_len);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Macros for keeping a global reference of object allocations.
|
||||
*/
|
||||
#ifdef CONFIG_SCTP_DBG_OBJCNT
|
||||
|
||||
extern atomic_t sctp_dbg_objcnt_sock;
|
||||
extern atomic_t sctp_dbg_objcnt_ep;
|
||||
extern atomic_t sctp_dbg_objcnt_assoc;
|
||||
extern atomic_t sctp_dbg_objcnt_transport;
|
||||
extern atomic_t sctp_dbg_objcnt_chunk;
|
||||
extern atomic_t sctp_dbg_objcnt_bind_addr;
|
||||
extern atomic_t sctp_dbg_objcnt_bind_bucket;
|
||||
extern atomic_t sctp_dbg_objcnt_addr;
|
||||
extern atomic_t sctp_dbg_objcnt_ssnmap;
|
||||
extern atomic_t sctp_dbg_objcnt_datamsg;
|
||||
extern atomic_t sctp_dbg_objcnt_keys;
|
||||
|
||||
/* Macros to atomically increment/decrement objcnt counters. */
|
||||
#define SCTP_DBG_OBJCNT_INC(name) \
|
||||
atomic_inc(&sctp_dbg_objcnt_## name)
|
||||
#define SCTP_DBG_OBJCNT_DEC(name) \
|
||||
atomic_dec(&sctp_dbg_objcnt_## name)
|
||||
#define SCTP_DBG_OBJCNT(name) \
|
||||
atomic_t sctp_dbg_objcnt_## name = ATOMIC_INIT(0)
|
||||
|
||||
/* Macro to help create new entries in in the global array of
|
||||
* objcnt counters.
|
||||
*/
|
||||
#define SCTP_DBG_OBJCNT_ENTRY(name) \
|
||||
{.label= #name, .counter= &sctp_dbg_objcnt_## name}
|
||||
|
||||
void sctp_dbg_objcnt_init(struct net *);
|
||||
void sctp_dbg_objcnt_exit(struct net *);
|
||||
|
||||
#else
|
||||
|
||||
#define SCTP_DBG_OBJCNT_INC(name)
|
||||
#define SCTP_DBG_OBJCNT_DEC(name)
|
||||
|
||||
static inline void sctp_dbg_objcnt_init(struct net *net) { return; }
|
||||
static inline void sctp_dbg_objcnt_exit(struct net *net) { return; }
|
||||
|
||||
#endif /* CONFIG_SCTP_DBG_OBJCOUNT */
|
||||
|
||||
#if defined CONFIG_SYSCTL
|
||||
void sctp_sysctl_register(void);
|
||||
void sctp_sysctl_unregister(void);
|
||||
int sctp_sysctl_net_register(struct net *net);
|
||||
void sctp_sysctl_net_unregister(struct net *net);
|
||||
#else
|
||||
static inline void sctp_sysctl_register(void) { return; }
|
||||
static inline void sctp_sysctl_unregister(void) { return; }
|
||||
static inline int sctp_sysctl_net_register(struct net *net) { return 0; }
|
||||
static inline void sctp_sysctl_net_unregister(struct net *net) { return; }
|
||||
#endif
|
||||
|
||||
/* Size of Supported Address Parameter for 'x' address types. */
|
||||
#define SCTP_SAT_LEN(x) (sizeof(struct sctp_paramhdr) + (x) * sizeof(__u16))
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
|
||||
void sctp_v6_pf_init(void);
|
||||
void sctp_v6_pf_exit(void);
|
||||
int sctp_v6_protosw_init(void);
|
||||
void sctp_v6_protosw_exit(void);
|
||||
int sctp_v6_add_protocol(void);
|
||||
void sctp_v6_del_protocol(void);
|
||||
|
||||
#else /* #ifdef defined(CONFIG_IPV6) */
|
||||
|
||||
static inline void sctp_v6_pf_init(void) { return; }
|
||||
static inline void sctp_v6_pf_exit(void) { return; }
|
||||
static inline int sctp_v6_protosw_init(void) { return 0; }
|
||||
static inline void sctp_v6_protosw_exit(void) { return; }
|
||||
static inline int sctp_v6_add_protocol(void) { return 0; }
|
||||
static inline void sctp_v6_del_protocol(void) { return; }
|
||||
|
||||
#endif /* #if defined(CONFIG_IPV6) */
|
||||
|
||||
|
||||
/* Map an association to an assoc_id. */
|
||||
static inline sctp_assoc_t sctp_assoc2id(const struct sctp_association *asoc)
|
||||
{
|
||||
return asoc ? asoc->assoc_id : 0;
|
||||
}
|
||||
|
||||
static inline enum sctp_sstat_state
|
||||
sctp_assoc_to_state(const struct sctp_association *asoc)
|
||||
{
|
||||
/* SCTP's uapi always had SCTP_EMPTY(=0) as a dummy state, but we
|
||||
* got rid of it in kernel space. Therefore SCTP_CLOSED et al
|
||||
* start at =1 in user space, but actually as =0 in kernel space.
|
||||
* Now that we can not break user space and SCTP_EMPTY is exposed
|
||||
* there, we need to fix it up with an ugly offset not to break
|
||||
* applications. :(
|
||||
*/
|
||||
return asoc->state + 1;
|
||||
}
|
||||
|
||||
/* Look up the association by its id. */
|
||||
struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id);
|
||||
|
||||
int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp);
|
||||
|
||||
/* A macro to walk a list of skbs. */
|
||||
#define sctp_skb_for_each(pos, head, tmp) \
|
||||
skb_queue_walk_safe(head, pos, tmp)
|
||||
|
||||
/* A helper to append an entire skb list (list) to another (head). */
|
||||
static inline void sctp_skb_list_tail(struct sk_buff_head *list,
|
||||
struct sk_buff_head *head)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&head->lock, flags);
|
||||
spin_lock(&list->lock);
|
||||
|
||||
skb_queue_splice_tail_init(list, head);
|
||||
|
||||
spin_unlock(&list->lock);
|
||||
spin_unlock_irqrestore(&head->lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* sctp_list_dequeue - remove from the head of the queue
|
||||
* @list: list to dequeue from
|
||||
*
|
||||
* Remove the head of the list. The head item is
|
||||
* returned or %NULL if the list is empty.
|
||||
*/
|
||||
|
||||
static inline struct list_head *sctp_list_dequeue(struct list_head *list)
|
||||
{
|
||||
struct list_head *result = NULL;
|
||||
|
||||
if (list->next != list) {
|
||||
result = list->next;
|
||||
list->next = result->next;
|
||||
list->next->prev = list;
|
||||
INIT_LIST_HEAD(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* SCTP version of skb_set_owner_r. We need this one because
|
||||
* of the way we have to do receive buffer accounting on bundled
|
||||
* chunks.
|
||||
*/
|
||||
static inline void sctp_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
|
||||
{
|
||||
struct sctp_ulpevent *event = sctp_skb2event(skb);
|
||||
|
||||
skb_orphan(skb);
|
||||
skb->sk = sk;
|
||||
skb->destructor = sctp_sock_rfree;
|
||||
atomic_add(event->rmem_len, &sk->sk_rmem_alloc);
|
||||
/*
|
||||
* This mimics the behavior of skb_set_owner_r
|
||||
*/
|
||||
sk->sk_forward_alloc -= event->rmem_len;
|
||||
}
|
||||
|
||||
/* Tests if the list has one and only one entry. */
|
||||
static inline int sctp_list_single_entry(struct list_head *head)
|
||||
{
|
||||
return (head->next != head) && (head->next == head->prev);
|
||||
}
|
||||
|
||||
/* Break down data chunks at this point. */
|
||||
static inline int sctp_frag_point(const struct sctp_association *asoc, int pmtu)
|
||||
{
|
||||
struct sctp_sock *sp = sctp_sk(asoc->base.sk);
|
||||
int frag = pmtu;
|
||||
|
||||
frag -= sp->pf->af->net_header_len;
|
||||
frag -= sizeof(struct sctphdr) + sizeof(struct sctp_data_chunk);
|
||||
|
||||
if (asoc->user_frag)
|
||||
frag = min_t(int, frag, asoc->user_frag);
|
||||
|
||||
frag = min_t(int, frag, SCTP_MAX_CHUNK_LEN);
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
static inline void sctp_assoc_pending_pmtu(struct sock *sk, struct sctp_association *asoc)
|
||||
{
|
||||
|
||||
sctp_assoc_sync_pmtu(sk, asoc);
|
||||
asoc->pmtu_pending = 0;
|
||||
}
|
||||
|
||||
static inline bool sctp_chunk_pending(const struct sctp_chunk *chunk)
|
||||
{
|
||||
return !list_empty(&chunk->list);
|
||||
}
|
||||
|
||||
/* Walk through a list of TLV parameters. Don't trust the
|
||||
* individual parameter lengths and instead depend on
|
||||
* the chunk length to indicate when to stop. Make sure
|
||||
* there is room for a param header too.
|
||||
*/
|
||||
#define sctp_walk_params(pos, chunk, member)\
|
||||
_sctp_walk_params((pos), (chunk), ntohs((chunk)->chunk_hdr.length), member)
|
||||
|
||||
#define _sctp_walk_params(pos, chunk, end, member)\
|
||||
for (pos.v = chunk->member;\
|
||||
pos.v <= (void *)chunk + end - ntohs(pos.p->length) &&\
|
||||
ntohs(pos.p->length) >= sizeof(sctp_paramhdr_t);\
|
||||
pos.v += WORD_ROUND(ntohs(pos.p->length)))
|
||||
|
||||
#define sctp_walk_errors(err, chunk_hdr)\
|
||||
_sctp_walk_errors((err), (chunk_hdr), ntohs((chunk_hdr)->length))
|
||||
|
||||
#define _sctp_walk_errors(err, chunk_hdr, end)\
|
||||
for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \
|
||||
sizeof(sctp_chunkhdr_t));\
|
||||
(void *)err <= (void *)chunk_hdr + end - ntohs(err->length) &&\
|
||||
ntohs(err->length) >= sizeof(sctp_errhdr_t); \
|
||||
err = (sctp_errhdr_t *)((void *)err + WORD_ROUND(ntohs(err->length))))
|
||||
|
||||
#define sctp_walk_fwdtsn(pos, chunk)\
|
||||
_sctp_walk_fwdtsn((pos), (chunk), ntohs((chunk)->chunk_hdr->length) - sizeof(struct sctp_fwdtsn_chunk))
|
||||
|
||||
#define _sctp_walk_fwdtsn(pos, chunk, end)\
|
||||
for (pos = chunk->subh.fwdtsn_hdr->skip;\
|
||||
(void *)pos <= (void *)chunk->subh.fwdtsn_hdr->skip + end - sizeof(struct sctp_fwdtsn_skip);\
|
||||
pos++)
|
||||
|
||||
/* Round an int up to the next multiple of 4. */
|
||||
#define WORD_ROUND(s) (((s)+3)&~3)
|
||||
|
||||
/* External references. */
|
||||
|
||||
extern struct proto sctp_prot;
|
||||
extern struct proto sctpv6_prot;
|
||||
void sctp_put_port(struct sock *sk);
|
||||
|
||||
extern struct idr sctp_assocs_id;
|
||||
extern spinlock_t sctp_assocs_id_lock;
|
||||
|
||||
/* Static inline functions. */
|
||||
|
||||
/* Convert from an IP version number to an Address Family symbol. */
|
||||
static inline int ipver2af(__u8 ipver)
|
||||
{
|
||||
switch (ipver) {
|
||||
case 4:
|
||||
return AF_INET;
|
||||
case 6:
|
||||
return AF_INET6;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert from an address parameter type to an address family. */
|
||||
static inline int param_type2af(__be16 type)
|
||||
{
|
||||
switch (type) {
|
||||
case SCTP_PARAM_IPV4_ADDRESS:
|
||||
return AF_INET;
|
||||
case SCTP_PARAM_IPV6_ADDRESS:
|
||||
return AF_INET6;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Warning: The following hash functions assume a power of two 'size'. */
|
||||
/* This is the hash function for the SCTP port hash table. */
|
||||
static inline int sctp_phashfn(struct net *net, __u16 lport)
|
||||
{
|
||||
return (net_hash_mix(net) + lport) & (sctp_port_hashsize - 1);
|
||||
}
|
||||
|
||||
/* This is the hash function for the endpoint hash table. */
|
||||
static inline int sctp_ep_hashfn(struct net *net, __u16 lport)
|
||||
{
|
||||
return (net_hash_mix(net) + lport) & (sctp_ep_hashsize - 1);
|
||||
}
|
||||
|
||||
/* This is the hash function for the association hash table. */
|
||||
static inline int sctp_assoc_hashfn(struct net *net, __u16 lport, __u16 rport)
|
||||
{
|
||||
int h = (lport << 16) + rport + net_hash_mix(net);
|
||||
h ^= h>>8;
|
||||
return h & (sctp_assoc_hashsize - 1);
|
||||
}
|
||||
|
||||
/* This is the hash function for the association hash table. This is
|
||||
* not used yet, but could be used as a better hash function when
|
||||
* we have a vtag.
|
||||
*/
|
||||
static inline int sctp_vtag_hashfn(__u16 lport, __u16 rport, __u32 vtag)
|
||||
{
|
||||
int h = (lport << 16) + rport;
|
||||
h ^= vtag;
|
||||
return h & (sctp_assoc_hashsize - 1);
|
||||
}
|
||||
|
||||
#define sctp_for_each_hentry(epb, head) \
|
||||
hlist_for_each_entry(epb, head, node)
|
||||
|
||||
/* Is a socket of this style? */
|
||||
#define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style))
|
||||
static inline int __sctp_style(const struct sock *sk, sctp_socket_type_t style)
|
||||
{
|
||||
return sctp_sk(sk)->type == style;
|
||||
}
|
||||
|
||||
/* Is the association in this state? */
|
||||
#define sctp_state(asoc, state) __sctp_state((asoc), (SCTP_STATE_##state))
|
||||
static inline int __sctp_state(const struct sctp_association *asoc,
|
||||
sctp_state_t state)
|
||||
{
|
||||
return asoc->state == state;
|
||||
}
|
||||
|
||||
/* Is the socket in this state? */
|
||||
#define sctp_sstate(sk, state) __sctp_sstate((sk), (SCTP_SS_##state))
|
||||
static inline int __sctp_sstate(const struct sock *sk, sctp_sock_state_t state)
|
||||
{
|
||||
return sk->sk_state == state;
|
||||
}
|
||||
|
||||
/* Map v4-mapped v6 address back to v4 address */
|
||||
static inline void sctp_v6_map_v4(union sctp_addr *addr)
|
||||
{
|
||||
addr->v4.sin_family = AF_INET;
|
||||
addr->v4.sin_port = addr->v6.sin6_port;
|
||||
addr->v4.sin_addr.s_addr = addr->v6.sin6_addr.s6_addr32[3];
|
||||
}
|
||||
|
||||
/* Map v4 address to v4-mapped v6 address */
|
||||
static inline void sctp_v4_map_v6(union sctp_addr *addr)
|
||||
{
|
||||
addr->v6.sin6_family = AF_INET6;
|
||||
addr->v6.sin6_flowinfo = 0;
|
||||
addr->v6.sin6_scope_id = 0;
|
||||
addr->v6.sin6_port = addr->v4.sin_port;
|
||||
addr->v6.sin6_addr.s6_addr32[3] = addr->v4.sin_addr.s_addr;
|
||||
addr->v6.sin6_addr.s6_addr32[0] = 0;
|
||||
addr->v6.sin6_addr.s6_addr32[1] = 0;
|
||||
addr->v6.sin6_addr.s6_addr32[2] = htonl(0x0000ffff);
|
||||
}
|
||||
|
||||
/* The cookie is always 0 since this is how it's used in the
|
||||
* pmtu code.
|
||||
*/
|
||||
static inline struct dst_entry *sctp_transport_dst_check(struct sctp_transport *t)
|
||||
{
|
||||
if (t->dst && !dst_check(t->dst, t->dst_cookie)) {
|
||||
dst_release(t->dst);
|
||||
t->dst = NULL;
|
||||
}
|
||||
|
||||
return t->dst;
|
||||
}
|
||||
|
||||
#endif /* __net_sctp_h__ */
|
445
include/net/sctp/sm.h
Normal file
445
include/net/sctp/sm.h
Normal file
|
@ -0,0 +1,445 @@
|
|||
/* 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.
|
||||
*
|
||||
* This file is part of the SCTP kernel implementation
|
||||
*
|
||||
* These are definitions needed by the 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 addresses:
|
||||
* 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>
|
||||
* 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>
|
||||
* Ardelle Fan <ardelle.fan@intel.com>
|
||||
* Kevin Gao <kevin.gao@intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/in.h>
|
||||
#include <net/sctp/command.h>
|
||||
#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;
|
||||
|
||||
typedef sctp_disposition_t (sctp_state_fn_t) (struct net *,
|
||||
const struct sctp_endpoint *,
|
||||
const struct sctp_association *,
|
||||
const sctp_subtype_t type,
|
||||
void *arg,
|
||||
sctp_cmd_seq_t *);
|
||||
typedef void (sctp_timer_event_t) (unsigned long);
|
||||
typedef struct {
|
||||
sctp_state_fn_t *fn;
|
||||
const char *name;
|
||||
} sctp_sm_table_entry_t;
|
||||
|
||||
/* A naming convention of "sctp_sf_xxx" applies to all the state functions
|
||||
* 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;
|
||||
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_1C_ack;
|
||||
sctp_state_fn_t sctp_sf_do_5_1D_ce;
|
||||
sctp_state_fn_t sctp_sf_do_5_1E_ca;
|
||||
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_operr_notify;
|
||||
sctp_state_fn_t sctp_sf_t1_init_timer_expire;
|
||||
sctp_state_fn_t sctp_sf_t1_cookie_timer_expire;
|
||||
sctp_state_fn_t sctp_sf_t2_timer_expire;
|
||||
sctp_state_fn_t sctp_sf_t4_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_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_9_2_shut_ctsn;
|
||||
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_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_3_initack;
|
||||
sctp_state_fn_t sctp_sf_do_5_2_4_dupcook;
|
||||
sctp_state_fn_t sctp_sf_unk_chunk;
|
||||
sctp_state_fn_t sctp_sf_do_8_5_1_E_sa;
|
||||
sctp_state_fn_t sctp_sf_cookie_echoed_err;
|
||||
sctp_state_fn_t sctp_sf_do_asconf;
|
||||
sctp_state_fn_t sctp_sf_do_asconf_ack;
|
||||
sctp_state_fn_t sctp_sf_do_9_2_reshutack;
|
||||
sctp_state_fn_t sctp_sf_eat_fwd_tsn;
|
||||
sctp_state_fn_t sctp_sf_eat_fwd_tsn_fast;
|
||||
sctp_state_fn_t sctp_sf_eat_auth;
|
||||
|
||||
/* 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;
|
||||
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;
|
||||
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_shutdown;
|
||||
sctp_state_fn_t sctp_sf_ignore_primitive;
|
||||
sctp_state_fn_t sctp_sf_do_prm_requestheartbeat;
|
||||
sctp_state_fn_t sctp_sf_do_prm_asconf;
|
||||
|
||||
/* Prototypes for other event state functions. */
|
||||
sctp_state_fn_t sctp_sf_do_no_pending_tsn;
|
||||
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;
|
||||
sctp_state_fn_t sctp_sf_cookie_wait_icmp_abort;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Prototypes for utility support functions. */
|
||||
__u8 sctp_get_chunk_type(struct sctp_chunk *chunk);
|
||||
const sctp_sm_table_entry_t *sctp_sm_lookup_event(struct net *,
|
||||
sctp_event_t,
|
||||
sctp_state_t,
|
||||
sctp_subtype_t);
|
||||
int sctp_chunk_iif(const struct sctp_chunk *);
|
||||
struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *,
|
||||
struct sctp_chunk *,
|
||||
gfp_t gfp);
|
||||
__u32 sctp_generate_verification_tag(void);
|
||||
void sctp_populate_tie_tags(__u8 *cookie, __u32 curTag, __u32 hisTag);
|
||||
|
||||
/* Prototypes for chunk-building functions. */
|
||||
struct sctp_chunk *sctp_make_init(const struct sctp_association *,
|
||||
const struct sctp_bind_addr *,
|
||||
gfp_t gfp, int vparam_len);
|
||||
struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *,
|
||||
const struct sctp_chunk *,
|
||||
const gfp_t gfp,
|
||||
const int unkparam_len);
|
||||
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 *,
|
||||
const __u32 lowest_tsn,
|
||||
const struct sctp_chunk *);
|
||||
struct sctp_chunk * sctp_make_datafrag_empty(struct sctp_association *,
|
||||
const struct sctp_sndrcvinfo *sinfo,
|
||||
int len, const __u8 flags,
|
||||
__u16 ssn);
|
||||
struct sctp_chunk *sctp_make_ecne(const struct sctp_association *,
|
||||
const __u32);
|
||||
struct sctp_chunk *sctp_make_sack(const struct sctp_association *);
|
||||
struct sctp_chunk *sctp_make_shutdown(const struct sctp_association *asoc,
|
||||
const struct sctp_chunk *chunk);
|
||||
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 *, __be16 cause, size_t);
|
||||
struct sctp_chunk *sctp_make_abort(const struct sctp_association *,
|
||||
const struct sctp_chunk *,
|
||||
const size_t hint);
|
||||
struct sctp_chunk *sctp_make_abort_no_data(const struct sctp_association *,
|
||||
const struct sctp_chunk *,
|
||||
__u32 tsn);
|
||||
struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *,
|
||||
const struct msghdr *, size_t msg_len);
|
||||
struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *,
|
||||
const struct sctp_chunk *,
|
||||
const __u8 *,
|
||||
const size_t );
|
||||
struct sctp_chunk *sctp_make_violation_paramlen(const struct sctp_association *,
|
||||
const struct sctp_chunk *,
|
||||
struct sctp_paramhdr *);
|
||||
struct sctp_chunk *sctp_make_violation_max_retrans(const struct sctp_association *,
|
||||
const struct sctp_chunk *);
|
||||
struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *,
|
||||
const struct sctp_transport *);
|
||||
struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *,
|
||||
const struct sctp_chunk *,
|
||||
const void *payload,
|
||||
const size_t paylen);
|
||||
struct sctp_chunk *sctp_make_op_error(const struct sctp_association *,
|
||||
const struct sctp_chunk *chunk,
|
||||
__be16 cause_code,
|
||||
const void *payload,
|
||||
size_t paylen,
|
||||
size_t reserve_tail);
|
||||
|
||||
struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *,
|
||||
union sctp_addr *,
|
||||
struct sockaddr *,
|
||||
int, __be16);
|
||||
struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
|
||||
union sctp_addr *addr);
|
||||
bool sctp_verify_asconf(const struct sctp_association *asoc,
|
||||
struct sctp_chunk *chunk, bool addr_param_needed,
|
||||
struct sctp_paramhdr **errp);
|
||||
struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
|
||||
struct sctp_chunk *asconf);
|
||||
int sctp_process_asconf_ack(struct sctp_association *asoc,
|
||||
struct sctp_chunk *asconf_ack);
|
||||
struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
|
||||
__u32 new_cum_tsn, size_t nstreams,
|
||||
struct sctp_fwdtsn_skip *skiplist);
|
||||
struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc);
|
||||
|
||||
void sctp_chunk_assign_tsn(struct sctp_chunk *);
|
||||
void sctp_chunk_assign_ssn(struct sctp_chunk *);
|
||||
|
||||
/* Prototypes for statetable processing. */
|
||||
|
||||
int sctp_do_sm(struct net *net, sctp_event_t event_type, sctp_subtype_t subtype,
|
||||
sctp_state_t state,
|
||||
struct sctp_endpoint *,
|
||||
struct sctp_association *asoc,
|
||||
void *event_arg,
|
||||
gfp_t gfp);
|
||||
|
||||
/* 2nd level prototypes */
|
||||
void sctp_generate_t3_rtx_event(unsigned long peer);
|
||||
void sctp_generate_heartbeat_event(unsigned long peer);
|
||||
void sctp_generate_proto_unreach_event(unsigned long peer);
|
||||
|
||||
void sctp_ootb_pkt_free(struct sctp_packet *);
|
||||
|
||||
struct sctp_association *sctp_unpack_cookie(const struct sctp_endpoint *,
|
||||
const struct sctp_association *,
|
||||
struct sctp_chunk *,
|
||||
gfp_t gfp, int *err,
|
||||
struct sctp_chunk **err_chk_p);
|
||||
int sctp_addip_addr_config(struct sctp_association *, sctp_param_t,
|
||||
struct sockaddr_storage*, int);
|
||||
|
||||
/* 3rd level prototypes */
|
||||
__u32 sctp_generate_tag(const struct sctp_endpoint *);
|
||||
__u32 sctp_generate_tsn(const struct sctp_endpoint *);
|
||||
|
||||
/* Extern declarations for major data structures. */
|
||||
extern sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES];
|
||||
|
||||
|
||||
/* Get the size of a DATA chunk payload. */
|
||||
static inline __u16 sctp_data_size(struct sctp_chunk *chunk)
|
||||
{
|
||||
__u16 size;
|
||||
|
||||
size = ntohs(chunk->chunk_hdr->length);
|
||||
size -= sizeof(sctp_data_chunk_t);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/* 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
|
||||
* (i1 > i2 and i1 - i2 < 2^(SERIAL_BITS - 1))
|
||||
*/
|
||||
|
||||
/*
|
||||
* RFC 2960
|
||||
* 1.6 Serial Number Arithmetic
|
||||
*
|
||||
* 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)
|
||||
};
|
||||
|
||||
static inline int TSN_lt(__u32 s, __u32 t)
|
||||
{
|
||||
return ((s) - (t)) & TSN_SIGN_BIT;
|
||||
}
|
||||
|
||||
static inline int TSN_lte(__u32 s, __u32 t)
|
||||
{
|
||||
return ((s) == (t)) || (((s) - (t)) & TSN_SIGN_BIT);
|
||||
}
|
||||
|
||||
/* Compare two SSNs */
|
||||
|
||||
/*
|
||||
* RFC 2960
|
||||
* 1.6 Serial Number Arithmetic
|
||||
*
|
||||
* Comparisons and arithmetic on Stream Sequence Numbers in this document
|
||||
* SHOULD use Serial Number Arithmetic as defined in [RFC1982] where
|
||||
* SERIAL_BITS = 16.
|
||||
*/
|
||||
enum {
|
||||
SSN_SIGN_BIT = (1<<15)
|
||||
};
|
||||
|
||||
static inline int SSN_lt(__u16 s, __u16 t)
|
||||
{
|
||||
return ((s) - (t)) & SSN_SIGN_BIT;
|
||||
}
|
||||
|
||||
static inline int SSN_lte(__u16 s, __u16 t)
|
||||
{
|
||||
return ((s) == (t)) || (((s) - (t)) & SSN_SIGN_BIT);
|
||||
}
|
||||
|
||||
/*
|
||||
* ADDIP 3.1.1
|
||||
* The valid range of Serial Number is from 0 to 4294967295 (2**32 - 1). Serial
|
||||
* Numbers wrap back to 0 after reaching 4294967295.
|
||||
*/
|
||||
enum {
|
||||
ADDIP_SERIAL_SIGN_BIT = (1<<31)
|
||||
};
|
||||
|
||||
static inline int ADDIP_SERIAL_gte(__u16 s, __u16 t)
|
||||
{
|
||||
return ((s) == (t)) || (((t) - (s)) & ADDIP_SERIAL_SIGN_BIT);
|
||||
}
|
||||
|
||||
/* Check VTAG of the packet matches the sender's own tag. */
|
||||
static inline int
|
||||
sctp_vtag_verify(const struct sctp_chunk *chunk,
|
||||
const struct sctp_association *asoc)
|
||||
{
|
||||
/* RFC 2960 Sec 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(chunk->sctp_hdr->vtag) == asoc->c.my_vtag)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check VTAG of the packet matches the sender's own tag and the T bit is
|
||||
* not set, OR its peer's tag and the T bit is set in the Chunk Flags.
|
||||
*/
|
||||
static inline int
|
||||
sctp_vtag_verify_either(const struct sctp_chunk *chunk,
|
||||
const struct sctp_association *asoc)
|
||||
{
|
||||
/* RFC 2960 Section 8.5.1, sctpimpguide Section 2.41
|
||||
*
|
||||
* B) The receiver of a ABORT MUST accept the packet
|
||||
* if the Verification Tag field of the packet matches its own tag
|
||||
* and the T bit is not set
|
||||
* 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
|
||||
* and the T bit is not set
|
||||
* 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. An endpoint MUST ignore the
|
||||
* SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT state.
|
||||
*/
|
||||
if ((!sctp_test_T_bit(chunk) &&
|
||||
(ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag)) ||
|
||||
(sctp_test_T_bit(chunk) && asoc->c.peer_vtag &&
|
||||
(ntohl(chunk->sctp_hdr->vtag) == asoc->c.peer_vtag))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __sctp_sm_h__ */
|
1934
include/net/sctp/structs.h
Normal file
1934
include/net/sctp/structs.h
Normal file
File diff suppressed because it is too large
Load diff
172
include/net/sctp/tsnmap.h
Normal file
172
include/net/sctp/tsnmap.h
Normal file
|
@ -0,0 +1,172 @@
|
|||
/* 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.
|
||||
*
|
||||
* This file is part of the SCTP kernel implementation
|
||||
*
|
||||
* These are the definitions needed for the tsnmap type. The tsnmap is used
|
||||
* to track out of order TSNs received.
|
||||
*
|
||||
* 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:
|
||||
* Jon Grimm <jgrimm@us.ibm.com>
|
||||
* La Monte H.P. Yarroll <piggy@acm.org>
|
||||
* Karl Knutson <karl@athena.chicago.il.us>
|
||||
* Sridhar Samudrala <sri@us.ibm.com>
|
||||
*/
|
||||
#include <net/sctp/constants.h>
|
||||
|
||||
#ifndef __sctp_tsnmap_h__
|
||||
#define __sctp_tsnmap_h__
|
||||
|
||||
/* RFC 2960 12.2 Parameters necessary per association (i.e. the TCB)
|
||||
* Mapping An array of bits or bytes indicating which out of
|
||||
* Array order TSN's have been received (relative to the
|
||||
* Last Rcvd TSN). If no gaps exist, i.e. no out of
|
||||
* order packets have been received, this array
|
||||
* will be set to all zero. This structure may be
|
||||
* in the form of a circular buffer or bit array.
|
||||
*/
|
||||
struct sctp_tsnmap {
|
||||
/* This array counts the number of chunks with each TSN.
|
||||
* It points at one of the two buffers with which we will
|
||||
* ping-pong between.
|
||||
*/
|
||||
unsigned long *tsn_map;
|
||||
|
||||
/* This is the TSN at tsn_map[0]. */
|
||||
__u32 base_tsn;
|
||||
|
||||
/* Last Rcvd : This is the last TSN received in
|
||||
* TSN : sequence. This value is set initially by
|
||||
* : taking the peer's Initial TSN, received in
|
||||
* : the INIT or INIT ACK chunk, and subtracting
|
||||
* : one from it.
|
||||
*
|
||||
* Throughout most of the specification this is called the
|
||||
* "Cumulative TSN ACK Point". In this case, we
|
||||
* ignore the advice in 12.2 in favour of the term
|
||||
* used in the bulk of the text.
|
||||
*/
|
||||
__u32 cumulative_tsn_ack_point;
|
||||
|
||||
/* This is the highest TSN we've marked. */
|
||||
__u32 max_tsn_seen;
|
||||
|
||||
/* This is the minimum number of TSNs we can track. This corresponds
|
||||
* to the size of tsn_map. Note: the overflow_map allows us to
|
||||
* potentially track more than this quantity.
|
||||
*/
|
||||
__u16 len;
|
||||
|
||||
/* Data chunks pending receipt. used by SCTP_STATUS sockopt */
|
||||
__u16 pending_data;
|
||||
|
||||
/* Record duplicate TSNs here. We clear this after
|
||||
* every SACK. Store up to SCTP_MAX_DUP_TSNS worth of
|
||||
* information.
|
||||
*/
|
||||
__u16 num_dup_tsns;
|
||||
__be32 dup_tsns[SCTP_MAX_DUP_TSNS];
|
||||
};
|
||||
|
||||
struct sctp_tsnmap_iter {
|
||||
__u32 start;
|
||||
};
|
||||
|
||||
/* Initialize a block of memory as a tsnmap. */
|
||||
struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *, __u16 len,
|
||||
__u32 initial_tsn, gfp_t gfp);
|
||||
|
||||
void sctp_tsnmap_free(struct sctp_tsnmap *map);
|
||||
|
||||
/* Test the tracking state of this TSN.
|
||||
* Returns:
|
||||
* 0 if the TSN has not yet been seen
|
||||
* >0 if the TSN has been seen (duplicate)
|
||||
* <0 if the TSN is invalid (too large to track)
|
||||
*/
|
||||
int sctp_tsnmap_check(const struct sctp_tsnmap *, __u32 tsn);
|
||||
|
||||
/* Mark this TSN as seen. */
|
||||
int sctp_tsnmap_mark(struct sctp_tsnmap *, __u32 tsn,
|
||||
struct sctp_transport *trans);
|
||||
|
||||
/* Mark this TSN and all lower as seen. */
|
||||
void sctp_tsnmap_skip(struct sctp_tsnmap *map, __u32 tsn);
|
||||
|
||||
/* Retrieve the Cumulative TSN ACK Point. */
|
||||
static inline __u32 sctp_tsnmap_get_ctsn(const struct sctp_tsnmap *map)
|
||||
{
|
||||
return map->cumulative_tsn_ack_point;
|
||||
}
|
||||
|
||||
/* Retrieve the highest TSN we've seen. */
|
||||
static inline __u32 sctp_tsnmap_get_max_tsn_seen(const struct sctp_tsnmap *map)
|
||||
{
|
||||
return map->max_tsn_seen;
|
||||
}
|
||||
|
||||
/* How many duplicate TSNs are stored? */
|
||||
static inline __u16 sctp_tsnmap_num_dups(struct sctp_tsnmap *map)
|
||||
{
|
||||
return map->num_dup_tsns;
|
||||
}
|
||||
|
||||
/* Return pointer to duplicate tsn array as needed by SACK. */
|
||||
static inline __be32 *sctp_tsnmap_get_dups(struct sctp_tsnmap *map)
|
||||
{
|
||||
map->num_dup_tsns = 0;
|
||||
return map->dup_tsns;
|
||||
}
|
||||
|
||||
/* How many gap ack blocks do we have recorded? */
|
||||
__u16 sctp_tsnmap_num_gabs(struct sctp_tsnmap *map,
|
||||
struct sctp_gap_ack_block *gabs);
|
||||
|
||||
/* Refresh the count on pending data. */
|
||||
__u16 sctp_tsnmap_pending(struct sctp_tsnmap *map);
|
||||
|
||||
/* Is there a gap in the TSN map? */
|
||||
static inline int sctp_tsnmap_has_gap(const struct sctp_tsnmap *map)
|
||||
{
|
||||
return map->cumulative_tsn_ack_point != map->max_tsn_seen;
|
||||
}
|
||||
|
||||
/* Mark a duplicate TSN. Note: limit the storage of duplicate TSN
|
||||
* information.
|
||||
*/
|
||||
static inline void sctp_tsnmap_mark_dup(struct sctp_tsnmap *map, __u32 tsn)
|
||||
{
|
||||
if (map->num_dup_tsns < SCTP_MAX_DUP_TSNS)
|
||||
map->dup_tsns[map->num_dup_tsns++] = htonl(tsn);
|
||||
}
|
||||
|
||||
/* Renege a TSN that was seen. */
|
||||
void sctp_tsnmap_renege(struct sctp_tsnmap *, __u32 tsn);
|
||||
|
||||
/* Is there a gap in the TSN map? */
|
||||
int sctp_tsnmap_has_gap(const struct sctp_tsnmap *);
|
||||
|
||||
#endif /* __sctp_tsnmap_h__ */
|
162
include/net/sctp/ulpevent.h
Normal file
162
include/net/sctp/ulpevent.h
Normal file
|
@ -0,0 +1,162 @@
|
|||
/* 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.
|
||||
* Copyright (c) 2001 La Monte H.P. Yarroll
|
||||
*
|
||||
* These are the definitions needed for the sctp_ulpevent type. The
|
||||
* sctp_ulpevent type is used to carry information from the state machine
|
||||
* upwards to the ULP.
|
||||
*
|
||||
* This file is part of the SCTP kernel implementation
|
||||
*
|
||||
* 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:
|
||||
* Jon Grimm <jgrimm@us.ibm.com>
|
||||
* La Monte H.P. Yarroll <piggy@acm.org>
|
||||
* Karl Knutson <karl@athena.chicago.il.us>
|
||||
* Sridhar Samudrala <sri@us.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef __sctp_ulpevent_h__
|
||||
#define __sctp_ulpevent_h__
|
||||
|
||||
/* A structure to carry information to the ULP (e.g. Sockets API) */
|
||||
/* Warning: This sits inside an skb.cb[] area. Be very careful of
|
||||
* growing this structure as it is at the maximum limit now.
|
||||
*/
|
||||
struct sctp_ulpevent {
|
||||
struct sctp_association *asoc;
|
||||
__u16 stream;
|
||||
__u16 ssn;
|
||||
__u16 flags;
|
||||
__u32 ppid;
|
||||
__u32 tsn;
|
||||
__u32 cumtsn;
|
||||
int msg_flags;
|
||||
int iif;
|
||||
unsigned int rmem_len;
|
||||
};
|
||||
|
||||
/* Retrieve the skb this event sits inside of. */
|
||||
static inline struct sk_buff *sctp_event2skb(const struct sctp_ulpevent *ev)
|
||||
{
|
||||
return container_of((void *)ev, struct sk_buff, cb);
|
||||
}
|
||||
|
||||
/* Retrieve & cast the event sitting inside the skb. */
|
||||
static inline struct sctp_ulpevent *sctp_skb2event(struct sk_buff *skb)
|
||||
{
|
||||
return (struct sctp_ulpevent *)skb->cb;
|
||||
}
|
||||
|
||||
void sctp_ulpevent_free(struct sctp_ulpevent *);
|
||||
int sctp_ulpevent_is_notification(const struct sctp_ulpevent *);
|
||||
unsigned int sctp_queue_purge_ulpevents(struct sk_buff_head *list);
|
||||
|
||||
struct sctp_ulpevent *sctp_ulpevent_make_assoc_change(
|
||||
const struct sctp_association *asoc,
|
||||
__u16 flags,
|
||||
__u16 state,
|
||||
__u16 error,
|
||||
__u16 outbound,
|
||||
__u16 inbound,
|
||||
struct sctp_chunk *chunk,
|
||||
gfp_t gfp);
|
||||
|
||||
struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change(
|
||||
const struct sctp_association *asoc,
|
||||
const struct sockaddr_storage *aaddr,
|
||||
int flags,
|
||||
int state,
|
||||
int error,
|
||||
gfp_t gfp);
|
||||
|
||||
struct sctp_ulpevent *sctp_ulpevent_make_remote_error(
|
||||
const struct sctp_association *asoc,
|
||||
struct sctp_chunk *chunk,
|
||||
__u16 flags,
|
||||
gfp_t gfp);
|
||||
struct sctp_ulpevent *sctp_ulpevent_make_send_failed(
|
||||
const struct sctp_association *asoc,
|
||||
struct sctp_chunk *chunk,
|
||||
__u16 flags,
|
||||
__u32 error,
|
||||
gfp_t gfp);
|
||||
|
||||
struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event(
|
||||
const struct sctp_association *asoc,
|
||||
__u16 flags,
|
||||
gfp_t gfp);
|
||||
|
||||
struct sctp_ulpevent *sctp_ulpevent_make_pdapi(
|
||||
const struct sctp_association *asoc,
|
||||
__u32 indication, gfp_t gfp);
|
||||
|
||||
struct sctp_ulpevent *sctp_ulpevent_make_adaptation_indication(
|
||||
const struct sctp_association *asoc, gfp_t gfp);
|
||||
|
||||
struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
|
||||
struct sctp_chunk *chunk,
|
||||
gfp_t gfp);
|
||||
|
||||
struct sctp_ulpevent *sctp_ulpevent_make_authkey(
|
||||
const struct sctp_association *asoc, __u16 key_id,
|
||||
__u32 indication, gfp_t gfp);
|
||||
|
||||
struct sctp_ulpevent *sctp_ulpevent_make_sender_dry_event(
|
||||
const struct sctp_association *asoc, gfp_t gfp);
|
||||
|
||||
void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
|
||||
struct msghdr *);
|
||||
void sctp_ulpevent_read_rcvinfo(const struct sctp_ulpevent *event,
|
||||
struct msghdr *);
|
||||
void sctp_ulpevent_read_nxtinfo(const struct sctp_ulpevent *event,
|
||||
struct msghdr *, struct sock *sk);
|
||||
|
||||
__u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event);
|
||||
|
||||
/* Is this event type enabled? */
|
||||
static inline int sctp_ulpevent_type_enabled(__u16 sn_type,
|
||||
struct sctp_event_subscribe *mask)
|
||||
{
|
||||
char *amask = (char *) mask;
|
||||
return amask[sn_type - SCTP_SN_TYPE_BASE];
|
||||
}
|
||||
|
||||
/* Given an event subscription, is this event enabled? */
|
||||
static inline int sctp_ulpevent_is_enabled(const struct sctp_ulpevent *event,
|
||||
struct sctp_event_subscribe *mask)
|
||||
{
|
||||
__u16 sn_type;
|
||||
int enabled = 1;
|
||||
|
||||
if (sctp_ulpevent_is_notification(event)) {
|
||||
sn_type = sctp_ulpevent_get_notification_type(event);
|
||||
enabled = sctp_ulpevent_type_enabled(sn_type, mask);
|
||||
}
|
||||
return enabled;
|
||||
}
|
||||
|
||||
#endif /* __sctp_ulpevent_h__ */
|
86
include/net/sctp/ulpqueue.h
Normal file
86
include/net/sctp/ulpqueue.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
/* 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.
|
||||
* Copyright (c) 2001 La Monte H.P. Yarroll
|
||||
*
|
||||
* These are the definitions needed for the sctp_ulpq type. The
|
||||
* sctp_ulpq is the interface between the Upper Layer Protocol, or ULP,
|
||||
* and the core SCTP state machine. This is the component which handles
|
||||
* reassembly and ordering.
|
||||
*
|
||||
* 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 addresses:
|
||||
* lksctp developers <linux-sctp@vger.kernel.org>
|
||||
*
|
||||
* Written or modified by:
|
||||
* Jon Grimm <jgrimm@us.ibm.com>
|
||||
* La Monte H.P. Yarroll <piggy@acm.org>
|
||||
* Sridhar Samudrala <sri@us.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef __sctp_ulpqueue_h__
|
||||
#define __sctp_ulpqueue_h__
|
||||
|
||||
/* A structure to carry information to the ULP (e.g. Sockets API) */
|
||||
struct sctp_ulpq {
|
||||
char pd_mode;
|
||||
struct sctp_association *asoc;
|
||||
struct sk_buff_head reasm;
|
||||
struct sk_buff_head lobby;
|
||||
};
|
||||
|
||||
/* Prototypes. */
|
||||
struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *,
|
||||
struct sctp_association *);
|
||||
void sctp_ulpq_flush(struct sctp_ulpq *ulpq);
|
||||
void sctp_ulpq_free(struct sctp_ulpq *);
|
||||
|
||||
/* Add a new DATA chunk for processing. */
|
||||
int sctp_ulpq_tail_data(struct sctp_ulpq *, struct sctp_chunk *, gfp_t);
|
||||
|
||||
/* Add a new event for propagation to the ULP. */
|
||||
int sctp_ulpq_tail_event(struct sctp_ulpq *, struct sctp_ulpevent *ev);
|
||||
|
||||
/* Renege previously received chunks. */
|
||||
void sctp_ulpq_renege(struct sctp_ulpq *, struct sctp_chunk *, gfp_t);
|
||||
|
||||
/* Perform partial delivery. */
|
||||
void sctp_ulpq_partial_delivery(struct sctp_ulpq *, gfp_t);
|
||||
|
||||
/* Abort the partial delivery. */
|
||||
void sctp_ulpq_abort_pd(struct sctp_ulpq *, gfp_t);
|
||||
|
||||
/* Clear the partial data delivery condition on this socket. */
|
||||
int sctp_clear_pd(struct sock *sk, struct sctp_association *asoc);
|
||||
|
||||
/* Skip over an SSN. */
|
||||
void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn);
|
||||
|
||||
void sctp_ulpq_reasm_flushtsn(struct sctp_ulpq *, __u32);
|
||||
#endif /* __sctp_ulpqueue_h__ */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue