[SK_BUFF]: Introduce tcp_hdr(), remove skb->h.th
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / include / net / tcp.h
index 246916c2321e91e1ec7e15eb3a1f9ceeda350c2b..af9273204cfd446857d5282b52a8ce733f03da79 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/percpu.h>
 #include <linux/skbuff.h>
 #include <linux/dmaengine.h>
+#include <linux/crypto.h>
 
 #include <net/inet_connection_sock.h>
 #include <net/inet_timewait_sock.h>
@@ -161,6 +162,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
 #define TCPOPT_SACK_PERM        4       /* SACK Permitted */
 #define TCPOPT_SACK             5       /* SACK Block */
 #define TCPOPT_TIMESTAMP       8       /* Better RTT estimations/PAWS */
+#define TCPOPT_MD5SIG          19      /* MD5 Signature (RFC2385) */
 
 /*
  *     TCP option lengths
@@ -170,6 +172,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
 #define TCPOLEN_WINDOW         3
 #define TCPOLEN_SACK_PERM      2
 #define TCPOLEN_TIMESTAMP      10
+#define TCPOLEN_MD5SIG         18
 
 /* But this is what stacks really send out. */
 #define TCPOLEN_TSTAMP_ALIGNED         12
@@ -178,6 +181,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
 #define TCPOLEN_SACK_BASE              2
 #define TCPOLEN_SACK_BASE_ALIGNED      4
 #define TCPOLEN_SACK_PERBLOCK          8
+#define TCPOLEN_MD5SIG_ALIGNED         20
 
 /* Flags in tp->nonagle */
 #define TCP_NAGLE_OFF          1       /* Nagle's algo is disabled */
@@ -216,6 +220,7 @@ extern int sysctl_tcp_app_win;
 extern int sysctl_tcp_adv_win_scale;
 extern int sysctl_tcp_tw_reuse;
 extern int sysctl_tcp_frto;
+extern int sysctl_tcp_frto_response;
 extern int sysctl_tcp_low_latency;
 extern int sysctl_tcp_dma_copybreak;
 extern int sysctl_tcp_nometrics_save;
@@ -226,6 +231,7 @@ extern int sysctl_tcp_mtu_probing;
 extern int sysctl_tcp_base_mss;
 extern int sysctl_tcp_workaround_signed_windows;
 extern int sysctl_tcp_slow_start_after_idle;
+extern int sysctl_tcp_max_ssthresh;
 
 extern atomic_t tcp_memory_allocated;
 extern atomic_t tcp_sockets_allocated;
@@ -240,12 +246,7 @@ static inline int before(__u32 seq1, __u32 seq2)
 {
         return (__s32)(seq1-seq2) < 0;
 }
-
-static inline int after(__u32 seq1, __u32 seq2)
-{
-       return (__s32)(seq2-seq1) < 0;
-}
-
+#define after(seq2, seq1)      before(seq1, seq2)
 
 /* is s2<=s1<=s3 ? */
 static inline int between(__u32 seq1, __u32 seq2, __u32 seq3)
@@ -299,6 +300,8 @@ extern void                 tcp_cleanup_rbuf(struct sock *sk, int copied);
 extern int                     tcp_twsk_unique(struct sock *sk,
                                                struct sock *sktw, void *twp);
 
