Skip to content

Commit

Permalink
Change in port mirroring tap locations
Browse files Browse the repository at this point in the history
For all types of virtual interfaces, the location from where we tap
packets for RX port mirroring is in a common function where all
the common virtual processing happens. For a vlan based sub-interface,
this means that the port mirroring happens post untagging the packet
and hence this is not a correct behavior.

Hence, move the tap locations to the lowest layers of vif receive.

Also, during transmission, since the tap is in the lowest common
layer, sub interface mirroring does not work. Hence, move the taps
to the highest layer of vif transmit.

Also, add taps for vhost and physical interfaces.

Change-Id: Ie42bfcedde2eba1167fa49e7ecd627b7762363e9
Closes-Bug: #1630889
  • Loading branch information
anandhk-juniper committed Oct 6, 2016
1 parent 93dc122 commit 85ca42b
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 28 deletions.
10 changes: 1 addition & 9 deletions dp-core/vr_datapath.c
Expand Up @@ -595,7 +595,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;
Expand All @@ -610,14 +610,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,
MIRROR_TYPE_PORT_RX);
}


/*
* we really do not allow any broadcast packets from interfaces
* that are part of transparent service chain, since transparent
Expand Down
56 changes: 47 additions & 9 deletions dp-core/vr_interface.c
Expand Up @@ -231,6 +231,35 @@ 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, unsigned int txrx_mirror)
{
unsigned int mirror_type;
struct vr_forwarding_md mfmd;

if (!txrx_mirror)
return;

if (txrx_mirror & VIF_FLAG_MIRROR_TX)
mirror_type = MIRROR_TYPE_PORT_TX;
else
mirror_type = MIRROR_TYPE_PORT_RX;

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, mirror_type);

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,
Expand Down Expand Up @@ -608,6 +637,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, vif->vif_flags & VIF_FLAG_MIRROR_RX);

return vr_fabric_input(vif, pkt, vlan_id);
}

Expand Down Expand Up @@ -674,6 +705,8 @@ vhost_tx(struct vr_interface *vif, struct vr_packet *pkt,
}
}

vif_mirror(vif, pkt, fmd, vif->vif_flags & VIF_FLAG_MIRROR_TX);

ret = hif_ops->hif_rx(vif, pkt);
if (ret < 0) {
ret = 0;
Expand Down Expand Up @@ -737,6 +770,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, vif->vif_flags & VIF_FLAG_MIRROR_RX);

tos = vr_vlan_get_tos(pkt_data(pkt));
if (tos >= 0)
pkt->vp_priority = tos;
Expand Down Expand Up @@ -780,6 +815,8 @@ vlan_tx(struct vr_interface *vif, struct vr_packet *pkt,
}
}

vif_mirror(vif, pkt, fmd, vif->vif_flags & VIF_FLAG_MIRROR_TX);

pvif = vif->vif_parent;
if (!pvif)
goto drop;
Expand Down Expand Up @@ -886,6 +923,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, vif->vif_flags & VIF_FLAG_MIRROR_RX);

return vr_virtual_input(vrf, vif, pkt, vlan_id);
}

Expand All @@ -910,6 +949,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, vif->vif_flags & VIF_FLAG_MIRROR_RX);

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,
Expand Down Expand Up @@ -951,6 +992,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, vif->vif_flags & VIF_FLAG_MIRROR_RX);

if (vif_mode_xconnect(vif))
pkt->vp_flags |= VP_FLAG_TO_ME;

Expand Down Expand Up @@ -1036,6 +1079,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, vif->vif_flags & VIF_FLAG_MIRROR_RX);

/*
* please see the text on xconnect mode
*
Expand Down Expand Up @@ -1074,9 +1119,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, vif->vif_flags & VIF_FLAG_MIRROR_TX);

if (vif_is_virtual(vif)) {
handled = vif_plug_mac_request(vif, pkt, fmd);
if (handled)
Expand Down Expand Up @@ -1108,13 +1154,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,
MIRROR_TYPE_PORT_TX);
}

ret = hif_ops->hif_tx(vif, pkt);
if (ret != 0) {
if (!from_subvif)
Expand Down Expand Up @@ -1220,7 +1259,6 @@ eth_drv_add(struct vr_interface *vif,
vif->vif_mtu = 1514;
}


if (vif->vif_type != VIF_TYPE_STATS) {
vif->vif_tx = eth_tx;

Expand Down
35 changes: 25 additions & 10 deletions dp-core/vr_mirror.c
Expand Up @@ -349,7 +349,9 @@ vr_mirror(struct vrouter *router, uint8_t mirror_id, struct vr_packet *pkt,
struct vr_forwarding_md *fmd, mirror_type_t mtype)
{
bool reset = true;
unsigned int captured_len, clone_len = 0, mirror_md_len = 0;
unsigned int captured_len, clone_len = 0;
unsigned int mirror_md_len = 0, drop_reason;

void *mirror_md;
unsigned char *buf;
struct vr_nexthop *nh, *pkt_nh;
Expand Down Expand Up @@ -404,14 +406,18 @@ vr_mirror(struct vrouter *router, uint8_t mirror_id, struct vr_packet *pkt,
}
}
} else if (mtype == MIRROR_TYPE_PORT_RX) {
if (!pkt->vp_if)
if (!pkt->vp_if) {
drop_reason = VP_DROP_INVALID_IF;
goto fail;
}

mirror_md_len = pkt->vp_if->vif_mirror_md_len;
mirror_md = pkt->vp_if->vif_mirror_md;
} else {
if (!pkt->vp_nh || !pkt->vp_nh->nh_dev)
goto fail;
if (!pkt->vp_nh || !pkt->vp_nh->nh_dev) {
drop_reason = VP_DROP_INVALID_NH;
goto fail;
}

mirror_md_len = pkt->vp_nh->nh_dev->vif_mirror_md_len;
mirror_md = pkt->vp_nh->nh_dev->vif_mirror_md;
Expand Down Expand Up @@ -445,13 +451,18 @@ vr_mirror(struct vrouter *router, uint8_t mirror_id, struct vr_packet *pkt,

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_dev->vif_set_rewrite(pkt_nh->nh_dev, pkt, fmd,
pkt_nh->nh_data, pkt_nh->nh_encap_len))
goto fail;
pkt_nh->nh_data, pkt_nh->nh_encap_len)) {
drop_reason = VP_DROP_REWRITE_FAIL;
goto fail;
}
}
}
}
Expand All @@ -460,15 +471,19 @@ vr_mirror(struct vrouter *router, uint8_t mirror_id, struct vr_packet *pkt,
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;
}
}

captured_len = htonl(pkt_len(pkt));
if (mirror_md_len) {
buf = pkt_push(pkt, mirror_md_len);
if (!buf)
if (!buf) {
drop_reason = VP_DROP_PUSH;
goto fail;
}
memcpy(buf, mirror_md, mirror_md_len);
}

Expand All @@ -485,7 +500,7 @@ vr_mirror(struct vrouter *router, uint8_t mirror_id, struct vr_packet *pkt,
return 0;

fail:
vr_pfree(pkt, VP_DROP_PUSH);
vr_pfree(pkt, drop_reason);
return 0;
}

Expand Down

0 comments on commit 85ca42b

Please sign in to comment.