From 6433c657043b236afb6545048f68cd272541653e Mon Sep 17 00:00:00 2001 From: "Anand H. Krishnan" Date: Wed, 4 Mar 2015 19:19:00 +0530 Subject: [PATCH] vrf for packets sent to agent via encap nexthop should come from metadata and not from ingress interface Till now, packets that were sent to agent via an encap nexthop, had the vrf in the agent header set to the ingress interface vrf. The vrf value in all cases have to be the vrf to which the packet has been classified to. Bug fix for arp behavior: If an arp request ingressed from fabric interface and if the proxy bit was set in the route, but the stitching information was not present, vrouter used to proxy with the vhost mac. This behavior is wrong. vrouter should proxy only if the destination is hosted by it or if the destination is not hosted and it is a TSN or if the request was meant for a host in the cp port. Closes-Bug: #1428135 Change-Id: Ibe543c743a07834a87e1512ac305f1e0f32d5d30 --- dp-core/vr_datapath.c | 33 ++++++++++++++++++--------------- dp-core/vr_interface.c | 13 ++++++++----- dp-core/vr_mirror.c | 2 +- dp-core/vr_nexthop.c | 14 +++++++------- include/vr_interface.h | 2 +- 5 files changed, 35 insertions(+), 29 deletions(-) diff --git a/dp-core/vr_datapath.c b/dp-core/vr_datapath.c index a78ffc599..9593d1b85 100644 --- a/dp-core/vr_datapath.c +++ b/dp-core/vr_datapath.c @@ -102,23 +102,26 @@ vr_get_proxy_mac(struct vr_packet *pkt, struct vr_forwarding_md *fmd, } /* - * if nh is not of ENCAP type, that means that the vm is not hosted by - * us or the request is for a host in vcp port. if the request is for - * a host in the vcp port, we should proxy. else, we should proxy only - * if - * i am a TSN, i have the mac information and the originator is a bare - * metal + * we should proxy if the vm is hosted by us, in which case nh will be + * of ENCAP type. we should also proxy for a host in vcp port. In all + * other cases, we should proxy only if + * + * i am a TSN(fmd->fmd_src), + * i amd the dns IP or + * i have the mac information (nh - (mostly tunnel)) and + * the originator is a bare metal (fmd->fmd_src) */ - if (!to_vcp && nh && nh->nh_type != NH_ENCAP) { - if (fmd->fmd_src != TOR_SOURCE) { - if (stats) - stats->vrf_arp_physical_flood++; - return MR_FLOOD; - } + if (to_vcp || to_gateway || + ((nh) && + ((nh->nh_type == NH_ENCAP) || + (fmd->fmd_src == TOR_SOURCE)))) { + if (stats) + stats->vrf_arp_physical_stitch++; + } else { + if (stats) + stats->vrf_arp_physical_flood++; + return MR_FLOOD; } - - if (stats) - stats->vrf_arp_physical_stitch++; } else { /* * if there is no stitching information, but flood flag is set diff --git a/dp-core/vr_interface.c b/dp-core/vr_interface.c index e33714169..68f58fba2 100644 --- a/dp-core/vr_interface.c +++ b/dp-core/vr_interface.c @@ -86,7 +86,8 @@ vif_drop_pkt(struct vr_interface *vif, struct vr_packet *pkt, bool input) */ static unsigned char * vif_cmn_rewrite(struct vr_interface *vif, struct vr_packet *pkt, - unsigned char *rewrite, unsigned short len) + struct vr_forwarding_md *fmd, unsigned char *rewrite, + unsigned short len) { unsigned char *head; @@ -232,7 +233,8 @@ vif_xconnect(struct vr_interface *vif, struct vr_packet *pkt, static unsigned char * agent_set_rewrite(struct vr_interface *vif, struct vr_packet *pkt, - unsigned char *rewrite, unsigned short len) + struct vr_forwarding_md *fmd, unsigned char *rewrite, + unsigned short len) { unsigned char *head; unsigned int hdr_len; @@ -256,7 +258,7 @@ agent_set_rewrite(struct vr_interface *vif, struct vr_packet *pkt, hdr = (struct agent_hdr *)(head + len); hdr->hdr_ifindex = htons(pkt->vp_if->vif_idx); - hdr->hdr_vrf = htons(pkt->vp_if->vif_vrf); + hdr->hdr_vrf = htons(fmd->fmd_dvrf); /* this needs some thought */ hdr->hdr_cmd = htons(AGENT_TRAP_NEXTHOP); hdr->hdr_cmd_param = 0; @@ -948,7 +950,8 @@ tun_rx(struct vr_interface *vif, struct vr_packet *pkt, static unsigned char * eth_set_rewrite(struct vr_interface *vif, struct vr_packet *pkt, - unsigned char *rewrite, unsigned short len) + struct vr_forwarding_md *fmd, unsigned char *rewrite, + unsigned short len) { if (!len) return pkt_data(pkt); @@ -958,7 +961,7 @@ eth_set_rewrite(struct vr_interface *vif, struct vr_packet *pkt, return pkt_data(pkt); } - return vif_cmn_rewrite(vif, pkt, rewrite, len); + return vif_cmn_rewrite(vif, pkt, fmd, rewrite, len); } static mac_response_t diff --git a/dp-core/vr_mirror.c b/dp-core/vr_mirror.c index 70325024f..6f9809081 100644 --- a/dp-core/vr_mirror.c +++ b/dp-core/vr_mirror.c @@ -417,7 +417,7 @@ vr_mirror(struct vrouter *router, uint8_t mirror_id, pkt_nh->nh_encap_len)) goto fail; - if (!pkt_nh->nh_dev->vif_set_rewrite(pkt_nh->nh_dev, pkt, + 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; } diff --git a/dp-core/vr_nexthop.c b/dp-core/vr_nexthop.c index e22702aa1..3f5518d2e 100644 --- a/dp-core/vr_nexthop.c +++ b/dp-core/vr_nexthop.c @@ -1290,8 +1290,8 @@ nh_vxlan_tunnel(struct vr_packet *pkt, struct vr_nexthop *nh, /* slap l2 header */ vif = nh->nh_dev; - if (!vif->vif_set_rewrite(vif, pkt, nh->nh_data, - nh->nh_udp_tun_encap_len)) { + if (!vif->vif_set_rewrite(vif, pkt, fmd, + nh->nh_data, nh->nh_udp_tun_encap_len)) { goto send_fail; } @@ -1426,8 +1426,8 @@ nh_mpls_udp_tunnel(struct vr_packet *pkt, struct vr_nexthop *nh, /* slap l2 header */ vif = nh->nh_dev; - tun_encap = vif->vif_set_rewrite(vif, pkt, nh->nh_data, - tun_encap_len); + tun_encap = vif->vif_set_rewrite(vif, pkt, fmd, + nh->nh_data, tun_encap_len); if (!tun_encap) { goto send_fail; } @@ -1584,8 +1584,8 @@ nh_gre_tunnel(struct vr_packet *pkt, struct vr_nexthop *nh, /* slap l2 header */ vif = nh->nh_dev; - tun_encap = vif->vif_set_rewrite(vif, pkt, nh->nh_data, - nh->nh_gre_tun_encap_len); + tun_encap = vif->vif_set_rewrite(vif, pkt, fmd, + nh->nh_data, nh->nh_gre_tun_encap_len); if (!tun_encap) { drop_reason = VP_DROP_PUSH; goto send_fail; @@ -1746,7 +1746,7 @@ nh_encap_l3(struct vr_packet *pkt, struct vr_nexthop *nh, return 0; } - if (!vif->vif_set_rewrite(vif, pkt, nh->nh_data, nh->nh_encap_len)) { + if (!vif->vif_set_rewrite(vif, pkt, fmd, nh->nh_data, nh->nh_encap_len)) { vr_pfree(pkt, VP_DROP_REWRITE_FAIL); return 0; } diff --git a/include/vr_interface.h b/include/vr_interface.h index 63fa181f2..af8efae5c 100644 --- a/include/vr_interface.h +++ b/include/vr_interface.h @@ -171,7 +171,7 @@ struct vr_interface { void *vif_os; int (*vif_send)(struct vr_interface *, struct vr_packet *, void *); unsigned char *(*vif_set_rewrite)(struct vr_interface *, struct vr_packet *, - unsigned char *, unsigned short); + struct vr_forwarding_md *, unsigned char *, unsigned short); int (*vif_tx)(struct vr_interface *, struct vr_packet *, struct vr_forwarding_md *); /*