]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/netfilter/ipvs/ip_vs_core.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[net-next-2.6.git] / net / netfilter / ipvs / ip_vs_core.c
index 4f8ddba480110167674fa36f6854e53f673e8d68..0c043b6ce65e1b3148b249d4560f2e0174798b65 100644 (file)
@@ -40,6 +40,7 @@
 #include <net/udp.h>
 #include <net/icmp.h>                   /* for icmp_send */
 #include <net/route.h>
+#include <net/ip6_checksum.h>
 
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv4.h>
@@ -637,10 +638,12 @@ void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,
        }
 
        /* And finally the ICMP checksum */
-       icmph->icmp6_cksum = 0;
-       /* TODO IPv6: is this correct for ICMPv6? */
-       ip_vs_checksum_complete(skb, icmp_offset);
-       skb->ip_summed = CHECKSUM_UNNECESSARY;
+       icmph->icmp6_cksum = ~csum_ipv6_magic(&iph->saddr, &iph->daddr,
+                                             skb->len - icmp_offset,
+                                             IPPROTO_ICMPV6, 0);
+       skb->csum_start = skb_network_header(skb) - skb->head + icmp_offset;
+       skb->csum_offset = offsetof(struct icmp6hdr, icmp6_cksum);
+       skb->ip_summed = CHECKSUM_PARTIAL;
 
        if (inout)
                IP_VS_DBG_PKT(11, pp, skb, (void *)ciph - (void *)iph,
@@ -924,6 +927,7 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
 
        ip_vs_out_stats(cp, skb);
        ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp);
+       ip_vs_update_conntrack(skb, cp, 0);
        ip_vs_conn_put(cp);
 
        skb->ipvs_property = 1;
@@ -1380,8 +1384,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
        if (af == AF_INET && (ip_vs_sync_state & IP_VS_STATE_MASTER) &&
            cp->protocol == IPPROTO_SCTP) {
                if ((cp->state == IP_VS_SCTP_S_ESTABLISHED &&
-                       (atomic_read(&cp->in_pkts) %
-                        sysctl_ip_vs_sync_threshold[1]
+                       (pkts % sysctl_ip_vs_sync_threshold[1]
                         == sysctl_ip_vs_sync_threshold[0])) ||
                                (cp->old_state != cp->state &&
                                 ((cp->state == IP_VS_SCTP_S_CLOSED) ||
@@ -1392,7 +1395,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
                }
        }
 
-       if (af == AF_INET &&
+       /* Keep this block last: TCP and others with pp->num_states <= 1 */
+       else if (af == AF_INET &&
            (ip_vs_sync_state & IP_VS_STATE_MASTER) &&
            (((cp->protocol != IPPROTO_TCP ||
               cp->state == IP_VS_TCP_S_ESTABLISHED) &&