LCOV - code coverage report
Current view: top level - vnsw/agent/oper - vxlan_routing_manager.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 217 589 36.8 %
Date: 2026-08-03 02:19:58 Functions: 31 50 62.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright (c) 2022 - 2026 Matvey Kraposhin.
       4             :  * Copyright (c) 2024 - 2026 Elena Zizganova.
       5             :  */
       6             : 
       7             : #include <boost/uuid/uuid_io.hpp>
       8             : #include <cmn/agent_cmn.h>
       9             : 
      10             : #include <base/logging.h>
      11             : #include <oper/operdb_init.h>
      12             : #include <oper/route_common.h>
      13             : #include <oper/vrf.h>
      14             : #include <oper/bridge_route.h>
      15             : #include <oper/inet_unicast_route.h>
      16             : #include <oper/evpn_route.h>
      17             : #include <oper/agent_route.h>
      18             : #include <oper/agent_route_walker.h>
      19             : #include <oper/vn.h>
      20             : #include <oper/vrf.h>
      21             : #include <oper/vxlan_routing_manager.h>
      22             : #include <oper/tunnel_nh.h> //for tunnel interception
      23             : 
      24             : using namespace std;
      25             : 
      26           6 : VxlanRoutingState::VxlanRoutingState(VxlanRoutingManager *mgr,
      27           6 :                                      VrfEntry *vrf) {
      28           6 :    inet4_table_ = vrf->GetInet4UnicastRouteTable();
      29           6 :    inet6_table_ = vrf->GetInet6UnicastRouteTable();
      30           6 :    evpn_table_ = vrf->GetEvpnRouteTable();
      31          12 :    std::string nm4 = std::string("vxlan_lstnr.") + inet4_table_->name();
      32          12 :    std::string nm6 = std::string("vxlan_lstnr.") + inet6_table_->name();
      33          12 :    std::string nme = std::string("vxlan_lstnr.") + evpn_table_->name();
      34             : 
      35          12 :    inet4_id_ = inet4_table_->
      36           6 :        Register(boost::bind(&VxlanRoutingManager::RouteNotify,
      37             :        mgr, _1, _2), nm4);
      38          12 :    inet6_id_ = inet6_table_->
      39           6 :        Register(boost::bind(&VxlanRoutingManager::RouteNotify,
      40             :        mgr, _1, _2), nm6);
      41          12 :    evpn_id_ = evpn_table_->
      42           6 :        Register(boost::bind(&VxlanRoutingManager::RouteNotify,
      43             :        mgr, _1, _2), nme);
      44           6 : }
      45             : 
      46          12 : VxlanRoutingState::~VxlanRoutingState() {
      47           6 :    evpn_table_->Unregister(evpn_id_);
      48           6 :    inet4_table_->Unregister(inet4_id_);
      49           6 :    inet6_table_->Unregister(inet6_id_);
      50          12 : }
      51             : 
      52           6 : VxlanRoutingVnState::VxlanRoutingVnState(VxlanRoutingManager *mgr) :
      53          12 :     vmi_list_(), is_routing_vn_(false),
      54           6 :     logical_router_uuid_(boost::uuids::nil_uuid()), mgr_(mgr) {
      55           6 : }
      56             : 
      57          12 : VxlanRoutingVnState::~VxlanRoutingVnState() {
      58          12 : }
      59             : 
      60           0 : void VxlanRoutingVnState::AddVmi(const VnEntry *vn, const VmInterface *vmi) {
      61           0 :     if (vmi->logical_router_uuid() == boost::uuids::nil_uuid()) {
      62           0 :         LOG(ERROR, "Error in VxlanRoutingManager::AddVmi"
      63             :         << ", vmi->logical_router_uuid() ==  boost::uuids::nil_uuid()");
      64           0 :         assert(vmi->logical_router_uuid() != boost::uuids::nil_uuid());
      65             :     }
      66           0 :     VmiListIter it = vmi_list_.find(vmi);
      67           0 :     if (it != vmi_list_.end()) {
      68           0 :         return;
      69             :     }
      70             : 
      71           0 :     vmi_list_.insert(vmi);
      72           0 :     if ((logical_router_uuid_ != vmi->logical_router_uuid()) &&
      73           0 :         (*(vmi_list_.begin()) == vmi)) {
      74           0 :         mgr_->BridgeVnNotify(vn, this);
      75             :     }
      76             : }
      77             : 
      78           0 : void VxlanRoutingVnState::DeleteVmi(const VnEntry *vn, const VmInterface *vmi) {
      79           0 :     VmiListIter it = vmi_list_.find(vmi);
      80           0 :     if (it == vmi_list_.end()) {
      81           0 :         return;
      82             :     }
      83           0 :     vmi_list_.erase(vmi);
      84           0 :     mgr_->BridgeVnNotify(vn, this);
      85             : }
      86             : 
      87           0 : VxlanRoutingVmiState::VxlanRoutingVmiState() :
      88           0 :     vn_entry_(NULL), logical_router_uuid_(boost::uuids::nil_uuid()) {
      89           0 : }
      90             : 
      91           0 : VxlanRoutingVmiState::~VxlanRoutingVmiState() {
      92           0 : }
      93             : 
      94           0 : boost::uuids::uuid VxlanRoutingVnState::logical_router_uuid() const {
      95           0 :     if (vmi_list_.size() == 0)
      96           0 :         return boost::uuids::nil_uuid();
      97             : 
      98           0 :     return (*(vmi_list_.begin()))->logical_router_uuid();
      99             : }
     100             : 
     101           3 : VxlanRoutingRouteWalker::VxlanRoutingRouteWalker(const std::string &name,
     102           3 :     VxlanRoutingManager *mgr, Agent *agent) :
     103           3 :     AgentRouteWalker(name, agent), mgr_(mgr) {
     104           3 : }
     105             : 
     106           6 : VxlanRoutingRouteWalker::~VxlanRoutingRouteWalker() {
     107           6 : }
     108             : 
     109             : // Only take notification of bridge inet routes.
     110             : // Change in them will trigger change in rest.
     111           0 : bool VxlanRoutingRouteWalker::RouteWalkNotify(DBTablePartBase *partition,
     112             :     DBEntryBase *e) {
     113             :     // Now route leaking is triggered by changes in the Inet table of
     114             :     // a bridge VRF instance
     115             :     const InetUnicastRouteEntry *inet_rt =
     116           0 :         dynamic_cast<const InetUnicastRouteEntry*>(e);
     117           0 :     if (inet_rt) {
     118           0 :         const VrfEntry *vrf = inet_rt->vrf();
     119           0 :         if (vrf && vrf->vn() && !mgr_->IsRoutingVrf(vrf)) {
     120           0 :             mgr_->InetRouteNotify(partition, e);
     121             :         }
     122             :     }
     123           0 :     return true;
     124             : }
     125             : 
     126           3 : VxlanRoutingVrfMapper::VxlanRoutingVrfMapper(VxlanRoutingManager *mgr) :
     127           3 :     mgr_(mgr), lr_vrf_info_map_(), vn_lr_set_(),
     128           6 :     inet4_table_walker_(), inet6_table_walker_() {
     129           3 : }
     130             : 
     131           3 : VxlanRoutingVrfMapper::~VxlanRoutingVrfMapper() {
     132           3 : }
     133             : 
     134           3 : void VxlanRoutingVrfMapper::WalkBridgeInetTables(
     135             :     InetUnicastAgentRouteTable *inet4_table,
     136             :     InetUnicastAgentRouteTable *inet6_table) {
     137             :     // Inet 4
     138             :     {
     139           3 :         DBTable::DBTableWalkRef walk_ref;
     140           3 :         InetTableWalker::iterator it = inet4_table_walker_.find(inet4_table);
     141           3 :         if (it == inet4_table_walker_.end()) {
     142             :             walk_ref = inet4_table->
     143           6 :                 AllocWalker(boost::bind(&VxlanRoutingManager::RouteNotify,
     144             :                                         mgr_, _1, _2),
     145             :                             boost::bind(&VxlanRoutingVrfMapper::BridgeInet4RouteWalkDone,
     146           3 :                                         this, _1, _2));
     147           3 :             inet4_table_walker_[inet4_table] = walk_ref;
     148             :         } else {
     149           0 :             walk_ref = it->second;
     150             :         }
     151           3 :         inet4_table->WalkAgain(walk_ref);
     152             :         //Every time walk is issued for bridge table revisit subnet routes
     153           3 :         mgr_->HandleSubnetRoute(inet4_table->vrf_entry());
     154           3 :     }
     155             :     // Inet 6
     156             :     {
     157           3 :         DBTable::DBTableWalkRef walk_ref;
     158           3 :         InetTableWalker::iterator it = inet6_table_walker_.find(inet6_table);
     159           3 :         if (it == inet6_table_walker_.end()) {
     160             :             walk_ref = inet6_table->
     161           6 :                 AllocWalker(boost::bind(&VxlanRoutingManager::RouteNotify,
     162             :                                         mgr_, _1, _2),
     163             :                             boost::bind(&VxlanRoutingVrfMapper::BridgeInet6RouteWalkDone,
     164           3 :                                         this, _1, _2));
     165           3 :             inet6_table_walker_[inet6_table] = walk_ref;
     166             :         } else {
     167           0 :             walk_ref = it->second;
     168             :         }
     169           3 :         inet6_table->WalkAgain(walk_ref);
     170             :         //Every time walk is issued for bridge table revisit subnet routes
     171           3 :         mgr_->HandleSubnetRoute(inet6_table->vrf_entry());
     172           3 :     }
     173           3 : }
     174             : 
     175           0 : void VxlanRoutingVrfMapper::WalkRoutingVrf(const boost::uuids::uuid &lr_uuid,
     176             :                     const VnEntry *vn, bool update, bool withdraw) {
     177           0 :     if (lr_uuid == boost::uuids::nil_uuid())
     178           0 :         return;
     179             :     VxlanRoutingVrfMapper::RoutedVrfInfo &routing_vrf_info =
     180           0 :             lr_vrf_info_map_[lr_uuid];
     181           0 :     const VrfEntry *routing_vrf = routing_vrf_info.routing_vrf_;
     182           0 :     DBTable::DBTableWalkRef walk_ref;
     183             : 
     184           0 :     if (withdraw) {
     185           0 :         InetUnicastAgentRouteTable *inet4_table = nullptr;
     186           0 :         InetUnicastAgentRouteTable *inet6_table = nullptr;
     187           0 :         const VrfEntry *bridge_vrf = VxlanRoutingManager::VnVrf(vn,
     188           0 :             routing_vrf_info.bridge_vrf_names_list_[vn]);
     189           0 :         if (bridge_vrf && routing_vrf) {
     190           0 :             inet4_table = bridge_vrf->GetInet4UnicastRouteTable();
     191           0 :             inet6_table = bridge_vrf->GetInet6UnicastRouteTable();
     192             :         }
     193           0 :         if (inet4_table) {
     194             :             walk_ref = inet4_table->
     195           0 :             AllocWalker(boost::bind(
     196             :                 &VxlanRoutingManager::WithdrawEvpnRouteFromRoutingVrf,
     197             :                 mgr_, routing_vrf, _1, _2),
     198             :                 boost::bind(&VxlanRoutingVrfMapper::RoutingVrfRouteWalkDone,
     199           0 :                 this, _1, _2));
     200           0 :             inet4_table->WalkAgain(walk_ref);
     201             :         }
     202           0 :         if (inet6_table) {
     203             :             walk_ref = inet6_table->
     204           0 :             AllocWalker(boost::bind(
     205             :                 &VxlanRoutingManager::WithdrawEvpnRouteFromRoutingVrf,
     206             :                 mgr_, routing_vrf, _1, _2),
     207             :                 boost::bind(&VxlanRoutingVrfMapper::RoutingVrfRouteWalkDone,
     208           0 :                 this, _1, _2));
     209           0 :             inet6_table->WalkAgain(walk_ref);
     210             :         }
     211             :     } else {
     212           0 :         EvpnAgentRouteTable *evpn_table = NULL;
     213           0 :         if (routing_vrf) {
     214             :             evpn_table =
     215             :             static_cast<EvpnAgentRouteTable *>(
     216           0 :                 routing_vrf->GetEvpnRouteTable());
     217             :         }
     218           0 :         if (!evpn_table) {
     219           0 :             return;
     220             :         }
     221             : 
     222             :         walk_ref = evpn_table->
     223           0 :         AllocWalker(boost::bind(&VxlanRoutingManager::LeakRoutesIntoBridgeTables,
     224             :             mgr_, _1, _2, lr_uuid, vn, update),
     225             :             boost::bind(&VxlanRoutingVrfMapper::RoutingVrfRouteWalkDone,
     226           0 :             this, _1, _2));
     227           0 :         evpn_table->WalkAgain(walk_ref);
     228             :     }
     229           0 : }
     230             : 
     231           0 : void VxlanRoutingVrfMapper::RoutingVrfRouteWalkDone(DBTable::DBTableWalkRef walk_ref,
     232             :                                           DBTableBase *partition) {
     233           0 :     if (walk_ref.get() != NULL)
     234           0 :         (static_cast<DBTable *>(partition))->ReleaseWalker(walk_ref);
     235           0 : }
     236             : 
     237           3 : void VxlanRoutingVrfMapper::BridgeInet4RouteWalkDone(DBTable::DBTableWalkRef walk_ref,
     238             :                                           DBTableBase *partition) {
     239             :     const InetUnicastAgentRouteTable *table = static_cast<const InetUnicastAgentRouteTable *>
     240           3 :         (walk_ref->table());
     241           3 :     InetTableWalker::iterator it = inet4_table_walker_.find(table);
     242           3 :     if(it == inet4_table_walker_.end()) {
     243           0 :         LOG(ERROR, "Error in VxlanRoutingManager::BridgeInet4RouteWalkDone"
     244             :         << ", it == inet4_table_walker_.end()");
     245           0 :         assert(it != inet4_table_walker_.end());
     246             :     }
     247           3 :     inet4_table_walker_.erase(it);
     248           3 : }
     249             : 
     250           3 : void VxlanRoutingVrfMapper::BridgeInet6RouteWalkDone(DBTable::DBTableWalkRef walk_ref,
     251             :                                           DBTableBase *partition) {
     252             :     const InetUnicastAgentRouteTable *table = static_cast<const InetUnicastAgentRouteTable *>
     253           3 :         (walk_ref->table());
     254           3 :     InetTableWalker::iterator it = inet6_table_walker_.find(table);
     255           3 :     if(it == inet6_table_walker_.end()){    
     256           0 :         LOG(ERROR, "Error in VxlanRoutingManager::BridgeInet6RouteWalkDone"
     257             :         << ", it == inet6_table_walker_.end()");
     258           0 :         assert(it != inet6_table_walker_.end());
     259             :     }
     260             : 
     261           3 :     inet6_table_walker_.erase(it);
     262           3 : }
     263             : 
     264           0 : void VxlanRoutingVrfMapper::WalkRoutingVrfRemoveExternalRoutes(
     265             :      const boost::uuids::uuid &lr_uuid, const VnEntry *vn,
     266             :      std::string bridge_vrf_name) {
     267           0 :     if (lr_uuid == boost::uuids::nil_uuid())
     268           0 :         return;
     269             :     VxlanRoutingVrfMapper::RoutedVrfInfo &routing_vrf_info =
     270           0 :             lr_vrf_info_map_[lr_uuid];
     271           0 :     const VrfEntry *routing_vrf = routing_vrf_info.routing_vrf_;
     272           0 :     DBTable::DBTableWalkRef walk_ref;
     273             : 
     274           0 :     EvpnAgentRouteTable *evpn_table = nullptr;
     275           0 :     if (routing_vrf != nullptr) {
     276             :         evpn_table =
     277             :         static_cast<EvpnAgentRouteTable *>(
     278           0 :             routing_vrf->GetEvpnRouteTable());
     279             :     }
     280           0 :     if (evpn_table == nullptr) {
     281           0 :         return;
     282             :     }
     283             : 
     284             :     walk_ref = evpn_table->
     285           0 :     AllocWalker(boost::bind(
     286             :         &VxlanRoutingManager::RemoveRoutesFromRoutingToBridgeVrf,
     287             :         mgr_, _1, _2, vn, bridge_vrf_name),
     288             :         boost::bind(&VxlanRoutingVrfMapper::RoutingVrfRouteWalkDone,
     289           0 :         this, _1, _2));
     290           0 :     evpn_table->WalkAgain(walk_ref);
     291           0 : }
     292             : 
     293           0 : void VxlanRoutingVrfMapper::WalkBridgeVrfs
     294             : (const VxlanRoutingVrfMapper::RoutedVrfInfo &routed_vrf_info)
     295             : {
     296             :     // Start walk on all l3 tables
     297             :     VxlanRoutingVrfMapper::RoutedVrfInfo::BridgeVnListIter it =
     298           0 :         routed_vrf_info.bridge_vn_list_.begin();
     299           0 :     while (it != routed_vrf_info.bridge_vn_list_.end()) {
     300           0 :         const VnEntry *vn = static_cast<const VnEntry *>(*it);
     301           0 :         const VrfEntry *vrf = VxlanRoutingManager::VnVrf(vn,
     302           0 :             routed_vrf_info.bridge_vrf_names_list_.at(vn));
     303           0 :         if (vrf) {
     304             :             InetUnicastAgentRouteTable *inet4_table =
     305             :                 static_cast<InetUnicastAgentRouteTable *>
     306           0 :                 (vrf->GetInet4UnicastRouteTable());
     307             :                 InetUnicastAgentRouteTable *inet6_table =
     308             :                 static_cast<InetUnicastAgentRouteTable *>
     309           0 :                 (vrf->GetInet6UnicastRouteTable());
     310           0 :             if (!inet4_table || !inet6_table)
     311           0 :                 continue;
     312           0 :             WalkBridgeInetTables(inet4_table, inet6_table);
     313             :         }
     314           0 :         it++;
     315             :     }
     316           0 : }
     317             : 
     318           6 : const VrfEntry *VxlanRoutingVrfMapper::GetRoutingVrfUsingVn
     319             : (const VnEntry *vn) {
     320           6 :     VnLrSetIter it = vn_lr_set_.find(vn);
     321           6 :     if (it != vn_lr_set_.end()) {
     322           0 :         return GetRoutingVrfUsingUuid(it->second);
     323             :     }
     324           6 :     return NULL;
     325             : }
     326             : 
     327          60 : const VrfEntry *VxlanRoutingVrfMapper::GetRoutingVrfUsingAgentRoute
     328             : (const AgentRoute *rt) {
     329          60 :     return GetRoutingVrfUsingUuid(GetLogicalRouterUuidUsingRoute(rt));
     330             : }
     331             : 
     332          60 : const VrfEntry *VxlanRoutingVrfMapper::GetRoutingVrfUsingUuid
     333             : (const boost::uuids::uuid &lr_uuid) {
     334          60 :     LrVrfInfoMapIter it = lr_vrf_info_map_.find(lr_uuid);
     335          60 :     if (it != lr_vrf_info_map_.end()) {
     336           0 :         return it->second.routing_vrf_;
     337             :     }
     338          60 :     return NULL;
     339             : }
     340             : 
     341          60 : const boost::uuids::uuid VxlanRoutingVrfMapper::GetLogicalRouterUuidUsingRoute
     342             : (const AgentRoute *rt) {
     343             :     using boost::uuids::nil_uuid;
     344             : 
     345          60 :     if (VxlanRoutingManager::IsRoutingVrf(rt->vrf())) {
     346           0 :         return rt->vrf()->vn()->logical_router_uuid();
     347             :     }
     348             : 
     349          60 :     const VnEntry* rt_vn = rt->vrf()->vn();
     350          60 :     if (!rt_vn) {
     351           0 :         return nil_uuid();
     352             :     }
     353             : 
     354             :     const VxlanRoutingVnState *vn_state =
     355          60 :         dynamic_cast<const VxlanRoutingVnState *>(rt_vn->
     356          60 :                            GetAgentDBEntryState(mgr_->vn_listener_id()));
     357          60 :     if ((vn_state == NULL) || (vn_state->vmi_list_.size() == 0)) {
     358          60 :         return nil_uuid();
     359             :     }
     360             : 
     361           0 :     return vn_state->logical_router_uuid_;
     362             : }
     363             : 
     364             : // Invoked everytime when a vrf is pulled out of use.
     365             : // Holds on object till all bridge and routing vrf are gone.
     366           0 : void VxlanRoutingVrfMapper::TryDeleteLogicalRouter(LrVrfInfoMapIter &it) {
     367           0 :     if ((it->second.routing_vrf_ == NULL) &&
     368           0 :         (it->second.bridge_vn_list_.size() == 0)) {
     369           0 :         lr_vrf_info_map_.erase(it);
     370             :     }
     371           0 : }
     372             : 
     373             : const Peer *VxlanRoutingManager::routing_vrf_interface_peer_ = NULL;
     374             : const Peer *VxlanRoutingManager::routing_vrf_vxlan_bgp_peer_ = NULL;
     375             : 
     376             : /**
     377             :  * VxlanRoutingManager
     378             :  */
     379           3 : VxlanRoutingManager::VxlanRoutingManager(Agent *agent) :
     380           6 :     agent_(agent), walker_(), vn_listener_id_(),
     381           3 :     vrf_listener_id_(), vmi_listener_id_(), vrf_mapper_(this) {
     382             :     //routing_vrf_interface_peer_ = agent_->evpn_routing_peer();
     383           3 :     routing_vrf_interface_peer_ = agent_->local_vm_export_peer();
     384           3 :     routing_vrf_vxlan_bgp_peer_ = agent_->vxlan_bgp_peer();
     385           3 : }
     386             : 
     387           6 : VxlanRoutingManager::~VxlanRoutingManager() {
     388           6 : }
     389             : 
     390           3 : void VxlanRoutingManager::Register() {
     391             :    // Walker to go through routes in bridge evpn tables.
     392           6 :    walker_.reset(new VxlanRoutingRouteWalker("VxlanRoutingManager", this,
     393           3 :                                              agent_));
     394           3 :    agent_->oper_db()->agent_route_walk_manager()->
     395           3 :        RegisterWalker(static_cast<AgentRouteWalker *>(walker_.get()));
     396             : 
     397             :    // Register all listener ids.
     398           3 :    vn_listener_id_ = agent_->vn_table()->
     399           3 :        Register(boost::bind(&VxlanRoutingManager::VnNotify,
     400             :                             this, _1, _2));
     401           3 :    vrf_listener_id_ = agent_->vrf_table()->Register(
     402             :        boost::bind(&VxlanRoutingManager::VrfNotify, this, _1, _2));
     403           3 :    vmi_listener_id_ = agent_->interface_table()->Register(
     404             :        boost::bind(&VxlanRoutingManager::VmiNotify, this, _1, _2));
     405           3 : }
     406             : 
     407           3 : void VxlanRoutingManager::Shutdown() {
     408           3 :    agent_->vn_table()->Unregister(vn_listener_id_);
     409           3 :    agent_->vrf_table()->Unregister(vrf_listener_id_);
     410           3 :    agent_->interface_table()->Unregister(vmi_listener_id_);
     411           3 :    agent_->oper_db()->agent_route_walk_manager()->
     412           3 :        ReleaseWalker(walker_.get());
     413           3 :    walker_.reset(NULL);
     414           3 : }
     415             : 
     416             : /**
     417             :  * VNNotify
     418             :  * Handles routing vrf i.e. VRF meant for doing evpn routing.
     419             :  * Addition or deletion of same add/withdraws route imported from bridge vrf in
     420             :  * routing vrf.
     421             :  * Walk is issued for the routes of bridge vrf's evpn table.
     422             :  *
     423             :  * For bridge VRF, only delete of VN is handled here. Add has no operation as
     424             :  * add of VN does not give any info on LR/Routing VRF to use.
     425             :  * When delete is seen withdraw from the list of bridge list.
     426             :  */
     427          19 : void VxlanRoutingManager::VnNotify(DBTablePartBase *partition, DBEntryBase *e) {
     428          19 :     VnEntry *vn = dynamic_cast<VnEntry *>(e);
     429          19 :     VxlanRoutingVnState *vn_state = dynamic_cast<VxlanRoutingVnState *>
     430          19 :         (vn->GetAgentDBEntryState(vn_listener_id_));
     431             : 
     432          19 :     if (vn->IsDeleted() && vn_state != NULL) {
     433           6 :         if (vn_state->is_routing_vn_) {
     434           0 :             RoutingVnNotify(vn, vn_state);
     435             :         } else {
     436           6 :             BridgeVnNotify(vn, vn_state);
     437             :         }
     438             : 
     439             :         //Delete State
     440           6 :         vn->ClearState(partition->parent(), vn_listener_id_);
     441           6 :         delete vn_state;
     442           6 :         return;
     443             :     }
     444             : 
     445             :     // if the VN had been deleted previously
     446          13 :     if (!vn_state && vn->IsDeleted()) {
     447           0 :         return;
     448             :     }
     449             : 
     450          13 :     if (!vn_state) {
     451           6 :         vn_state = new VxlanRoutingVnState(this);
     452           6 :         vn->SetState(partition->parent(), vn_listener_id_, vn_state);
     453             :     }
     454             : 
     455          13 :     if (vn->vxlan_routing_vn()) {
     456           0 :         vn_state->is_routing_vn_ = vn->vxlan_routing_vn();
     457             :     }
     458             : 
     459          13 :     vn_state->vrf_ref_ = vn->GetVrf();
     460          13 :     if (vn_state->is_routing_vn_) {
     461           0 :         vn_state->logical_router_uuid_ = vn->logical_router_uuid();
     462           0 :         RoutingVnNotify(vn, vn_state);
     463             :     } else {
     464          13 :         BridgeVnNotify(vn, vn_state);
     465             :     }
     466             : 
     467          13 :     return;
     468             : }
     469             : 
     470          19 : void UpdateLogicalRouterUuid(const VnEntry *vn,
     471             :                              VxlanRoutingVnState *vn_state) {
     472             :     using boost::uuids::nil_uuid;
     473             : 
     474          19 :     if (vn_state->vmi_list_.size() == 0) {
     475          19 :         vn_state->logical_router_uuid_ = nil_uuid();
     476             :     }
     477             : 
     478          19 :     VxlanRoutingVnState::VmiListIter it = vn_state->vmi_list_.begin();
     479          19 :     while (it != vn_state->vmi_list_.end()) {
     480           0 :         vn_state->logical_router_uuid_ = (*it)->logical_router_uuid();
     481           0 :         if ((*it)->logical_router_uuid() != nil_uuid()) {
     482           0 :             return;
     483             :         }
     484             :         //Delete VMI with no lr uuid, vmi update will handle rest.
     485           0 :         vn_state->vmi_list_.erase(it);
     486           0 :         if (vn_state->vmi_list_.size() == 0) {
     487           0 :             vn_state->logical_router_uuid_ = nil_uuid();
     488           0 :             return;
     489             :         }
     490           0 :         it = vn_state->vmi_list_.begin();
     491             :     }
     492          19 :     return;
     493             : }
     494             : 
     495          19 : void VxlanRoutingManager::BridgeVnNotify(const VnEntry *vn,
     496             :                                          VxlanRoutingVnState *vn_state) {
     497             :     using boost::uuids::nil_uuid;
     498             : 
     499          19 :     if (vn->logical_router_uuid() != nil_uuid()) {
     500           0 :         return;
     501             :     }
     502             : 
     503          19 :     VxlanRoutingVrfMapper::VnLrSetIter it = vrf_mapper_.vn_lr_set_.find(vn);
     504             :     VxlanRoutingVrfMapper::LrVrfInfoMapIter routing_info_it =
     505          19 :         vrf_mapper_.lr_vrf_info_map_.end();
     506          19 :     VrfEntry *vn_vrf = vn->GetVrf();
     507          19 :     bool withdraw = false;
     508          19 :     bool update = true;
     509             : 
     510             :     // Update lr uuid in case some vmi is deleted or added.
     511          19 :     UpdateLogicalRouterUuid(vn, vn_state);
     512          19 :     if (vn->IsDeleted() || (vn_vrf == nullptr)) {
     513          16 :         withdraw = true;
     514          16 :         update = false;
     515             :     }
     516             : 
     517          19 :     if (it != vrf_mapper_.vn_lr_set_.end() &&
     518          19 :         (it->second != vn_state->logical_router_uuid_) &&
     519          19 :         (vn_state->logical_router_uuid_ != nil_uuid())) {
     520           0 :         withdraw = true;
     521             :     }
     522             : 
     523          19 :     if (vn_state->logical_router_uuid_ == nil_uuid()) {
     524          19 :         withdraw = true;
     525          19 :         update = false;
     526             :     }
     527             : 
     528          19 :     if (it != vrf_mapper_.vn_lr_set_.end()) {
     529           0 :         routing_info_it = vrf_mapper_.lr_vrf_info_map_.find(it->second);
     530             :     }
     531             : 
     532             :     // Handles deletion case
     533          19 :     if (withdraw) {
     534          19 :         if (routing_info_it != vrf_mapper_.lr_vrf_info_map_.end()) {
     535             :             VxlanRoutingVrfMapper::RoutedVrfInfo::BridgeVnListIter br_it =
     536           0 :                 routing_info_it->second.bridge_vn_list_.find(vn);
     537           0 :             std::string vrf_name = "";
     538           0 :             if (routing_info_it->second.bridge_vrf_names_list_.count(vn) == 1) {
     539           0 :                 vrf_name = routing_info_it->second.bridge_vrf_names_list_.at(vn);
     540           0 :                 DeleteSubnetRoute(vn, vrf_name);
     541             :             }
     542           0 :             if (br_it != routing_info_it->second.bridge_vn_list_.end()) {
     543           0 :                 vrf_mapper_.WalkRoutingVrf(it->second, vn, false, true);
     544           0 :                 routing_info_it->second.bridge_vn_list_.erase(br_it);
     545           0 :                 routing_info_it->second.bridge_vrf_names_list_.erase(vn);
     546           0 :                 vrf_mapper_.WalkRoutingVrfRemoveExternalRoutes(it->second, vn,
     547             :                                                                vrf_name);
     548             :             }
     549             :             // Trigger delete of logical router
     550           0 :             vrf_mapper_.TryDeleteLogicalRouter(routing_info_it);
     551           0 :         }
     552          19 :         vrf_mapper_.vn_lr_set_.erase(vn);
     553             :     }
     554             : 
     555          19 :     if (update) {
     556           0 :         vrf_mapper_.vn_lr_set_[vn] = vn_state->logical_router_uuid_;
     557           0 :         if (vrf_mapper_.vn_lr_set_[vn] == nil_uuid()) {
     558           0 :             return;
     559             :         }
     560             : 
     561             :         VxlanRoutingVrfMapper::RoutedVrfInfo &lr_vrf_info =
     562           0 :             vrf_mapper_.lr_vrf_info_map_[vn_state->logical_router_uuid_];
     563           0 :         lr_vrf_info.bridge_vn_list_.insert(vn);
     564           0 :         if (vn->GetVrf())
     565           0 :             lr_vrf_info.bridge_vrf_names_list_[vn] = vn->GetVrf()->GetName();
     566             :         else {
     567           0 :             lr_vrf_info.bridge_vrf_names_list_[vn] = std::string{""};
     568             :         }
     569           0 :         vrf_mapper_.WalkRoutingVrf(vrf_mapper_.vn_lr_set_[vn], vn, true, false);
     570             :     }
     571             : 
     572             :     // Without vrf walks cant be scheduled
     573          19 :     if (!vn_state->vrf_ref_.get()) {
     574          16 :         return;
     575             :     }
     576             : 
     577             :     // Walk Evpn table if withdraw or update was done
     578           3 :     if (update || withdraw) {
     579             :         InetUnicastAgentRouteTable *inet4_table =
     580             :             static_cast<InetUnicastAgentRouteTable *>(vn_state->vrf_ref_.get()->
     581           3 :                                                GetInet4UnicastRouteTable());
     582             :         InetUnicastAgentRouteTable *inet6_table =
     583             :             static_cast<InetUnicastAgentRouteTable *>(vn_state->vrf_ref_.get()->
     584           3 :                                                GetInet6UnicastRouteTable());
     585           3 :         if (inet4_table && inet6_table) {
     586           3 :             vrf_mapper_.WalkBridgeInetTables(inet4_table, inet6_table);
     587             :         }
     588             :     }
     589           3 :     return;
     590             : }
     591             : 
     592           0 : void VxlanRoutingManager::RoutingVrfDeleteAllRoutes(VrfEntry* rt_vrf) {
     593           0 :     if (rt_vrf == nullptr) {
     594           0 :         return;
     595             :     }
     596             :     // Loop over all EVPN routes and delete them
     597             : 
     598           0 :     EvpnAgentRouteTable *evpn_table = dynamic_cast<EvpnAgentRouteTable *>
     599           0 :         (rt_vrf->GetEvpnRouteTable());
     600           0 :     if (evpn_table == nullptr) {
     601           0 :         return;
     602             :     }
     603           0 :     EvpnRouteEntry *c_entry = dynamic_cast<EvpnRouteEntry *>
     604           0 :         (evpn_table->GetTablePartition(0)->GetFirst());
     605             : 
     606           0 :     const std::string vrf_name = rt_vrf->GetName();
     607           0 :     const uint32_t ethernet_tag = 0;
     608           0 :     const MacAddress mac_addr;
     609           0 :     while (c_entry != nullptr) {
     610           0 :         const IpAddress &prefix_ip = c_entry->prefix_address();
     611           0 :         const uint8_t plen = c_entry->prefix_length();
     612           0 :         const AgentPath *rt_active_path = c_entry->GetActivePath();
     613           0 :         const Peer *rt_active_peer = nullptr;
     614           0 :         const auto &path_list = c_entry->GetPathList();
     615           0 :         if (rt_active_path != nullptr)
     616           0 :             rt_active_peer = rt_active_path->peer();
     617             : 
     618             :         // Compute next entry in advance
     619           0 :         if (c_entry != nullptr && c_entry->get_table_partition()) {
     620           0 :             c_entry = dynamic_cast<EvpnRouteEntry *>
     621           0 :                 (c_entry->get_table_partition()->GetNext(c_entry));
     622             :         } else {
     623           0 :             break;
     624             :         }
     625             : 
     626           0 :         InetUnicastAgentRouteTable::DeleteReq(routing_vrf_interface_peer_,
     627             :                                               vrf_name, prefix_ip, plen,
     628             :                                               nullptr);
     629           0 :         InetUnicastAgentRouteTable::DeleteReq(routing_vrf_vxlan_bgp_peer_,
     630             :                                               vrf_name, prefix_ip, plen,
     631             :                                               nullptr);
     632             : 
     633           0 :         if ((rt_active_peer != nullptr) &&
     634           0 :             (rt_active_peer->GetType() != Peer::BGP_PEER)) {
     635             :             // Delete routes originated from bridge networks
     636           0 :             EvpnAgentRouteTable::DeleteReq(rt_active_peer,
     637             :                                            vrf_name,
     638             :                                            mac_addr,
     639             :                                            prefix_ip,
     640             :                                            plen,
     641             :                                            ethernet_tag,  // ethernet_tag = 0 for Type5
     642             :                                            nullptr);
     643             :         } else {
     644           0 :             for (auto &path_ref : path_list) {
     645           0 :                 EvpnAgentRouteTable::DeleteReq(
     646             :                     static_cast<const AgentPath*>
     647             :                         (&path_ref)->peer(),
     648             :                     vrf_name,
     649             :                     mac_addr,
     650             :                     prefix_ip,
     651             :                     plen,
     652             :                     ethernet_tag,  // ethernet_tag = 0 for Type5
     653             :                     nullptr);
     654             :            }
     655             :         }
     656             :     }
     657           0 : }
     658             : 
     659           0 : void VxlanRoutingManager::RoutingVnNotify(const VnEntry *vn,
     660             :                                           VxlanRoutingVnState *vn_state) {
     661             : 
     662           0 :     bool withdraw = false;
     663           0 :     bool update = false;
     664           0 :     VxlanRoutingVrfMapper::VnLrSetIter it = vrf_mapper_.vn_lr_set_.find(vn);
     665             : 
     666           0 :     if (vn->IsDeleted() ||
     667           0 :         (vn->GetVrf() == NULL) ||
     668           0 :         (vn_state->is_routing_vn_ == false)) {
     669           0 :         update = false;
     670           0 :         withdraw = true;
     671             :     } else {
     672           0 :         update = true;
     673           0 :         if (it != vrf_mapper_.vn_lr_set_.end()) {
     674             :             // LR uuid changed, so withdraw from old and add new.
     675           0 :             if (it->second != vn_state->logical_router_uuid_) {
     676           0 :                 withdraw = true;
     677             :             }
     678             :         }
     679             :     }
     680             : 
     681           0 :     if (withdraw && (it != vrf_mapper_.vn_lr_set_.end())) {
     682             :         VxlanRoutingVrfMapper::LrVrfInfoMapIter routing_info_it =
     683           0 :             vrf_mapper_.lr_vrf_info_map_.find(it->second);
     684             :         // Delete only if parent VN is same as notified VN coz it may so happen
     685             :         // that some other VN has taken the ownership  of this LR and
     686             :         // notification of same came before this VN.
     687           0 :         if (routing_info_it != vrf_mapper_.lr_vrf_info_map_.end()) {
     688           0 :             if (routing_info_it->second.routing_vn_ == vn) {
     689           0 :                 RoutingVrfDeleteAllRoutes(
     690           0 :                     routing_info_it->second.routing_vrf_);
     691             :                 // Routing VN/VRF
     692             :                 // Reset parent vn and routing vrf
     693           0 :                 routing_info_it->second.routing_vn_ = nullptr;
     694           0 :                 routing_info_it->second.routing_vrf_ = nullptr;
     695             :             }
     696             :             // Trigger delete of logical router
     697           0 :             vrf_mapper_.TryDeleteLogicalRouter(routing_info_it);
     698             :         }
     699           0 :         vrf_mapper_.vn_lr_set_.erase(it);
     700             :     }
     701             : 
     702           0 :     if (update) {
     703           0 :         if (vn_state->logical_router_uuid_ == boost::uuids::nil_uuid()) {
     704           0 :             return;
     705             :         }
     706             : 
     707           0 :         if (it == vrf_mapper_.vn_lr_set_.end()) {
     708           0 :             vrf_mapper_.vn_lr_set_[vn] = vn_state->logical_router_uuid_;
     709             :         }
     710             : 
     711             :         VxlanRoutingVrfMapper::RoutedVrfInfo &routed_vrf_info =
     712           0 :             vrf_mapper_.lr_vrf_info_map_[vn_state->logical_router_uuid_];
     713             :         // Take the ownership of LR
     714           0 :         routed_vrf_info.routing_vn_ = vn;
     715           0 :         if (routed_vrf_info.routing_vrf_ != vn->GetVrf()) {
     716           0 :             routed_vrf_info.routing_vrf_ = vn->GetVrf();
     717           0 :             vrf_mapper_.WalkBridgeVrfs(routed_vrf_info);
     718             :         }
     719             :     }
     720             : }
     721             : 
     722             : /**
     723             :  * Updates (sets or deletes) VxlanRoutingState for the given
     724             :  * modified VrfEntry
     725             :  */
     726         106 : void VxlanRoutingManager::VrfNotify(DBTablePartBase *partition,
     727             :                                     DBEntryBase *e) {
     728         106 :     VrfEntry *vrf = static_cast<VrfEntry *>(e);
     729         106 :     if (vrf->GetName().compare(agent_->fabric_vrf_name()) == 0)
     730          19 :         return;
     731          87 :     if (vrf->GetName().compare(agent_->fabric_policy_vrf_name()) == 0)
     732          27 :         return;
     733             : 
     734          60 :     VxlanRoutingState *state = dynamic_cast<VxlanRoutingState *>(vrf->
     735          60 :                              GetState(partition->parent(), vrf_listener_id_));
     736          60 :     if (vrf->IsDeleted()) {
     737          48 :         if (state) {
     738           6 :             vrf->ClearState(partition->parent(), vrf_listener_id_);
     739           6 :             delete state;
     740             :         }
     741             :     } else {
     742             :         // Vrf was added/changed.
     743          12 :         if (!state) {
     744           6 :             state = new VxlanRoutingState(this, vrf);
     745           6 :             vrf->SetState(partition->parent(), vrf_listener_id_, state);
     746             :         }
     747          12 :         if (vrf->vn() && vrf->vn()->vxlan_routing_vn()) {
     748           0 :             vrf->set_routing_vrf(true);
     749             :         }
     750             :     }
     751             : }
     752             : 
     753          98 : void VxlanRoutingManager::VmiNotify(DBTablePartBase *partition,
     754             :                                     DBEntryBase *e) {
     755          98 :     VmInterface *vmi = dynamic_cast<VmInterface *>(e);
     756          98 :     if (!vmi) {
     757          27 :         return;
     758             :     }
     759             : 
     760          71 :     VnEntry *vn = vmi->GetNonConstVn();
     761          71 :     VxlanRoutingVnState *vn_state = NULL;
     762          71 :     VxlanRoutingVmiState *vmi_state = dynamic_cast<VxlanRoutingVmiState *>(vmi->
     763          71 :                              GetAgentDBEntryState(vmi_listener_id_));
     764         108 :     if (vmi->IsDeleted() || (vn == NULL) ||
     765         108 :         (vmi->logical_router_uuid() == boost::uuids::nil_uuid())) {
     766          71 :         if (!vmi_state) {
     767          71 :             return;
     768             :         }
     769           0 :         vn = vmi_state->vn_entry_.get();
     770           0 :         vn_state = dynamic_cast<VxlanRoutingVnState *>
     771           0 :             (vn->GetAgentDBEntryState(vn_listener_id_));
     772           0 :         if (vn_state)
     773           0 :             vn_state->DeleteVmi(vn, vmi);
     774           0 :         vmi->ClearState(partition->parent(), vmi_listener_id_);
     775           0 :         delete vmi_state;
     776           0 :         return;
     777             :     }
     778             : 
     779           0 :     if ((vmi->device_type() != VmInterface::VMI_ON_LR) ||
     780           0 :         (vmi->vmi_type() != VmInterface::ROUTER)) {
     781           0 :         return;
     782             :     }
     783             : 
     784           0 :     if (vmi->logical_router_uuid() == boost::uuids::nil_uuid()) {
     785           0 :         return;
     786             :     }
     787             : 
     788             :     // Without VN no point of update
     789           0 :     if (!vn) {
     790           0 :         return;
     791             :     }
     792             : 
     793           0 :     if (!vmi_state) {
     794           0 :         vmi_state = new VxlanRoutingVmiState();
     795           0 :         vmi->SetState(partition->parent(), vmi_listener_id_, vmi_state);
     796           0 :         vmi_state->vn_entry_ = vn;
     797             :     }
     798             :     // Update logical_router_uuid
     799           0 :     vmi_state->logical_router_uuid_ = vmi->logical_router_uuid();
     800             : 
     801             :     // Its necessary to add state on VN so as to push VMI. VN notify can come
     802             :     // after VMI notify.
     803           0 :     VnNotify(vn->get_table_partition(), vn);
     804             :     // Now get VN state and add/delete VMI there
     805           0 :     vn_state = dynamic_cast<VxlanRoutingVnState *>
     806           0 :         (vn->GetAgentDBEntryState(vn_listener_id_));
     807           0 :     if (vn_state) {
     808           0 :         vn_state->AddVmi(vn, vmi);
     809             :     }
     810             : }
     811             : 
     812           6 : void VxlanRoutingManager::HandleSubnetRoute(const VrfEntry *vrf, bool bridge_vrf) {
     813             :     //
     814             :     // New version
     815             :     //
     816           6 :     if (vrf->vn() && vrf->vn()->vxlan_routing_vn() == false) {
     817             :         const VrfEntry *routing_vrf =
     818           6 :             vrf_mapper_.GetRoutingVrfUsingVn(vrf->vn());
     819           6 :         if (!routing_vrf || vrf->IsDeleted()) {
     820           6 :              DeleteSubnetRoute(vrf);
     821           6 :              vrf->vn()->set_lr_vrf(NULL);
     822             :         } else {
     823           0 :             UpdateSubnetRoute(vrf, routing_vrf);
     824           0 :             vrf->vn()->set_lr_vrf(routing_vrf);
     825             :         }
     826             :     }
     827           6 : }
     828             : 
     829           0 : void VxlanRoutingManager::DeleteIpamRoutes(const VnEntry *vn,
     830             :     const std::string& vrf_name,
     831             :     const IpAddress& ipam_prefix,
     832             :     const uint32_t plen) {
     833           0 :     if (vn == NULL || vrf_name == std::string(""))
     834           0 :         return;
     835             : 
     836           0 :     VxlanRoutingVrfMapper::VnLrSetIter lr_it = vrf_mapper_.vn_lr_set_.find(vn);
     837             : 
     838           0 :     if (lr_it == vrf_mapper_.vn_lr_set_.end() ||
     839           0 :         lr_it->second == boost::uuids::nil_uuid())
     840           0 :         return;
     841             : 
     842             :     VxlanRoutingVrfMapper::RoutedVrfInfo &lr_vrf_info =
     843           0 :         vrf_mapper_.lr_vrf_info_map_[lr_it->second];
     844             : 
     845           0 :     if (lr_vrf_info.bridge_vn_list_.size() == 0)
     846           0 :         return;
     847             : 
     848           0 :     for (auto bridge_vn_entry : lr_vrf_info.bridge_vn_list_) {
     849           0 :         if (vn == bridge_vn_entry) {
     850           0 :             continue;
     851             :         }
     852             : 
     853           0 :         VrfEntry* it_vrf = VnVrf(bridge_vn_entry, lr_vrf_info.bridge_vrf_names_list_[bridge_vn_entry]);
     854           0 :         if (it_vrf == nullptr) {
     855           0 :             continue;
     856             :         }
     857             : 
     858             :         it_vrf->GetInetUnicastRouteTable(ipam_prefix)->
     859           0 :             Delete(agent_->evpn_routing_peer(), it_vrf->GetName(),
     860             :                 ipam_prefix, plen, NULL);
     861             :     }
     862             : }
     863             : 
     864           6 : void VxlanRoutingManager::DeleteSubnetRoute(const VnEntry *vn, const std::string& vrf_name) {
     865           6 :     if (vn == NULL || vrf_name == std::string(""))
     866           6 :         return;
     867           6 :     std::vector<VnIpam> bridge_vn_ipam = vn->GetVnIpam();
     868             : 
     869           6 :     if (bridge_vn_ipam.size() == 0)
     870           0 :         return;
     871             : 
     872           6 :     VxlanRoutingVrfMapper::VnLrSetIter lr_it = vrf_mapper_.vn_lr_set_.find(vn);
     873             : 
     874           6 :     if (lr_it == vrf_mapper_.vn_lr_set_.end() ||
     875           6 :         lr_it->second == boost::uuids::nil_uuid())
     876           6 :         return;
     877             : 
     878             :     VxlanRoutingVrfMapper::RoutedVrfInfo &lr_vrf_info =
     879           0 :         vrf_mapper_.lr_vrf_info_map_[lr_it->second];
     880             : 
     881           0 :     if (lr_vrf_info.bridge_vn_list_.size() == 0)
     882           0 :         return;
     883             : 
     884           0 :     for (auto bridge_vn_entry : lr_vrf_info.bridge_vn_list_) {
     885           0 :         if (vn == bridge_vn_entry) {
     886           0 :             continue;
     887             :         }
     888             : 
     889           0 :         for (auto br_ipam : bridge_vn_ipam) {
     890           0 :             VrfEntry* it_vrf = VnVrf(bridge_vn_entry, lr_vrf_info.bridge_vrf_names_list_[bridge_vn_entry]);
     891           0 :             if (it_vrf == nullptr) {
     892           0 :                 continue;
     893             :             }
     894             : 
     895           0 :             it_vrf->GetInetUnicastRouteTable(br_ipam.ip_prefix)->
     896           0 :                     DeleteReq(agent_->evpn_routing_peer(), it_vrf->GetName(),
     897           0 :                         br_ipam.GetSubnetAddress(), br_ipam.plen, NULL);
     898           0 :         }
     899             : 
     900           0 :         std::vector<VnIpam> vn_ipam = bridge_vn_entry->GetVnIpam();
     901             : 
     902           0 :         if (vn_ipam.size() == 0) {
     903           0 :             continue;
     904             :         }
     905           0 :         for (auto br_vn_ipam : vn_ipam) {
     906           0 :             InetUnicastAgentRouteTable::DeleteReq(agent_->evpn_routing_peer(),
     907           0 :                 vrf_name, br_vn_ipam.GetSubnetAddress(),
     908           0 :                 br_vn_ipam.plen, NULL);
     909           0 :         }
     910           0 :     }
     911           6 : }
     912             : 
     913             : //void VxlanRoutingManager::DeleteSubnetRoute(const VrfEntry *vrf, VnIpam *ipam) {
     914           6 : void VxlanRoutingManager::DeleteSubnetRoute(const VrfEntry *vrf) {
     915           6 :     if (vrf == NULL)
     916           0 :         return;
     917           6 :     DeleteSubnetRoute(vrf->vn(), vrf->GetName());
     918             : }
     919             : 
     920           0 : void VxlanRoutingManager::UpdateSubnetRoute(const VrfEntry *bridge_vrf,
     921             :                                              const VrfEntry *routing_vrf) {
     922           0 :     if (!bridge_vrf->vn())
     923           0 :         return;
     924             : 
     925           0 :     std::vector<VnIpam> bridge_vn_ipam = bridge_vrf->vn()->GetVnIpam();
     926             : 
     927           0 :     if (bridge_vn_ipam.size() == 0)
     928           0 :         return;
     929             : 
     930             :     VxlanRoutingVrfMapper::VnLrSetIter lr_it =
     931           0 :         vrf_mapper_.vn_lr_set_.find(bridge_vrf->vn());
     932             : 
     933           0 :     if (lr_it == vrf_mapper_.vn_lr_set_.end() ||
     934           0 :         lr_it->second == boost::uuids::nil_uuid())
     935           0 :         return;
     936             : 
     937             :     VxlanRoutingVrfMapper::RoutedVrfInfo &lr_vrf_info =
     938           0 :         vrf_mapper_.lr_vrf_info_map_[lr_it->second];
     939             : 
     940           0 :     if (lr_vrf_info.bridge_vn_list_.size() == 0)
     941           0 :         return;
     942             : 
     943             :     VxlanRoutingVrfMapper::RoutedVrfInfo::BridgeVnListIter it =
     944           0 :         lr_vrf_info.bridge_vn_list_.begin();
     945           0 :     while (it != lr_vrf_info.bridge_vn_list_.end()) {
     946           0 :         if (bridge_vrf->vn() == *it) {
     947           0 :             it++;
     948           0 :             continue;
     949             :         }
     950             : 
     951           0 :         for (std::vector<VnIpam>::iterator ipam_itr = bridge_vn_ipam.begin();
     952           0 :             ipam_itr < bridge_vn_ipam.end(); ipam_itr++) {
     953           0 :             DBRequest nh_req(DBRequest::DB_ENTRY_ADD_CHANGE);
     954           0 :             nh_req.key.reset(new VrfNHKey(routing_vrf->GetName(), false, false));
     955           0 :             nh_req.data.reset(new VrfNHData(false, false, false));
     956           0 :             VrfEntry* it_vrf = VnVrf((*it), lr_vrf_info.bridge_vrf_names_list_[(*it)]);
     957           0 :             if (it_vrf == nullptr) {
     958           0 :                 continue;
     959             :             }
     960           0 :             it_vrf->GetInetUnicastRouteTable(ipam_itr->ip_prefix)->
     961           0 :             AddEvpnRoutingRouteReq(ipam_itr->ip_prefix, ipam_itr->plen, routing_vrf,
     962           0 :                         agent_->evpn_routing_peer(),
     963           0 :                         SecurityGroupList(),
     964           0 :                         CommunityList(),
     965           0 :                         PathPreference(),
     966           0 :                         EcmpLoadBalance(),
     967           0 :                         TagList(),
     968             :                         nh_req,
     969             :                         routing_vrf->vxlan_id(),
     970           0 :                         VnListType());
     971           0 :         }
     972             : 
     973           0 :         std::vector<VnIpam> vn_ipam = (*it)->GetVnIpam();
     974           0 :         for (std::vector<VnIpam>::iterator vn_ipam_itr = vn_ipam.begin();
     975           0 :             vn_ipam_itr != vn_ipam.end(); vn_ipam_itr++) {
     976             : 
     977           0 :             DBRequest nh_req(DBRequest::DB_ENTRY_ADD_CHANGE);
     978           0 :             nh_req.key.reset(new VrfNHKey(routing_vrf->GetName(), false, false));
     979           0 :             nh_req.data.reset(new VrfNHData(false, false, false));
     980           0 :             bridge_vrf->GetInetUnicastRouteTable(vn_ipam_itr->ip_prefix)->
     981           0 :             AddEvpnRoutingRouteReq(vn_ipam_itr->ip_prefix, vn_ipam_itr->plen, routing_vrf,
     982           0 :                         agent_->evpn_routing_peer(),
     983           0 :                         SecurityGroupList(),
     984           0 :                         CommunityList(),
     985           0 :                         PathPreference(),
     986           0 :                         EcmpLoadBalance(),
     987           0 :                         TagList(),
     988             :                         nh_req,
     989             :                         routing_vrf->vxlan_id(),
     990           0 :                         VnListType());
     991           0 :         }
     992           0 :         it++;
     993           0 :     }
     994           0 : }
     995             : 
     996             : /**
     997             :  * sandesh request
     998             :  */
     999           0 : void VxlanRoutingManager::FillSandeshInfo(VxlanRoutingResp *resp) {
    1000             :     VxlanRoutingVrfMapper::LrVrfInfoMapIter it1 =
    1001           0 :        vrf_mapper_.lr_vrf_info_map_.begin();
    1002           0 :     std::vector<VxlanRoutingMap> vr_map;
    1003           0 :     while (it1 != vrf_mapper_.lr_vrf_info_map_.end()) {
    1004           0 :         VxlanRoutingMap vxlan_routing_map;
    1005           0 :         vxlan_routing_map.set_logical_router_uuid(UuidToString(it1->first));
    1006           0 :         vxlan_routing_map.set_routing_vrf(it1->second.routing_vrf_->
    1007             :                                             GetName());
    1008           0 :         vxlan_routing_map.set_parent_routing_vn(it1->second.routing_vn_->
    1009             :                                             GetName());
    1010             :         VxlanRoutingVrfMapper::RoutedVrfInfo::BridgeVnListIter it2 =
    1011           0 :             it1->second.bridge_vn_list_.begin();
    1012           0 :         while (it2 != it1->second.bridge_vn_list_.end()) {
    1013           0 :             VxlanRoutingBridgeVrf bridge_vrf;
    1014           0 :             if ((*it2)->GetVrf()) {
    1015           0 :                 bridge_vrf.set_bridge_vrf((*it2)->GetVrf()->GetName());
    1016             :             }
    1017           0 :             bridge_vrf.set_bridge_vn((*it2)->GetName());
    1018           0 :             vxlan_routing_map.bridge_vrfs.push_back(bridge_vrf);
    1019           0 :             it2++;
    1020           0 :         }
    1021           0 :         vr_map.push_back(vxlan_routing_map);
    1022           0 :         it1++;
    1023           0 :     }
    1024           0 :     resp->set_vr_map(vr_map);
    1025           0 : }
    1026             : 
    1027           0 : void VxlanRoutingReq::HandleRequest() const {
    1028           0 :     VxlanRoutingResp *resp = new VxlanRoutingResp();
    1029           0 :     Agent *agent = Agent::GetInstance();
    1030             :     VxlanRoutingManager *vxlan_routing_mgr =
    1031           0 :         agent->oper_db()->vxlan_routing_manager();
    1032           0 :     if (vxlan_routing_mgr) {
    1033           0 :         resp->set_context(context());
    1034           0 :         vxlan_routing_mgr->FillSandeshInfo(resp);
    1035             :     }
    1036           0 :     resp->set_more(false);
    1037           0 :     resp->Response();
    1038           0 :     return;
    1039             : }

Generated by: LCOV version 1.14