Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / net / ipv4 / ipvs / ip_vs_proto_tcp.c
index 2f00e91..bc28b11 100644 (file)
@@ -29,19 +29,20 @@ static struct ip_vs_conn *
 tcp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
                const struct iphdr *iph, unsigned int proto_off, int inverse)
 {
-       __u16 ports[2];
+       __u16 _ports[2], *pptr;
 
-       if (skb_copy_bits(skb, proto_off, ports, sizeof(ports)) < 0)
+       pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports);
+       if (pptr == NULL)
                return NULL;
 
        if (likely(!inverse)) {
                return ip_vs_conn_in_get(iph->protocol,
-                                        iph->saddr, ports[0],
-                                        iph->daddr, ports[1]);
+                                        iph->saddr, pptr[0],
+                                        iph->daddr, pptr[1]);
        } else {
                return ip_vs_conn_in_get(iph->protocol,
-                                        iph->daddr, ports[1],
-                                        iph->saddr, ports[0]);
+                                        iph->daddr, pptr[1],
+                                        iph->saddr, pptr[0]);
        }
 }
 
@@ -49,19 +50,20 @@ static struct ip_vs_conn *
 tcp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
                 const struct iphdr *iph, unsigned int proto_off, int inverse)
 {
-       __u16 ports[2];
+       __u16 _ports[2], *pptr;
 
-       if (skb_copy_bits(skb, proto_off, ports, sizeof(ports)) < 0)
+       pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports);
+       if (pptr == NULL)
                return NULL;
 
        if (likely(!inverse)) {
                return ip_vs_conn_out_get(iph->protocol,
-                                         iph->saddr, ports[0],
-                                         iph->daddr, ports[1]);
+                                         iph->saddr, pptr[0],
+                                         iph->daddr, pptr[1]);
        } else {
                return ip_vs_conn_out_get(iph->protocol,
-                                         iph->daddr, ports[1],
-                                         iph->saddr, ports[0]);
+                                         iph->daddr, pptr[1],
+                                         iph->saddr, pptr[0]);
        }
 }
 
