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

Generated by: LCOV version 1.14