From 6d336bf8ab619c2e9e3c7fd9ab1660b35616ebd5 Mon Sep 17 00:00:00 2001 From: Manish Date: Thu, 7 Jan 2016 16:20:08 +0530 Subject: [PATCH] Agent didnt send proper label in evpn inclusive replication. Problem: While exporting subscription for inclusive replication tree when local peer was only added, exporter used to search for multicast_peer. In its absence it will mark label as 0. In case local_vm_peer(local interface list) gets added before local-peer, it will result in creation of path with multicast_peer, hence label will be picked as vxlan-id. Solution: Before picking label as 0 check for presence of local_peer as well and pick up vxlan of same as label. Change-Id: Ie7958aa3cb7175e6df4534d8e66234b8f92c4138 Closes-bug: 1529665 --- src/vnsw/agent/controller/controller_peer.cc | 11 +++- src/vnsw/agent/controller/controller_peer.h | 24 +++---- src/vnsw/agent/test/test_l2route.cc | 66 ++++++++++++++++++++ 3 files changed, 86 insertions(+), 15 deletions(-) diff --git a/src/vnsw/agent/controller/controller_peer.cc b/src/vnsw/agent/controller/controller_peer.cc index 060ea2f19e0..74fb005406a 100644 --- a/src/vnsw/agent/controller/controller_peer.cc +++ b/src/vnsw/agent/controller/controller_peer.cc @@ -1931,6 +1931,7 @@ bool AgentXmppChannel::BuildTorMulticastMessage(EnetItemType &item, return true; } +//TODO simplify label selection below. bool AgentXmppChannel::BuildEvpnMulticastMessage(EnetItemType &item, stringstream &node_id, AgentRoute *route, @@ -2000,7 +2001,10 @@ bool AgentXmppChannel::BuildEvpnMulticastMessage(EnetItemType &item, nh.label = path->vxlan_id(); item.entry.nlri.ethernet_tag = nh.label; } else { - nh.label = 0; + //Before marking label as 0 check for local_peer path as well. + path = route->FindPath(agent_->local_peer()); + if (path == NULL) + nh.label = 0; } nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("vxlan"); } @@ -2197,11 +2201,12 @@ bool AgentXmppChannel::ControllerSendEvpnRouteCommon(AgentRoute *route, return false;; ret = BuildAndSendEvpnDom(item, ss_node, route, associate); } else { + const AgentPath *path = + l2_route->FindPath(agent_->multicast_peer()); if (BuildEvpnMulticastMessage(item, ss_node, route, nh_ip, vn, sg_list, communities, label, tunnel_bmap, associate, - l2_route->FindPath(agent_-> - multicast_peer()), + path, false) == false) return false; ret = BuildAndSendEvpnDom(item, ss_node, route, associate); diff --git a/src/vnsw/agent/controller/controller_peer.h b/src/vnsw/agent/controller/controller_peer.h index 1399167bb70..dd4fb522285 100644 --- a/src/vnsw/agent/controller/controller_peer.h +++ b/src/vnsw/agent/controller/controller_peer.h @@ -147,6 +147,18 @@ class AgentXmppChannel { bool associate); bool ControllerSendMcastRouteCommon(AgentRoute *route, bool associate); + bool BuildEvpnMulticastMessage(autogen::EnetItemType &item, + std::stringstream &node_id, + AgentRoute *route, + const Ip4Address *nh_ip, + const std::string &vn, + const SecurityGroupList *sg_list, + const CommunityList *communities, + uint32_t label, + uint32_t tunnel_bmap, + bool associate, + const AgentPath *path, + bool assisted_replication); protected: virtual void WriteReadyCb(const boost::system::error_code &ec); @@ -188,18 +200,6 @@ class AgentXmppChannel { const std::string &destination, const std::string &source, bool associate); - bool BuildEvpnMulticastMessage(autogen::EnetItemType &item, - std::stringstream &node_id, - AgentRoute *route, - const Ip4Address *nh_ip, - const std::string &vn, - const SecurityGroupList *sg_list, - const CommunityList *communities, - uint32_t label, - uint32_t tunnel_bmap, - bool associate, - const AgentPath *path, - bool assisted_replication); bool BuildEvpnUnicastMessage(autogen::EnetItemType &item, std::stringstream &node_id, AgentRoute *route, diff --git a/src/vnsw/agent/test/test_l2route.cc b/src/vnsw/agent/test/test_l2route.cc index 3b291ec644b..8223b0d0206 100644 --- a/src/vnsw/agent/test/test_l2route.cc +++ b/src/vnsw/agent/test/test_l2route.cc @@ -35,6 +35,10 @@ #include "kstate/test/test_kstate_util.h" #include "vr_types.h" +#include "xmpp/xmpp_init.h" +#include "xmpp_multicast_types.h" +#include +#include #include #include using namespace boost::assign; @@ -1407,6 +1411,68 @@ TEST_F(RouteTest, multiple_peer_evpn_label_check) { client->WaitForIdle(); } +// Bug# 1529665 +TEST_F(RouteTest, evpn_mcast_label_check_with_no_vm) { + client->Reset(); + AddEncapList("VXLAN", "MPLSoUDP", "MPLSoGRE"); + client->WaitForIdle(); + struct PortInfo input[] = { + {"vnet1", 1, "1.1.1.10", "00:00:01:01:01:10", 1, 1}, + }; + AddVrf("vrf1", 1); + AddVn("vn1", 1, true); + AddLink("virtual-network", "vn1", "routing-instance", "vrf1"); + client->WaitForIdle(); + BgpPeer *bgp_peer_ptr = CreateBgpPeer(Ip4Address(1), "BGP Peer1"); + boost::shared_ptr bgp_peer = + bgp_peer_ptr->GetBgpXmppPeer()->bgp_peer_id_ref(); + client->WaitForIdle(); + + BridgeRouteEntry *rt = L2RouteGet("vrf1", + MacAddress::FromString("ff:ff:ff:ff:ff:ff"), + Ip4Address(0)); + EXPECT_TRUE(rt != NULL); + RouteExport::State *route_state = static_cast + (bgp_peer_ptr->GetRouteExportState(rt->get_table_partition(), + rt)); + //EXPECT_TRUE(route_state->label_ != 0); + + autogen::EnetItemType item; + stringstream ss_node; + AgentXmppChannel *channel1 = agent_->controller_xmpp_channel(1); + SecurityGroupList sg; + CommunityList communities; + channel1->BuildEvpnMulticastMessage(item, + ss_node, + rt, + agent_->router_ip_ptr(), + "vn1", + &sg, + &communities, + route_state->label_, + TunnelType::AllType(), + true, + rt->FindPath(agent_->multicast_peer()), + false); + autogen::EnetNextHopType nh = item.entry.next_hops.next_hop.back(); + EXPECT_TRUE(nh.label != 0); + //Add VM + CreateVmportEnv(input, 1); + client->WaitForIdle(); + route_state = static_cast + (bgp_peer_ptr->GetRouteExportState(rt->get_table_partition(), + rt)); + EXPECT_TRUE(route_state->label_ != 0); + + //Delete all + DelLink("virtual-network", "vn1", "routing-instance", "vrf1"); + DeleteVmportEnv(input, 1, true); + client->WaitForIdle(); + DeleteBgpPeer(bgp_peer.get()); + client->WaitForIdle(); + bgp_peer.reset(); +} + int main(int argc, char *argv[]) { ::testing::InitGoogleTest(&argc, argv); GETUSERARGS();