[SK_BUFF]: Introduce skb_network_header()
[linux-2.6.git] / net / ipv4 / ipvs / ip_vs_core.c
index 6dee039..5d54dd2 100644 (file)
@@ -536,9 +536,9 @@ static unsigned int ip_vs_post_routing(unsigned int hooknum,
        return NF_STOP;
 }
 
-u16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)
+__sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)
 {
-       return (u16) csum_fold(skb_checksum(skb, offset, skb->len - offset, 0));
+       return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0));
 }
 
 static inline struct sk_buff *
@@ -559,7 +559,8 @@ void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
 {
        struct iphdr *iph        = skb->nh.iph;
        unsigned int icmp_offset = iph->ihl*4;
-       struct icmphdr *icmph    = (struct icmphdr *)(skb->nh.raw + icmp_offset);
+       struct icmphdr *icmph    = (struct icmphdr *)(skb_network_header(skb) +
+                                                     icmp_offset);
        struct iphdr *ciph       = (struct iphdr *)(icmph + 1);
 
        if (inout) {
@@ -617,7 +618,7 @@ static int ip_vs_out_icmp(struct sk_buff **pskb, int *related)
        *related = 1;
 
        /* reassemble IP fragments */
-       if (skb->nh.iph->frag_off & __constant_htons(IP_MF|IP_OFFSET)) {
+       if (skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
                skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT);
                if (!skb)
                        return NF_STOLEN;
@@ -659,7 +660,7 @@ static int ip_vs_out_icmp(struct sk_buff **pskb, int *related)
                return NF_ACCEPT;
 
        /* Is the embedded protocol header present? */
-       if (unlikely(cih->frag_off & __constant_htons(IP_OFFSET) &&
+       if (unlikely(cih->frag_off & htons(IP_OFFSET) &&
                     pp->dont_defrag))
                return NF_ACCEPT;
 
@@ -755,7 +756,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
                return NF_ACCEPT;
 
        /* reassemble IP fragments */
-       if (unlikely(iph->frag_off & __constant_htons(IP_MF|IP_OFFSET) &&
+       if (unlikely(iph->frag_off & htons(IP_MF|IP_OFFSET) &&
                     !pp->dont_defrag)) {
                skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT);
                if (!skb)
@@ -813,6 +814,16 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
        skb->nh.iph->saddr = cp->vaddr;
        ip_send_check(skb->nh.iph);
 
+       /* For policy routing, packets originating from this
+        * machine itself may be routed differently to packets
+        * passing through.  We want this packet to be routed as
+        * if it came from this machine itself.  So re-compute
+        * the routing information.
+        */
+       if (ip_route_me_harder(pskb, RTN_LOCAL) != 0)
+               goto drop;
+       skb = *pskb;
+
        IP_VS_DBG_PKT(10, pp, skb, 0, "After SNAT");
 
        ip_vs_out_stats(cp, skb);
@@ -837,7 +848,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
  *     forward to the right destination host if relevant.
  *     Currently handles error types - unreachable, quench, ttl exceeded.
  */
-static int 
+static int
 ip_vs_in_icmp(struct sk_buff **pskb, int *related, unsigned int hooknum)
 {
        struct sk_buff *skb = *pskb;
@@ -851,9 +862,9 @@ ip_vs_in_icmp(struct sk_buff **pskb, int *related, unsigned int hooknum)
        *related = 1;
 
        /* reassemble IP fragments */
-       if (skb->nh.iph->frag_off & __constant_htons(IP_MF|IP_OFFSET)) {
+       if (skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
                skb = ip_vs_gather_frags(skb,
-                                        hooknum == NF_IP_LOCAL_IN ?
+                                        hooknum == NF_IP_LOCAL_IN ?
                                         IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD);
                if (!skb)
                        return NF_STOLEN;
@@ -895,7 +906,7 @@ ip_vs_in_icmp(struct sk_buff **pskb, int *related, unsigned int hooknum)
                return NF_ACCEPT;
 
        /* Is the embedded protocol header present? */
-       if (unlikely(cih->frag_off & __constant_htons(IP_OFFSET) &&
+       if (unlikely(cih->frag_off & htons(IP_OFFSET) &&
                     pp->dont_defrag))
                return NF_ACCEPT;