This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / net / ipv6 / tcp_ipv6.c
index 2949cd1..4a198fb 100644 (file)
@@ -51,6 +51,7 @@
 #include <net/transp_v6.h>
 #include <net/addrconf.h>
 #include <net/ip6_route.h>
+#include <net/ip6_checksum.h>
 #include <net/inet_ecn.h>
 #include <net/protocol.h>
 #include <net/xfrm.h>
@@ -479,7 +480,7 @@ static int tcp_v6_check_established(struct sock *sk)
 
        /* And established part... */
        sk_for_each(sk2, node, &head->chain) {
-               if(TCP_IPV6_MATCH(sk, saddr, daddr, ports, dif))
+               if(TCP_IPV6_MATCH(sk2, saddr, daddr, ports, dif))
                        goto not_unique;
        }
 
@@ -536,8 +537,7 @@ static int tcp_v6_hash_connect(struct sock *sk)
 
 static __inline__ int tcp_v6_iif(struct sk_buff *skb)
 {
-       struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
-       return opt->iif;
+       return IP6CB(skb)->iif;
 }
 
 static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, 
@@ -879,7 +879,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct open_request *req,
                    np->rxopt.bits.srcrt == 2 &&
                    req->af.v6_req.pktopts) {
                        struct sk_buff *pktopts = req->af.v6_req.pktopts;
-                       struct inet6_skb_parm *rxopt = (struct inet6_skb_parm *)pktopts->cb;
+                       struct inet6_skb_parm *rxopt = IP6CB(pktopts);
                        if (rxopt->srcrt)
                                opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(pktopts->nh.raw + rxopt->srcrt));
                }
