Use UDP Tunnel segmention.

Signed-off-by: Pravin B Shelar <pshe...@nicira.com>
---
 drivers/net/vxlan.c |   27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 983a239..07e43bb 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -616,6 +616,21 @@ static u16 vxlan_src_port(const struct vxlan_dev *vxlan, 
struct sk_buff *skb)
        return (((u64) hash * range) >> 32) + vxlan->port_min;
 }
 
+static int handle_gso(struct sk_buff *skb)
+{
+       if (skb_is_gso(skb)) {
+               int err = unclone_skb(skb, GFP_ATOMIC);
+               if (unlikely(err))
+                       return err;
+
+               skb_shinfo(skb)->gso_type |= (SKB_GSO_UDP_TUNNEL | SKB_GSO_UDP);
+               skb->tunnel_hlen = sizeof(struct vxlanhdr);
+       } else {
+               skb->ip_summed = CHECKSUM_NONE;
+       }
+       return 0;
+}
+
 /* Transmit local packets over Vxlan
  *
  * Outer IP header inherits ECN and DF from inner header.
@@ -638,7 +653,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct 
net_device *dev)
        __u8 tos, ttl;
        int err;
 
-       if (skb->ip_summed == CHECKSUM_PARTIAL) {
+       if (!skb_is_gso(skb) && skb->ip_summed == CHECKSUM_PARTIAL) {
                /* Pages aren't locked and could change at any time.
                 * If this happens after we compute the checksum, the
                 * checksum will be wrong.  We linearize now to avoid
@@ -725,11 +740,14 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct 
net_device *dev)
        iph->saddr      = fl4.saddr;
        iph->ttl        = ttl ? : ip4_dst_hoplimit(&rt->dst);
 
+       skb->local_df = 1;
+       __ip_select_ident(ip_hdr(skb), &rt->dst, 0);
+
        vxlan_set_owner(dev, skb);
 
        /* See __IPTUNNEL_XMIT */
-       skb->ip_summed = CHECKSUM_NONE;
-       ip_select_ident(iph, &rt->dst, NULL);
+       if (handle_gso(skb))
+               goto drop;
 
        err = ip_local_out(skb);
        if (likely(net_xmit_eval(err) == 0)) {
@@ -887,7 +905,8 @@ static void vxlan_free(struct net_device *dev)
 #define VXLAN_FEATURES (NETIF_F_SG |           \
                      NETIF_F_FRAGLIST |        \
                      NETIF_F_HIGHDMA |         \
-                     NETIF_F_HW_CSUM)
+                     NETIF_F_HW_CSUM |         \
+                     NETIF_F_TSO)
 
 /* Initialize the device structure. */
 static void vxlan_setup(struct net_device *dev)
-- 
1.7.10

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to