X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=datapath%2Fvport-lisp.c;h=e33cffea234f48d54ff8fb40a7bf3622148ea75e;hb=317e49b4aaa71aa4e96817e035083db7f1b964f0;hp=c7da276b8637291576161b320ae3db9137dad046;hpb=2b897011eeb4a0b06fc555009b2b3e138b809a0d;p=sliver-openvswitch.git diff --git a/datapath/vport-lisp.c b/datapath/vport-lisp.c index c7da276b8..e33cffea2 100644 --- a/datapath/vport-lisp.c +++ b/datapath/vport-lisp.c @@ -165,12 +165,17 @@ static __be64 instance_id_to_tunnel_id(__u8 *iid) */ static u16 get_src_port(struct sk_buff *skb) { - int low; - int high; + u32 hash = skb_get_rxhash(skb); unsigned int range; - struct sw_flow_key *pkt_key = OVS_CB(skb)->pkt_key; - u32 hash = jhash2((const u32 *)pkt_key, - sizeof(*pkt_key) / sizeof(u32), 0); + int high; + int low; + + if (!hash) { + struct sw_flow_key *pkt_key = OVS_CB(skb)->pkt_key; + + hash = jhash2((const u32 *)pkt_key, + sizeof(*pkt_key) / sizeof(u32), 0); + } inet_get_local_port_range(&low, &high); range = (high - low) + 1; @@ -376,6 +381,8 @@ error: return ERR_PTR(err); } +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0) + static void lisp_fix_segment(struct sk_buff *skb) { struct udphdr *udph = udp_hdr(skb); @@ -383,13 +390,30 @@ static void lisp_fix_segment(struct sk_buff *skb) udph->len = htons(skb->len - skb_transport_offset(skb)); } -static void handle_offloads(struct sk_buff *skb) +static int handle_offloads(struct sk_buff *skb) { if (skb_is_gso(skb)) OVS_GSO_CB(skb)->fix_segment = lisp_fix_segment; else if (skb->ip_summed != CHECKSUM_PARTIAL) skb->ip_summed = CHECKSUM_NONE; + return 0; } +#else +static int handle_offloads(struct sk_buff *skb) +{ + if (skb_is_gso(skb)) { + int err = skb_unclone(skb, GFP_ATOMIC); + if (unlikely(err)) + return err; + + skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL; + } else if (skb->ip_summed != CHECKSUM_PARTIAL) + skb->ip_summed = CHECKSUM_NONE; + + skb->encapsulation = 1; + return 0; +} +#endif static int lisp_send(struct vport *vport, struct sk_buff *skb) { @@ -437,8 +461,11 @@ static int lisp_send(struct vport *vport, struct sk_buff *skb) goto err_free_rt; } + /* Reset l2 headers. */ skb_pull(skb, network_offset); skb_reset_mac_header(skb); + vlan_set_tci(skb, 0); + skb_reset_inner_headers(skb); __skb_push(skb, LISP_HLEN); @@ -447,7 +474,10 @@ static int lisp_send(struct vport *vport, struct sk_buff *skb) lisp_build_header(vport, skb); /* Offloading */ - handle_offloads(skb); + err = handle_offloads(skb); + if (err) + goto err_free_rt; + skb->local_df = 1; df = OVS_CB(skb)->tun_key->tun_flags & @@ -455,7 +485,7 @@ static int lisp_send(struct vport *vport, struct sk_buff *skb) sent_len = iptunnel_xmit(rt, skb, saddr, OVS_CB(skb)->tun_key->ipv4_dst, IPPROTO_UDP, OVS_CB(skb)->tun_key->ipv4_tos, - OVS_CB(skb)->tun_key->ipv4_ttl, df); + OVS_CB(skb)->tun_key->ipv4_ttl, df, false); return sent_len > 0 ? sent_len + network_offset : sent_len;