- Update to 3.4-rc7.
[linux-flexiantxendom0-3.2.10.git] / include / net / sctp / sctp.h
index 67c997c..a2ef814 100644 (file)
@@ -1,20 +1,20 @@
-/* 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-2003 Intel Corp.
  *
- * This file is part of the SCTP kernel reference Implementation
+ * This file is part of the SCTP kernel implementation
  *
  * The base lksctp header.
  *
- * 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.
  *   and will continue to evolve.
  */
 
-
-
-#ifdef TEST_FRAME
-#undef CONFIG_PROC_FS
-#undef CONFIG_SCTP_DBG_OBJCNT
-#undef CONFIG_SYSCTL
-#endif /* TEST_FRAME */
-
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/in.h>
@@ -79,7 +71,7 @@
 #include <linux/jiffies.h>
 #include <linux/idr.h>
 
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+#if IS_ENABLED(CONFIG_IPV6)
 #include <net/ipv6.h>
 #include <net/ip6_route.h>
 #endif
  * sctp/protocol.c
  */
 extern struct sock *sctp_get_ctl_sock(void);
-extern void sctp_local_addr_free(struct rcu_head *head);
 extern int sctp_copy_local_addr_list(struct sctp_bind_addr *,
                                     sctp_scope_t, gfp_t gfp,
                                     int flags);
 extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family);
 extern int sctp_register_pf(struct sctp_pf *, sa_family_t);
+extern void sctp_addr_wq_mgmt(struct sctp_sockaddr_entry *, int);
 
 /*
  * sctp/socket.c
@@ -136,9 +128,14 @@ extern int sctp_register_pf(struct sctp_pf *, sa_family_t);
 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, int len);
 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;
+extern int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *);
 
 /*
  * sctp/primitive.c
@@ -151,13 +148,6 @@ int sctp_primitive_REQUESTHEARTBEAT(struct sctp_association *, void *arg);
 int sctp_primitive_ASCONF(struct sctp_association *, void *arg);
 
 /*
- * sctp/crc32c.c
- */
-__u32 sctp_start_cksum(__u8 *ptr, __u16 count);
-__u32 sctp_update_cksum(__u8 *ptr, __u16 count, __u32 cksum);
-__u32 sctp_end_cksum(__u32 cksum);
-
-/*
  * sctp/input.c
  */
 int sctp_rcv(struct sk_buff *skb);
@@ -187,6 +177,8 @@ int sctp_eps_proc_init(void);
 void sctp_eps_proc_exit(void);
 int sctp_assocs_proc_init(void);
 void sctp_assocs_proc_exit(void);
+int sctp_remaddr_proc_init(void);
+void sctp_remaddr_proc_exit(void);
 
 
 /*
@@ -226,8 +218,6 @@ extern struct kmem_cache *sctp_bucket_cachep __read_mostly;
 #define sctp_release_sock(sk)    release_sock(sk)
 #define sctp_bh_lock_sock(sk)    bh_lock_sock(sk)
 #define sctp_bh_unlock_sock(sk)  bh_unlock_sock(sk)
-#define SCTP_SOCK_SLEEP_PRE(sk)  SOCK_SLEEP_PRE(sk)
-#define SCTP_SOCK_SLEEP_POST(sk) SOCK_SLEEP_POST(sk)
 
 /* SCTP SNMP MIB stats handlers */
 DECLARE_SNMP_STAT(struct sctp_mib, sctp_statistics);
@@ -239,8 +229,7 @@ DECLARE_SNMP_STAT(struct sctp_mib, sctp_statistics);
 #endif /* !TEST_FRAME */
 
 /* sctp mib definitions */
