Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[safe/jmp/linux-2.6] / include / net / sctp / structs.h
index 47e54f8..ab1c472 100644 (file)
@@ -1,18 +1,18 @@
-/* SCTP kernel reference Implementation
+/* 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 reference Implementation
+ * This file is part of the SCTP kernel implementation
  *
- * The SCTP reference implementation is free software;
+ * 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.
  *
- * The SCTP reference implementation is distributed in the hope that it
+ * 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.
@@ -100,20 +100,19 @@ struct crypto_hash;
 struct sctp_bind_bucket {
        unsigned short  port;
        unsigned short  fastreuse;
-       struct sctp_bind_bucket *next;
-       struct sctp_bind_bucket **pprev;
+       struct hlist_node       node;
        struct hlist_head       owner;
 };
 
 struct sctp_bind_hashbucket {
        spinlock_t      lock;
-       struct sctp_bind_bucket *chain;
+       struct hlist_head       chain;
 };
 
 /* Used for hashing all associations.  */
 struct sctp_hashbucket {
        rwlock_t        lock;
-       struct sctp_ep_common  *chain;
+       struct hlist_head       chain;
 } __attribute__((__aligned__(8)));
 
 
@@ -197,8 +196,6 @@ extern struct sctp_globals {
 
        /* This is the sctp port control hash.  */
        int port_hashsize;
-       int port_rover;
-       spinlock_t port_alloc_lock;  /* Protects port_rover. */
        struct sctp_bind_hashbucket *port_hashtable;
 
        /* This is the global local address list.
@@ -214,6 +211,7 @@ extern struct sctp_globals {
        
        /* Flag to indicate if addip is enabled. */
        int addip_enable;
+       int addip_noauth_enable;
 
        /* Flag to indicate if PR-SCTP is enabled. */
        int prsctp_enable;
@@ -251,6 +249,7 @@ extern struct sctp_globals {
 #define sctp_local_addr_list           (sctp_globals.local_addr_list)
 #define sctp_local_addr_lock           (sctp_globals.addr_list_lock)
 #define sctp_addip_enable              (sctp_globals.addip_enable)
+#define sctp_addip_noauth              (sctp_globals.addip_noauth_enable)
 #define sctp_prsctp_enable             (sctp_globals.prsctp_enable)
 #define sctp_auth_enable               (sctp_globals.auth_enable)
 
@@ -301,8 +300,9 @@ struct sctp_sock {
 
        /* The default SACK delay timeout for new associations. */
        __u32 sackdelay;
+       __u32 sackfreq;
 
-       /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
+       /* Flags controlling Heartbeat, SACK delay, and Path MTU Discovery. */
        __u32 param_flags;
 
        struct sctp_initmsg initmsg;
@@ -452,6 +452,7 @@ union sctp_params {
        struct sctp_random_param *random;
        struct sctp_chunks_param *chunks;
        struct sctp_hmac_algo_param *hmac_algo;
+       struct sctp_addip_param *addip;
 };
 
 /* RFC 2960.  Section 3.3.5 Heartbeat.
@@ -523,8 +524,7 @@ static inline void sctp_ssn_skip(struct sctp_stream *stream, __u16 id,
  */
 struct sctp_af {
        int             (*sctp_xmit)    (struct sk_buff *skb,
-                                        struct sctp_transport *,
-                                        int ipfragok);
+                                        struct sctp_transport *);
        int             (*setsockopt)   (struct sock *sk,
                                         int level,
                                         int optname,
@@ -548,7 +548,8 @@ struct sctp_af {
        struct dst_entry *(*get_dst)    (struct sctp_association *asoc,
                                         union sctp_addr *daddr,
                                         union sctp_addr *saddr);
-       void            (*get_saddr)    (struct sctp_association *asoc,
+       void            (*get_saddr)    (struct sctp_sock *sk,
+                                        struct sctp_association *asoc,
                                         struct dst_entry *dst,
                                         union sctp_addr *daddr,
                                         union sctp_addr *saddr);
@@ -587,6 +588,7 @@ struct sctp_af {
        int             (*is_ce)        (const struct sk_buff *sk);
        void            (*seq_dump_addr)(struct seq_file *seq,
                                         union sctp_addr *addr);
+       void            (*ecn_capable)(struct sock *sk);
        __u16           net_header_len;
        int             sockaddr_len;
        sa_family_t     sa_family;
@@ -637,8 +639,6 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *,
                                            struct sctp_sndrcvinfo *,
                                            struct msghdr *, int len);
 void sctp_datamsg_put(struct sctp_datamsg *);
-void sctp_datamsg_free(struct sctp_datamsg *);
-void sctp_datamsg_track(struct sctp_chunk *);
 void sctp_chunk_fail(struct sctp_chunk *, int error);
 int sctp_chunk_abandoned(struct sctp_chunk *);
 
@@ -744,6 +744,7 @@ struct sctp_chunk {
        __u8 tsn_missing_report; /* Data chunk missing counter. */
        __u8 data_accepted;     /* At least 1 chunk in this packet accepted */
        __u8 auth;              /* IN: was auth'ed | OUT: needs auth */
+       __u8 has_asconf;        /* IN: have seen an asconf before */
 };
 
 void sctp_chunk_hold(struct sctp_chunk *);
@@ -759,12 +760,18 @@ void sctp_init_addrs(struct sctp_chunk *, union sctp_addr *,
                     union sctp_addr *);
 const union sctp_addr *sctp_source(const struct sctp_chunk *chunk);
 
+enum {
+       SCTP_ADDR_NEW,          /* new address added to assoc/ep */
+       SCTP_ADDR_SRC,          /* address can be used as source */
+       SCTP_ADDR_DEL,          /* address about to be deleted */
+};
+
 /* This is a structure for holding either an IPv6 or an IPv4 address.  */
 struct sctp_sockaddr_entry {
        struct list_head list;
        struct rcu_head rcu;
        union sctp_addr a;
-       __u8 use_as_src;
+       __u8 state;
        __u8 valid;
 };
 
@@ -819,7 +826,7 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *,
                                     __u16 sport, __u16 dport);
 struct sctp_packet *sctp_packet_config(struct sctp_packet *, __u32 vtag, int);
 sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *,
-                                       struct sctp_chunk *);
+                                       struct sctp_chunk *, int);
 sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *,
                                      struct sctp_chunk *);
 int sctp_packet_transmit(struct sctp_packet *);
@@ -875,10 +882,11 @@ struct sctp_transport {
         * address list derived from the INIT or INIT ACK chunk, a
         * number of data elements needs to be maintained including:
         */
-       __u32 rtt;              /* This is the most recent RTT.  */
-
        /* RTO         : The current retransmission timeout value.  */
        unsigned long rto;
+       unsigned long last_rto;
+
+       __u32 rtt;              /* This is the most recent RTT.  */
 
        /* RTTVAR      : The current RTT variation.  */
        __u32 rttvar;
@@ -895,7 +903,10 @@ struct sctp_transport {
         *              calculation completes (i.e. the DATA chunk
         *              is SACK'd) clear this flag.
         */
-       int rto_pending;
+       __u8 rto_pending;
+
+       /* Flag to track the current fast recovery state */
+       __u8 fast_recovery;
 
        /*
         * These are the congestion stats.
@@ -914,6 +925,9 @@ struct sctp_transport {
        /* Data that has been sent, but not acknowledged. */
        __u32 flight_size;
 
+       /* TSN marking the fast recovery exit point */
+       __u32 fast_recovery_exit;
+
        /* Destination */
        struct dst_entry *dst;
        /* Source address. */
@@ -932,6 +946,7 @@ struct sctp_transport {
 
        /* SACK delay timeout */
        unsigned long sackdelay;
+       __u32 sackfreq;
 
        /* When was the last time (in jiffies) that we heard from this
         * transport?  We use this to pick new active and retran paths.
@@ -955,7 +970,7 @@ struct sctp_transport {
        /* PMTU       : The current known path MTU.  */
        __u32 pathmtu;
 
-       /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
+       /* Flags controlling Heartbeat, SACK delay, and Path MTU Discovery. */
        __u32 param_flags;
 
        /* The number of times INIT has been sent on this transport. */
@@ -1038,7 +1053,7 @@ void sctp_transport_route(struct sctp_transport *, union sctp_addr *,
                          struct sctp_sock *);
 void sctp_transport_pmtu(struct sctp_transport *);
 void sctp_transport_free(struct sctp_transport *);
-void sctp_transport_reset_timers(struct sctp_transport *);
+void sctp_transport_reset_timers(struct sctp_transport *, int);
 void sctp_transport_hold(struct sctp_transport *);
 void sctp_transport_put(struct sctp_transport *);
 void sctp_transport_update_rto(struct sctp_transport *, __u32);
@@ -1128,6 +1143,9 @@ struct sctp_outq {
        /* How many unackd bytes do we have in-flight?  */
        __u32 outstanding_bytes;
 
+       /* Are we doing fast-rtx on this queue */
+       char fast_rtx;
+
        /* Corked? */
        char cork;
 
@@ -1142,7 +1160,6 @@ void sctp_outq_init(struct sctp_association *, struct sctp_outq *);
 void sctp_outq_teardown(struct sctp_outq *);
 void sctp_outq_free(struct sctp_outq*);
 int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk);
-int sctp_outq_flush(struct sctp_outq *, int);
 int sctp_outq_sack(struct sctp_outq *, struct sctp_sackhdr *);
 int sctp_outq_is_empty(const struct sctp_outq *);
 void sctp_outq_restart(struct sctp_outq *);
@@ -1184,13 +1201,18 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
                        const struct sctp_bind_addr *src,
                        sctp_scope_t scope, gfp_t gfp,
                        int flags);
+int sctp_bind_addr_dup(struct sctp_bind_addr *dest,
+                       const struct sctp_bind_addr *src,
+                       gfp_t gfp);
 int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *,
-                      __u8 use_as_src, gfp_t gfp);
-int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *,
-                       void fastcall (*rcu_call)(struct rcu_head *,
-                                         void (*func)(struct rcu_head *)));
+                      __u8 addr_state, gfp_t gfp);
+int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *);
 int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *,
                         struct sctp_sock *);
