It's far easier to deal with GSO if we don't have to parse the packet
to figure out the header length.  Add the field to the virtio_net_hdr
struct (and fix the spaces that somehow crept in there).

Signed-off-by: Rusty Russell <[EMAIL PROTECTED]>
---
 drivers/net/virtio_net.c   |    4 +++-
 include/linux/virtio_net.h |   11 ++++++-----
 2 files changed, 9 insertions(+), 6 deletions(-)

diff -r 24ef33a4ab14 drivers/net/virtio_net.c
--- a/drivers/net/virtio_net.c  Tue Jan 15 16:59:58 2008 +1100
+++ b/drivers/net/virtio_net.c  Tue Jan 15 21:21:40 2008 +1100
@@ -126,6 +126,7 @@ static void receive_skb(struct net_devic
                /* Header must be checked, and gso_segs computed. */
                skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
                skb_shinfo(skb)->gso_segs = 0;
+               skb_set_transport_header(skb, hdr->gso_hdr_len);
        }
 
        netif_receive_skb(skb);
@@ -247,6 +248,7 @@ static int start_xmit(struct sk_buff *sk
        }
 
        if (skb_is_gso(skb)) {
+               hdr->gso_hdr_len = skb_transport_header(skb) - skb->data;
                hdr->gso_size = skb_shinfo(skb)->gso_size;
                if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN)
                        hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4_ECN;
@@ -260,7 +262,7 @@ static int start_xmit(struct sk_buff *sk
                        BUG();
        } else {
                hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
-               hdr->gso_size = 0;
+               hdr->gso_size = hdr->gso_hdr_len = 0;
        }
 
        vnet_hdr_to_sg(sg, skb);
diff -r 24ef33a4ab14 include/linux/virtio_net.h
--- a/include/linux/virtio_net.h        Tue Jan 15 16:59:58 2008 +1100
+++ b/include/linux/virtio_net.h        Tue Jan 15 21:21:40 2008 +1100
@@ -24,16 +24,17 @@ struct virtio_net_hdr
 struct virtio_net_hdr
 {
 #define VIRTIO_NET_HDR_F_NEEDS_CSUM    1       // Use csum_start, csum_offset
-      __u8 flags;
+       __u8 flags;
 #define VIRTIO_NET_HDR_GSO_NONE                0       // Not a GSO frame
 #define VIRTIO_NET_HDR_GSO_TCPV4       1       // GSO frame, IPv4 TCP (TSO)
 /* FIXME: Do we need this?  If they said they can handle ECN, do they care? */
 #define VIRTIO_NET_HDR_GSO_TCPV4_ECN   2       // GSO frame, IPv4 TCP w/ ECN
 #define VIRTIO_NET_HDR_GSO_UDP         3       // GSO frame, IPv4 UDP (UFO)
 #define VIRTIO_NET_HDR_GSO_TCPV6       4       // GSO frame, IPv6 TCP
-      __u8 gso_type;
-      __u16 gso_size;
-      __u16 csum_start;
-      __u16 csum_offset;
+       __u8 gso_type;
+       __u16 gso_hdr_len;      /* Ethernet + IP + tcp/udp hdrs */
+       __u16 gso_size;         /* Bytes to append to gso_hdr_len per frame */
+       __u16 csum_start;       /* Position to start checksumming from */
+       __u16 csum_offset;      /* Offset after that to place checksum */
 };
 #endif /* _LINUX_VIRTIO_NET_H */
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to