@@ -72,16 +74,18 @@ tcp_conn_schedule(struct sk_buff *skb,
                  int *verdict, struct ip_vs_conn **cpp)
 {
        struct ip_vs_service *svc;
-       struct tcphdr tcph;
+       struct tcphdr _tcph, *th;
 
-       if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0) {
+       th = skb_header_pointer(skb, skb->nh.iph->ihl*4,
+                               sizeof(_tcph), &_tcph);
+       if (th == NULL) {
                *verdict = NF_DROP;
                return 0;
        }
 
-       if (tcph.syn &&
+       if (th->syn &&
            (svc = ip_vs_service_get(skb->nfmark, skb->nh.iph->protocol,
-                                    skb->nh.iph->daddr, tcph.dest))) {
+                                    skb->nh.iph->daddr, th->dest))) {
                if (ip_vs_todrop()) {
                        /*
                         * It seems that we are very loaded.
@@ -247,7 +251,7 @@ tcp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp)
 #define TCP_DIR_OUTPUT         4
 #define TCP_DIR_INPUT_ONLY     8
 
-static int tcp_state_off[IP_VS_DIR_LAST] = {
+static const int tcp_state_off[IP_VS_DIR_LAST] = {
        [IP_VS_DIR_INPUT]               =       TCP_DIR_INPUT,
        [IP_VS_DIR_OUTPUT]              =       TCP_DIR_OUTPUT,
        [IP_VS_DIR_INPUT_ONLY]          =       TCP_DIR_INPUT_ONLY,
@@ -271,28 +275,6 @@ static int tcp_timeouts[IP_VS_TCP_S_LAST+1] = {
        [IP_VS_TCP_S_LAST]              =       2*HZ,
 };
 
-
-#if 0
-
-/* FIXME: This is going to die */
-
-static int tcp_timeouts_dos[IP_VS_TCP_S_LAST+1] = {
-       [IP_VS_TCP_S_NONE]              =       2*HZ,
-       [IP_VS_TCP_S_ESTABLISHED]       =       8*60*HZ,
-       [IP_VS_TCP_S_SYN_SENT]          =       60*HZ,
-       [IP_VS_TCP_S_SYN_RECV]          =       10*HZ,
-       [IP_VS_TCP_S_FIN_WAIT]          =       60*HZ,
-       [IP_VS_TCP_S_TIME_WAIT]         =       60*HZ,
-       [IP_VS_TCP_S_CLOSE]             =       10*HZ,
-       [IP_VS_TCP_S_CLOSE_WAIT]        =       60*HZ,
-       [IP_VS_TCP_S_LAST_ACK]          =       30*HZ,
-       [IP_VS_TCP_S_LISTEN]            =       2*60*HZ,
-       [IP_VS_TCP_S_SYNACK]            =       100*HZ,
-       [IP_VS_TCP_S_LAST]              =       2*HZ,
-};
-
-#endif
-
 static char * tcp_state_name_table[IP_VS_TCP_S_LAST+1] = {
        [IP_VS_TCP_S_NONE]              =       "NONE",
        [IP_VS_TCP_S_ESTABLISHED]       =       "ESTABLISHED",
@@ -444,7 +426,7 @@ set_tcp_state(struct ip_vs_protocol *pp, struct ip_vs_conn *cp,
                struct ip_vs_dest *dest = cp->dest;
 
                IP_VS_DBG(8, "%s %s [%c%c%c%c] %u.%u.%u.%u:%d->"
-                         "%u.%u.%u.%u:%d state: %s->%s cnt:%d\n",
+                         "%u.%u.%u.%u:%d state: %s->%s conn->refcnt:%d\n",
                          pp->name,
                          (state_off==TCP_DIR_OUTPUT)?"output ":"input ",
                          th->syn? 'S' : '.',
@@ -483,13 +465,15 @@ tcp_state_transition(struct ip_vs_conn *cp, int direction,
                     const struct sk_buff *skb,
                     struct ip_vs_protocol *pp)
 {
-       struct tcphdr tcph;
+       struct tcphdr _tcph, *th;
 
-       if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0)
+       th = skb_header_pointer(skb, skb->nh.iph->ihl*4,
+                               sizeof(_tcph), &_tcph);
+       if (th == NULL)
                return 0;
 
        spin_lock(&cp->lock);
-       set_tcp_state(pp, cp, direction, &tcph);
+       set_tcp_state(pp, cp, direction, th);
        spin_unlock(&cp->lock);
 
        return 1;
@@ -504,7 +488,7 @@ tcp_state_transition(struct ip_vs_conn *cp, int direction,
 #define        TCP_APP_TAB_MASK        (TCP_APP_TAB_SIZE - 1)
 
 static struct list_head tcp_apps[TCP_APP_TAB_SIZE];
-static spinlock_t tcp_app_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(tcp_app_lock);
 
 static inline __u16 tcp_app_hashkey(__u16 port)
 {
@@ -598,14 +582,14 @@ void ip_vs_tcp_conn_listen(struct ip_vs_conn *cp)
 }
 
 
-static void tcp_init(struct ip_vs_protocol *pp)
+static void ip_vs_tcp_init(struct ip_vs_protocol *pp)
 {
        IP_VS_INIT_HASH_TABLE(tcp_apps);
        pp->timeout_table = tcp_timeouts;
 }
 
 
-static void tcp_exit(struct ip_vs_protocol *pp)
+static void ip_vs_tcp_exit(struct ip_vs_protocol *pp)
 {
 }
 
@@ -615,8 +599,8 @@ struct ip_vs_protocol ip_vs_protocol_tcp = {
        .protocol =             IPPROTO_TCP,
        .dont_defrag =          0,
        .appcnt =               ATOMIC_INIT(0),
-       .init =                 tcp_init,
-       .exit =                 tcp_exit,
+       .init =                 ip_vs_tcp_init,
+       .exit =                 ip_vs_tcp_exit,
        .register_app =         tcp_register_app,
        .unregister_app =       tcp_unregister_app,
        .conn_schedule =        tcp_conn_schedule,