@@ -932,7 +932,7 @@ static struct or_calltable or_ipv6 = {
 static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
 {
        struct ipv6_pinfo *np = inet6_sk(sk);
-       struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
+       struct inet6_skb_parm *opt = IP6CB(skb);
 
        if (np->rxopt.all) {
                if ((opt->hop && np->rxopt.bits.hopopts) ||
@@ -1154,7 +1154,11 @@ static void tcp_v6_synq_add(struct sock *sk, struct open_request *req)
        lopt->syn_table[h] = req;
        write_unlock(&tp->syn_wait_lock);
 
+#ifdef CONFIG_ACCEPT_QUEUES
+       tcp_synq_added(sk, req);
+#else
        tcp_synq_added(sk);
+#endif
 }
 
 
@@ -1167,6 +1171,9 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
        struct tcp_opt tmptp, *tp = tcp_sk(sk);
        struct open_request *req = NULL;
        __u32 isn = TCP_SKB_CB(skb)->when;
+#ifdef CONFIG_ACCEPT_QUEUES
+       int class = 0;
+#endif
 
        if (skb->protocol == htons(ETH_P_IP))
                return tcp_v4_conn_request(sk, skb);
@@ -1174,6 +1181,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
        if (!ipv6_unicast_destination(skb))
                goto drop; 
 
+
        /*
         *      There are no SYN attacks on IPv6, yet...        
         */
@@ -1183,9 +1191,27 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
                goto drop;              
        }
 
-       if (tcp_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
+#ifdef CONFIG_ACCEPT_QUEUES
+        class = (skb->nfmark <= 0) ? 0 :
+                       ((skb->nfmark >= NUM_ACCEPT_QUEUES) ? 0: skb->nfmark);
+        /*
+        * Accept only if the class has shares set or if the default class
+        * i.e. class 0 has shares
+        */
+        if (!(tcp_sk(sk)->acceptq[class].aq_ratio)) {
+               if (tcp_sk(sk)->acceptq[0].aq_ratio) 
+                       class = 0; 
+               else 
+                       goto drop;
+       }
+
+       if (sk_acceptq_is_full(sk, class) && tcp_synq_young(sk, class) > 1)
+#else
+       if (sk_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
+#endif
                goto drop;
 
+
        req = tcp_openreq_alloc();
        if (req == NULL)
                goto drop;
@@ -1198,7 +1224,10 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
 
        tmptp.tstamp_ok = tmptp.saw_tstamp;
        tcp_openreq_init(req, &tmptp, skb);
-
+#ifdef CONFIG_ACCEPT_QUEUES
+       req->acceptq_class = class;
+       req->acceptq_time_stamp = jiffies;
+#endif
        req->class = &or_ipv6;
        ipv6_addr_copy(&req->af.v6_req.rmt_addr, &skb->nh.ipv6h->saddr);
        ipv6_addr_copy(&req->af.v6_req.loc_addr, &skb->nh.ipv6h->daddr);
@@ -1300,12 +1329,16 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
 
        opt = np->opt;
 
-       if (tcp_acceptq_is_full(sk))
+#ifdef CONFIG_ACCEPT_QUEUES
+       if (sk_acceptq_is_full(sk, req->acceptq_class))
+#else
+       if (sk_acceptq_is_full(sk))
+#endif
                goto out_overflow;
 
        if (np->rxopt.bits.srcrt == 2 &&
            opt == NULL && req->af.v6_req.pktopts) {
-               struct inet6_skb_parm *rxopt = (struct inet6_skb_parm *)req->af.v6_req.pktopts->cb;
+               struct inet6_skb_parm *rxopt = IP6CB(req->af.v6_req.pktopts);
                if (rxopt->srcrt)
                        opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(req->af.v6_req.pktopts->nh.raw+rxopt->srcrt));
        }
@@ -1879,7 +1912,7 @@ static int tcp_v6_init_sock(struct sock *sk)
 
        tp->af_specific = &ipv6_specific;
 
-       sk->sk_write_space = tcp_write_space;
+       sk->sk_write_space = sk_stream_write_space;
        sk->sk_use_write_queue = 1;
 
        sk->sk_sndbuf = sysctl_tcp_wmem[1];
@@ -1892,30 +1925,9 @@ static int tcp_v6_init_sock(struct sock *sk)
 
 static int tcp_v6_destroy_sock(struct sock *sk)
 {
-       struct tcp_opt *tp = tcp_sk(sk);
-       struct inet_opt *inet = inet_sk(sk);
-
-       tcp_clear_xmit_timers(sk);
-
-       /* Cleanup up the write buffer. */
-       tcp_writequeue_purge(sk);
-
-       /* Cleans up our, hopefully empty, out_of_order_queue. */
-       __skb_queue_purge(&tp->out_of_order_queue);
-
-       /* Clean prequeue, it must be empty really */
-       __skb_queue_purge(&tp->ucopy.prequeue);
-
-       /* Clean up a referenced TCP bind bucket. */
-       if (tcp_sk(sk)->bind_hash)
-               tcp_put_port(sk);
-
-       /* If sendmsg cached page exists, toss it. */
-       if (inet->sndmsg_page != NULL)
-               __free_page(inet->sndmsg_page);
-
-       atomic_dec(&tcp_sockets_allocated);
+       extern int tcp_v4_destroy_sock(struct sock *sk);
 
+       tcp_v4_destroy_sock(sk);
        return inet6_destroy_sock(sk);
 }
 
@@ -1933,7 +1945,7 @@ static void get_openreq6(struct seq_file *seq,
        dest = &req->af.v6_req.rmt_addr;
        seq_printf(seq,
                   "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
-                  "%02X %08X:%08X %02X:%08X %08X %5d %8d %d %d %p\n",
+                  "%02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p\n",
                   i,
                   src->s6_addr32[0], src->s6_addr32[1],
                   src->s6_addr32[2], src->s6_addr32[3],
@@ -2019,7 +2031,7 @@ static void get_timewait6_sock(struct seq_file *seq,
 
        seq_printf(seq,
                   "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
-                  "%02X %08X:%08X %02X:%08X %08X %5d %8d %d %d %p\n",
+                  "%02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p\n",
                   i,
                   src->s6_addr32[0], src->s6_addr32[1],
                   src->s6_addr32[2], src->s6_addr32[3], srcp,
@@ -2083,23 +2095,31 @@ void tcp6_proc_exit(void)
 #endif
 
 struct proto tcpv6_prot = {
-       .name           =       "TCPv6",
-       .close          =       tcp_close,
-       .connect        =       tcp_v6_connect,
-       .disconnect     =       tcp_disconnect,
-       .accept         =       tcp_accept,
-       .ioctl          =       tcp_ioctl,
-       .init           =       tcp_v6_init_sock,
-       .destroy        =       tcp_v6_destroy_sock,
-       .shutdown       =       tcp_shutdown,
-       .setsockopt     =       tcp_setsockopt,
-       .getsockopt     =       tcp_getsockopt,
-       .sendmsg        =       tcp_sendmsg,
-       .recvmsg        =       tcp_recvmsg,
-       .backlog_rcv    =       tcp_v6_do_rcv,
-       .hash           =       tcp_v6_hash,
-       .unhash         =       tcp_unhash,
-       .get_port       =       tcp_v6_get_port,
+       .name                   = "TCPv6",
+       .close                  = tcp_close,
+       .connect                = tcp_v6_connect,
+       .disconnect             = tcp_disconnect,
+       .accept                 = tcp_accept,
+       .ioctl                  = tcp_ioctl,
+       .init                   = tcp_v6_init_sock,
+       .destroy                = tcp_v6_destroy_sock,
+       .shutdown               = tcp_shutdown,
+       .setsockopt             = tcp_setsockopt,
+       .getsockopt             = tcp_getsockopt,
+       .sendmsg                = tcp_sendmsg,
+       .recvmsg                = tcp_recvmsg,
+       .backlog_rcv            = tcp_v6_do_rcv,
+       .hash                   = tcp_v6_hash,
+       .unhash                 = tcp_unhash,
+       .get_port               = tcp_v6_get_port,
+       .enter_memory_pressure  = tcp_enter_memory_pressure,
+       .sockets_allocated      = &tcp_sockets_allocated,
+       .memory_allocated       = &tcp_memory_allocated,
+       .memory_pressure        = &tcp_memory_pressure,
+       .sysctl_mem             = sysctl_tcp_mem,
+       .sysctl_wmem            = sysctl_tcp_wmem,
+       .sysctl_rmem            = sysctl_tcp_rmem,
+       .max_header             = MAX_TCP_HEADER,
 };
 
 static struct inet6_protocol tcpv6_protocol = {