+extern void                    tcp_twsk_destructor(struct sock *sk);
+
 static inline void tcp_dec_quickack_mode(struct sock *sk,
                                         const unsigned int pkts)
 {
@@ -340,6 +343,7 @@ extern struct sock *                tcp_check_req(struct sock *sk,struct sk_buff *skb,
 extern int                     tcp_child_process(struct sock *parent,
                                                  struct sock *child,
                                                  struct sk_buff *skb);
+extern int                     tcp_use_frto(struct sock *sk);
 extern void                    tcp_enter_frto(struct sock *sk);
 extern void                    tcp_enter_loss(struct sock *sk, int how);
 extern void                    tcp_clear_retrans(struct tcp_sock *tp);
@@ -620,8 +624,12 @@ enum tcp_ca_event {
  * Interface for adding new TCP congestion control handlers
  */
 #define TCP_CA_NAME_MAX        16
+#define TCP_CA_MAX     128
+#define TCP_CA_BUF_MAX (TCP_CA_NAME_MAX*TCP_CA_MAX)
+
 struct tcp_congestion_ops {
        struct list_head        list;
+       int     non_restricted;
 
        /* initialize private data (optional) */
        void (*init)(struct sock *sk);
@@ -659,6 +667,9 @@ extern void tcp_init_congestion_control(struct sock *sk);
 extern void tcp_cleanup_congestion_control(struct sock *sk);
 extern int tcp_set_default_congestion_control(const char *name);
 extern void tcp_get_default_congestion_control(char *name);
+extern void tcp_get_available_congestion_control(char *buf, size_t len);
+extern void tcp_get_allowed_congestion_control(char *buf, size_t len);
+extern int tcp_set_allowed_congestion_control(char *allowed);
 extern int tcp_set_congestion_control(struct sock *sk, const char *name);
 extern void tcp_slow_start(struct tcp_sock *tp);
 
@@ -728,7 +739,7 @@ static inline void tcp_sync_left_out(struct tcp_sock *tp)
        tp->left_out = tp->sacked_out + tp->lost_out;
 }
 
-extern void tcp_enter_cwr(struct sock *sk);
+extern void tcp_enter_cwr(struct sock *sk, const int set_ssthresh);
 extern __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst);
 
 /* Slow start with delack produces 3 packets of burst, so that
@@ -794,14 +805,13 @@ static inline void tcp_update_wl(struct tcp_sock *tp, u32 ack, u32 seq)
 /*
  * Calculate(/check) TCP checksum
  */
-static inline u16 tcp_v4_check(struct tcphdr *th, int len,
-                              unsigned long saddr, unsigned long daddr, 
-                              unsigned long base)
+static inline __sum16 tcp_v4_check(int len, __be32 saddr,
+                                  __be32 daddr, __wsum base)
 {
        return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base);
 }
 
-static inline int __tcp_checksum_complete(struct sk_buff *skb)
+static inline __sum16 __tcp_checksum_complete(struct sk_buff *skb)
 {
        return __skb_checksum_complete(skb);
 }
@@ -974,7 +984,7 @@ static inline void tcp_openreq_init(struct request_sock *req,
        ireq->wscale_ok = rx_opt->wscale_ok;
        ireq->acked = 0;
        ireq->ecn_ok = 0;
-       ireq->rmt_port = skb->h.th->source;
+       ireq->rmt_port = tcp_hdr(skb)->source;
 }
 
 extern void tcp_enter_memory_pressure(void);
@@ -1004,7 +1014,7 @@ static inline int tcp_paws_check(const struct tcp_options_received *rx_opt, int
 {
        if ((s32)(rx_opt->rcv_tsval - rx_opt->ts_recent) >= 0)
                return 0;
-       if (xtime.tv_sec >= rx_opt->ts_recent_stamp + TCP_PAWS_24DAYS)
+       if (get_seconds() >= rx_opt->ts_recent_stamp + TCP_PAWS_24DAYS)
                return 0;
 
        /* RST segments are not recommended to carry timestamp,
@@ -1019,26 +1029,13 @@ static inline int tcp_paws_check(const struct tcp_options_received *rx_opt, int
 
           However, we can relax time bounds for RST segments to MSL.
         */
-       if (rst && xtime.tv_sec >= rx_opt->ts_recent_stamp + TCP_PAWS_MSL)
+       if (rst && get_seconds() >= rx_opt->ts_recent_stamp + TCP_PAWS_MSL)
                return 0;
        return 1;
 }
 
 #define TCP_CHECK_TIMER(sk) do { } while (0)
 
-static inline int tcp_use_frto(const struct sock *sk)
-{
-       const struct tcp_sock *tp = tcp_sk(sk);
-       
-       /* F-RTO must be activated in sysctl and there must be some
-        * unsent new data, and the advertised window should allow
-        * sending it.
-        */
-       return (sysctl_tcp_frto && sk->sk_send_head &&
-               !after(TCP_SKB_CB(sk->sk_send_head)->end_seq,
-                      tp->snd_una + tp->snd_wnd));
-}
-
 static inline void tcp_mib_init(void)
 {
        /* See RFC 2012 */
@@ -1057,6 +1054,228 @@ static inline void clear_all_retrans_hints(struct tcp_sock *tp){
        tp->fastpath_skb_hint = NULL;
 }
 
+/* MD5 Signature */
+struct crypto_hash;
+
+/* - key database */
+struct tcp_md5sig_key {
+       u8                      *key;
+       u8                      keylen;
+};
+
+struct tcp4_md5sig_key {
+       u8                      *key;
+       u16                     keylen;
+       __be32                  addr;
+};
+
+struct tcp6_md5sig_key {
+       u8                      *key;
+       u16                     keylen;
+#if 0
+       u32                     scope_id;       /* XXX */
+#endif
+       struct in6_addr         addr;
+};
+
+/* - sock block */
+struct tcp_md5sig_info {
+       struct tcp4_md5sig_key  *keys4;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+       struct tcp6_md5sig_key  *keys6;
+       u32                     entries6;
+       u32                     alloced6;
+#endif
+       u32                     entries4;
+       u32                     alloced4;
+};
+
+/* - pseudo header */
+struct tcp4_pseudohdr {
+       __be32          saddr;
+       __be32          daddr;
+       __u8            pad;
+       __u8            protocol;
+       __be16          len;
+};
+
+struct tcp6_pseudohdr {
+       struct in6_addr saddr;
+       struct in6_addr daddr;
+       __be32          len;
+       __be32          protocol;       /* including padding */
+};
+
+union tcp_md5sum_block {
+       struct tcp4_pseudohdr ip4;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+       struct tcp6_pseudohdr ip6;
+#endif
+};
+
+/* - pool: digest algorithm, hash description and scratch buffer */
+struct tcp_md5sig_pool {
+       struct hash_desc        md5_desc;
+       union tcp_md5sum_block  md5_blk;
+};
+
+#define TCP_MD5SIG_MAXKEYS     (~(u32)0)       /* really?! */
+
+/* - functions */
+extern int                     tcp_v4_calc_md5_hash(char *md5_hash,
+                                                    struct tcp_md5sig_key *key,
+                                                    struct sock *sk,
+                                                    struct dst_entry *dst,
+                                                    struct request_sock *req,
+                                                    struct tcphdr *th,
+                                                    int protocol, int tcplen);
+extern struct tcp_md5sig_key   *tcp_v4_md5_lookup(struct sock *sk,
+                                                  struct sock *addr_sk);
+
+extern int                     tcp_v4_md5_do_add(struct sock *sk,
+                                                 __be32 addr,
+                                                 u8 *newkey,
+                                                 u8 newkeylen);
+
+extern int                     tcp_v4_md5_do_del(struct sock *sk,
+                                                 __be32 addr);
+
+extern struct tcp_md5sig_pool  **tcp_alloc_md5sig_pool(void);
+extern void                    tcp_free_md5sig_pool(void);
+
+extern struct tcp_md5sig_pool  *__tcp_get_md5sig_pool(int cpu);
+extern void                    __tcp_put_md5sig_pool(void);
+
+static inline
+struct tcp_md5sig_pool         *tcp_get_md5sig_pool(void)
+{
+       int cpu = get_cpu();
+       struct tcp_md5sig_pool *ret = __tcp_get_md5sig_pool(cpu);
+       if (!ret)
+               put_cpu();
+       return ret;
+}
+
+static inline void             tcp_put_md5sig_pool(void)
+{
+       __tcp_put_md5sig_pool();
+       put_cpu();
+}
+
+/* write queue abstraction */
+static inline void tcp_write_queue_purge(struct sock *sk)
+{
+       struct sk_buff *skb;
+
+       while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
+               sk_stream_free_skb(sk, skb);
+       sk_stream_mem_reclaim(sk);
+}
+
+static inline struct sk_buff *tcp_write_queue_head(struct sock *sk)
+{
+       struct sk_buff *skb = sk->sk_write_queue.next;
+       if (skb == (struct sk_buff *) &sk->sk_write_queue)
+               return NULL;
+       return skb;
+}
+
+static inline struct sk_buff *tcp_write_queue_tail(struct sock *sk)
+{
+       struct sk_buff *skb = sk->sk_write_queue.prev;
+       if (skb == (struct sk_buff *) &sk->sk_write_queue)
+               return NULL;
+       return skb;
+}
+
+static inline struct sk_buff *tcp_write_queue_next(struct sock *sk, struct sk_buff *skb)
+{
+       return skb->next;
+}
+
+#define tcp_for_write_queue(skb, sk)                                   \
+               for (skb = (sk)->sk_write_queue.next;                   \
+                    (skb != (struct sk_buff *)&(sk)->sk_write_queue);  \
+                    skb = skb->next)
+
+#define tcp_for_write_queue_from(skb, sk)                              \
+               for (; (skb != (struct sk_buff *)&(sk)->sk_write_queue);\
+                    skb = skb->next)
+
+static inline struct sk_buff *tcp_send_head(struct sock *sk)
+{
+       return sk->sk_send_head;
+}
+
+static inline void tcp_advance_send_head(struct sock *sk, struct sk_buff *skb)
+{
+       sk->sk_send_head = skb->next;
+       if (sk->sk_send_head == (struct sk_buff *)&sk->sk_write_queue)
+               sk->sk_send_head = NULL;
+}
+
+static inline void tcp_check_send_head(struct sock *sk, struct sk_buff *skb_unlinked)
+{
+       if (sk->sk_send_head == skb_unlinked)
+               sk->sk_send_head = NULL;
+}
+
+static inline void tcp_init_send_head(struct sock *sk)
+{
+       sk->sk_send_head = NULL;
+}
+
+static inline void __tcp_add_write_queue_tail(struct sock *sk, struct sk_buff *skb)
+{
+       __skb_queue_tail(&sk->sk_write_queue, skb);
+}
+
+static inline void tcp_add_write_queue_tail(struct sock *sk, struct sk_buff *skb)
+{
+       __tcp_add_write_queue_tail(sk, skb);
+
+       /* Queue it, remembering where we must start sending. */
+       if (sk->sk_send_head == NULL)
+               sk->sk_send_head = skb;
+}
+
+static inline void __tcp_add_write_queue_head(struct sock *sk, struct sk_buff *skb)
+{
+       __skb_queue_head(&sk->sk_write_queue, skb);
+}
+
+/* Insert buff after skb on the write queue of sk.  */
+static inline void tcp_insert_write_queue_after(struct sk_buff *skb,
+                                               struct sk_buff *buff,
+                                               struct sock *sk)
+{
+       __skb_append(skb, buff, &sk->sk_write_queue);
+}
+
+/* Insert skb between prev and next on the write queue of sk.  */
+static inline void tcp_insert_write_queue_before(struct sk_buff *new,
+                                                 struct sk_buff *skb,
+                                                 struct sock *sk)
+{
+       __skb_insert(new, skb->prev, skb, &sk->sk_write_queue);
+}
+
+static inline void tcp_unlink_write_queue(struct sk_buff *skb, struct sock *sk)
+{
+       __skb_unlink(skb, &sk->sk_write_queue);
+}
+
+static inline int tcp_skb_is_last(const struct sock *sk,
+                                 const struct sk_buff *skb)
+{
+       return skb->next == (struct sk_buff *)&sk->sk_write_queue;
+}
+
+static inline int tcp_write_queue_empty(struct sock *sk)
+{
+       return skb_queue_empty(&sk->sk_write_queue);
+}
+
 /* /proc */
 enum tcp_seq_states {
        TCP_SEQ_STATE_LISTENING,
@@ -1096,6 +1315,35 @@ extern int  tcp4_proc_init(void);
 extern void tcp4_proc_exit(void);
 #endif
 
+/* TCP af-specific functions */
+struct tcp_sock_af_ops {
+#ifdef CONFIG_TCP_MD5SIG
+       struct tcp_md5sig_key   *(*md5_lookup) (struct sock *sk,
+                                               struct sock *addr_sk);
+       int                     (*calc_md5_hash) (char *location,
+                                                 struct tcp_md5sig_key *md5,
+                                                 struct sock *sk,
+                                                 struct dst_entry *dst,
+                                                 struct request_sock *req,
+                                                 struct tcphdr *th,
+                                                 int protocol, int len);
+       int                     (*md5_add) (struct sock *sk,
+                                           struct sock *addr_sk,
+                                           u8 *newkey,
+                                           u8 len);
+       int                     (*md5_parse) (struct sock *sk,
+                                             char __user *optval,
+                                             int optlen);
+#endif
+};
+
+struct tcp_request_sock_ops {
+#ifdef CONFIG_TCP_MD5SIG
+       struct tcp_md5sig_key   *(*md5_lookup) (struct sock *sk,
+                                               struct request_sock *req);
+#endif
+};
+
 extern void tcp_v4_init(struct net_proto_family *ops);
 extern void tcp_init(void);