Commit:     35fc92a9deee0da6e35fdc3150bb134e58f2fd63
Parent:     2d771cd86d4c3af26f34a7bcdc1b87696824cad9
Author:     Herbert Xu <[EMAIL PROTECTED]>
AuthorDate: Mon Mar 26 23:22:20 2007 -0700
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Wed Apr 25 22:28:16 2007 -0700

    [NET]: Allow forwarding of ip_summed except CHECKSUM_COMPLETE
    Right now Xen has a horrible hack that lets it forward packets with
    partial checksums.  One of the reasons that CHECKSUM_PARTIAL and
    CHECKSUM_COMPLETE were added is so that we can get rid of this hack
    (where it creates two extra bits in the skbuff to essentially mirror
    ip_summed without being destroyed by the forwarding code).
    I had forgotten that I've already gone through all the deivce drivers
    last time around to make sure that they're looking at ip_summed ==
    CHECKSUM_PARTIAL rather than ip_summed != 0 on transmit.  In any case,
    I've now done that again so it should definitely be safe.
    Unfortunately nobody has yet added any code to update CHECKSUM_COMPLETE
    values on forward so we I'm setting that to CHECKSUM_NONE.  This should
    be safe to remove for bridging but I'd like to check that code path
    So here is the patch that lets us get rid of the hack by preserving
    ip_summed (mostly) on forwarded packets.
    Signed-off-by: Herbert Xu <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
 include/linux/skbuff.h  |    7 +++++++
 net/bridge/br_forward.c |    2 +-
 net/ipv4/ip_forward.c   |    2 +-
 net/ipv6/ip6_output.c   |    2 +-
 4 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 3724790..1c19b2d 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1654,5 +1654,12 @@ static inline int skb_is_gso(const struct sk_buff *skb)
        return skb_shinfo(skb)->gso_size;
+static inline void skb_forward_csum(struct sk_buff *skb)
+       /* Unfortunately we don't support this one.  Any brave souls? */
+       if (skb->ip_summed == CHECKSUM_COMPLETE)
+               skb->ip_summed = CHECKSUM_NONE;
 #endif /* __KERNEL__ */
 #endif /* _LINUX_SKBUFF_H */
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index 3e45c1a..ada7f49 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -71,7 +71,7 @@ static void __br_forward(const struct net_bridge_port *to, 
struct sk_buff *skb)
        indev = skb->dev;
        skb->dev = to->dev;
-       skb->ip_summed = CHECKSUM_NONE;
+       skb_forward_csum(skb);
        NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev,
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
index 61b30d1..9cb04df 100644
--- a/net/ipv4/ip_forward.c
+++ b/net/ipv4/ip_forward.c
@@ -67,7 +67,7 @@ int ip_forward(struct sk_buff *skb)
        if (skb->pkt_type != PACKET_HOST)
                goto drop;
-       skb->ip_summed = CHECKSUM_NONE;
+       skb_forward_csum(skb);
         *      According to the RFC, we must first decrease the TTL field. If
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index e2b8db6..be3f082 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -378,7 +378,7 @@ int ip6_forward(struct sk_buff *skb)
                goto drop;
-       skb->ip_summed = CHECKSUM_NONE;
+       skb_forward_csum(skb);
         *      We DO NOT make any processing on
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at

Reply via email to