From ce86dd46913a85e16a56099d7df2066bf0ef2625 Mon Sep 17 00:00:00 2001 From: Divakar Date: Sat, 27 Feb 2016 09:37:41 +0530 Subject: [PATCH] Use innerpacket's destip as source ip while doing Tx Port mirroring When Transmit port mirroring is enabled, packet received on Fabric interface is right now mirrored using the source IP of the inner packet. This results in RPF failure on Analyzer VM's compute node because the compute node which is doing the port mirroring is using other compute node's VM IP. As a fix, if mirroring is Tax mirroring, rather using inner packets source ip, dest ip is used, so that Analyzer VM's RPF will not have any issues Change-Id: I5beaa0dd0cc3c886a1e77f244c8003595ed348e2 closes-bug: #1550312 --- dp-core/vr_mirror.c | 34 ++++++++++++++++++---------------- dp-core/vr_nexthop.c | 20 +++++++++++++++++++- 2 files changed, 37 insertions(+), 17 deletions(-) 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; }