[SCTP]: Implement the receive and verification of AUTH chunk
[safe/jmp/linux-2.6] / include / net / sctp / structs.h
index 60b6844..47e54f8 100644 (file)
@@ -64,6 +64,7 @@
 #include <linux/skbuff.h>      /* We need sk_buff_head. */
 #include <linux/workqueue.h>   /* We need tq_struct.    */
 #include <linux/sctp.h>                /* We need sctp* header structs.  */
+#include <net/sctp/auth.h>     /* We need auth specific structs */
 
 /* A convenience structure for handling sockaddr structures.
  * We should wean ourselves off this.
@@ -201,19 +202,24 @@ extern struct sctp_globals {
        struct sctp_bind_hashbucket *port_hashtable;
 
        /* This is the global local address list.
-        * We actively maintain this complete list of interfaces on
-        * the system by catching routing events.
+        * We actively maintain this complete list of addresses on
+        * the system by catching address add/delete events.
         *
         * It is a list of sctp_sockaddr_entry.
         */
        struct list_head local_addr_list;
-       spinlock_t local_addr_lock;
+
+       /* Lock that protects the local_addr_list writers */
+       spinlock_t addr_list_lock;
        
        /* Flag to indicate if addip is enabled. */
        int addip_enable;
 
        /* Flag to indicate if PR-SCTP is enabled. */
        int prsctp_enable;
+
+       /* Flag to idicate if SCTP-AUTH is enabled */
+       int auth_enable;
 } sctp_globals;
 
 #define sctp_rto_initial               (sctp_globals.rto_initial)
