Skip to content

Commit

Permalink
Use innerpacket's destip as source ip while doing Tx Port mirroring
Browse files Browse the repository at this point in the history
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
  • Loading branch information
divakardhar committed Feb 27, 2016
1 parent 4da87fc commit ce86dd4
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 17 deletions.
34 changes: 18 additions & 16 deletions dp-core/vr_mirror.c
Expand Up @@ -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};
Expand Down Expand Up @@ -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);
Expand Down
20 changes: 19 additions & 1 deletion dp-core/vr_nexthop.c
Expand Up @@ -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];

Expand All @@ -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;
}
}
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit ce86dd4

Please sign in to comment.