From a06f19d60761287728dba554fe57e91da205861a 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 | 34 +++++++++++++++++++--------------- 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, 36 insertions(+), 29 deletions(-) diff --git a/dp-core/vr_datapath.c b/dp-core/vr_datapath.c index 80098f581..488997ad8 100644 --- a/dp-core/vr_datapath.c +++ b/dp-core/vr_datapath.c @@ -101,24 +101,28 @@ vr_get_proxy_mac(struct vr_packet *pkt, struct vr_forwarding_md *fmd, return MR_DROP; } } + /* - * 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 0d6f07e21..94fdbb653 100644 --- a/dp-core/vr_interface.c +++ b/dp-core/vr_interface.c @@ -87,7 +87,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; @@ -233,7 +234,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; @@ -257,7 +259,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; @@ -954,7 +956,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); @@ -964,7 +967,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 03da4ff45..6896f7057 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 3a5470078..44c31ad64 100644 --- a/dp-core/vr_nexthop.c +++ b/dp-core/vr_nexthop.c @@ -1292,8 +1292,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; } @@ -1429,8 +1429,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; } @@ -1588,8 +1588,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; @@ -1749,7 +1749,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 7fc47ce62..f8dca4c4a 100644 --- a/include/vr_interface.h +++ b/include/vr_interface.h @@ -150,7 +150,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 *); /*