diff --git a/dp-core/vr_datapath.c b/dp-core/vr_datapath.c index 2579be107..57c2cdecf 100644 --- a/dp-core/vr_datapath.c +++ b/dp-core/vr_datapath.c @@ -610,7 +610,7 @@ unsigned int vr_virtual_input(unsigned short vrf, struct vr_interface *vif, struct vr_packet *pkt, unsigned short vlan_id) { - struct vr_forwarding_md fmd, mfmd; + struct vr_forwarding_md fmd; vr_init_forwarding_md(&fmd); fmd.fmd_vlan = vlan_id; @@ -621,12 +621,6 @@ vr_virtual_input(unsigned short vrf, struct vr_interface *vif, 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, &mfmd); - } - /* * we really do not allow any broadcast packets from interfaces * that are part of transparent service chain, since transparent diff --git a/dp-core/vr_interface.c b/dp-core/vr_interface.c index ecdd32d86..3b21a94bc 100644 --- a/dp-core/vr_interface.c +++ b/dp-core/vr_interface.c @@ -231,6 +231,25 @@ vif_xconnect(struct vr_interface *vif, struct vr_packet *pkt, return 0; } +static inline void +vif_mirror(struct vr_interface *vif, struct vr_packet *pkt, + struct vr_forwarding_md *fmd) +{ + struct vr_forwarding_md mfmd; + + if (!fmd) { + vr_init_forwarding_md(&mfmd); + } else { + mfmd = *fmd; + } + + mfmd.fmd_dvrf = vif->vif_vrf; + vr_mirror(vif->vif_router, vif->vif_mirror_id, pkt, &mfmd); + + return; +} + +/* agent driver */ static unsigned char * agent_set_rewrite(struct vr_interface *vif, struct vr_packet *pkt, struct vr_forwarding_md *fmd, unsigned char *rewrite, @@ -608,6 +627,8 @@ vhost_rx(struct vr_interface *vif, struct vr_packet *pkt, if (vif_mode_xconnect(vif)) return vif_xconnect(vif, pkt, &fmd); + vif_mirror(vif, pkt, &fmd); + return vr_fabric_input(vif, pkt, vlan_id); } @@ -674,6 +695,8 @@ vhost_tx(struct vr_interface *vif, struct vr_packet *pkt, } } + vif_mirror(vif, pkt, fmd); + ret = hif_ops->hif_rx(vif, pkt); if (ret < 0) { ret = 0; @@ -736,6 +759,8 @@ vlan_rx(struct vr_interface *vif, struct vr_packet *pkt, stats->vis_ibytes += pkt_len(pkt); stats->vis_ipackets++; + vif_mirror(vif, pkt, NULL); + if (vr_untag_pkt(pkt)) { stats->vis_ierrors++; vr_pfree(pkt, VP_DROP_PULL); @@ -770,6 +795,7 @@ vlan_tx(struct vr_interface *vif, struct vr_packet *pkt, vr_pset_data(pkt, pkt->vp_data); } + vif_mirror(vif, pkt, fmd); pvif = vif->vif_parent; if (!pvif) @@ -877,6 +903,8 @@ vm_srx(struct vr_interface *vif, struct vr_packet *pkt, else vrf = vif->vif_vrf_table[vlan_id].va_vrf; + vif_mirror(vif, pkt, NULL); + return vr_virtual_input(vrf, vif, pkt, vlan_id); } @@ -901,6 +929,8 @@ vm_rx(struct vr_interface *vif, struct vr_packet *pkt, struct vr_interface_stats *stats = vif_get_stats(vif, pkt->vp_cpu); struct vr_eth *eth = (struct vr_eth *)pkt_data(pkt); + vif_mirror(vif, pkt, NULL); + if (vlan_id != VLAN_ID_INVALID && vlan_id < VLAN_ID_MAX) { if (vif->vif_btable) { sub_vif = vif_bridge_get_sub_interface(vif->vif_btable, vlan_id, @@ -942,6 +972,8 @@ tun_rx(struct vr_interface *vif, struct vr_packet *pkt, stats->vis_ibytes += pkt_len(pkt); stats->vis_ipackets++; + vif_mirror(vif, pkt, NULL); + if (vif_mode_xconnect(vif)) pkt->vp_flags |= VP_FLAG_TO_ME; @@ -1027,6 +1059,8 @@ eth_rx(struct vr_interface *vif, struct vr_packet *pkt, stats->vis_ibytes += pkt_len(pkt); stats->vis_ipackets++; + vif_mirror(vif, pkt, NULL); + /* * please see the text on xconnect mode * @@ -1065,9 +1099,10 @@ eth_tx(struct vr_interface *vif, struct vr_packet *pkt, int ret, handled; bool stats_count = true, from_subvif = false; - struct vr_forwarding_md m_fmd; struct vr_interface_stats *stats = vif_get_stats(vif, pkt->vp_cpu); + vif_mirror(vif, pkt, fmd); + if (vif_is_virtual(vif)) { handled = vif_plug_mac_request(vif, pkt, fmd); if (handled) @@ -1099,12 +1134,6 @@ eth_tx(struct vr_interface *vif, struct vr_packet *pkt, stats->vis_opackets++; } - if (vif->vif_flags & VIF_FLAG_MIRROR_TX) { - vr_init_forwarding_md(&m_fmd); - m_fmd.fmd_dvrf = vif->vif_vrf; - vr_mirror(vif->vif_router, vif->vif_mirror_id, pkt, &m_fmd); - } - ret = hif_ops->hif_tx(vif, pkt); if (ret != 0) { if (!from_subvif) @@ -1210,7 +1239,6 @@ eth_drv_add(struct vr_interface *vif, vif->vif_mtu = 1514; } - if (vif->vif_type != VIF_TYPE_STATS) { vif->vif_tx = eth_tx; diff --git a/dp-core/vr_mirror.c b/dp-core/vr_mirror.c index 7f539a050..8ea799e18 100644 --- a/dp-core/vr_mirror.c +++ b/dp-core/vr_mirror.c @@ -377,8 +377,8 @@ vr_mirror(struct vrouter *router, uint8_t mirror_id, struct vr_packet *pkt, struct vr_forwarding_md *fmd) { bool reset = true; - unsigned int captured_len, clone_len = VR_MIRROR_PKT_HEAD_SPACE, - mirror_md_len = 0; + unsigned int captured_len, clone_len = VR_MIRROR_PKT_HEAD_SPACE; + unsigned int mirror_md_len = 0, drop_reason; unsigned char default_mme[2] = {0xff, 0x0}; unsigned long sec, usec; @@ -437,14 +437,19 @@ vr_mirror(struct vrouter *router, uint8_t mirror_id, if (pkt_nh->nh_family == AF_INET) clone_len += pkt_nh->nh_encap_len; - if (vr_pcow(&pkt, clone_len)) + if (vr_pcow(&pkt, clone_len)) { + drop_reason = VP_DROP_PCOW_FAIL; 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)) + pkt_nh->nh_data, pkt_nh->nh_encap_len)) { + drop_reason = VP_DROP_REWRITE_FAIL; goto fail; + } } } } @@ -454,8 +459,10 @@ vr_mirror(struct vrouter *router, uint8_t mirror_id, vr_preset(pkt); if (clone_len) { - if (vr_pcow(&pkt, clone_len)) + if (vr_pcow(&pkt, clone_len)) { + drop_reason = VP_DROP_PCOW_FAIL; goto fail; + } } pkt->vp_flags |= VP_FLAG_FROM_DP; @@ -463,8 +470,10 @@ vr_mirror(struct vrouter *router, uint8_t mirror_id, pkt->vp_flags |= (VP_FLAG_FLOW_SET | VP_FLAG_GSO | VP_FLAG_CSUM_PARTIAL); pkt->vp_flags &= ~VP_FLAG_GRO; buf = pkt_push(pkt, mirror_md_len); - if (!buf) + if (!buf) { + drop_reason = VP_DROP_PUSH; goto fail; + } captured_len = htonl(pkt_len(pkt)); if (mirror_md_len) @@ -473,8 +482,10 @@ vr_mirror(struct vrouter *router, uint8_t mirror_id, if (mirror->mir_flags & VR_MIRROR_PCAP) { /* Add the pcap header */ pcap = (struct vr_pcap *)pkt_push(pkt, sizeof(struct vr_pcap)); - if (!pcap) + if (!pcap) { + drop_reason = VP_DROP_PUSH; goto fail; + } pcap->pcap_incl_len = captured_len; pcap->pcap_orig_len = captured_len; @@ -495,7 +506,7 @@ vr_mirror(struct vrouter *router, uint8_t mirror_id, return 0; fail: - vr_pfree(pkt, VP_DROP_PUSH); + vr_pfree(pkt, drop_reason); return 0; }