-enum
-{
+enum {
        SCTP_MIB_NUM = 0,
        SCTP_MIB_CURRESTAB,                     /* CurrEstab */
        SCTP_MIB_ACTIVEESTABS,                  /* ActiveEstabs */
@@ -281,43 +270,56 @@ enum
 #define SCTP_MIB_MAX    __SCTP_MIB_MAX
 struct sctp_mib {
         unsigned long   mibs[SCTP_MIB_MAX];
-} __SNMP_MIB_ALIGN__;
+};
 
 
 /* Print debugging messages.  */
 #if SCTP_DEBUG
 extern int sctp_debug_flag;
-#define SCTP_DEBUG_PRINTK(whatever...) \
-       ((void) (sctp_debug_flag && printk(KERN_DEBUG whatever)))
-#define SCTP_DEBUG_PRINTK_IPADDR(lead, trail, leadparm, saddr, otherparms...) \
-       if (sctp_debug_flag) { \
-               if (saddr->sa.sa_family == AF_INET6) { \
-                       printk(KERN_DEBUG \
-                              lead NIP6_FMT trail, \
-                              leadparm, \
-                              NIP6(saddr->v6.sin6_addr), \
-                              otherparms); \
-               } else { \
-                       printk(KERN_DEBUG \
-                              lead NIPQUAD_FMT trail, \
-                              leadparm, \
-                              NIPQUAD(saddr->v4.sin_addr.s_addr), \
-                              otherparms); \
-               } \
-       }
+#define SCTP_DEBUG_PRINTK(fmt, args...)                        \
+do {                                                   \
+       if (sctp_debug_flag)                            \
+               printk(KERN_DEBUG pr_fmt(fmt), ##args); \
+} while (0)
+#define SCTP_DEBUG_PRINTK_CONT(fmt, args...)           \
+do {                                                   \
+       if (sctp_debug_flag)                            \
+               pr_cont(fmt, ##args);                   \
+} while (0)
+#define SCTP_DEBUG_PRINTK_IPADDR(fmt_lead, fmt_trail,                  \
+                                args_lead, addr, args_trail...)        \
+do {                                                                   \
+       const union sctp_addr *_addr = (addr);                          \
+       if (sctp_debug_flag) {                                          \
+               if (_addr->sa.sa_family == AF_INET6) {                  \
+                       printk(KERN_DEBUG                               \
+                              pr_fmt(fmt_lead "%pI6" fmt_trail),       \
+                              args_lead,                               \
+                              &_addr->v6.sin6_addr,                    \
+                              args_trail);                             \
+               } else {                                                \
+                       printk(KERN_DEBUG                               \
+                              pr_fmt(fmt_lead "%pI4" fmt_trail),       \
+                              args_lead,                               \
+                              &_addr->v4.sin_addr.s_addr,              \
+                              args_trail);                             \
+               }                                                       \
+       }                                                               \
+} while (0)
 #define SCTP_ENABLE_DEBUG { sctp_debug_flag = 1; }
 #define SCTP_DISABLE_DEBUG { sctp_debug_flag = 0; }
 
 #define SCTP_ASSERT(expr, str, func) \
        if (!(expr)) { \
                SCTP_DEBUG_PRINTK("Assertion Failed: %s(%s) at %s:%s:%d\n", \
-                       str, (#expr), __FILE__, __FUNCTION__, __LINE__); \
+                       str, (#expr), __FILE__, __func__, __LINE__); \
                func; \
        }
 
 #else  /* SCTP_DEBUG */
 
 #define SCTP_DEBUG_PRINTK(whatever...)
+#define SCTP_DEBUG_PRINTK_CONT(fmt, args...)
 #define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
 #define SCTP_ENABLE_DEBUG
 #define SCTP_DISABLE_DEBUG
@@ -376,27 +378,26 @@ void sctp_sysctl_unregister(void);
 #else
 static inline void sctp_sysctl_register(void) { return; }
 static inline void sctp_sysctl_unregister(void) { return; }
-static inline int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen,
-               void __user *oldval, size_t __user *oldlenp,
-               void __user *newval, size_t newlen) {
-       return -ENOSYS;
-}
 #endif
 
 /* Size of Supported Address Parameter for 'x' address types. */
 #define SCTP_SAT_LEN(x) (sizeof(struct sctp_paramhdr) + (x) * sizeof(__u16))
 
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+#if IS_ENABLED(CONFIG_IPV6)
 
-int sctp_v6_init(void);
-void sctp_v6_exit(void);
+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 int sctp_v6_init(void) { return 0; }
-static inline void sctp_v6_exit(void) { return; }
+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; }
 
@@ -406,19 +407,17 @@ static inline void sctp_v6_del_protocol(void) { return; }
 /* 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);
+       return asoc ? asoc->assoc_id : 0;
 }
 
 /* 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) \
-for (pos = (head)->next;\
-     tmp = (pos)->next, pos != ((struct sk_buff *)(head));\
-     pos = 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,
@@ -429,10 +428,7 @@ static inline void sctp_skb_list_tail(struct sk_buff_head *list,
        sctp_spin_lock_irqsave(&head->lock, flags);
        sctp_spin_lock(&list->lock);
 
-       list_splice((struct list_head *)list, (struct list_head *)head->prev);
-
-       head->qlen += list->qlen;
-       list->qlen = 0;
+       skb_queue_splice_tail_init(list, head);
 
        sctp_spin_unlock(&list->lock);
        sctp_spin_unlock_irqrestore(&head->lock, flags);
@@ -467,12 +463,12 @@ 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
-        * sk_stream_set_owner_r
+        * This mimics the behavior of skb_set_owner_r
         */
        sk->sk_forward_alloc -= event->rmem_len;
 }
@@ -480,7 +476,7 @@ static inline void sctp_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
 /* 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));
+       return (head->next != head) && (head->next == head->prev);
 }
 
 /* Generate a random jitter in the range of -50% ~ +50% of input RTO. */
@@ -505,15 +501,16 @@ static inline __s32 sctp_jitter(__u32 rto)
 }
 
 /* Break down data chunks at this point.  */
-static inline int sctp_frag_point(const struct sctp_sock *sp, int pmtu)
+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 (sp->user_frag)
-               frag = min_t(int, frag, sp->user_frag);
+       if (asoc->user_frag)
+               frag = min_t(int, frag, asoc->user_frag);
 
        frag = min_t(int, frag, SCTP_MAX_CHUNK_LEN);
 
@@ -537,7 +534,6 @@ _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 - sizeof(sctp_paramhdr_t) &&\
      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)))
