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

Generated by: LCOV version 1.14