diff --git a/dp-core/vr_nexthop.c b/dp-core/vr_nexthop.c index fe1a57fea..fff09db51 100644 --- a/dp-core/vr_nexthop.c +++ b/dp-core/vr_nexthop.c @@ -1266,6 +1266,13 @@ nh_udp_tunnel(struct vr_packet *pkt, struct vr_nexthop *nh, */ pkt_set_inner_network_header(pkt, pkt->vp_data); + if (pkt->vp_type == VP_TYPE_IP6) + pkt->vp_type = VP_TYPE_IP6OIP; + else if (pkt->vp_type == VP_TYPE_IP) + pkt->vp_type = VP_TYPE_IPOIP; + else + pkt->vp_type = VP_TYPE_IP; + /* * Calculate the partial checksum for udp header */ @@ -1338,6 +1345,12 @@ nh_vxlan_tunnel(struct vr_packet *pkt, struct vr_nexthop *nh, goto send_fail; pkt_set_network_header(pkt, pkt->vp_data); + + if (pkt->vp_type == VP_TYPE_IPOIP) + pkt->vp_type = VP_TYPE_IP; + else if (pkt->vp_type == VP_TYPE_IP6OIP) + pkt->vp_type = VP_TYPE_IP6; + /* * Change the packet type */ @@ -1476,6 +1489,11 @@ nh_mpls_udp_tunnel(struct vr_packet *pkt, struct vr_nexthop *nh, pkt->vp_flags |= VP_FLAG_GSO; + if (pkt->vp_type == VP_TYPE_IPOIP) + pkt->vp_type = VP_TYPE_IP; + else if (pkt->vp_type == VP_TYPE_IP6OIP) + pkt->vp_type = VP_TYPE_IP6; + /* * Change the packet type */ @@ -1624,6 +1642,12 @@ nh_gre_tunnel(struct vr_packet *pkt, struct vr_nexthop *nh, goto send_fail; } pkt_set_network_header(pkt, pkt->vp_data); + + if (pkt->vp_type == VP_TYPE_IPOIP) + pkt->vp_type = VP_TYPE_IP; + else if (pkt->vp_type == VP_TYPE_IP6OIP) + pkt->vp_type = VP_TYPE_IP6; + if (pkt->vp_type == VP_TYPE_IP6) pkt->vp_type = VP_TYPE_IP6OIP; else if (pkt->vp_type == VP_TYPE_IP) diff --git a/include/vr_packet.h b/include/vr_packet.h index 728b8eed0..f25190d80 100644 --- a/include/vr_packet.h +++ b/include/vr_packet.h @@ -493,6 +493,17 @@ vr_pkt_type_is_overlay(unsigned short type) return false; } +static inline bool +vr_pkt_needs_csum_gso_update(struct vr_packet *pkt) +{ + if (pkt->vp_flags & VP_FLAG_FROM_DP) { + if (pkt->vp_flags & (VP_FLAG_CSUM_PARTIAL | VP_FLAG_GSO)) + return true; + } + + return false; +} + static inline bool vr_pkt_is_diag(struct vr_packet *pkt) { diff --git a/linux/vr_host_interface.c b/linux/vr_host_interface.c index 4dbfd8617..7d7949ba7 100644 --- a/linux/vr_host_interface.c +++ b/linux/vr_host_interface.c @@ -782,7 +782,8 @@ linux_if_tx(struct vr_interface *vif, struct vr_packet *pkt) skb_set_network_header(skb, (network_off - skb_headroom(skb))); skb_reset_mac_len(skb); } - } else if (vr_pkt_type_is_overlay(pkt->vp_type)) { + } else if (vr_pkt_type_is_overlay(pkt->vp_type) || + vr_pkt_needs_csum_gso_update(pkt)) { network_off = pkt_get_inner_network_header_off(pkt); if (network_off) { diff --git a/linux/vrouter_mod.c b/linux/vrouter_mod.c index 37fab038d..50e4defea 100644 --- a/linux/vrouter_mod.c +++ b/linux/vrouter_mod.c @@ -207,6 +207,7 @@ lh_palloc_head(struct vr_packet *pkt, unsigned int size) npkt->vp_ttl = pkt->vp_ttl; npkt->vp_flags = pkt->vp_flags; + npkt->vp_type = pkt->vp_type; skb_frag_list_init(skb_head); skb_frag_add_head(skb_head, skb);