@@ -548,7 +544,6 @@ _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 - sizeof(sctp_errhdr_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))))
@@ -565,7 +560,7 @@ for (pos = chunk->subh.fwdtsn_hdr->skip;\
 #define WORD_ROUND(s) (((s)+3)&~3)
 
 /* Make a new instance of type.  */
-#define t_new(type, flags)     (type *)kmalloc(sizeof(type), flags)
+#define t_new(type, flags)     (type *)kzalloc(sizeof(type), flags)
 
 /* Compare two timevals.  */
 #define tv_lt(s, t) \
@@ -607,7 +602,7 @@ static inline int ipver2af(__u8 ipver)
                return AF_INET6;
        default:
                return 0;
-       };
+       }
 }
 
 /* Convert from an address parameter type to an address family.  */
@@ -620,7 +615,7 @@ static inline int param_type2af(__be16 type)
                return AF_INET6;
        default:
                return 0;
-       };
+       }
 }
 
 /* Perform some sanity checks. */
@@ -637,13 +632,13 @@ static inline int sctp_sanity_check(void)
 /* This is the hash function for the SCTP port hash table. */
 static inline int sctp_phashfn(__u16 lport)
 {
-       return (lport & (sctp_port_hashsize - 1));
+       return lport & (sctp_port_hashsize - 1);
 }
 
 /* This is the hash function for the endpoint hash table. */
 static inline int sctp_ep_hashfn(__u16 lport)
 {
-       return (lport & (sctp_ep_hashsize - 1));
+       return lport & (sctp_ep_hashsize - 1);
 }
 
 /* This is the hash function for the association hash table. */
@@ -651,7 +646,7 @@ static inline int sctp_assoc_hashfn(__u16 lport, __u16 rport)
 {
        int h = (lport << 16) + rport;
        h ^= h>>8;
-       return (h & (sctp_assoc_hashsize - 1));
+       return h & (sctp_assoc_hashsize - 1);
 }
 
 /* This is the hash function for the association hash table.  This is
@@ -662,7 +657,7 @@ 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));
+       return h & (sctp_assoc_hashsize - 1);
 }
 
 #define sctp_for_each_hentry(epb, node, head) \
@@ -709,4 +704,17 @@ static inline void sctp_v4_map_v6(union sctp_addr *addr)
        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, 0)) {
+               dst_release(t->dst);
+               t->dst = NULL;
+       }
+
+       return t->dst;
+}
+
 #endif /* __net_sctp_h__ */