summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/net/sctp/command.h5
-rw-r--r--include/net/sctp/sctp.h1
-rw-r--r--include/net/sctp/structs.h85
-rw-r--r--include/net/sctp/tsnmap.h96
-rw-r--r--include/net/sctp/ulpevent.h162
-rw-r--r--include/net/sctp/ulpqueue.h15
-rw-r--r--include/net/sctp/user.h4
7 files changed, 206 insertions, 162 deletions
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
index 9cb1b7087423..03ab4422b683 100644
--- a/include/net/sctp/command.h
+++ b/include/net/sctp/command.h
@@ -86,6 +86,7 @@ typedef enum {
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_CHUNK_PD, /* Partial data delivery considerations. */
SCTP_CMD_LAST
} sctp_verb_t;
@@ -115,7 +116,7 @@ typedef union {
struct sctp_transport *transport;
sctp_bind_addr_t *bp;
sctp_init_chunk_t *init;
- sctp_ulpevent_t *ulpevent;
+ struct sctp_ulpevent *ulpevent;
sctp_packet_t *packet;
sctp_sackhdr_t *sackh;
} sctp_arg_t;
@@ -163,7 +164,7 @@ SCTP_ARG_CONSTRUCTOR(ASOC, sctp_association_t *, asoc)
SCTP_ARG_CONSTRUCTOR(TRANSPORT, struct sctp_transport *, transport)
SCTP_ARG_CONSTRUCTOR(BA, sctp_bind_addr_t *, bp)
SCTP_ARG_CONSTRUCTOR(PEER_INIT, sctp_init_chunk_t *, init)
-SCTP_ARG_CONSTRUCTOR(ULPEVENT, sctp_ulpevent_t *, ulpevent)
+SCTP_ARG_CONSTRUCTOR(ULPEVENT, struct sctp_ulpevent *, ulpevent)
SCTP_ARG_CONSTRUCTOR(PACKET, sctp_packet_t *, packet)
SCTP_ARG_CONSTRUCTOR(SACKH, sctp_sackhdr_t *, sackh)
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 4ce62633f2e5..b2e19ebde563 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -214,6 +214,7 @@ DECLARE_SNMP_STAT(struct sctp_mib, sctp_statistics);
#define SCTP_INC_STATS(field) SNMP_INC_STATS(sctp_statistics, field)
#define SCTP_INC_STATS_BH(field) SNMP_INC_STATS_BH(sctp_statistics, field)
#define SCTP_INC_STATS_USER(field) SNMP_INC_STATS_USER(sctp_statistics, field)
+#define SCTP_DEC_STATS(field) SNMP_DEC_STATS(sctp_statistics, field)
/* Determine if this is a valid kernel address. */
static inline int sctp_is_valid_kaddr(unsigned long addr)
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 45bd3fc4df77..d136122af892 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -2,7 +2,7 @@
* 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.
+ * Copyright (c) 2001-2003 International Business Machines Corp.
*
* This file is part of the SCTP kernel reference Implementation
*
@@ -105,27 +105,25 @@ union sctp_addr {
/* Forward declarations for data structures. */
struct sctp_protocol;
-struct SCTP_endpoint;
-struct SCTP_association;
+struct sctp_endpoint;
+struct sctp_association;
struct sctp_transport;
-struct SCTP_packet;
-struct SCTP_chunk;
-struct SCTP_inqueue;
+struct sctp_packet;
+struct sctp_chunk;
+struct sctp_inq;
struct sctp_outq;
-struct SCTP_bind_addr;
+struct sctp_bind_addr;
struct sctp_ulpq;
struct sctp_opt;
struct sctp_endpoint_common;
struct sctp_ssnmap;
typedef struct sctp_protocol sctp_protocol_t;
-typedef struct SCTP_endpoint sctp_endpoint_t;
-typedef struct SCTP_association sctp_association_t;
-typedef struct SCTP_packet sctp_packet_t;
-typedef struct SCTP_chunk sctp_chunk_t;
-typedef struct SCTP_inqueue sctp_inqueue_t;
-typedef struct SCTP_bind_addr sctp_bind_addr_t;
-typedef struct sctp_opt sctp_opt_t;
+typedef struct sctp_endpoint sctp_endpoint_t;
+typedef struct sctp_association sctp_association_t;
+typedef struct sctp_packet sctp_packet_t;
+typedef struct sctp_chunk sctp_chunk_t;
+typedef struct sctp_bind_addr sctp_bind_addr_t;
typedef struct sctp_endpoint_common sctp_endpoint_common_t;
#include <net/sctp/tsnmap.h>
@@ -250,10 +248,10 @@ struct sctp_af {
int optname,
char *optval,
int *optlen);
- struct dst_entry *(*get_dst) (sctp_association_t *asoc,
+ struct dst_entry *(*get_dst) (struct sctp_association *asoc,
union sctp_addr *daddr,
union sctp_addr *saddr);
- void (*get_saddr) (sctp_association_t *asoc,
+ void (*get_saddr) (struct sctp_association *asoc,
struct dst_entry *dst,
union sctp_addr *daddr,
union sctp_addr *saddr);
@@ -289,7 +287,7 @@ int sctp_register_af(struct sctp_af *);
/* Protocol family functions. */
struct sctp_pf {
- void (*event_msgname)(sctp_ulpevent_t *, char *, int *);
+ void (*event_msgname)(struct sctp_ulpevent *, char *, int *);
void (*skb_msgname) (struct sk_buff *, char *, int *);
int (*af_supported) (sa_family_t);
int (*cmp_addr) (const union sctp_addr *,
@@ -311,6 +309,9 @@ struct sctp_opt {
/* What kind of a socket is this? */
sctp_socket_type_t type;
+ /* PF_ family specific functions. */
+ struct sctp_pf *pf;
+
/* What is our base endpointer? */
sctp_endpoint_t *ep;
@@ -324,7 +325,10 @@ struct sctp_opt {
__u32 autoclose;
__u8 nodelay;
__u8 disable_fragments;
- struct sctp_pf *pf;
+ __u8 pd_mode;
+
+ /* Receive to here while partial delivery is in effect. */
+ struct sk_buff_head pd_lobby;
};
@@ -484,7 +488,7 @@ static inline __u16 sctp_ssn_next(struct sctp_stream *stream, __u16 id)
* As a matter of convenience, we remember the SCTP common header for
* each chunk as well as a few other header pointers...
*/
-struct SCTP_chunk {
+struct sctp_chunk {
/* These first three elements MUST PRECISELY match the first
* three elements of struct sk_buff. This allows us to reuse
* all the skb_* queue management functions.
@@ -594,7 +598,7 @@ typedef sctp_chunk_t *(sctp_packet_phandler_t)(sctp_association_t *);
/* This structure holds lists of chunks as we are assembling for
* transmission.
*/
-struct SCTP_packet {
+struct sctp_packet {
/* These are the SCTP header values (host order) for the packet. */
__u16 source_port;
__u16 destination_port;
@@ -846,8 +850,8 @@ unsigned long sctp_transport_timeout(struct sctp_transport *);
/* This is the structure we use to queue packets as they come into
* SCTP. We write packets to it and read chunks from it.
*/
-struct SCTP_inqueue {
- /* This is actually a queue of sctp_chunk_t each
+struct sctp_inq {
+ /* This is actually a queue of sctp_chunk each
* containing a partially decoded packet.
*/
struct sk_buff_head in;
@@ -864,13 +868,12 @@ struct SCTP_inqueue {
int malloced; /* Is this structure kfree()able? */
};
-sctp_inqueue_t *sctp_inqueue_new(void);
-void sctp_inqueue_init(sctp_inqueue_t *);
-void sctp_inqueue_free(sctp_inqueue_t *);
-void sctp_push_inqueue(sctp_inqueue_t *, sctp_chunk_t *packet);
-sctp_chunk_t *sctp_pop_inqueue(sctp_inqueue_t *);
-void sctp_inqueue_set_th_handler(sctp_inqueue_t *,
- void (*)(void *), void *);
+struct sctp_inq *sctp_inq_new(void);
+void sctp_inq_init(struct sctp_inq *);
+void sctp_inq_free(struct sctp_inq *);
+void sctp_inq_push(struct sctp_inq *, sctp_chunk_t *packet);
+struct sctp_chunk *sctp_inq_pop(struct sctp_inq *);
+void sctp_inq_set_th_handler(struct sctp_inq *, void (*)(void *), void *);
/* This is the structure we use to hold outbound chunks. You push
* chunks in and they automatically pop out the other end as bundled
@@ -954,7 +957,7 @@ void sctp_retransmit_mark(struct sctp_outq *, struct sctp_transport *, __u8);
/* These bind address data fields common between endpoints and associations */
-struct SCTP_bind_addr {
+struct sctp_bind_addr {
/* RFC 2960 12.1 Parameters necessary for the SCTP instance
*
@@ -1043,7 +1046,7 @@ struct sctp_endpoint_common {
struct sock *sk;
/* This is where we receive inbound chunks. */
- sctp_inqueue_t inqueue;
+ struct sctp_inq inqueue;
/* This substructure includes the defining parameters of the
* endpoint:
@@ -1076,7 +1079,7 @@ struct sctp_endpoint_common {
* off one of these.
*/
-struct SCTP_endpoint {
+struct sctp_endpoint {
/* Common substructure for endpoint and association. */
sctp_endpoint_common_t base;
@@ -1172,7 +1175,7 @@ __u32 sctp_generate_tsn(const sctp_endpoint_t *ep);
/* Here we have information about each individual association. */
-struct SCTP_association {
+struct sctp_association {
/* A base structure common to endpoint and association.
* In this context, it represents the associations's view
@@ -1288,19 +1291,11 @@ struct SCTP_association {
* used in the bulk of the text. This value is hidden
* in tsn_map--we get it by calling sctp_tsnmap_get_ctsn().
*/
- sctp_tsnmap_t tsn_map;
+ struct sctp_tsnmap tsn_map;
__u8 _map[sctp_tsnmap_storage_size(SCTP_TSN_MAP_SIZE)];
- /* We record duplicate TSNs here. We clear this after
- * every SACK.
- * FIXME: We should move this into the tsnmap? --jgrimm
- */
- sctp_dup_tsn_t dup_tsns[SCTP_MAX_DUP_TSNS];
- int next_dup_tsn;
-
/* Do we need to sack the peer? */
- uint8_t sack_needed;
-
+ __u8 sack_needed;
/* These are capabilities which our peer advertised. */
__u8 ecn_capable; /* Can peer do ECN? */
__u8 ipv4_address; /* Peer understands IPv4 addresses? */
@@ -1457,7 +1452,10 @@ struct SCTP_association {
struct {
__u16 stream;
+ __u16 flags;
__u32 ppid;
+ __u32 context;
+ __u32 timetolive;
} defaults;
/* This tracks outbound ssn for a given stream. */
@@ -1615,6 +1613,7 @@ void sctp_association_put(sctp_association_t *);
void sctp_association_hold(sctp_association_t *);
struct sctp_transport *sctp_assoc_choose_shutdown_transport(sctp_association_t *);
+void sctp_assoc_update_retran_path(sctp_association_t *);
struct sctp_transport *sctp_assoc_lookup_paddr(const sctp_association_t *,
const union sctp_addr *);
struct sctp_transport *sctp_assoc_add_peer(sctp_association_t *,
diff --git a/include/net/sctp/tsnmap.h b/include/net/sctp/tsnmap.h
index af775264a785..70bea4ce1a98 100644
--- a/include/net/sctp/tsnmap.h
+++ b/include/net/sctp/tsnmap.h
@@ -1,35 +1,35 @@
/* SCTP kernel reference Implementation Copyright (C) 1999-2001
* Cisco, Motorola, Intel, and International Business Machines Corp.
- *
+ *
* This file is part of the SCTP kernel reference Implementation
- *
+ *
* These are the definitions needed for the tsnmap type. The tsnmap is used
* to track out of order TSNs received.
- *
- * The SCTP reference implementation is free software;
- * you can redistribute it and/or modify it under the terms of
+ *
+ * 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
+ *
+ * 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, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
+ * Boston, MA 02111-1307, USA.
+ *
* Please send any bug reports or fixes you make to one of the
* following email addresses:
- *
+ *
* Jon Grimm <jgrimm@us.ibm.com>
* La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us>
- *
+ *
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
*/
@@ -38,8 +38,6 @@
#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
@@ -48,9 +46,7 @@
* will be set to all zero. This structure may be
* in the form of a circular buffer or bit array.
*/
-typedef struct sctp_tsnmap {
-
-
+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.
@@ -93,25 +89,30 @@ typedef struct sctp_tsnmap {
/* This is the highest TSN we've marked. */
__u32 max_tsn_seen;
- /* No. of data chunks pending receipt. used by SCTP_STATUS sockopt */
+ /* Data chunks pending receipt. used by SCTP_STATUS sockopt */
__u16 pending_data;
+ /* We record duplicate TSNs here. We clear this after
+ * every SACK. Store up to SCTP_MAX_DUP_TSNS worth of
+ * information.
+ */
+ __u32 dup_tsns[SCTP_MAX_DUP_TSNS];
+ __u16 num_dup_tsns;
+
int malloced;
__u8 raw_map[0];
-} sctp_tsnmap_t;
+};
-typedef struct sctp_tsnmap_iter {
+struct sctp_tsnmap_iter {
__u32 start;
-} sctp_tsnmap_iter_t;
-
+};
/* Create a new tsnmap. */
-sctp_tsnmap_t *sctp_tsnmap_new(__u16 len, __u32 initial_tsn,
- int priority);
+struct sctp_tsnmap *sctp_tsnmap_new(__u16 len, __u32 init_tsn, int priority);
/* Dispose of a tsnmap. */
-void sctp_tsnmap_free(sctp_tsnmap_t *map);
+void sctp_tsnmap_free(struct sctp_tsnmap *);
/* This macro assists in creation of external storage for variable length
* internal buffers. We double allocate so the overflow map works.
@@ -119,9 +120,8 @@ void sctp_tsnmap_free(sctp_tsnmap_t *map);
#define sctp_tsnmap_storage_size(count) (sizeof(__u8) * (count) * 2)
/* Initialize a block of memory as a tsnmap. */
-sctp_tsnmap_t *sctp_tsnmap_init(sctp_tsnmap_t *map, __u16 len, __u32 initial_tsn);
-
-
+struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *, __u16 len,
+ __u32 initial_tsn);
/* Test the tracking state of this TSN.
* Returns:
@@ -129,29 +129,51 @@ sctp_tsnmap_t *sctp_tsnmap_init(sctp_tsnmap_t *map, __u16 len, __u32 initial_tsn
* >0 if the TSN has been seen (duplicate)
* <0 if the TSN is invalid (too large to track)
*/
-int sctp_tsnmap_check(const sctp_tsnmap_t *map, __u32 tsn);
+int sctp_tsnmap_check(const struct sctp_tsnmap *, __u32 tsn);
/* Mark this TSN as seen. */
-void sctp_tsnmap_mark(sctp_tsnmap_t *map, __u32 tsn);
+void sctp_tsnmap_mark(struct sctp_tsnmap *, __u32 tsn);
/* Retrieve the Cumulative TSN ACK Point. */
-__u32 sctp_tsnmap_get_ctsn(const sctp_tsnmap_t *map);
+__u32 sctp_tsnmap_get_ctsn(const struct sctp_tsnmap *);
/* Retrieve the highest TSN we've seen. */
-__u32 sctp_tsnmap_get_max_tsn_seen(const sctp_tsnmap_t *map);
+__u32 sctp_tsnmap_get_max_tsn_seen(const struct sctp_tsnmap *);
+
+/* 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 __u32 *sctp_tsnmap_get_dups(struct sctp_tsnmap *map)
+{
+ map->num_dup_tsns = 0;
+ return map->dup_tsns;
+}
+
+/* Mark a duplicate TSN. Note: we limit how many we are willing to
+ * store and consequently report.
+ */
+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++] = tsn;
+}
/* Is there a gap in the TSN map? */
-int sctp_tsnmap_has_gap(const sctp_tsnmap_t *map);
+int sctp_tsnmap_has_gap(const struct sctp_tsnmap *);
/* Initialize a gap ack block interator from user-provided memory. */
-void sctp_tsnmap_iter_init(const sctp_tsnmap_t *map, sctp_tsnmap_iter_t *iter);
+void sctp_tsnmap_iter_init(const struct sctp_tsnmap *,
+ struct sctp_tsnmap_iter *);
/* Get the next gap ack blocks. We return 0 if there are no more
* gap ack blocks.
*/
-int sctp_tsnmap_next_gap_ack(const sctp_tsnmap_t *map, sctp_tsnmap_iter_t *iter,
- __u16 *start, __u16 *end);
-
+int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *,
+ struct sctp_tsnmap_iter *,__u16 *start, __u16 *end);
#endif /* __sctp_tsnmap_h__ */
diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
index 6e90b83a7013..8d0edaf22025 100644
--- a/include/net/sctp/ulpevent.h
+++ b/include/net/sctp/ulpevent.h
@@ -6,34 +6,34 @@
* Copyright (c) 2001 Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll
*
- * These are the definitions needed for the sctp_ulpevent type. The
+ * 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.
- *
- * The SCTP reference implementation is free software;
- * you can redistribute it and/or modify it under the terms of
+ * upwards to the ULP.
+ *
+ * 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
+ *
+ * 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, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
+ * Boston, MA 02111-1307, USA.
+ *
* Please send any bug reports or fixes you make to one of the
* following email addresses:
- *
+ *
* Jon Grimm <jgrimm@us.ibm.com>
* La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us>
- *
+ *
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
*/
@@ -46,85 +46,97 @@
/* Warning: This sits inside an skb.cb[] area. Be very careful of
* growing this structure as it is at the maximum limit now.
*/
-typedef struct sctp_ulpevent {
- int malloced;
- sctp_association_t *asoc;
- struct sk_buff *parent;
+struct sctp_ulpevent {
+ struct sctp_association *asoc;
struct sctp_sndrcvinfo sndrcvinfo;
- int chunk_flags; /* Temp. until we get a new chunk_t */
int msg_flags;
-} sctp_ulpevent_t;
-
-
-sctp_ulpevent_t *sctp_ulpevent_new(int size, int msg_flags, int priority);
-
-sctp_ulpevent_t *sctp_ulpevent_init(sctp_ulpevent_t *event, struct sk_buff *skb, int msg_flags);
-
-void sctp_ulpevent_free(sctp_ulpevent_t *event);
-
-int sctp_ulpevent_is_notification(const sctp_ulpevent_t *event);
-
-sctp_ulpevent_t *sctp_ulpevent_make_assoc_change(
- const struct SCTP_association *asoc,
- __u16 flags,
- __u16 state,
- __u16 error,
- __u16 outbound,
- __u16 inbound,
- int priority);
-
-sctp_ulpevent_t *sctp_ulpevent_make_peer_addr_change(
- const struct SCTP_association *asoc,
- const struct sockaddr_storage *aaddr,
- int flags,
- int state,
- int error,
- int priority);
-
-sctp_ulpevent_t *sctp_ulpevent_make_remote_error(
- const struct SCTP_association *asoc,
- struct SCTP_chunk *chunk,
- __u16 flags,
- int priority);
-sctp_ulpevent_t *sctp_ulpevent_make_send_failed(
- const struct SCTP_association *asoc,
- struct SCTP_chunk *chunk,
- __u16 flags,
- __u32 error,
- int priority);
-
-sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(
- const struct SCTP_association *asoc,
- __u16 flags,
- int priority);
-
-sctp_ulpevent_t *sctp_ulpevent_make_rcvmsg(struct SCTP_association *asoc,
- struct SCTP_chunk *chunk,
- int priority);
-
-void sctp_ulpevent_read_sndrcvinfo(const sctp_ulpevent_t *event,
- struct msghdr *msghdr);
-
-__u16 sctp_ulpevent_get_notification_type(const sctp_ulpevent_t *event);
+};
+/* Retrieve the skb this event sits inside of. */
+static inline struct sk_buff *sctp_event2skb(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;
+}
+
+struct sctp_ulpevent *sctp_ulpevent_new(int size, int flags, int priority);
+struct sctp_ulpevent *sctp_ulpevent_init(struct sctp_ulpevent *, int flags);
+void sctp_ulpevent_free(struct sctp_ulpevent *);
+int sctp_ulpevent_is_notification(const struct sctp_ulpevent *);
+
+struct sctp_ulpevent *sctp_ulpevent_make_assoc_change(
+ const struct sctp_association *asoc,
+ __u16 flags,
+ __u16 state,
+ __u16 error,
+ __u16 outbound,
+ __u16 inbound,
+ int priority);
+
+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,
+ int priority);
+
+struct sctp_ulpevent *sctp_ulpevent_make_remote_error(
+ const struct sctp_association *asoc,
+ struct sctp_chunk *chunk,
+ __u16 flags,
+ int priority);
+struct sctp_ulpevent *sctp_ulpevent_make_send_failed(
+ const struct sctp_association *asoc,
+ struct sctp_chunk *chunk,
+ __u16 flags,
+ __u32 error,
+ int priority);
+
+struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event(
+ const struct sctp_association *asoc,
+ __u16 flags,
+ int priority);
+
+struct sctp_ulpevent *sctp_ulpevent_make_pdapi(
+ const struct sctp_association *asoc,
+ __u32 indication, int priority);
+
+struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
+ struct sctp_chunk *chunk,
+ int priority);
+
+void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
+ struct msghdr *);
+__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 sctp_ulpevent_t *event,
- const struct sctp_event_subscribe *mask)
+static inline int sctp_ulpevent_is_enabled(const struct sctp_ulpevent *event,
+ struct sctp_event_subscribe *mask)
{
- const char *amask = (const char *) mask;
__u16 sn_type;
int enabled = 1;
if (sctp_ulpevent_is_notification(event)) {
sn_type = sctp_ulpevent_get_notification_type(event);
- enabled = amask[sn_type - SCTP_SN_TYPE_BASE];
+ enabled = sctp_ulpevent_type_enabled(sn_type, mask);
}
return enabled;
}
-
#endif /* __sctp_ulpevent_h__ */
diff --git a/include/net/sctp/ulpqueue.h b/include/net/sctp/ulpqueue.h
index 689abb810eb2..dd7823b0a737 100644
--- a/include/net/sctp/ulpqueue.h
+++ b/include/net/sctp/ulpqueue.h
@@ -48,7 +48,8 @@
/* A structure to carry information to the ULP (e.g. Sockets API) */
struct sctp_ulpq {
- int malloced;
+ char malloced;
+ char pd_mode;
sctp_association_t *asoc;
struct sk_buff_head reasm;
struct sk_buff_head lobby;
@@ -60,13 +61,19 @@ struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *, sctp_association_t *);
void sctp_ulpq_free(struct sctp_ulpq *);
/* Add a new DATA chunk for processing. */
-int sctp_ulpq_tail_data(struct sctp_ulpq *, sctp_chunk_t *chunk, int priority);
+int sctp_ulpq_tail_data(struct sctp_ulpq *, struct sctp_chunk *, int);
/* Add a new event for propogation to the ULP. */
int sctp_ulpq_tail_event(struct sctp_ulpq *, struct sctp_ulpevent *ev);
-/* Is the ulpqueue empty. */
-int sctp_ulpqueue_is_empty(struct sctp_ulpq *);
+/* Perform partial delivery. */
+void sctp_ulpq_partial_delivery(struct sctp_ulpq *, struct sctp_chunk *, int);
+
+/* Abort the partial delivery. */
+void sctp_ulpq_abort_pd(struct sctp_ulpq *, int);
+
+/* Clear the partial data delivery condition on this socket. */
+int sctp_clear_pd(struct sock *sk);
#endif /* __sctp_ulpqueue_h__ */
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index e95ef92ff9b9..69e241b1a88a 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -166,6 +166,7 @@ struct sctp_sndrcvinfo {
__u32 sinfo_context;
__u32 sinfo_timetolive;
__u32 sinfo_tsn;
+ __u32 sinfo_cumtsn;
sctp_assoc_t sinfo_assoc_id;
};
@@ -367,6 +368,7 @@ struct sctp_rcv_pdapi_event {
sctp_assoc_t pdapi_assoc_id;
};
+enum { SCTP_PARTIAL_DELIVERY_ABORTED=0, };
/*
* Described in Section 7.3
@@ -414,8 +416,8 @@ enum sctp_sn_type {
SCTP_SN_TYPE_BASE = (1<<15),
SCTP_ASSOC_CHANGE,
SCTP_PEER_ADDR_CHANGE,
- SCTP_REMOTE_ERROR,
SCTP_SEND_FAILED,
+ SCTP_REMOTE_ERROR,
SCTP_SHUTDOWN_EVENT,
SCTP_PARTIAL_DELIVERY_EVENT,
SCTP_ADAPTION_INDICATION,