+int sctp_bind_addr_conflict(struct sctp_bind_addr *, const union sctp_addr *,
+                        struct sctp_sock *, struct sctp_sock *);
+int sctp_bind_addr_state(const struct sctp_bind_addr *bp,
+                        const union sctp_addr *addr);
 union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr  *bp,
                                        const union sctp_addr   *addrs,
                                        int                     addrcnt,
@@ -1231,8 +1253,7 @@ typedef enum {
 
 struct sctp_ep_common {
        /* Fields to help us manage our entries in the hash tables. */
-       struct sctp_ep_common *next;
-       struct sctp_ep_common **pprev;
+       struct hlist_node node;
        int hashent;
 
        /* Runtime type information.  What kind of endpoint is this? */
@@ -1534,6 +1555,7 @@ struct sctp_association {
                 *             : SACK's are not delayed (see Section 6).
                 */
                __u8    sack_needed;     /* Do we need to sack the peer? */
+               __u32   sack_cnt;
 
                /* These are capabilities which our peer advertised.  */
                __u8    ecn_capable;     /* Can peer do ECN? */
@@ -1638,11 +1660,12 @@ struct sctp_association {
         */
        __u32 pathmtu;
 
-       /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
+       /* Flags controlling Heartbeat, SACK delay, and Path MTU Discovery. */
        __u32 param_flags;
 
        /* SACK delay timeout */
        unsigned long sackdelay;
+       __u32 sackfreq;
 
 
        unsigned long timeouts[SCTP_NUM_TIMEOUT_TYPES];
@@ -1651,6 +1674,9 @@ struct sctp_association {
        /* Transport to which SHUTDOWN chunk was last sent.  */
        struct sctp_transport *shutdown_last_sent_to;
 
+       /* How many times have we resent a SHUTDOWN */
+       int shutdown_retries;
+
        /* Transport to which INIT chunk was last sent.  */
        struct sctp_transport *init_last_sent_to;
 
@@ -1685,6 +1711,11 @@ struct sctp_association {
         */
        __u16 unack_data;
 
+       /* The total number of data chunks that we've had to retransmit
+        * as the result of a T3 timer expiration
+        */
+       __u32 rtx_data_chunks;
+
        /* This is the association's receive buffer space.  This value is used
         * to set a_rwnd field in an INIT or a SACK chunk.
         */
@@ -1784,20 +1815,16 @@ struct sctp_association {
         */
        struct sctp_chunk *addip_last_asconf;
 
-       /* ADDIP Section 4.2 Upon reception of an ASCONF Chunk.
+       /* ADDIP Section 5.2 Upon reception of an ASCONF Chunk.
         *
-        * IMPLEMENTATION NOTE: As an optimization a receiver may wish
-        * to save the last ASCONF-ACK for some predetermined period
-        * of time and instead of re-processing the ASCONF (with the
-        * same serial number) it may just re-transmit the
-        * ASCONF-ACK. It may wish to use the arrival of a new serial
-        * number to discard the previously saved ASCONF-ACK or any
-        * other means it may choose to expire the saved ASCONF-ACK.
+        * This is needed to implement itmes E1 - E4 of the updated
+        * spec.  Here is the justification:
         *
-        * [This is our saved ASCONF-ACK.  We invalidate it when a new
-        * ASCONF serial number arrives.]
+        * Since the peer may bundle multiple ASCONF chunks toward us,
+        * we now need the ability to cache multiple ACKs.  The section
+        * describes in detail how they are cached and cleaned up.
         */
-       struct sctp_chunk *addip_last_asconf_ack;
+       struct list_head asconf_ack_list;
 
        /* These ASCONF chunks are waiting to be sent.
         *
@@ -1938,12 +1965,19 @@ void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned);
 void sctp_assoc_rwnd_decrease(struct sctp_association *, unsigned);
 void sctp_assoc_set_primary(struct sctp_association *,
                            struct sctp_transport *);
+void sctp_assoc_del_nonprimary_peers(struct sctp_association *,
+                                   struct sctp_transport *);
 int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *,
                                     gfp_t);
 int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *,
                                         struct sctp_cookie*,
                                         gfp_t gfp);
 int sctp_assoc_set_id(struct sctp_association *, gfp_t);
+void sctp_assoc_clean_asconf_ack_cache(const struct sctp_association *asoc);
+struct sctp_chunk *sctp_assoc_lookup_asconf_ack(
+                                       const struct sctp_association *asoc,
+                                       __be32 serial);
+
 
 int sctp_cmp_addr_exact(const union sctp_addr *ss1,
                        const union sctp_addr *ss2);