@@ -243,9 +249,10 @@ extern struct sctp_globals {
 #define sctp_port_alloc_lock           (sctp_globals.port_alloc_lock)
 #define sctp_port_hashtable            (sctp_globals.port_hashtable)
 #define sctp_local_addr_list           (sctp_globals.local_addr_list)
-#define sctp_local_addr_lock           (sctp_globals.local_addr_lock)
+#define sctp_local_addr_lock           (sctp_globals.addr_list_lock)
 #define sctp_addip_enable              (sctp_globals.addip_enable)
 #define sctp_prsctp_enable             (sctp_globals.prsctp_enable)
+#define sctp_auth_enable               (sctp_globals.auth_enable)
 
 /* SCTP Socket type: UDP or TCP style. */
 typedef enum {
@@ -277,6 +284,8 @@ struct sctp_sock {
        __u16 default_flags;
        __u32 default_context;
        __u32 default_timetolive;
+       __u32 default_rcv_context;
+       int max_burst;
 
        /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
         * the destination address every heartbeat interval. This value
@@ -305,10 +314,12 @@ struct sctp_sock {
        __u32 autoclose;
        __u8 nodelay;
        __u8 disable_fragments;
-       __u8 pd_mode;
        __u8 v4mapped;
-       __u32 adaption_ind;
+       __u8 frag_interleave;
+       __u32 adaptation_ind;
+       __u32 pd_point;
 
+       atomic_t pd_mode;
        /* Receive to here while partial delivery is in effect. */
        struct sk_buff_head pd_lobby;
 };
@@ -389,8 +400,11 @@ struct sctp_cookie {
        /* Padding for future use */
        __u8 padding;           
 
-       __u32 adaption_ind;     
+       __u32 adaptation_ind;
 
+       __u8 auth_random[sizeof(sctp_paramhdr_t) + SCTP_AUTH_RANDOM_LENGTH];
+       __u8 auth_hmacs[SCTP_AUTH_NUM_HMACS + 2];
+       __u8 auth_chunks[sizeof(sctp_paramhdr_t) + SCTP_AUTH_MAX_CHUNKS];
 
        /* This is a shim for my peer's INIT packet, followed by
         * a copy of the raw address list of the association.
@@ -415,6 +429,7 @@ struct sctp_signed_cookie {
  * internally.
  */
 union sctp_addr_param {
+       struct sctp_paramhdr p;
        struct sctp_ipv4addr_param v4;
        struct sctp_ipv6addr_param v6;
 };
@@ -432,7 +447,11 @@ union sctp_params {
        struct sctp_ipv4addr_param *v4;
        struct sctp_ipv6addr_param *v6;
        union sctp_addr_param *addr;
-       struct sctp_adaption_ind_param *aind;
+       struct sctp_adaptation_ind_param *aind;
+       struct sctp_supported_ext_param *ext;
+       struct sctp_random_param *random;
+       struct sctp_chunks_param *chunks;
+       struct sctp_hmac_algo_param *hmac_algo;
 };
 
 /* RFC 2960.  Section 3.3.5 Heartbeat.
@@ -537,7 +556,7 @@ struct sctp_af {
                                          struct net_device *);
        void            (*dst_saddr)    (union sctp_addr *saddr,
                                         struct dst_entry *dst,
-                                        unsigned short port);
+                                        __be16 port);
        int             (*cmp_addr)     (const union sctp_addr *addr1,
                                         const union sctp_addr *addr2);
        void            (*addr_copy)    (union sctp_addr *dst,
@@ -553,14 +572,14 @@ struct sctp_af {
                                         struct sock *sk);
        void            (*from_addr_param) (union sctp_addr *,
                                            union sctp_addr_param *,
-                                           __u16 port, int iif);       
+                                           __be16 port, int iif);
        int             (*to_addr_param) (const union sctp_addr *,
                                          union sctp_addr_param *); 
        int             (*addr_valid)   (union sctp_addr *,
                                         struct sctp_sock *,
                                         const struct sk_buff *);
        sctp_scope_t    (*scope) (union sctp_addr *);
-       void            (*inaddr_any)   (union sctp_addr *, unsigned short);
+       void            (*inaddr_any)   (union sctp_addr *, __be16);
        int             (*is_any)       (const union sctp_addr *);
        int             (*available)    (union sctp_addr *,
                                         struct sctp_sock *);
@@ -587,7 +606,7 @@ struct sctp_pf {
                          struct sctp_sock *);
        int  (*bind_verify) (struct sctp_sock *, union sctp_addr *);
        int  (*send_verify) (struct sctp_sock *, union sctp_addr *);
-       int  (*supported_addrs)(const struct sctp_sock *, __u16 *);
+       int  (*supported_addrs)(const struct sctp_sock *, __be16 *);
        struct sock *(*create_accept_sk) (struct sock *sk,
                                          struct sctp_association *asoc);
        void (*addr_v4map) (struct sctp_sock *, union sctp_addr *);
@@ -671,6 +690,7 @@ struct sctp_chunk {
                struct sctp_errhdr *err_hdr;
                struct sctp_addiphdr *addip_hdr;
                struct sctp_fwdtsn_hdr *fwdtsn_hdr;
+               struct sctp_authhdr *auth_hdr;
        } subh;
 
        __u8 *chunk_end;
@@ -704,6 +724,13 @@ struct sctp_chunk {
         */
        struct sctp_transport *transport;
 
+       /* SCTP-AUTH:  For the special case inbound processing of COOKIE-ECHO
+        * we need save a pointer to the AUTH chunk, since the SCTP-AUTH
+        * spec violates the principle premis that all chunks are processed
+        * in order.
+        */
+       struct sk_buff *auth_chunk;
+
        __u8 rtt_in_progress;   /* Is this chunk used for RTT calculation? */
        __u8 resent;            /* Has this chunk ever been retransmitted. */
        __u8 has_tsn;           /* Does this chunk have a TSN yet? */
@@ -716,6 +743,7 @@ struct sctp_chunk {
        __s8 fast_retransmit;    /* Is this chunk fast retransmitted? */
        __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 */
 };
 
 void sctp_chunk_hold(struct sctp_chunk *);
@@ -734,8 +762,10 @@ const union sctp_addr *sctp_source(const struct sctp_chunk *chunk);
 /* 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 valid;
 };
 
 typedef struct sctp_chunk *(sctp_packet_phandler_t)(struct sctp_association *);
@@ -763,16 +793,25 @@ struct sctp_packet {
         */
        struct sctp_transport *transport;
 
+       /* pointer to the auth chunk for this packet */
+       struct sctp_chunk *auth;
+
        /* This packet contains a COOKIE-ECHO chunk. */
-       char has_cookie_echo;
+       __u8 has_cookie_echo;
+
+       /* This packet contains a SACK chunk. */
+       __u8 has_sack;
+
+       /* This packet contains an AUTH chunk */
+       __u8 has_auth;
 
-       /* This packet containsa SACK chunk. */
-       char has_sack;
+       /* This packet contains at least 1 DATA chunk */
+       __u8 has_data;
 
        /* SCTP cannot fragment this packet. So let ip fragment it. */
-       char ipfragok;
+       __u8 ipfragok;
 
-       int malloced;
+       __u8 malloced;
 };
 
 struct sctp_packet *sctp_packet_init(struct sctp_packet *,
@@ -910,6 +949,9 @@ struct sctp_transport {
         */
        __u16 pathmaxrxt;
 
+       /* is the Path MTU update pending on this tranport */
+       __u8 pmtu_pending;
+
        /* PMTU       : The current known path MTU.  */
        __u32 pathmtu;
 
@@ -1003,6 +1045,8 @@ void sctp_transport_update_rto(struct sctp_transport *, __u32);
 void sctp_transport_raise_cwnd(struct sctp_transport *, __u32, __u32);
 void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t);
 unsigned long sctp_transport_timeout(struct sctp_transport *);
+void sctp_transport_reset(struct sctp_transport *);
+void sctp_transport_update_pmtu(struct sctp_transport *, u32);
 
 
 /* This is the structure we use to queue packets as they come into
@@ -1030,6 +1074,7 @@ void sctp_inq_init(struct sctp_inq *);
 void sctp_inq_free(struct sctp_inq *);
 void sctp_inq_push(struct sctp_inq *, struct sctp_chunk *packet);
 struct sctp_chunk *sctp_inq_pop(struct sctp_inq *);
+struct sctp_chunkhdr *sctp_inq_peek(struct sctp_inq *);
 void sctp_inq_set_th_handler(struct sctp_inq *, work_func_t);
 
 /* This is the structure we use to hold outbound chunks.  You push
@@ -1141,7 +1186,9 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
                        int flags);
 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 *);
+int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *,
+                       void fastcall (*rcu_call)(struct rcu_head *,
+                                         void (*func)(struct rcu_head *)));
 int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *,
                         struct sctp_sock *);
 union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr  *bp,
@@ -1212,9 +1259,6 @@ struct sctp_ep_common {
         * bind_addr.address_list is our set of local IP addresses.
         */
        struct sctp_bind_addr bind_addr;
-
-       /* Protection during address list comparisons. */
-       rwlock_t   addr_lock;
 };
 
 
@@ -1270,13 +1314,28 @@ struct sctp_endpoint {
         *          this here so we pre-allocate this once and can re-use
         *          on every receive.
         */
-       __u8 digest[SCTP_SIGNATURE_SIZE];
+       __u8 *digest;
  
        /* sendbuf acct. policy.        */
        __u32 sndbuf_policy;
 
        /* rcvbuf acct. policy. */
        __u32 rcvbuf_policy;
+
+       /* SCTP AUTH: array of the HMACs that will be allocated
+        * we need this per association so that we don't serialize
+        */
+       struct crypto_hash **auth_hmacs;
+
+       /* SCTP-AUTH: hmacs for the endpoint encoded into parameter */
+        struct sctp_hmac_algo_param *auth_hmacs_list;
+
+       /* SCTP-AUTH: chunks to authenticate encoded into parameter */
+       struct sctp_chunks_param *auth_chunk_list;
+
+       /* SCTP-AUTH: endpoint shared keys */
+       struct list_head endpoint_shared_keys;
+       __u16 active_key_id;
 };
 
 /* Recover the outter endpoint structure. */
@@ -1314,6 +1373,13 @@ int sctp_process_init(struct sctp_association *, sctp_cid_t cid,
 __u32 sctp_generate_tag(const struct sctp_endpoint *);
 __u32 sctp_generate_tsn(const struct sctp_endpoint *);
 
+struct sctp_inithdr_host {
+       __u32 init_tag;
+       __u32 a_rwnd;
+       __u16 num_outbound_streams;
+       __u16 num_inbound_streams;
+       __u32 initial_tsn;
+};
 
 /* RFC2960
  *
@@ -1476,15 +1542,16 @@ struct sctp_association {
                __u8    hostname_address;/* Peer understands DNS addresses? */
                __u8    asconf_capable;  /* Does peer support ADDIP? */
                __u8    prsctp_capable;  /* Can peer do PR-SCTP? */
+               __u8    auth_capable;    /* Is peer doing SCTP-AUTH? */
 
-               __u32   adaption_ind;    /* Adaption Code point. */
+               __u32   adaptation_ind;  /* Adaptation Code point. */
 
                /* This mask is used to disable sending the ASCONF chunk
                 * with specified parameter to peer.
                 */
-               __u16 addip_disabled_mask;
+               __be16 addip_disabled_mask;
 
-               struct sctp_inithdr i;
+               struct sctp_inithdr_host i;
                int cookie_len;
                void *cookie;
 
@@ -1493,6 +1560,14 @@ struct sctp_association {
                 * Initial TSN Value minus 1
                 */
                __u32 addip_serial;
+
+               /* SCTP-AUTH: We need to know pears random number, hmac list
+                * and authenticated chunk list.  All that is part of the
+                * cookie and these are just pointers to those locations
+                */
+               sctp_random_param_t *peer_random;
+               sctp_chunks_param_t *peer_chunks;
+               sctp_hmac_algo_param_t *peer_hmacs;
        } peer;
 
        /* State       : A state variable indicating what state the
@@ -1555,6 +1630,9 @@ struct sctp_association {
         */
        __u16 pathmaxrxt;
 
+       /* Flag that path mtu update is pending */
+       __u8   pmtu_pending;
+
        /* Association : The smallest PMTU discovered for all of the
         * PMTU        : peer's transport addresses.
         */
@@ -1652,6 +1730,9 @@ struct sctp_association {
        __u32 default_context;
        __u32 default_timetolive;
 
+       /* Default receive parameters */
+       __u32 default_rcv_context;
+
        /* This tracks outbound ssn for a given stream.  */
        struct sctp_ssnmap *ssnmap;
 
@@ -1770,6 +1851,24 @@ struct sctp_association {
         */
        __u32 addip_serial;
 
+       /* SCTP AUTH: list of the endpoint shared keys.  These
+        * keys are provided out of band by the user applicaton
+        * and can't change during the lifetime of the association
+        */
+       struct list_head endpoint_shared_keys;
+
+       /* SCTP AUTH:
+        * The current generated assocaition shared key (secret)
+        */
+       struct sctp_auth_bytes *asoc_shared_key;
+
+       /* SCTP AUTH: hmac id of the first peer requested algorithm
+        * that we support.
+        */
+       __u16 default_hmac_id;
+
+       __u16 active_key_id;
+
        /* Need to send an ECNE Chunk? */
        char need_ecne;
 
@@ -1844,6 +1943,7 @@ int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *,
 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);
 
 int sctp_cmp_addr_exact(const union sctp_addr *ss1,
                        const union sctp_addr *ss2);