From 72efe8e70cc65b6029d3e7f322003daadd36ec64 Mon Sep 17 00:00:00 2001 From: Manish Date: Thu, 8 Jun 2017 01:17:30 +0530 Subject: [PATCH] BUM tree subscription skipped. With the introduction of same RD for Tor agent for vrf, change of vnid was not handled. In cases where a vn was added with vnid as not set or 0 and then updated later with non zero value, vrf was not notified. This used to result in skipping of notify registeration for the problematic vrf. In turn subscriptions were missed. Solution: Handle vnid change. Closes-bug: #1692795 Conflicts: src/vnsw/agent/controller/controller_vrf_export.cc src/vnsw/agent/oper/agent_route_walker.cc src/vnsw/agent/oper/vrf.cc src/vnsw/agent/oper/vrf.h Conflicts: src/vnsw/agent/oper/vrf.h Change-Id: I7ea7332eb1e64cb0e534f992ef5c8680a54b0313 --- src/vnsw/agent/controller/controller_peer.cc | 2 +- .../agent/controller/controller_vrf_export.cc | 2 +- src/vnsw/agent/oper/vrf.cc | 26 ++++++++++++++----- src/vnsw/agent/oper/vrf.h | 7 ++++- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/vnsw/agent/controller/controller_peer.cc b/src/vnsw/agent/controller/controller_peer.cc index 5e0f5df2fb0..d8faedcec48 100644 --- a/src/vnsw/agent/controller/controller_peer.cc +++ b/src/vnsw/agent/controller/controller_peer.cc @@ -1665,7 +1665,7 @@ bool AgentXmppChannel::ControllerSendSubscribe(AgentXmppChannel *peer, pugi->AddAttribute("node", vrf->GetName()); pugi->AddChildNode("options", "" ); stringstream vrf_id; - vrf_id << vrf->RDInstanceId(); + vrf_id << vrf->rd(); pugi->AddChildNode("instance-id", vrf_id.str()); datalen_ = XmppProto::EncodeMessage(impl.get(), data_, sizeof(data_)); diff --git a/src/vnsw/agent/controller/controller_vrf_export.cc b/src/vnsw/agent/controller/controller_vrf_export.cc index da0a9364bd5..9e62d4b8c97 100644 --- a/src/vnsw/agent/controller/controller_vrf_export.cc +++ b/src/vnsw/agent/controller/controller_vrf_export.cc @@ -50,7 +50,7 @@ void VrfExport::Notify(const Agent *agent, AgentXmppChannel *bgp_xmpp_peer, //building ingress replication tree bool send_subscribe = vrf->ShouldExportRoute(); - uint32_t instance_id = vrf->RDInstanceId(); + uint32_t instance_id = vrf->rd(); //Instance ID being zero is possible because of VN unavailability and VRF //ending up with NULL VRF. Reason being config sequence. //So seeing 0 instance_id delete the state so that resubscribe can be done diff --git a/src/vnsw/agent/oper/vrf.cc b/src/vnsw/agent/oper/vrf.cc index 76b110930c0..af11f65e725 100644 --- a/src/vnsw/agent/oper/vrf.cc +++ b/src/vnsw/agent/oper/vrf.cc @@ -66,7 +66,8 @@ VrfEntry::VrfEntry(const string &name, uint32_t flags, Agent *agent) : vxlan_id_(VxLanTable::kInvalidvxlan_id), rt_table_delete_bmap_(0), route_resync_walker_(NULL), allow_route_add_on_deleted_vrf_(false), - layer2_control_word_(false) { + layer2_control_word_(false), + rd_(0) { nh_.reset(); } @@ -317,7 +318,8 @@ bool VrfEntry::DBEntrySandesh(Sandesh *sresp, std::string &name) const { data.set_table_label(table_label()); VrfTable *table = static_cast(get_table()); stringstream rd; - rd << table->agent()->compute_node_ip().to_string() << ":" << RDInstanceId(); + rd << table->agent()->compute_node_ip().to_string() << ":" << + RDInstanceId(table->agent()->tor_agent_enabled()); data.set_RD(rd.str()); std::vector &list = @@ -399,9 +401,8 @@ void VrfEntry::ResyncRoutes() { // two different RD causing undefined behavior. // To avoid this both TA should generate same RD. As VN id is generated by config // it is unique and common across both TA so same can be used. -int VrfEntry::RDInstanceId() const { - Agent *agent = (static_cast(get_table()))->agent(); - if (agent->tor_agent_enabled() == false) { +int VrfEntry::RDInstanceId(bool tor_agent_enabled) const { + if (tor_agent_enabled == false) { return id_; } @@ -489,6 +490,7 @@ DBEntry *VrfTable::OperDBAdd(const DBRequest *req) { if (vrf->vn_.get()) { vrf->layer2_control_word_ = vrf->vn_->layer2_control_word(); } + vrf->set_rd(vrf->RDInstanceId(agent()->tor_agent_enabled())); return vrf; } @@ -505,9 +507,11 @@ bool VrfTable::OperDBOnChange(DBEntry *entry, const DBRequest *req) { } VnEntry *vn = agent()->vn_table()->Find(data->vn_uuid_); + bool resync_routes = false; + if (vn != vrf->vn_.get()) { + resync_routes = true; vrf->vn_.reset(vn); - vrf->ResyncRoutes(); ret = true; } @@ -532,6 +536,16 @@ bool VrfTable::OperDBOnChange(DBEntry *entry, const DBRequest *req) { ret = true; } + if (vrf->rd() != vrf->RDInstanceId(agent()->tor_agent_enabled())) { + resync_routes = true; + vrf->set_rd(vrf->RDInstanceId(agent()->tor_agent_enabled())); + ret = true; + } + + if (resync_routes) { + vrf->ResyncRoutes(); + } + uint32_t vxlan_id = VxLanTable::kInvalidvxlan_id; if (vn) { vxlan_id = vn->GetVxLanId(); diff --git a/src/vnsw/agent/oper/vrf.h b/src/vnsw/agent/oper/vrf.h index a2cb0768a45..97984cdbaf0 100644 --- a/src/vnsw/agent/oper/vrf.h +++ b/src/vnsw/agent/oper/vrf.h @@ -171,7 +171,7 @@ class VrfEntry : AgentRefCount, public AgentOperDBEntry { allow_route_add_on_deleted_vrf_ = val; } InetUnicastAgentRouteTable *GetInetUnicastRouteTable(const IpAddress &addr) const; - int RDInstanceId() const; + void ReleaseWalker(); uint32_t isid() const { return isid_; @@ -193,10 +193,14 @@ class VrfEntry : AgentRefCount, public AgentOperDBEntry { mac_aging_time_ = aging_time; } + int rd() const {return rd_;} + void set_rd(int rd) {rd_ = rd;} + private: friend class VrfTable; void CreateRouteTables(); void SetNotify(); + int RDInstanceId(bool tor_agent_enabled) const; class DeleteActor; string name_; @@ -220,6 +224,7 @@ class VrfEntry : AgentRefCount, public AgentOperDBEntry { bool learning_enabled_; bool layer2_control_word_; bool l2_; + int rd_; DISALLOW_COPY_AND_ASSIGN(VrfEntry); };