diff --git a/src/vnsw/agent/controller/controller_peer.h b/src/vnsw/agent/controller/controller_peer.h index 357fd3f56e3..d318fd785eb 100644 --- a/src/vnsw/agent/controller/controller_peer.h +++ b/src/vnsw/agent/controller/controller_peer.h @@ -123,6 +123,7 @@ class AgentXmppChannel { Agent *agent() const {return agent_;} BgpPeer *bgp_peer_id() const {return bgp_peer_id_.get();} + boost::shared_ptr bgp_peer_id_ref() {return bgp_peer_id_;} std::string GetBgpPeerName() const; void UpdateConnectionInfo(xmps::PeerState state); diff --git a/src/vnsw/agent/controller/controller_route_path.cc b/src/vnsw/agent/controller/controller_route_path.cc index 46878eae871..86ae66abc29 100644 --- a/src/vnsw/agent/controller/controller_route_path.cc +++ b/src/vnsw/agent/controller/controller_route_path.cc @@ -344,3 +344,18 @@ bool ClonedLocalPath::AddChangePath(Agent *agent, AgentPath *path, bool ClonedLocalPath::IsPeerValid() const { return CheckPeerValidity(channel_, sequence_number_); } + +ControllerMulticastRoute::ControllerMulticastRoute(const string &vn_name, + uint32_t label, + int vxlan_id, + uint32_t tunnel_type, + DBRequest &nh_req, + COMPOSITETYPE comp_nh_type, + uint64_t sequence_number, + const AgentXmppChannel *channel) : + MulticastRoute(vn_name, label, vxlan_id, tunnel_type, nh_req, comp_nh_type), + sequence_number_(sequence_number), channel_(channel) { } + +bool ControllerMulticastRoute::IsPeerValid() const { + return CheckPeerValidity(channel_, sequence_number_); +} diff --git a/src/vnsw/agent/controller/controller_route_path.h b/src/vnsw/agent/controller/controller_route_path.h index 0846ff1b95a..0301e21bb21 100644 --- a/src/vnsw/agent/controller/controller_route_path.h +++ b/src/vnsw/agent/controller/controller_route_path.h @@ -247,4 +247,24 @@ class ClonedLocalPath : public AgentRouteData { const SecurityGroupList sg_list_; DISALLOW_COPY_AND_ASSIGN(ClonedLocalPath); }; + +class ControllerMulticastRoute : public MulticastRoute { +public: + ControllerMulticastRoute(const string &vn_name, + uint32_t label, + int vxlan_id, + uint32_t tunnel_type, + DBRequest &nh_req, + COMPOSITETYPE comp_nh_type, + uint64_t sequence_number, + const AgentXmppChannel *channel); + virtual ~ControllerMulticastRoute() { } + virtual bool IsPeerValid() const; + +private: + uint64_t sequence_number_; + const AgentXmppChannel *channel_; + DISALLOW_COPY_AND_ASSIGN(ControllerMulticastRoute); +}; + #endif //controller_route_path_hpp diff --git a/src/vnsw/agent/oper/bridge_route.cc b/src/vnsw/agent/oper/bridge_route.cc index 7032a435908..da4ec70fc19 100644 --- a/src/vnsw/agent/oper/bridge_route.cc +++ b/src/vnsw/agent/oper/bridge_route.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include using namespace std; @@ -229,10 +230,19 @@ void BridgeAgentRouteTable::AddBridgeBroadcastRoute(const Peer *peer, DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE); req.key.reset(new BridgeRouteKey(peer, vrf_name, MacAddress::BroadcastMac(), ethernet_tag)); - req.data.reset(new MulticastRoute(vn_name, label, - ((peer->GetType() == Peer::BGP_PEER) ? - ethernet_tag : vxlan_id), tunnel_type, - nh_req, type)); + const BgpPeer *bgp_peer = dynamic_cast(peer); + if (bgp_peer) { + req.data.reset(new ControllerMulticastRoute(vn_name, label, + ethernet_tag, tunnel_type, + nh_req, type, + bgp_peer->GetBgpXmppPeerConst()-> + unicast_sequence_number(), + bgp_peer->GetBgpXmppPeerConst())); + } else { + req.data.reset(new MulticastRoute(vn_name, label, + vxlan_id, tunnel_type, + nh_req, type)); + } BridgeTableEnqueue(Agent::GetInstance(), &req); } diff --git a/src/vnsw/agent/test/test_l2route.cc b/src/vnsw/agent/test/test_l2route.cc index 27fa0410dbf..11810a6a2b1 100644 --- a/src/vnsw/agent/test/test_l2route.cc +++ b/src/vnsw/agent/test/test_l2route.cc @@ -7,6 +7,7 @@ // #include "base/os.h" #include +#include #include #include #include @@ -693,6 +694,49 @@ TEST_F(RouteTest, Enqueue_l2_route_del_on_deleted_vrf) { client->WaitForIdle(); } +TEST_F(RouteTest, add_deleted_peer_to_multicast_route) { + struct PortInfo input[] = { + {"vnet1", 1, "1.1.1.10", "00:00:00:01:01:01", 1, 1}, + }; + + client->Reset(); + CreateVmportEnv(input, 1); + client->WaitForIdle(); + + //Add a peer and enqueue path add in multicast route. + BgpPeer *bgp_peer_ptr = CreateBgpPeer(Ip4Address(1), "BGP Peer1"); + boost::shared_ptr bgp_peer = + bgp_peer_ptr->GetBgpXmppPeer()->bgp_peer_id_ref(); + MulticastHandler *mc_handler = static_cast(agent_-> + oper_db()->multicast()); + TunnelOlist olist; + olist.push_back(OlistTunnelEntry(nil_uuid(), 10, + IpAddress::from_string("8.8.8.8").to_v4(), + TunnelType::VxlanType())); + TaskScheduler::GetInstance()->Stop(); + client->WaitForIdle(); + AgentXmppChannel::HandleAgentXmppClientChannelEvent(bgp_peer.get()->GetBgpXmppPeer(), + xmps::NOT_READY); + TaskScheduler::GetInstance()->Start(); + client->WaitForIdle(); + mc_handler->ModifyTorMembers(bgp_peer.get(), + "vrf1", + olist, + 10, + 1); + client->WaitForIdle(); + BridgeRouteEntry *rt = L2RouteGet("vrf1", + MacAddress::FromString("ff:ff:ff:ff:ff:ff"), + Ip4Address(0)); + EXPECT_FALSE(rt->FindPath(bgp_peer.get())); + + 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();