Merge branch 'master' of git://openvswitch.org/openvswitch
[sliver-openvswitch.git] / datapath / tunnel.c
index 8c93e18..bd63da5 100644 (file)
 #include "vlan.h"
 #include "vport.h"
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
-#define rt_dst(rt) (rt->dst)
-#else
-#define rt_dst(rt) (rt->u.dst)
-#endif
-
 /**
  *     ovs_tnl_rcv - ingress point for generic tunnel code
  *
@@ -85,9 +79,9 @@ void ovs_tnl_rcv(struct vport *vport, struct sk_buff *skb,
        ovs_vport_receive(vport, skb, tun_key);
 }
 
-static struct rtable *find_route(struct net *net,
-               __be32 *saddr, __be32 daddr, u8 ipproto,
-               u8 tos, u32 skb_mark)
+struct rtable *find_route(struct net *net,
+                         __be32 *saddr, __be32 daddr, u8 ipproto,
+                         u8 tos, u32 skb_mark)
 {
        struct rtable *rt;
        /* Tunnel configuration keeps DSCP part of TOS bits, But Linux
@@ -150,6 +144,9 @@ static struct sk_buff *handle_offloads(struct sk_buff *skb)
 
        if (skb_is_gso(skb)) {
                struct sk_buff *nskb;
+               char cb[sizeof(skb->cb)];
+
+               memcpy(cb, skb->cb, sizeof(cb));
 
                nskb = __skb_gso_segment(skb, 0, false);
                if (IS_ERR(nskb)) {
@@ -159,6 +156,10 @@ static struct sk_buff *handle_offloads(struct sk_buff *skb)
 
                consume_skb(skb);
                skb = nskb;
+               while (nskb) {
+                       memcpy(nskb->cb, cb, sizeof(cb));
+                       nskb = nskb->next;
+               }
        } else if (get_ip_summed(skb) == OVS_CSUM_PARTIAL) {
                /* Pages aren't locked and could change at any time.
                 * If this happens after we compute the checksum, the
@@ -192,7 +193,9 @@ u16 ovs_tnl_get_src_port(struct sk_buff *skb)
        int low;
        int high;
        unsigned int range;
-       u32 hash = OVS_CB(skb)->flow->hash;
+       struct sw_flow_key *pkt_key = OVS_CB(skb)->pkt_key;
+       u32 hash = jhash2((const u32 *)pkt_key,
+                         sizeof(*pkt_key) / sizeof(u32), 0);
 
        inet_get_local_port_range(&low, &high);
        range = (high - low) + 1;
@@ -289,7 +292,7 @@ int ovs_tnl_send(struct vport *vport, struct sk_buff *skb,
                iph->tos        = OVS_CB(skb)->tun_key->ipv4_tos;
                iph->ttl        = OVS_CB(skb)->tun_key->ipv4_ttl;
                iph->frag_off   = OVS_CB(skb)->tun_key->tun_flags &
-                                 OVS_TNL_F_DONT_FRAGMENT ?  htons(IP_DF) : 0;
+                                 TUNNEL_DONT_FRAGMENT ?  htons(IP_DF) : 0;
                /*
                 * Allow our local IP stack to fragment the outer packet even
                 * if the DF bit is set as a last resort.  We also need to