diff --git a/dp-core/vr_mirror.c b/dp-core/vr_mirror.c index d73b03592..667411c6d 100644 --- a/dp-core/vr_mirror.c +++ b/dp-core/vr_mirror.c @@ -368,7 +368,7 @@ int vr_mirror(struct vrouter *router, uint8_t mirror_id, struct vr_packet *pkt, struct vr_forwarding_md *fmd) { - bool reset; + bool reset = true; unsigned int captured_len, clone_len = VR_MIRROR_PKT_HEAD_SPACE, mirror_md_len = 0; unsigned char default_mme[2] = {0xff, 0x0}; @@ -417,35 +417,37 @@ vr_mirror(struct vrouter *router, uint8_t mirror_id, * header. If not get the processed headers by resetting the packet * and mirror it */ - reset = true; - if (pkt->vp_if && pkt->vp_if->vif_type == VIF_TYPE_PHYSICAL) { + if (pkt->vp_if && (pkt->vp_if->vif_type == VIF_TYPE_PHYSICAL)) { pkt_nh = pkt->vp_nh; if (pkt_nh && (pkt_nh->nh_flags & NH_FLAG_VALID) && (pkt_nh->nh_type == NH_ENCAP)) { reset = false; - if (pkt_nh->nh_family == AF_INET) - clone_len += pkt_nh->nh_encap_len; - - if (vr_pcow(pkt, clone_len)) - goto fail; - - - if (pkt_nh->nh_family == AF_INET) { - if (!pkt_nh->nh_dev->vif_set_rewrite(pkt_nh->nh_dev, pkt, fmd, - pkt_nh->nh_data, pkt_nh->nh_encap_len)) - goto fail; + if (fmd->fmd_flow_index >= 0) { + if (pkt_nh->nh_family == AF_INET) + clone_len += pkt_nh->nh_encap_len; + + if (vr_pcow(pkt, clone_len)) + goto fail; + clone_len = 0; + + if (pkt_nh->nh_family == AF_INET) { + if (!pkt_nh->nh_dev->vif_set_rewrite(pkt_nh->nh_dev, pkt, fmd, + pkt_nh->nh_data, pkt_nh->nh_encap_len)) + goto fail; + } } } } - if (reset) { + if (reset) vr_preset(pkt); + + if (clone_len) { if (vr_pcow(pkt, clone_len)) goto fail; } - pkt->vp_flags |= VP_FLAG_FROM_DP; /* Set the GSO and partial checksum flag */ pkt->vp_flags |= (VP_FLAG_FLOW_SET | VP_FLAG_GSO | VP_FLAG_CSUM_PARTIAL); diff --git a/dp-core/vr_nexthop.c b/dp-core/vr_nexthop.c index b03fdcd29..39d8c68f3 100644 --- a/dp-core/vr_nexthop.c +++ b/dp-core/vr_nexthop.c @@ -407,6 +407,7 @@ nh_udp_tunnel_helper(struct vr_packet *pkt, unsigned short sport, static bool nh_udp_tunnel6_helper(struct vr_packet *pkt, struct vr_nexthop *nh) { + unsigned int v4_ip; uint8_t *sip = NULL; uint8_t sip6[VR_IP6_ADDRESS_LEN]; @@ -417,10 +418,19 @@ nh_udp_tunnel6_helper(struct vr_packet *pkt, struct vr_nexthop *nh) if (nh->nh_flags & NH_FLAG_TUNNEL_SIP_COPY) { if (pkt->vp_type == VP_TYPE_IP6) { ip6 = (struct vr_ip6 *)pkt_network_header(pkt); + + if (pkt->vp_if->vif_type == VIF_TYPE_PHYSICAL) + sip = ip6->ip6_dst; sip = ip6->ip6_src; + } else if (pkt->vp_type == VP_TYPE_IP) { ip = (struct vr_ip *)pkt_network_header(pkt); - vr_inet6_generate_ip6(sip6, ip->ip_saddr); + + v4_ip = ip->ip_saddr; + if (pkt->vp_if->vif_type == VIF_TYPE_PHYSICAL) + v4_ip = ip->ip_daddr; + + vr_inet6_generate_ip6(sip6, v4_ip); sip = sip6; } } @@ -1302,6 +1312,14 @@ nh_generate_sip(struct vr_nexthop *nh, struct vr_packet *pkt) iph = (struct vr_ip *)pkt_network_header(pkt); if (pkt->vp_type == VP_TYPE_IP) { + + /* + * If the packet is from fabric, it must be destined to a VM on + * this compute, so lets use dest ip + */ + if (pkt->vp_if->vif_type == VIF_TYPE_PHYSICAL) + return iph->ip_daddr; + return iph->ip_saddr; }