From 40d058fb71e98e1a3e9ca96c8135849646d90901 Mon Sep 17 00:00:00 2001 From: Divakar Date: Thu, 25 Feb 2016 21:39:27 +0530 Subject: [PATCH] Using the correct FMD and setting pkt_type correctly for mirrored packets If port mirroring is enabled, cloned packet is subjected to mirroring using the original packet's forwarding metadata. If mirroring code changes the metadata content, original packet will be forwarded as per the changed fmd and results in wrong forwarding. In the current case, mirroring is to a VM in different VN (hence new VRF) and mirroring code is modifying the fmd's dvrf to new VRF. The original ARP packet's L2 and L3 looksups are happening on the modified VRF resulting in ARP getting dropped. Also the type of packet is identified using vr_pkt_type() after packet is mirrored. This is resulting in wrong pkt_type being used for mirrored packet hence the source IP packet the mirrored packet is not correctly computed. As a fix, new FMD is used for mirrored packet and packet type is identified before mirroring itself. Change-Id: I00cc36161aac47be799c00083d8b82ecc030ba15 closes-bug: #1549727 --- dp-core/vr_datapath.c | 11 ++++++----- dp-core/vr_mirror.c | 9 +++++++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/dp-core/vr_datapath.c b/dp-core/vr_datapath.c index 7629f0cfd..911029e7e 100644 --- a/dp-core/vr_datapath.c +++ b/dp-core/vr_datapath.c @@ -553,16 +553,17 @@ vr_virtual_input(unsigned short vrf, struct vr_interface *vif, fmd.fmd_vlan = vlan_id; fmd.fmd_dvrf = vrf; + if (vr_pkt_type(pkt, 0, &fmd) < 0) { + vif_drop_pkt(vif, pkt, 1); + return 0; + } + if (vif->vif_flags & VIF_FLAG_MIRROR_RX) { mfmd = fmd; mfmd.fmd_dvrf = vif->vif_vrf; - vr_mirror(vif->vif_router, vif->vif_mirror_id, pkt, &fmd); + vr_mirror(vif->vif_router, vif->vif_mirror_id, pkt, &mfmd); } - if (vr_pkt_type(pkt, 0, &fmd) < 0) { - vif_drop_pkt(vif, pkt, 1); - return 0; - } /* * we really do not allow any broadcast packets from interfaces diff --git a/dp-core/vr_mirror.c b/dp-core/vr_mirror.c index c5f531efb..64828cd70 100644 --- a/dp-core/vr_mirror.c +++ b/dp-core/vr_mirror.c @@ -374,11 +374,11 @@ vr_mirror(struct vrouter *router, uint8_t mirror_id, unsigned char default_mme[2] = {0xff, 0x0}; void *mirror_md; unsigned char *buf; - struct vr_nexthop *nh; + struct vr_nexthop *nh, *pkt_nh; struct vr_pcap *pcap; struct vr_mirror_entry *mirror; struct vr_mirror_meta_entry *mme; - struct vr_nexthop *pkt_nh; + struct vr_forwarding_md new_fmd; /* If the packet is already mirrored, dont mirror again */ if (pkt->vp_flags & VP_FLAG_FROM_DP) @@ -388,6 +388,11 @@ vr_mirror(struct vrouter *router, uint8_t mirror_id, if (!mirror) return 0; + if (fmd) { + memcpy(&new_fmd, fmd, sizeof(*fmd)); + fmd = &new_fmd; + } + if (fmd->fmd_flow_index >= 0) { mme = (struct vr_mirror_meta_entry *)vr_itable_get(router->vr_mirror_md, fmd->fmd_flow_index);