LCOV - code coverage report
Current view: top level - vnsw/agent/oper - bgp_as_service.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 36 528 6.8 %
Date: 2026-08-03 02:19:58 Functions: 6 30 20.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include <string>
       6             : #include <vector>
       7             : #include <boost/uuid/uuid_io.hpp>
       8             : 
       9             : #include <vnc_cfg_types.h>
      10             : #include <base/logging.h>
      11             : #include <base/string_util.h>
      12             : #include <base/bgp_as_service_utils.h>
      13             : #include <base/address_util.h>
      14             : #include <cmn/agent_cmn.h>
      15             : #include <init/agent_param.h>
      16             : #include <ifmap/ifmap_node.h>
      17             : #include <ifmap/ifmap_link.h>
      18             : #include <cfg/cfg_init.h>
      19             : #include <cmn/agent.h>
      20             : #include <oper/operdb_init.h>
      21             : #include <oper/bgp_as_service.h>
      22             : #include <oper/bgp_router.h>
      23             : #include <oper/audit_list.h>
      24             : #include <oper/agent_sandesh.h>
      25             : #include <oper/config_manager.h>
      26             : #include <oper/vn.h>
      27             : #include <bgp_schema_types.h>
      28             : 
      29             : #include <arpa/inet.h>
      30             : #include <netinet/in.h>
      31             : #include <fcntl.h>
      32             : #include "oper/global_system_config.h"
      33             : #include <resource_manager/resource_manager.h>
      34             : #include <resource_manager/resource_table.h>
      35             : #include <resource_manager/bgp_as_service_index.h>
      36             : 
      37             : SandeshTraceBufferPtr BgpAsAServiceTraceBuf(SandeshTraceBufferCreate
      38             :                                             ("BgpAsAService", 500));
      39             : 
      40           3 : BgpAsAService::BgpAsAService(const Agent *agent) :
      41           3 :     agent_(agent),
      42           3 :     bgp_as_a_service_entry_map_(),
      43           3 :     bgp_as_a_service_port_map_(),
      44           3 :     service_delete_cb_list_(), health_check_cb_list_() {
      45           3 : }
      46             : 
      47           3 : BgpAsAService::~BgpAsAService() {
      48           3 : }
      49             : 
      50           0 : const BgpAsAService::BgpAsAServiceEntryMap &BgpAsAService::bgp_as_a_service_map() const {
      51           0 :     return bgp_as_a_service_entry_map_;
      52             : }
      53             : 
      54           0 : const BgpAsAService::BgpAsAServicePortMap &BgpAsAService::bgp_as_a_service_port_map() const {
      55           0 :     return bgp_as_a_service_port_map_;
      56             : }
      57             : 
      58           0 : void BgpAsAService::BgpAsAServiceList::Insert(const BgpAsAServiceEntry *rhs) {
      59           0 :     if (rhs->health_check_configured_)
      60           0 :         rhs->new_health_check_add_ = true;
      61           0 :     list_.insert(*rhs);
      62           0 : }
      63             : 
      64           0 : void BgpAsAService::BgpAsAServiceList::Update(const BgpAsAServiceEntry *lhs,
      65             :                                               const BgpAsAServiceEntry *rhs) {
      66           0 :     lhs->dest_port_ = rhs->dest_port_;
      67           0 :     lhs->primary_control_node_zone_ = rhs->primary_control_node_zone_;
      68           0 :     lhs->secondary_control_node_zone_ = rhs->secondary_control_node_zone_;
      69           0 :     if (rhs->health_check_configured_) {
      70           0 :         if (lhs->hc_delay_usecs_ != rhs->hc_delay_usecs_ ||
      71           0 :             lhs->hc_timeout_usecs_ != rhs->hc_timeout_usecs_ ||
      72           0 :             lhs->hc_retries_ != rhs->hc_retries_) {
      73             :             // if HC properties change, trigger update
      74           0 :             lhs->new_health_check_add_ = true;
      75           0 :             lhs->hc_delay_usecs_ = rhs->hc_delay_usecs_;
      76           0 :             lhs->hc_timeout_usecs_ = rhs->hc_timeout_usecs_;
      77           0 :             lhs->hc_retries_ = rhs->hc_retries_;
      78             :         }
      79             :     }
      80           0 :     if (lhs->health_check_configured_ != rhs->health_check_configured_) {
      81           0 :         lhs->health_check_configured_ = rhs->health_check_configured_;
      82           0 :         if (lhs->health_check_configured_) {
      83           0 :             lhs->old_health_check_delete_ = false;
      84           0 :             lhs->new_health_check_add_ = true;
      85           0 :             lhs->old_health_check_uuid_ = boost::uuids::nil_uuid();
      86           0 :             lhs->health_check_uuid_ = rhs->health_check_uuid_;
      87             :         } else {
      88           0 :             lhs->old_health_check_delete_ = true;
      89           0 :             lhs->new_health_check_add_ = false;
      90           0 :             lhs->old_health_check_uuid_ = lhs->health_check_uuid_;
      91           0 :             lhs->health_check_uuid_ = boost::uuids::nil_uuid();
      92             :         }
      93           0 :         return;
      94             :     }
      95           0 :     if (lhs->health_check_uuid_ != rhs->health_check_uuid_) {
      96             :         // delete old health check and add new
      97           0 :         lhs->new_health_check_add_ = true;
      98           0 :         lhs->old_health_check_delete_ = true;
      99           0 :         lhs->old_health_check_uuid_ = lhs->health_check_uuid_;
     100           0 :         lhs->health_check_uuid_ = rhs->health_check_uuid_;
     101             :     }
     102             : }
     103             : 
     104           0 : void BgpAsAService::BgpAsAServiceList::Remove(BgpAsAServiceEntryListIterator &it) {
     105           0 :     it->set_del_pending(true);
     106           0 : }
     107             : 
     108           0 : void BgpAsAService::BgpAsAServiceList::Flush() {
     109           0 :     list_.clear();
     110           0 : }
     111             : 
     112           0 : void BgpAsAService::StartHealthCheck(const boost::uuids::uuid &vm_uuid,
     113             :                                      const BgpAsAServiceEntryList &list) {
     114           0 :     for (BgpAsAServiceEntryListConstIterator iter = list.begin();
     115           0 :          iter != list.end(); ++iter) {
     116           0 :         if (!health_check_cb_list_.empty() && iter->new_health_check_add_ &&
     117           0 :             iter->health_check_uuid_ != boost::uuids::nil_uuid()) {
     118             :             std::vector<HealthCheckCb>::iterator hcb_it =
     119           0 :                 health_check_cb_list_.begin();
     120           0 :             while (hcb_it != health_check_cb_list_.end()) {
     121           0 :                 (*hcb_it)(vm_uuid, iter->source_port_,
     122           0 :                              iter->health_check_uuid_, true);
     123           0 :                 hcb_it++;
     124             :             }
     125             :         }
     126           0 :         iter->new_health_check_add_ = false;
     127             :     }
     128           0 : }
     129             : 
     130           0 : static const std::string GetBgpRouterVrfName(const Agent *agent,
     131             :                                              IFMapNode *node) {
     132           0 :     IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table());
     133           0 :     for (DBGraphVertex::adjacency_iterator it = node->begin(table->GetGraph());
     134           0 :          it != node->end(table->GetGraph()); ++it) {
     135           0 :         IFMapNode *vrf_node = static_cast<IFMapNode *>(it.operator->());
     136           0 :         if (agent->config_manager()->SkipNode
     137           0 :             (vrf_node, agent->cfg()->cfg_vrf_table())) {
     138           0 :             continue;
     139             :         }
     140           0 :         return vrf_node->name();
     141             :     }
     142           0 :     return std::string();
     143             : }
     144             : 
     145           0 : static const std::string GetControlNodeZoneName(IFMapNode *node) {
     146             :     IFMapAgentTable *table =
     147           0 :         static_cast<IFMapAgentTable *>(node->table());
     148           0 :     for (DBGraphVertex::adjacency_iterator it = node->begin(table->GetGraph());
     149           0 :          it != node->end(table->GetGraph()); ++it) {
     150           0 :         IFMapNode *adj_node = static_cast<IFMapNode *>(it.operator->());
     151           0 :         if (strcmp(adj_node->table()->Typename(),
     152           0 :                 CONTROL_NODE_ZONE_CONFIG_NAME) == 0) {
     153           0 :             return adj_node->name();
     154             :         }
     155             :     }
     156           0 :     return std::string();
     157             : }
     158             : 
     159           0 : void BgpAsAService::BuildBgpAsAServiceInfo(IFMapNode *bgp_as_a_service_node,
     160             :                                       std::list<IFMapNode *> &bgp_router_nodes,
     161             :                                       BgpAsAServiceEntryList &new_list,
     162             :                                       const std::string &vm_vrf_name,
     163             :                                       const boost::uuids::uuid &vm_uuid) {
     164             :     IFMapAgentTable *table =
     165           0 :         static_cast<IFMapAgentTable *>(bgp_as_a_service_node->table());
     166             :     autogen::BgpAsAService *bgp_as_a_service =
     167           0 :         dynamic_cast<autogen::BgpAsAService *>(bgp_as_a_service_node->GetObject());
     168           0 :     assert(bgp_as_a_service);
     169             : 
     170           0 :     IpAddress peer_ip;
     171           0 :     uint32_t source_port = 0;
     172           0 :     bool health_check_configured = false;
     173           0 :     boost::uuids::uuid health_check_uuid = boost::uuids::nil_uuid();
     174           0 :     uint64_t hc_delay_usecs = 0;
     175           0 :     uint64_t hc_timeout_usecs = 0;
     176           0 :     uint32_t hc_retries = 0;
     177           0 :     std::string primary_control_node_zone;
     178           0 :     std::string secondary_control_node_zone;
     179             : 
     180             :     // Find the health check config first
     181           0 :     for (DBGraphVertex::adjacency_iterator it = bgp_as_a_service_node->begin(table->GetGraph());
     182           0 :          it != bgp_as_a_service_node->end(table->GetGraph()); ++it) {
     183           0 :         IFMapNode *adj_node = static_cast<IFMapNode *>(it.operator->());
     184             : 
     185           0 :         if (adj_node->table() == agent_->cfg()->cfg_health_check_table()) {
     186           0 :             if (agent_->config_manager()->SkipNode(adj_node)) {
     187           0 :                 continue;
     188             :             }
     189             :             autogen::ServiceHealthCheck *hc =
     190           0 :                 static_cast<autogen::ServiceHealthCheck *> (adj_node->GetObject());
     191           0 :             assert(hc);
     192             :             // consider only BFD health check for BGPaaS
     193           0 :             if (hc->properties().monitor_type.find("BFD") == std::string::npos)
     194           0 :                 continue;
     195           0 :             health_check_configured = true;
     196           0 :             autogen::IdPermsType id_perms = hc->id_perms();
     197           0 :             CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong,
     198             :                        health_check_uuid);
     199           0 :             hc_delay_usecs = hc->properties().delay * 1000000 +
     200           0 :                              hc->properties().delayUsecs;
     201           0 :             hc_timeout_usecs = hc->properties().timeout * 1000000 +
     202           0 :                                hc->properties().timeoutUsecs;
     203           0 :             hc_retries = hc->properties().max_retries;
     204           0 :         }
     205             : 
     206           0 :         if (strcmp(adj_node->table()->Typename(),
     207           0 :                     BGPAAS_CONTROL_NODE_ZONE_CONFIG_NAME) == 0) {
     208             :             autogen::BgpaasControlNodeZone
     209             :                 *bgpaas_cnz = static_cast<autogen::BgpaasControlNodeZone *>
     210           0 :                     (adj_node->GetObject());
     211             :             const autogen::BGPaaSControlNodeZoneAttributes &attr =
     212             :                 static_cast<autogen::BGPaaSControlNodeZoneAttributes>
     213           0 :                     (bgpaas_cnz->data());
     214           0 :             const std::string cnz_name = GetControlNodeZoneName(adj_node);
     215           0 :             if (cnz_name.size()) {
     216           0 :                 if (strcmp(attr.bgpaas_control_node_zone_type.c_str(),
     217           0 :                            "primary") == 0) {
     218           0 :                     primary_control_node_zone = cnz_name;
     219           0 :                     continue;
     220             :                 }
     221           0 :                 if (strcmp(attr.bgpaas_control_node_zone_type.c_str(),
     222           0 :                            "secondary") == 0) {
     223           0 :                     secondary_control_node_zone = cnz_name;
     224           0 :                     continue;
     225             :                 }
     226             :             }
     227           0 :         }
     228             :     }
     229             : 
     230             :     //Look for neighbour bgp-router to take the source port
     231           0 :     for (DBGraphVertex::adjacency_iterator it = bgp_as_a_service_node->begin(table->GetGraph());
     232           0 :          it != bgp_as_a_service_node->end(table->GetGraph()); ++it) {
     233           0 :         IFMapNode *adj_node = static_cast<IFMapNode *>(it.operator->());
     234           0 :         if (strcmp(adj_node->table()->Typename(), BGP_ROUTER_CONFIG_NAME) == 0) {
     235             :             //Verify that bgp-router object is of use for this VMI.
     236             :             //List of valid bgp-router for vmi is in bgp_router_nodes.
     237           0 :             if (std::find(bgp_router_nodes.begin(), bgp_router_nodes.end(),
     238           0 :                           adj_node) == bgp_router_nodes.end()) {
     239           0 :                 continue;
     240             :             }
     241             :             autogen::BgpRouter *bgp_router=
     242           0 :                 dynamic_cast<autogen::BgpRouter *>(adj_node->GetObject());
     243             :             const std::string &vrf_name =
     244           0 :                 GetBgpRouterVrfName(agent_, adj_node);
     245           0 :             if (vrf_name.empty() || (vrf_name != vm_vrf_name) ||
     246           0 :                 (strcmp(bgp_router->parameters().router_type.c_str(),
     247             :                         VALID_BGP_ROUTER_TYPE) != 0))
     248           0 :                 continue; //Skip the node with no VRF, notification will come.
     249           0 :             boost::system::error_code ec;
     250             :             peer_ip =
     251           0 :                 IpAddress::from_string(bgp_router->parameters().address, ec);
     252           0 :             if (ec.value() != 0) {
     253           0 :                 std::stringstream ss;
     254           0 :                 ss << "Ip address parsing failed for ";
     255           0 :                 ss << bgp_router->parameters().address;
     256           0 :                 BGPASASERVICETRACE(Trace, ss.str().c_str());
     257           0 :                 continue;
     258           0 :             }
     259             : 
     260             :             BgpAsAServiceEntryMapIterator old_bgp_as_a_service_entry_list_iter =
     261           0 :                                     bgp_as_a_service_entry_map_.find(vm_uuid);
     262           0 :             source_port = 0;
     263             :             /*
     264             :              *  verify the same session is added again here
     265             :              */
     266           0 :             if (old_bgp_as_a_service_entry_list_iter !=
     267           0 :                         bgp_as_a_service_entry_map_.end()) {
     268           0 :                 BgpAsAServiceEntryList temp_bgp_as_a_service_entry_list;
     269           0 :                 temp_bgp_as_a_service_entry_list.insert(
     270           0 :                                     BgpAsAServiceEntry(peer_ip,
     271           0 :                                         bgp_router->parameters().source_port,
     272           0 :                                         bgp_router->parameters().port,
     273             :                                         health_check_configured,
     274             :                                         health_check_uuid,
     275           0 :                                         bgp_as_a_service->bgpaas_shared(),
     276             :                                         hc_delay_usecs,
     277             :                                         hc_timeout_usecs,
     278             :                                         hc_retries,
     279             :                                         primary_control_node_zone,
     280             :                                         secondary_control_node_zone));
     281             :                 /*
     282             :                  * if it is same session then retain original source port
     283             :                  */
     284           0 :                 if (temp_bgp_as_a_service_entry_list ==
     285           0 :                      old_bgp_as_a_service_entry_list_iter->second->list_) {
     286           0 :                     source_port = bgp_router->parameters().source_port;
     287             :                 }
     288           0 :             }
     289           0 :             if (!source_port) {
     290           0 :                 if (bgp_as_a_service->bgpaas_shared()) {
     291           0 :                     source_port = AddBgpVmiServicePortIndex(
     292           0 :                                         bgp_router->parameters().source_port,
     293             :                                         vm_uuid);
     294             :                 } else {
     295           0 :                     source_port = bgp_router->parameters().source_port;
     296             :                 }
     297             :             }
     298           0 :             if (source_port) {
     299           0 :                 new_list.insert(BgpAsAServiceEntry(peer_ip, source_port,
     300           0 :                                             bgp_router->parameters().port,
     301             :                                                    health_check_configured,
     302             :                                                    health_check_uuid,
     303           0 :                                                    bgp_as_a_service->bgpaas_shared(),
     304             :                                                    hc_delay_usecs,
     305             :                                                    hc_timeout_usecs,
     306             :                                                    hc_retries,
     307             :                                                    primary_control_node_zone,
     308             :                                                    secondary_control_node_zone));
     309             :             }
     310           0 :         }
     311             :     }
     312             : 
     313           0 : }
     314             : 
     315          70 : void BgpAsAService::ProcessConfig(const std::string &vrf_name,
     316             :                            std::list<IFMapNode *> &bgp_router_node_map,
     317             :                            std::list<IFMapNode *> &bgp_as_service_node_map,
     318             :                            const boost::uuids::uuid &vm_uuid) {
     319             :     std::list<IFMapNode *>::const_iterator it =
     320          70 :         bgp_as_service_node_map.begin();
     321          70 :     BgpAsAServiceEntryList new_bgp_as_a_service_entry_list;
     322             : 
     323          70 :     while (it != bgp_as_service_node_map.end()) {
     324           0 :         BuildBgpAsAServiceInfo(*it, bgp_router_node_map,
     325             :                                new_bgp_as_a_service_entry_list,
     326             :                                vrf_name, vm_uuid);
     327           0 :         it++;
     328             :     }
     329             : 
     330             :     //Audit and enqueue updates/deletes of flow
     331             :     BgpAsAServiceEntryMapIterator old_bgp_as_a_service_entry_list_iter =
     332          70 :         bgp_as_a_service_entry_map_.find(vm_uuid);
     333          70 :     bool changed = false;
     334          70 :     if (old_bgp_as_a_service_entry_list_iter !=
     335         140 :         bgp_as_a_service_entry_map_.end()) {
     336             :         //Audit
     337             :         changed = AuditList<BgpAsAServiceList, BgpAsAServiceEntryListIterator>
     338           0 :             (*(old_bgp_as_a_service_entry_list_iter->second),
     339           0 :              old_bgp_as_a_service_entry_list_iter->second->list_.begin(),
     340           0 :              old_bgp_as_a_service_entry_list_iter->second->list_.end(),
     341             :              new_bgp_as_a_service_entry_list.begin(),
     342             :              new_bgp_as_a_service_entry_list.end());
     343          70 :     } else if (new_bgp_as_a_service_entry_list.size() != 0) {
     344           0 :         StartHealthCheck(vm_uuid, new_bgp_as_a_service_entry_list);
     345           0 :         bgp_as_a_service_entry_map_[vm_uuid] =
     346           0 :             new BgpAsAServiceList(new_bgp_as_a_service_entry_list);
     347             :     }
     348             : 
     349          70 :     if (changed && !service_delete_cb_list_.empty()) {
     350             :         //Enqueue flow handler request.
     351             :         BgpAsAServiceEntryListIterator iter =
     352           0 :             old_bgp_as_a_service_entry_list_iter->second->list_.begin();
     353           0 :         while (iter !=
     354           0 :                old_bgp_as_a_service_entry_list_iter->second->list_.end()) {
     355           0 :             BgpAsAServiceEntryListIterator prev = iter++;
     356           0 :             if (prev->del_pending_) {
     357             :                 std::vector<ServiceDeleteCb>::iterator scb_it =
     358           0 :                     service_delete_cb_list_.begin();
     359           0 :                 while (scb_it != service_delete_cb_list_.end()) {
     360           0 :                     (*scb_it)(vm_uuid, prev->source_port_);
     361           0 :                     scb_it++;
     362             :                 }
     363           0 :                 InterfaceConstRef vm_intf = agent_->interface_table()->FindVmi(vm_uuid);
     364           0 :                 const VmInterface *vmi = dynamic_cast<const VmInterface *>(vm_intf.get());
     365           0 :                 if ((prev->is_shared_ && vmi==NULL) || (prev->is_shared_ && vmi && vmi->IsDeleted())) {
     366           0 :                     FreeBgpVmiServicePortIndex(prev->source_port_);
     367             :                 }
     368           0 :                 else if(vmi && !(vmi->IsDeleted())){
     369           0 :                     LOG(DEBUG, "Undeleted vmi might have active bgp session with source port");
     370             :                 }
     371             : 
     372           0 :                 old_bgp_as_a_service_entry_list_iter->second->list_.erase(prev);
     373           0 :                 continue;
     374           0 :             }
     375           0 :             if (prev->old_health_check_delete_) {
     376           0 :                 if (!health_check_cb_list_.empty() &&
     377           0 :                     prev->old_health_check_uuid_ != boost::uuids::nil_uuid()) {
     378             :                     std::vector<HealthCheckCb>::iterator hcb_it =
     379           0 :                         health_check_cb_list_.begin();
     380           0 :                     while (hcb_it != health_check_cb_list_.end()) {
     381           0 :                         (*hcb_it)(vm_uuid, prev->source_port_,
     382           0 :                                      prev->old_health_check_uuid_, false);
     383           0 :                         hcb_it++;
     384             :                      }
     385             :                 }
     386           0 :                 prev->old_health_check_delete_ = false;
     387           0 :                 prev->old_health_check_uuid_ = boost::uuids::nil_uuid();
     388             :             }
     389           0 :             if (prev->new_health_check_add_) {
     390           0 :                 if (!health_check_cb_list_.empty() &&
     391           0 :                     prev->health_check_uuid_ != boost::uuids::nil_uuid()) {
     392             :                     std::vector<HealthCheckCb>::iterator hcb_it =
     393           0 :                         health_check_cb_list_.begin();
     394           0 :                     while (hcb_it != health_check_cb_list_.end()) {
     395           0 :                         (*hcb_it)(vm_uuid, prev->source_port_,
     396           0 :                                      prev->health_check_uuid_, true);
     397           0 :                         hcb_it++;
     398             :                      }
     399             :                 }
     400           0 :                 prev->new_health_check_add_ = false;
     401             :             }
     402             :         }
     403             :     }
     404          70 : }
     405             : 
     406          24 : void BgpAsAService::DeleteVmInterface(const boost::uuids::uuid &vm_uuid) {
     407          24 :     if (service_delete_cb_list_.empty())
     408          24 :         return;
     409             : 
     410             :     BgpAsAServiceEntryMapIterator iter =
     411          24 :        bgp_as_a_service_entry_map_.find(vm_uuid);
     412          24 :     if (iter == bgp_as_a_service_entry_map_.end())
     413          24 :         return;
     414             : 
     415           0 :     BgpAsAServiceEntryList list = iter->second->list_;
     416           0 :     BgpAsAServiceEntryListIterator list_iter = list.begin();
     417           0 :     while (list_iter != list.end()) {
     418             :         std::vector<ServiceDeleteCb>::iterator scb_it =
     419           0 :             service_delete_cb_list_.begin();
     420           0 :         while (scb_it != service_delete_cb_list_.end()) {
     421           0 :             (*scb_it)(vm_uuid, (*list_iter).source_port_);
     422           0 :             scb_it++;
     423             :         }
     424           0 :         if ((*list_iter).is_shared_) {
     425           0 :             FreeBgpVmiServicePortIndex((*list_iter).source_port_);
     426             :         }
     427           0 :         list_iter++;
     428             :     }
     429           0 :     delete iter->second;
     430           0 :     bgp_as_a_service_entry_map_.erase(iter);
     431           0 : }
     432             : 
     433             : 
     434           0 : bool BgpAsAService::IsBgpService(const VmInterface *vm_intf,
     435             :                                  const IpAddress &source_ip,
     436             :                                  const IpAddress &dest_ip) const {
     437           0 :     bool ret = false;
     438             :     BgpAsAServiceEntryMapConstIterator iter =
     439           0 :        bgp_as_a_service_entry_map_.find(vm_intf->GetUuid());
     440           0 :     if (iter == bgp_as_a_service_entry_map_.end()) {
     441           0 :         return false;
     442             :     }
     443             : 
     444           0 :     while (iter != bgp_as_a_service_entry_map_.end()) {
     445             :         BgpAsAService::BgpAsAServiceEntryListIterator it =
     446           0 :             iter->second->list_.begin();
     447           0 :         while (it != iter->second->list_.end()) {
     448           0 :             if ((*it).local_peer_ip_ == source_ip)
     449           0 :                 return true;
     450           0 :             it++;
     451             :         }
     452           0 :         iter++;
     453             :     }
     454             : 
     455           0 :     const VnEntry *vn = vm_intf->vn();
     456           0 :     if (vn == NULL) return false;
     457             : 
     458           0 :     const IpAddress &vm_ip = vm_intf->primary_ip_addr();
     459           0 :     if ((vn->GetGatewayFromIpam(vm_ip) == dest_ip) ||
     460           0 :         (vn->GetDnsFromIpam(vm_ip) == dest_ip)) {
     461           0 :         ret = true;
     462             :     }
     463           0 :     return ret;
     464             : }
     465             : 
     466           0 : void BgpAsAService::FreeBgpVmiServicePortIndex(const uint32_t sport) {
     467             :     BGPaaServiceParameters:: BGPaaServicePortRangePair ports =
     468           0 :                         bgp_as_a_service_port_range();
     469             :     BGPaaSUtils::BgpAsServicePortIndexPair portinfo =
     470           0 :                     BGPaaSUtils::DecodeBgpaasServicePort(sport,
     471           0 :                         ports.first, ports.second);
     472             : 
     473             :     BgpAsAServicePortMapIterator port_map_it =
     474           0 :                     bgp_as_a_service_port_map_.find(portinfo.first);
     475           0 :     if (port_map_it == bgp_as_a_service_port_map_.end()) {
     476           0 :         return;
     477             :     }
     478             : 
     479           0 :     size_t vmi_service_port_index = portinfo.second;
     480           0 :     agent_->resource_manager()->Release(Resource::BGP_AS_SERVICE_INDEX,
     481             :                                         vmi_service_port_index);
     482           0 :     port_map_it->second->Remove(vmi_service_port_index);
     483             : 
     484           0 :     if (port_map_it->second->NoneIndexSet()) {
     485           0 :         delete port_map_it->second;
     486           0 :         bgp_as_a_service_port_map_.erase(port_map_it);
     487             :     }
     488             : }
     489             : 
     490           0 : size_t BgpAsAService::AllocateBgpVmiServicePortIndex(const uint32_t sport,
     491             :                                         const boost::uuids::uuid vm_uuid) {
     492             :     BgpAsAServicePortMapIterator port_map_it =
     493           0 :                     bgp_as_a_service_port_map_.find(sport);
     494           0 :     if (port_map_it == bgp_as_a_service_port_map_.end()) {
     495           0 :         bgp_as_a_service_port_map_[sport] = new IndexVector<boost::uuids::uuid>();
     496             :     }
     497             :     ResourceManager::KeyPtr rkey(new BgpAsServiceIndexResourceKey
     498           0 :                                  (agent_->resource_manager(), vm_uuid));
     499             :     uint32_t index = static_cast<IndexResourceData *>
     500           0 :         (agent_->resource_manager()->Allocate(rkey).get())->index();
     501           0 :     bgp_as_a_service_port_map_[sport]->InsertAtIndex(index, vm_uuid);
     502           0 :     return index;
     503           0 : }
     504             : 
     505           0 : uint32_t BgpAsAService::AddBgpVmiServicePortIndex(const uint32_t source_port,
     506             :                                             const boost::uuids::uuid vm_uuid) {
     507             :     BGPaaServiceParameters:: BGPaaServicePortRangePair ports =
     508           0 :                         bgp_as_a_service_port_range();
     509             : 
     510           0 :     size_t vmi_service_port_index = AllocateBgpVmiServicePortIndex(source_port,
     511             :                                                                    vm_uuid);
     512           0 :     if (vmi_service_port_index == BitSet::npos) {
     513           0 :         std::stringstream ss;
     514           0 :         ss << "Service Port Index is not available for ";
     515           0 :         ss << source_port;
     516           0 :         BGPASASERVICETRACE(Trace, ss.str().c_str());
     517           0 :         return 0;
     518           0 :     }
     519           0 :     return BGPaaSUtils::EncodeBgpaasServicePort(
     520             :                                 source_port,
     521             :                                 vmi_service_port_index,
     522           0 :                                 ports.first, ports.second);
     523             : }
     524             : 
     525           0 : bool BgpAsAService::GetBgpRouterServiceDestination(
     526             :                     const VmInterface *vm_intf, const IpAddress &source_ip,
     527             :                     const IpAddress &dest, IpAddress *nat_server,
     528             :                     uint32_t *sport, uint32_t *dport) const {
     529           0 :     const VnEntry *vn = vm_intf->vn();
     530           0 :     if (vn == NULL) return false;
     531             : 
     532           0 :     const IpAddress &vm_ip = vm_intf->primary_ip_addr();
     533           0 :     const IpAddress &gw = vn->GetGatewayFromIpam(vm_ip);
     534           0 :     const IpAddress &dns = vn->GetDnsFromIpam(vm_ip);
     535             : 
     536           0 :     std::stringstream ss;
     537             :     BgpAsAServiceEntryMapConstIterator map_it =
     538           0 :         bgp_as_a_service_entry_map_.find(vm_intf->GetUuid());
     539           0 :     if (map_it == bgp_as_a_service_entry_map_.end()) {
     540           0 :         ss << "vmi-uuid:" << vm_intf->GetUuid() << " not found";
     541           0 :         BGPASASERVICETRACE(Trace, ss.str().c_str());
     542           0 :         return false;
     543             :     }
     544             : 
     545           0 :     BgpRouterConfig *bgp_router_cfg = agent_->oper_db()->bgp_router_config();
     546           0 :     BgpAsAServiceEntryListConstIterator it = map_it->second->list_.begin();
     547           0 :     while (it != map_it->second->list_.end()) {
     548           0 :         bool cnz_configured = it->IsControlNodeZoneConfigured();
     549           0 :         BgpRouterPtr bgp_router;
     550           0 :         IpAddress ip_address;
     551           0 :         std::string xmpp_server;
     552           0 :         std::string control_node_zone;
     553             :         std::string *bgp_router_name;
     554           0 :         if (dest == gw) {
     555           0 :             if (cnz_configured) {
     556             :                 bgp_router = bgp_router_cfg->
     557           0 :                     GetBgpRouterFromControlNodeZone(
     558           0 :                         it->primary_control_node_zone_);
     559           0 :                 control_node_zone = it->primary_control_node_zone_;
     560             :             } else {
     561           0 :                 xmpp_server = agent_->controller_ifmap_xmpp_server(0);
     562           0 :                 if (xmpp_server.size())
     563             :                     bgp_router = bgp_router_cfg->
     564           0 :                         GetBgpRouterFromXmppServer(xmpp_server);
     565             :             }
     566           0 :             bgp_router_name = &it->primary_bgp_peer_;
     567           0 :         } else if (dest == dns) {
     568           0 :             if (cnz_configured) {
     569             :                 bgp_router = bgp_router_cfg->
     570           0 :                     GetBgpRouterFromControlNodeZone(
     571           0 :                         it->secondary_control_node_zone_);
     572           0 :                 control_node_zone = it->secondary_control_node_zone_;
     573             :             } else {
     574           0 :                 xmpp_server = agent_->controller_ifmap_xmpp_server(1);
     575           0 :                 if (xmpp_server.size())
     576             :                     bgp_router = bgp_router_cfg->
     577           0 :                         GetBgpRouterFromXmppServer(xmpp_server);
     578             :             }
     579           0 :             bgp_router_name = &it->secondary_bgp_peer_;
     580             :         } else {
     581           0 :             it++;
     582           0 :             continue;
     583             :         }
     584           0 :         if (bgp_router.get() == NULL) {
     585           0 :             ss << "BgpRouter not found.";
     586           0 :             ss << " bgpaas-source-ip:" << source_ip.to_string();
     587           0 :             ss << " bgpaas-destination-ip:" << dest.to_string();
     588           0 :             ss << " control-node-zone:" << control_node_zone;
     589           0 :             ss << " xmpp-server:" << xmpp_server;
     590           0 :             BGPASASERVICETRACE(Trace, ss.str().c_str());
     591             :             //reset bgp_router for sandesh
     592           0 :             *bgp_router_name = "";
     593           0 :             return false;
     594             :         }
     595           0 :         *nat_server = bgp_router->ipv4_address();
     596           0 :         *sport = it->source_port_;
     597           0 :         *dport = it->dest_port_?it->dest_port_:bgp_router->port();
     598             :         //update bgp_router for sandesh
     599           0 :         *bgp_router_name = bgp_router->name();
     600           0 :         return true;
     601           0 :     }
     602           0 :     ss << "BgpRouter not found ";
     603           0 :     ss << " bgpaas-source-ip:" << source_ip.to_string();
     604           0 :     ss << " bgpaas-destination-ip" << dest.to_string();
     605           0 :     BGPASASERVICETRACE(Trace, ss.str().c_str());
     606           0 :     return false;
     607           0 : }
     608             : 
     609           0 : bool BgpAsAService::GetBgpHealthCheck(const VmInterface *vm_intf,
     610             :                     boost::uuids::uuid *health_check_uuid) const {
     611             :     BgpAsAServiceEntryMapConstIterator found =
     612           0 :        bgp_as_a_service_entry_map_.find(vm_intf->GetUuid());
     613             : 
     614           0 :     if (found != bgp_as_a_service_entry_map_.end()) {
     615             :         BgpAsAService::BgpAsAServiceEntryListIterator it =
     616           0 :             found->second->list_.begin();
     617           0 :         while (it != found->second->list_.end()) {
     618           0 :             if (it->health_check_configured_) {
     619           0 :                 *health_check_uuid = it->health_check_uuid_;
     620           0 :                 std::ostringstream ss;
     621           0 :                 ss<<"searched for vm_intf_uuid: "<<boost::uuids::to_string(vm_intf->GetUuid())
     622           0 :                   <<" - found: "<<boost::uuids::to_string(*health_check_uuid);
     623           0 :                 BGPASASERVICETRACE(Trace, ss.str().c_str());
     624           0 :                 return true;
     625           0 :             }
     626           0 :             it++;
     627             :         }
     628             :     }
     629           0 :     std::ostringstream ss;
     630           0 :     ss<<"vm_intf_uuid: "<<boost::uuids::to_string(vm_intf->GetUuid())+" - not found in BgpAaS entry map";
     631           0 :     BGPASASERVICETRACE(Trace, ss.str().c_str());
     632           0 :     return false;
     633           0 : }
     634             : 
     635           0 : void BgpAsAService::UpdateBgpAsAServiceSessionInfo() {
     636           0 :     if (service_delete_cb_list_.empty())
     637           0 :         return;
     638           0 :     unsigned int source_port = 0;
     639           0 :     unsigned int index = 0;
     640             :     BGPaaServiceParameters:: BGPaaServicePortRangePair old_ports =
     641           0 :                                 bgp_as_a_service_port_range();
     642             :     BGPaaServiceParameters:: BGPaaServicePortRangePair new_ports =
     643           0 :              agent_->oper_db()->global_system_config()->bgpaas_port_range();
     644           0 :     std::pair<BgpAsAServiceEntryListIterator, bool> ret;
     645             :     BgpAsAServiceEntryMapIterator iter =
     646           0 :                 bgp_as_a_service_entry_map_.begin();
     647           0 :     while (iter != bgp_as_a_service_entry_map_.end()) {
     648           0 :         BgpAsAServiceEntryList list = iter->second->list_;
     649           0 :         BgpAsAServiceEntryListIterator list_iter = list.begin();
     650           0 :         while (list_iter != list.end()) {
     651             :             BGPaaSUtils::BgpAsServicePortIndexPair portinfo =
     652           0 :                 BGPaaSUtils::DecodeBgpaasServicePort(
     653           0 :                                 list_iter->source_port_,
     654           0 :                                 old_ports.first,
     655           0 :                                 old_ports.second);
     656           0 :             source_port = portinfo.first;
     657           0 :             index = portinfo.second;
     658             :             // encode source port with new port range
     659             :             source_port =
     660           0 :                 BGPaaSUtils::EncodeBgpaasServicePort(source_port,
     661             :                                                     index,
     662           0 :                                                     new_ports.first,
     663           0 :                                                     new_ports.second);
     664             :             // if old source port is not same as new source pott
     665             :             // delte the flow and entry from the list
     666             :             // and then insert the entry with the new source port
     667           0 :             if (list_iter->source_port_ != source_port) {
     668           0 :                 BgpAsAServiceEntry temp(list_iter->local_peer_ip_,
     669             :                                     source_port,
     670           0 :                                     list_iter->dest_port_,
     671           0 :                                     list_iter->health_check_configured_,
     672           0 :                                     list_iter->health_check_uuid_,
     673           0 :                                     list_iter->is_shared_,
     674           0 :                                     list_iter->hc_delay_usecs_,
     675           0 :                                     list_iter->hc_timeout_usecs_,
     676           0 :                                     list_iter->hc_retries_,
     677           0 :                                     list_iter->primary_control_node_zone_,
     678           0 :                                     list_iter->secondary_control_node_zone_);
     679             :                 std::vector<ServiceDeleteCb>::iterator scb_it =
     680           0 :                     service_delete_cb_list_.begin();
     681           0 :                 while (scb_it != service_delete_cb_list_.end()) {
     682           0 :                     (*scb_it)(iter->first, list_iter->source_port_);
     683           0 :                     scb_it++;
     684             :                 }
     685           0 :                 iter->second->list_.erase(*list_iter);
     686           0 :                 iter->second->list_.insert(temp);
     687           0 :             }
     688           0 :             list_iter++;
     689             :         }
     690           0 :         iter++;
     691           0 :     }
     692             :     //update BgpaaS port range
     693           0 :     bgp_as_a_service_parameters_.port_start = new_ports.first;
     694           0 :     bgp_as_a_service_parameters_.port_end = new_ports.second;
     695             : }
     696             : 
     697             : ////////////////////////////////////////////////////////////////////////////
     698             : // BGP as a service routines.
     699             : ////////////////////////////////////////////////////////////////////////////
     700          70 : BgpAsAService::BgpAsAServiceEntry::BgpAsAServiceEntry() :
     701          70 :     VmInterface::ListEntry(), installed_(false),
     702         140 :     local_peer_ip_(), source_port_(0), dest_port_(0),
     703          70 :     health_check_configured_(false), health_check_uuid_(),
     704          70 :     new_health_check_add_(false),old_health_check_delete_(false),
     705          70 :     old_health_check_uuid_(),hc_delay_usecs_(0),
     706          70 :     hc_timeout_usecs_(0), hc_retries_(0), is_shared_(false),
     707          70 :     primary_control_node_zone_(), secondary_control_node_zone_() {
     708          70 : }
     709             : 
     710           0 : BgpAsAService::BgpAsAServiceEntry::BgpAsAServiceEntry
     711           0 : (const BgpAsAService::BgpAsAServiceEntry &rhs) :
     712           0 :     VmInterface::ListEntry(rhs.del_pending_),
     713           0 :     installed_(rhs.installed_),
     714           0 :     local_peer_ip_(rhs.local_peer_ip_),
     715           0 :     source_port_(rhs.source_port_),
     716           0 :     dest_port_(rhs.dest_port_),
     717           0 :     health_check_configured_(rhs.health_check_configured_),
     718           0 :     health_check_uuid_(rhs.health_check_uuid_),
     719           0 :     new_health_check_add_(rhs.new_health_check_add_),
     720           0 :     old_health_check_delete_(rhs.old_health_check_delete_),
     721           0 :     old_health_check_uuid_(rhs.old_health_check_uuid_),
     722           0 :     hc_delay_usecs_(rhs.hc_delay_usecs_),
     723           0 :     hc_timeout_usecs_(rhs.hc_timeout_usecs_),
     724           0 :     hc_retries_(rhs.hc_retries_), is_shared_(rhs.is_shared_),
     725           0 :     primary_control_node_zone_(rhs.primary_control_node_zone_),
     726           0 :     secondary_control_node_zone_(rhs.secondary_control_node_zone_) {
     727           0 : }
     728             : 
     729           0 : BgpAsAService::BgpAsAServiceEntry::BgpAsAServiceEntry
     730             : (const IpAddress &local_peer_ip, uint32_t source_port, uint32_t dest_port,
     731             :  bool health_check_configured, const boost::uuids::uuid &health_check_uuid,
     732             :  bool is_shared, uint64_t hc_delay_usecs, uint64_t hc_timeout_usecs,
     733             :  uint32_t hc_retries, const std::string &primary_control_node_zone,
     734           0 :  const std::string &secondary_control_node_zone) :
     735             :     VmInterface::ListEntry(),
     736           0 :     installed_(false),
     737           0 :     local_peer_ip_(local_peer_ip),
     738           0 :     source_port_(source_port),
     739           0 :     dest_port_(dest_port),
     740           0 :     health_check_configured_(health_check_configured),
     741           0 :     health_check_uuid_(health_check_uuid),
     742           0 :     new_health_check_add_(health_check_configured),
     743           0 :     old_health_check_delete_(false), old_health_check_uuid_(),
     744           0 :     hc_delay_usecs_(hc_delay_usecs), hc_timeout_usecs_(hc_timeout_usecs),
     745           0 :     hc_retries_(hc_retries), is_shared_(is_shared),
     746           0 :     primary_control_node_zone_(primary_control_node_zone),
     747           0 :     secondary_control_node_zone_(secondary_control_node_zone) {
     748           0 : }
     749             : 
     750          70 : BgpAsAService::BgpAsAServiceEntry::~BgpAsAServiceEntry() {
     751          70 : }
     752             : 
     753           0 : bool BgpAsAService::BgpAsAServiceEntry::operator ==
     754             :     (const BgpAsAServiceEntry &rhs) const {
     755           0 :     return ((source_port_ == rhs.source_port_) &&
     756           0 :             (local_peer_ip_ == rhs.local_peer_ip_) &&
     757           0 :             (is_shared_ == rhs.is_shared_));
     758             : }
     759             : 
     760           0 : bool BgpAsAService::BgpAsAServiceEntry::operator()
     761             :     (const BgpAsAServiceEntry &lhs, const BgpAsAServiceEntry &rhs) const {
     762           0 :     return lhs.IsLess(&rhs);
     763             : }
     764             : 
     765           0 : bool BgpAsAService::BgpAsAServiceEntry::IsLess
     766             :     (const BgpAsAServiceEntry *rhs) const {
     767           0 :     if (source_port_ != rhs->source_port_)
     768           0 :         return source_port_ < rhs->source_port_;
     769           0 :     if (local_peer_ip_ != rhs->local_peer_ip_)
     770           0 :          return local_peer_ip_ < rhs->local_peer_ip_;
     771           0 :     if (primary_control_node_zone_ != rhs->primary_control_node_zone_)
     772           0 :         return primary_control_node_zone_ < rhs->primary_control_node_zone_;
     773           0 :     if (secondary_control_node_zone_ != rhs->secondary_control_node_zone_)
     774           0 :         return secondary_control_node_zone_ < rhs->secondary_control_node_zone_;
     775           0 :     return is_shared_ < rhs->is_shared_;
     776             : }
     777             : 
     778           0 : void BgpAsAServiceSandeshReq::HandleRequest() const {
     779           0 :    BgpAsAServiceSandeshResp *resp = new BgpAsAServiceSandeshResp();
     780           0 :    resp->set_context(context());
     781             : 
     782           0 :    Agent *agent = Agent::GetInstance();
     783             : 
     784             :    BgpAsAService::BgpAsAServiceEntryMap map_entry =
     785           0 :        agent->oper_db()->bgp_as_a_service()->bgp_as_a_service_map();
     786             :    BgpAsAService::BgpAsAServiceEntryMapIterator map_it =
     787           0 :        map_entry.begin();
     788           0 :    std::vector<BgpAsAServiceSandeshList> bgpaas_map;
     789           0 :    std::string vmi_uuid_str = get_vmi_uuid();
     790           0 :    while (map_it != map_entry.end()) {
     791           0 :        if (vmi_uuid_str.empty() == false) {
     792           0 :            boost::uuids::uuid vmi_uuid = StringToUuid(vmi_uuid_str);
     793           0 :            if (vmi_uuid != map_it->first) {
     794           0 :                map_it++;
     795           0 :                continue;
     796             :            }
     797             :        }
     798             :        BgpAsAService::BgpAsAServiceEntryListIterator it =
     799           0 :            map_it->second->list_.begin();
     800           0 :        while (it != map_it->second->list_.end()) {
     801           0 :            BgpAsAServiceSandeshList entry;
     802           0 :            entry.set_vm_bgp_peer_ip((*it).local_peer_ip_.to_string());
     803           0 :            entry.set_vm_nat_source_port((*it).source_port_);
     804           0 :            entry.set_vmi_uuid(UuidToString(map_it->first));
     805           0 :            entry.set_health_check_configured((*it).health_check_configured_);
     806           0 :            entry.set_health_check_uuid(UuidToString((*it).health_check_uuid_));
     807           0 :            entry.set_health_check_delay_usecs((*it).hc_delay_usecs_);
     808           0 :            entry.set_health_check_timeout_usecs((*it).hc_timeout_usecs_);
     809           0 :            entry.set_health_check_retries((*it).hc_retries_);
     810           0 :            entry.set_is_shared((*it).is_shared_);
     811           0 :            entry.set_primary_control_node_zone(
     812           0 :                 (*it).primary_control_node_zone_);
     813           0 :            entry.set_secondary_control_node_zone(
     814           0 :                 (*it).secondary_control_node_zone_);
     815           0 :            entry.set_primary_bgp_peer((*it).primary_bgp_peer_);
     816           0 :            entry.set_secondary_bgp_peer((*it).secondary_bgp_peer_);
     817           0 :            bgpaas_map.push_back(entry);
     818           0 :            it++;
     819           0 :        }
     820           0 :        map_it++;
     821             :    }
     822           0 :    resp->set_bgp_as_a_service_list(bgpaas_map);
     823           0 :    resp->Response();
     824           0 : }

Generated by: LCOV version 1.14