LCOV - code coverage report
Current view: top level - bgp - bgp_config_ifmap.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 1380 1455 94.8 %
Date: 2026-11-09 02:10:49 Functions: 126 131 96.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #include "bgp/bgp_config_ifmap.h"
       7             : 
       8             : #include <boost/foreach.hpp>
       9             : 
      10             : #include <algorithm>
      11             : 
      12             : #include "base/string_util.h"
      13             : #include "base/task_annotations.h"
      14             : #include "bgp/bgp_common.h"
      15             : #include "bgp/bgp_config_listener.h"
      16             : #include "bgp/bgp_log.h"
      17             : #include "bgp/routing-instance/iservice_chain_mgr.h"
      18             : #include "ifmap/ifmap_node.h"
      19             : #include "ifmap/ifmap_table.h"
      20             : 
      21             : #include "schema/bgp_schema_types.h"
      22             : #include "schema/vnc_cfg_types.h"
      23             : 
      24             : using std::unique_ptr;
      25             : using std::find;
      26             : using std::make_pair;
      27             : using std::pair;
      28             : using std::set;
      29             : using std::sort;
      30             : using std::string;
      31             : using std::vector;
      32             : using boost::iequals;
      33             : 
      34             : const int BgpIfmapConfigManager::kConfigTaskInstanceId = 0;
      35             : 
      36             : static BgpNeighborConfig::AddressFamilyList default_addr_family_list;
      37             : 
      38         125 : void DefaultAddressFamilyInit() {
      39         125 :     default_addr_family_list.push_back("inet");
      40         125 :     default_addr_family_list.push_back("inet-vpn");
      41         125 : }
      42             : 
      43             : MODULE_INITIALIZER(DefaultAddressFamilyInit);
      44             : 
      45       69500 : static string IdentifierParent(const string &identifier) {
      46       69500 :     string parent;
      47             :     size_t last;
      48       69500 :     last = identifier.rfind(':');
      49       69500 :     if (last == 0 || last == string::npos) {
      50           0 :         return parent;
      51             :     }
      52       69500 :     parent = identifier.substr(0, last);
      53       69500 :     return parent;
      54           0 : }
      55             : 
      56       69815 : static uint32_t IpAddressToBgpIdentifier(const IpAddress &address) {
      57       69815 :     return htonl(address.to_v4().to_ulong());
      58             : }
      59             : 
      60       13392 : static string BgpIdentifierToString(uint32_t identifier) {
      61       13392 :     Ip4Address addr(ntohl(identifier));
      62       26784 :     return addr.to_string();
      63             : }
      64             : 
      65        4312 : BgpIfmapPeeringConfig::BgpIfmapPeeringConfig(BgpIfmapInstanceConfig *instance)
      66        4312 :     : instance_(instance) {
      67        4312 : }
      68             : 
      69        4312 : BgpIfmapPeeringConfig::~BgpIfmapPeeringConfig() {
      70        4312 :     STLDeleteElements(&neighbors_);
      71        4312 : }
      72             : 
      73        4312 : void BgpIfmapPeeringConfig::SetNodeProxy(IFMapNodeProxy *proxy) {
      74        4312 :     if (proxy != NULL) {
      75        4312 :         node_proxy_.Swap(proxy);
      76        4312 :         name_ = node_proxy_.node()->name();
      77             :     }
      78        4312 : }
      79             : 
      80         165 : BgpIfmapRoutingPolicyLinkConfig::BgpIfmapRoutingPolicyLinkConfig(
      81         165 :     BgpIfmapInstanceConfig *rti, BgpIfmapRoutingPolicyConfig *rtp) :
      82         165 :      instance_(rti), policy_(rtp) {
      83         165 : }
      84             : 
      85         165 : BgpIfmapRoutingPolicyLinkConfig::~BgpIfmapRoutingPolicyLinkConfig() {
      86         165 : }
      87             : 
      88         165 : void BgpIfmapRoutingPolicyLinkConfig::SetNodeProxy(IFMapNodeProxy *proxy) {
      89         165 :     if (proxy != NULL) {
      90         165 :         node_proxy_.Swap(proxy);
      91         165 :         name_ = node_proxy_.node()->name();
      92             :     }
      93         165 : }
      94             : 
      95         165 : bool BgpIfmapRoutingPolicyLinkConfig::GetInstancePolicyPair(
      96             :     DBGraph *graph, IFMapNode *node, pair<IFMapNode *, IFMapNode *> *pair) {
      97         165 :     IFMapNode *routing_instance = NULL;
      98         165 :     IFMapNode *routing_policy = NULL;
      99             : 
     100         165 :     for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
     101         495 :          iter != node->end(graph); ++iter) {
     102         330 :         IFMapNode *adj = static_cast<IFMapNode *>(iter.operator->());
     103         330 :         if (strcmp(adj->table()->Typename(), "routing-instance") == 0)
     104         165 :             routing_instance = adj;
     105         330 :         if (strcmp(adj->table()->Typename(), "routing-policy") == 0)
     106         165 :             routing_policy = adj;
     107             :     }
     108         165 :     if (routing_policy == NULL || routing_instance == NULL) {
     109           0 :         return false;
     110             :     }
     111             : 
     112         165 :     pair->first = routing_instance;
     113         165 :     pair->second = routing_policy;
     114         165 :     return true;
     115             : }
     116             : 
     117         190 : void BgpIfmapRoutingPolicyLinkConfig::Update(BgpIfmapConfigManager *manager,
     118             :     const autogen::RoutingPolicyRoutingInstance *ri_rp) {
     119         190 :     ri_rp_link_.reset(ri_rp);
     120         190 : }
     121             : 
     122           0 : void BgpIfmapRoutingPolicyLinkConfig::Delete(BgpIfmapConfigManager *manager) {
     123           0 :     ri_rp_link_.reset();
     124           0 : }
     125             : 
     126       59312 : static AuthenticationData::KeyType KeyChainType(const string &value) {
     127             :     // Case-insensitive comparison
     128       59312 :     if (boost::iequals(value, "md5")) {
     129         761 :         return AuthenticationData::MD5;
     130             :     }
     131       58551 :     return AuthenticationData::NIL;
     132             : }
     133             : 
     134       59312 : static void BuildKeyChain(BgpNeighborConfig *neighbor,
     135             :     const autogen::AuthenticationData &values) {
     136       59312 :     AuthenticationData keydata;
     137       59312 :     keydata.set_key_type(KeyChainType(values.key_type));
     138             : 
     139       59312 :     AuthenticationKey key;
     140       59312 :     for (vector<autogen::AuthenticationKeyItem>::const_iterator iter =
     141      119281 :             values.key_items.begin(); iter != values.key_items.end(); ++iter) {
     142         657 :         key.id = iter->key_id;
     143         657 :         key.value = iter->key;
     144         657 :         key.start_time = 0;
     145         657 :         keydata.AddKeyToKeyChain(key);
     146             :     }
     147       59312 :     neighbor->set_keydata(keydata);
     148       59312 : }
     149             : 
     150             : //
     151             : // Check if the family is allowed to be configured for BgpNeighborConfig.
     152             : // Only families inet and inet6 are allowed on non-master instances.
     153             : //
     154        9461 : static bool AddressFamilyIsValid(BgpNeighborConfig *neighbor,
     155             :     const string &family) {
     156        9461 :     if (neighbor->instance_name() == BgpConfigManager::kMasterInstance)
     157        8263 :         return true;
     158        1198 :     return (family == "inet" || family == "inet6");
     159             : }
     160             : 
     161             : //
     162             : // Build list of BgpFamilyAttributesConfig elements from the list of address
     163             : // families. This is provided for backward compatibility with configurations
     164             : // that represent each family with a simple string.
     165             : //
     166        3583 : static void BuildFamilyAttributesList(BgpNeighborConfig *neighbor,
     167             :     const BgpNeighborConfig::AddressFamilyList &family_list,
     168             :     const vector<string> &remote_family_list) {
     169        3583 :     BgpNeighborConfig::FamilyAttributesList family_attributes_list;
     170       17561 :     BOOST_FOREACH(const string &family, family_list) {
     171             :         // Skip families that are not valid/supported for the neighbor.
     172        6989 :         if (!AddressFamilyIsValid(neighbor, family))
     173          26 :             continue;
     174             : 
     175             :         // Skip families that are not configured on remote bgp-router.
     176        6971 :         if (!remote_family_list.empty()) {
     177        4971 :             vector<string>::const_iterator it = find(
     178             :                 remote_family_list.begin(), remote_family_list.end(), family);
     179        4971 :             if (it == remote_family_list.end())
     180           8 :                 continue;
     181             :         }
     182             : 
     183        6963 :         BgpFamilyAttributesConfig family_attributes(family);
     184        6963 :         family_attributes_list.push_back(family_attributes);
     185        6963 :     }
     186             : 
     187        3583 :     neighbor->set_family_attributes_list(family_attributes_list);
     188        3583 : }
     189             : 
     190             : //
     191             : // Build list of BgpFamilyAttributesConfig elements from BgpFamilyAttributes
     192             : // list in BgpSessionAttributes.
     193             : //
     194             : // Implement backward compatibility by also adding BgpFamilyAttributesConfig
     195             : // elements for families that are not in BgpFamilyAttributes list but are in
     196             : // the address_families list.
     197             : //
     198       29182 : static void BuildFamilyAttributesList(BgpNeighborConfig *neighbor,
     199             :     const autogen::BgpSessionAttributes *attributes) {
     200       29182 :     set<string> family_set;
     201       29182 :     BgpNeighborConfig::FamilyAttributesList family_attributes_list;
     202       34126 :     BOOST_FOREACH(const autogen::BgpFamilyAttributes &family_config,
     203             :         attributes->family_attributes) {
     204        2472 :         if (!AddressFamilyIsValid(neighbor, family_config.address_family))
     205         166 :             continue;
     206             :         BgpFamilyAttributesConfig family_attributes(
     207        2306 :             family_config.address_family);
     208        2306 :         family_attributes.loop_count = family_config.loop_count;
     209        2306 :         family_attributes.prefix_limit = family_config.prefix_limit.maximum;
     210        2306 :         family_attributes.idle_timeout =
     211        2306 :             family_config.prefix_limit.idle_timeout;
     212             :         family_attributes.default_tunnel_encap_list =
     213        2306 :             family_config.default_tunnel_encap;
     214        2306 :         family_attributes_list.push_back(family_attributes);
     215        2306 :         family_set.insert(family_config.address_family);
     216        2306 :     }
     217             : 
     218      100576 :     BOOST_FOREACH(const string &family, attributes->address_families.family) {
     219       35697 :         if (family_set.find(family) != family_set.end())
     220           0 :             continue;
     221       35697 :         BgpFamilyAttributesConfig family_attributes(family);
     222       35697 :         family_attributes_list.push_back(family_attributes);
     223       35697 :     }
     224             : 
     225       29182 :     neighbor->set_family_attributes_list(family_attributes_list);
     226       29182 : }
     227             : 
     228             : //
     229             : // Set the autogen::BgpSessionAttributes for this BgpNeighborConfig.
     230             : //
     231             : // The autogen::BgpSession will have up to 3 session attributes - one that
     232             : // applies to the local router, one that applies the remote router and one
     233             : // that applies to both.
     234             : //
     235       30698 : static void NeighborSetSessionAttributes(
     236             :     BgpNeighborConfig *neighbor, const string &localname,
     237             :     const autogen::BgpSession *session) {
     238             :     typedef vector<autogen::BgpSessionAttributes> AttributeVec;
     239       30698 :     const autogen::BgpSessionAttributes *common = NULL;
     240       30698 :     const autogen::BgpSessionAttributes *local = NULL;
     241       30698 :     for (AttributeVec::const_iterator iter = session->attributes.begin();
     242       88573 :          iter != session->attributes.end(); ++iter) {
     243       57875 :         const autogen::BgpSessionAttributes *attr = iter.operator->();
     244       57875 :         if (attr->bgp_router.empty()) {
     245         197 :             common = attr;
     246      114360 :         } else if (neighbor->router_type() != "bgpaas-client" &&
     247       56682 :             attr->bgp_router == localname) {
     248       28487 :             local = attr;
     249       30187 :         } else if (neighbor->router_type() == "bgpaas-client" &&
     250         996 :             attr->bgp_router == "bgpaas-server") {
     251         498 :             local = attr;
     252             :         }
     253             :     }
     254             : 
     255             :     // TODO(nsheth): local should override rather than replace common.
     256       30698 :     const autogen::BgpSessionAttributes *attributes = NULL;
     257       30698 :     if (common != NULL) {
     258         197 :         attributes = common;
     259       30501 :     } else if (local != NULL) {
     260       28985 :         attributes = local;
     261             :     }
     262       30698 :     if (attributes != NULL) {
     263       29182 :         neighbor->set_passive(attributes->passive);
     264       29182 :         neighbor->set_as_override(attributes->as_override);
     265       29182 :         neighbor->set_private_as_action(attributes->private_as_action);
     266       29182 :         neighbor->set_loop_count(attributes->loop_count);
     267       29182 :         if (attributes->admin_down) {
     268         108 :             neighbor->set_admin_down(true);
     269             :         }
     270       29182 :         if (attributes->local_autonomous_system) {
     271         184 :             neighbor->set_local_as(attributes->local_autonomous_system);
     272             :         }
     273       29182 :         if (attributes->hold_time) {
     274         312 :             neighbor->set_hold_time(attributes->hold_time);
     275             :         }
     276       29182 :         BuildFamilyAttributesList(neighbor, attributes);
     277       29182 :         BuildKeyChain(neighbor, attributes->auth_data);
     278       29182 :         const autogen::RouteOriginOverride &origin_override =
     279             :                 attributes->route_origin_override;
     280       29182 :         neighbor->SetOriginOverride(origin_override.origin_override,
     281       29182 :                                     origin_override.origin);
     282             :     }
     283       30698 : }
     284             : 
     285       31079 : static BgpNeighborConfig *MakeBgpNeighborConfig(
     286             :     const BgpIfmapInstanceConfig *instance,
     287             :     const BgpIfmapInstanceConfig *master_instance,
     288             :     const string &local_name,
     289             :     const string &remote_name,
     290             :     const autogen::BgpRouter *local_router,
     291             :     const autogen::BgpRouter *remote_router,
     292             :     const autogen::BgpSession *session) {
     293       31079 :     BgpNeighborConfig *neighbor = new BgpNeighborConfig();
     294             : 
     295       31079 :     neighbor->set_instance_name(instance->name());
     296             : 
     297             :     // If the autogen::BgpSession has a uuid, we append it to the remote
     298             :     // bgp-router's name to make the BgpNeighborConfig's name unique.
     299       31079 :     if (session && !session->uuid.empty()) {
     300       30694 :         neighbor->set_uuid(session->uuid);
     301       30694 :         neighbor->set_name(remote_name + ":" + session->uuid);
     302             :     } else {
     303         385 :         neighbor->set_name(remote_name);
     304             :     }
     305             : 
     306             :     // Store a copy of the remote bgp-router's autogen::BgpRouterParams and
     307             :     // derive the autogen::BgpSessionAttributes for the session.
     308       31079 :     const autogen::BgpRouterParams &params = remote_router->parameters();
     309       31079 :     neighbor->set_router_type(params.router_type);
     310       31079 :     if (params.admin_down) {
     311          78 :         neighbor->set_admin_down(true);
     312             :     }
     313       31079 :     if (params.local_autonomous_system) {
     314        4259 :         neighbor->set_peer_as(params.local_autonomous_system);
     315             :     } else {
     316       26820 :         neighbor->set_peer_as(params.autonomous_system);
     317             :     }
     318       31079 :     boost::system::error_code err;
     319       31079 :     neighbor->set_peer_address(
     320       31079 :         IpAddress::from_string(params.address, err));
     321       31079 :     if (err) {
     322          12 :         BGP_LOG_WARNING_STR(BgpConfig, BGP_LOG_FLAG_ALL,
     323             :                             "Invalid peer address " << params.address <<
     324             :                             " for neighbor " << neighbor->name());
     325             :     }
     326             : 
     327       31079 :     Ip4Address identifier = Ip4Address::from_string(params.identifier, err);
     328       31079 :     if (err) {
     329           0 :         BGP_LOG_WARNING_STR(BgpConfig, BGP_LOG_FLAG_ALL,
     330             :                             "Invalid peer identifier " << params.identifier <<
     331             :                             " for neighbor " << neighbor->name());
     332             :     }
     333       31079 :     neighbor->set_peer_identifier(IpAddressToBgpIdentifier(identifier));
     334             : 
     335       31079 :     if (params.router_type == "bgpaas-client") {
     336             :         IpAddress inet_gw_address =
     337         510 :             Ip4Address::from_string(params.gateway_address, err);
     338         510 :         if (!params.gateway_address.empty() && err) {
     339           0 :             BGP_LOG_WARNING_STR(BgpConfig, BGP_LOG_FLAG_ALL,
     340             :                                 "Invalid gateway address " <<
     341             :                                 params.gateway_address <<
     342             :                                 " for neighbor " << neighbor->name());
     343             :         } else {
     344         510 :             neighbor->set_gateway_address(Address::INET, inet_gw_address);
     345             :         }
     346             : 
     347             :         IpAddress inet6_gw_address =
     348         510 :             Ip6Address::from_string(params.ipv6_gateway_address, err);
     349         510 :         if (!params.ipv6_gateway_address.empty() && err) {
     350           0 :             BGP_LOG_WARNING_STR(BgpConfig, BGP_LOG_FLAG_ALL,
     351             :                 "Invalid ipv6 gateway address " <<
     352             :                 params.ipv6_gateway_address <<
     353             :                 " for neighbor " << neighbor->name());
     354             :         } else {
     355         510 :             neighbor->set_gateway_address(Address::INET6, inet6_gw_address);
     356             :         }
     357             :     }
     358             : 
     359       31079 :     neighbor->set_port(params.port);
     360       31079 :     neighbor->set_source_port(params.source_port);
     361       31079 :     neighbor->set_hold_time(params.hold_time);
     362             : 
     363       31079 :     if (session != NULL) {
     364       30698 :         NeighborSetSessionAttributes(neighbor, local_name, session);
     365             :     }
     366             : 
     367             :     // Get the local identifier and local as from the master protocol config.
     368             :     const BgpIfmapProtocolConfig *master_protocol =
     369       31079 :         master_instance->protocol_config();
     370       31079 :     if (master_protocol && master_protocol->bgp_router()) {
     371             :         const autogen::BgpRouterParams &master_params =
     372       31079 :             master_protocol->router_params();
     373       31079 :         if (master_params.admin_down) {
     374          78 :             neighbor->set_admin_down(true);
     375             :         }
     376             :         Ip4Address localid =
     377       31079 :             Ip4Address::from_string(master_params.identifier, err);
     378       31079 :         if (!err) {
     379       31066 :             neighbor->set_local_identifier(IpAddressToBgpIdentifier(localid));
     380             :         }
     381       31079 :         if (!neighbor->local_as()) {
     382       30895 :             if (master_params.local_autonomous_system) {
     383        4267 :                 neighbor->set_local_as(master_params.local_autonomous_system);
     384             :             } else {
     385       26628 :                 neighbor->set_local_as(master_params.autonomous_system);
     386             :             }
     387             :         }
     388       31079 :         if (instance != master_instance) {
     389         516 :             neighbor->set_passive(true);
     390             :         }
     391             :     }
     392             : 
     393             :     // Get other parameters from the instance protocol config.
     394             :     // Note that there's no instance protocol config for non-master instances.
     395       31079 :     const BgpIfmapProtocolConfig *protocol = instance->protocol_config();
     396       31079 :     if (protocol && protocol->bgp_router()) {
     397             :         const autogen::BgpRouterParams &protocol_params =
     398       30563 :             protocol->router_params();
     399       30563 :         if (neighbor->family_attributes_list().empty()) {
     400        2574 :             BuildFamilyAttributesList(neighbor,
     401        2574 :                 protocol_params.address_families.family,
     402        2574 :                 params.address_families.family);
     403             :         }
     404       30563 :         if (neighbor->auth_data().Empty()) {
     405             :             const autogen::BgpRouterParams &local_params =
     406       30130 :                 local_router->parameters();
     407       30130 :             BuildKeyChain(neighbor, local_params.auth_data);
     408             :         }
     409             :     }
     410             : 
     411       31079 :     if (neighbor->family_attributes_list().empty()) {
     412        1009 :         BuildFamilyAttributesList(neighbor, default_addr_family_list,
     413        1009 :             params.address_families.family);
     414             :     }
     415             : 
     416       31079 :     return neighbor;
     417             : }
     418             : 
     419             : //
     420             : // Build map of BgpNeighborConfigs based on the data in autogen::BgpPeering.
     421             : //
     422       13693 : void BgpIfmapPeeringConfig::BuildNeighbors(BgpIfmapConfigManager *manager,
     423             :     const autogen::BgpRouter *local_rt_config,
     424             :     const string &peername, const autogen::BgpRouter *remote_rt_config,
     425             :     const autogen::BgpPeering *peering, NeighborMap *map) {
     426             :     const BgpIfmapInstanceConfig *master_instance =
     427       13693 :         manager->config()->FindInstance(BgpConfigManager::kMasterInstance);
     428             : 
     429             :     // If there are one or more autogen::BgpSessions for the peering, use
     430             :     // those to create the BgpNeighborConfigs.
     431       13693 :     const autogen::BgpPeeringAttributes &attr = peering->data();
     432       13693 :     for (autogen::BgpPeeringAttributes::const_iterator iter = attr.begin();
     433       44391 :          iter != attr.end(); ++iter) {
     434       30698 :         BgpNeighborConfig *neighbor = MakeBgpNeighborConfig(
     435       30698 :             instance_, master_instance, manager->localname(), peername,
     436       30698 :             local_rt_config, remote_rt_config, iter.operator->());
     437       30698 :         map->insert(make_pair(neighbor->name(), neighbor));
     438             :     }
     439             : 
     440             :     // When no sessions are present, create a single BgpNeighborConfig with
     441             :     // no per-session configuration.
     442       13693 :     if (map->empty()) {
     443        1143 :         BgpNeighborConfig *neighbor = MakeBgpNeighborConfig(
     444         381 :             instance_, master_instance, manager->localname(), peername,
     445         381 :             local_rt_config, remote_rt_config, NULL);
     446         381 :         map->insert(make_pair(neighbor->name(), neighbor));
     447             :     }
     448       13693 : }
     449             : 
     450             : //
     451             : // Update BgpIfmapPeeringConfig based on updated autogen::BgpPeering.
     452             : //
     453             : // This mainly involves building future BgpNeighborConfigs and doing a diff of
     454             : // the current and future BgpNeighborConfigs.  Note that BgpIfmapInstanceConfig
     455             : // also has references to BgpNeighborConfigs, so it also needs to be updated as
     456             : // part of the process.
     457             : //
     458       15733 : void BgpIfmapPeeringConfig::Update(BgpIfmapConfigManager *manager,
     459             :     const autogen::BgpPeering *peering) {
     460       15733 :     IFMapNode *node = node_proxy_.node();
     461       15733 :     assert(node != NULL);
     462       15733 :     bgp_peering_.reset(peering);
     463             : 
     464             :     // Build the future NeighborMap.  The future map should be empty if the
     465             :     // bgp-peering is deleted or if the parameters for the remote bgp-router
     466             :     // are not available.
     467       15733 :     NeighborMap future;
     468       15733 :     pair<IFMapNode *, IFMapNode *> routers;
     469       29434 :     if (!node->IsDeleted() &&
     470       13701 :         GetRouterPair(manager->graph(), manager->localname(), node, &routers)) {
     471             :         const autogen::BgpRouter *local_rt_config =
     472             :                 static_cast<const autogen::BgpRouter *>(
     473       13693 :                     routers.first->GetObject());
     474             :         const autogen::BgpRouter *remote_rt_config =
     475             :                 static_cast<const autogen::BgpRouter *>(
     476       13693 :                     routers.second->GetObject());
     477       27386 :         if (local_rt_config &&
     478       13693 :             local_rt_config->IsPropertySet(autogen::BgpRouter::PARAMETERS) &&
     479       27386 :             remote_rt_config &&
     480       13693 :             remote_rt_config->IsPropertySet(autogen::BgpRouter::PARAMETERS)) {
     481       13693 :             BuildNeighbors(manager, local_rt_config, routers.second->name(),
     482             :                            remote_rt_config, peering, &future);
     483             :         }
     484             :     }
     485             : 
     486             :     // Swap out the NeighborMap in preparation for doing a diff.
     487       15733 :     NeighborMap current;
     488       15733 :     current.swap(neighbors_);
     489             : 
     490             :     // Do a diff on the current and future BgpNeighborConfigs, making sure
     491             :     // that the BgpIfmapInstanceConfig is updated accordingly.  We add any new
     492             :     // BgpNeighborConfigs to our NeighborMap.
     493       15733 :     NeighborMap::iterator it1 = current.begin();
     494       15733 :     NeighborMap::iterator it2 = future.begin();
     495       42017 :     while (it1 != current.end() && it2 != future.end()) {
     496       26284 :         if (it1->first < it2->first) {
     497        2311 :             BgpNeighborConfig *prev = it1->second;
     498        2311 :             instance_->DeleteNeighbor(manager, prev);
     499        2311 :             ++it1;
     500       23973 :         } else if (it1->first > it2->first) {
     501        2311 :             BgpNeighborConfig *neighbor = it2->second;
     502        2311 :             instance_->AddNeighbor(manager, neighbor);
     503        2311 :             neighbors_.insert(*it2);
     504        2311 :             it2->second = NULL;
     505        2311 :             ++it2;
     506             :         } else {
     507       21662 :             BgpNeighborConfig *neighbor = it1->second;
     508       21662 :             BgpNeighborConfig *update = it2->second;
     509       21662 :             if (*neighbor != *update) {
     510         764 :                 instance_->ChangeNeighbor(manager, update);
     511         764 :                 neighbors_.insert(*it2);
     512         764 :                 it2->second = NULL;
     513             :             } else {
     514       20898 :                 neighbors_.insert(*it1);
     515       20898 :                 it1->second = NULL;
     516             :             }
     517       21662 :             ++it1;
     518       21662 :             ++it2;
     519             :         }
     520             :     }
     521       20052 :     for (; it1 != current.end(); ++it1) {
     522        4319 :         BgpNeighborConfig *prev = it1->second;
     523        4319 :         instance_->DeleteNeighbor(manager, prev);
     524             :     }
     525       22839 :     for (; it2 != future.end(); ++it2) {
     526        7106 :         BgpNeighborConfig *neighbor = it2->second;
     527        7106 :         instance_->AddNeighbor(manager, neighbor);
     528        7106 :         neighbors_.insert(*it2);
     529        7106 :         it2->second = NULL;
     530             :     }
     531             : 
     532             :     // Get rid of the current and future NeighborMaps and destroy any mapped
     533             :     // BgpNeighborConfigs. Note that we have carefully reset mapped values to
     534             :     // NULL above when we don't want a BgpNeighborConfig to get destroyed.
     535       15733 :     STLDeleteElements(&current);
     536       15733 :     STLDeleteElements(&future);
     537       15733 : }
     538             : 
     539             : //
     540             : // Delete all state for the given BgpPeeringConfig.
     541             : //
     542             : // This mainly involves getting rid of BgpNeighborConfigs in the NeighborMap.
     543             : //
     544        2121 : void BgpIfmapPeeringConfig::Delete(BgpIfmapConfigManager *manager) {
     545        2121 :     NeighborMap current;
     546        2121 :     current.swap(neighbors_);
     547        2121 :     for (NeighborMap::iterator iter = current.begin();
     548        2210 :          iter != current.end(); ++iter) {
     549          89 :         instance_->DeleteNeighbor(manager, iter->second);
     550             :     }
     551        2121 :     STLDeleteElements(&current);
     552        2121 :     bgp_peering_.reset();
     553        2121 : }
     554             : 
     555             : //
     556             : // Find the IFMapNodes for a bgp-peering.
     557             : //
     558             : // The "node" is the IFMapNode for the bgp-peering link.  The bgp-peering is
     559             : // interesting only if one of the bgp-routers is the local node.
     560             : //
     561             : // Return true if both bgp-routers for the bgp-peering exist and one of them
     562             : // is the local one. Also fill in the local and remote IFMapNode pointers if
     563             : // we return true.
     564             : //
     565       19879 : bool BgpIfmapPeeringConfig::GetRouterPair(DBGraph *db_graph,
     566             :     const string  &localname, IFMapNode *node,
     567             :     pair<IFMapNode *, IFMapNode *> *pair) {
     568       19879 :     IFMapNode *local = NULL;
     569       19879 :     IFMapNode *remote = NULL;
     570       19879 :     string local_router_type;
     571       19879 :     string remote_router_type;
     572       19879 :     string local_instance;
     573       19879 :     string remote_instance;
     574             : 
     575       19879 :     for (DBGraphVertex::adjacency_iterator iter = node->begin(db_graph);
     576       59637 :          iter != node->end(db_graph); ++iter) {
     577       39758 :         IFMapNode *adj = static_cast<IFMapNode *>(iter.operator->());
     578       39758 :         if (strcmp(adj->table()->Typename(), "bgp-router") != 0)
     579          23 :             continue;
     580             :         autogen::BgpRouter *router =
     581       39758 :             static_cast<autogen::BgpRouter *>(adj->GetObject());
     582       39758 :         if (!router)
     583          23 :             continue;
     584       39735 :         const autogen::BgpRouterParams &params = router->parameters();
     585       39735 :         string instance_name(IdentifierParent(adj->name()));
     586       39735 :         string name = adj->name().substr(instance_name.size() + 1);
     587       39735 :         if (name == localname && params.router_type != "bgpaas-client") {
     588       17389 :             local = adj;
     589       17389 :             local_router_type = params.router_type;
     590       17389 :             local_instance = instance_name;
     591       23618 :         } else if (instance_name != BgpConfigManager::kMasterInstance &&
     592        1272 :             params.router_type == "bgpaas-server") {
     593         632 :             local = adj;
     594         632 :             local_router_type = params.router_type;
     595         632 :             local_instance = instance_name;
     596             :         } else {
     597       21714 :             remote = adj;
     598       21714 :             remote_router_type = params.router_type;
     599       21714 :             remote_instance = instance_name;
     600             :         }
     601       39735 :     }
     602             : 
     603       18021 :     if ((local == NULL || remote == NULL) || (local_router_type ==
     604       18639 :          "bgpaas-server" && remote_router_type != "bgpaas-client") ||
     605       35383 :         (local_router_type != "bgpaas-server" && remote_router_type ==
     606       37900 :          "bgpaas-client") || (local_instance != remote_instance)) {
     607        1874 :         BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_SYSLOG,
     608             :                  "localname: " << localname <<
     609             :                  ((local == NULL) ? " Local node not present" :
     610             :                                   " Local node present") <<
     611             :                  ((remote == NULL) ? " Remote node not present" :
     612             :                                   " Remote node present") <<
     613             :                  " local_router_type: " << local_router_type <<
     614             :                  " remote_router_type: " << remote_router_type <<
     615             :                  " local instance: " << local_instance <<
     616             :                  " remote instance: " << remote_instance);
     617        1874 :         return false;
     618             :     }
     619             : 
     620       18005 :     pair->first = local;
     621       18005 :     pair->second = remote;
     622       18005 :     return true;
     623       19879 : }
     624             : 
     625             : //
     626             : // Constructor for BgpIfmapProtocolConfig.
     627             : //
     628        8596 : BgpIfmapProtocolConfig::BgpIfmapProtocolConfig(BgpIfmapInstanceConfig *instance)
     629        8596 :     : instance_(instance),
     630        8596 :       data_(instance->name()) {
     631        8596 : }
     632             : 
     633             : //
     634             : // Destructor for BgpIfmapProtocolConfig.
     635             : //
     636        8596 : BgpIfmapProtocolConfig::~BgpIfmapProtocolConfig() {
     637        8596 : }
     638             : 
     639      161414 : const autogen::BgpRouterParams &BgpIfmapProtocolConfig::router_params() const {
     640      161414 :     return bgp_router_->parameters();
     641             : }
     642             : 
     643             : //
     644             : // Set the IFMapNodeProxy for the BgpIfmapProtocolConfig.
     645             : //
     646        5900 : void BgpIfmapProtocolConfig::SetNodeProxy(IFMapNodeProxy *proxy) {
     647        5900 :     if (proxy != NULL) {
     648        5900 :         node_proxy_.Swap(proxy);
     649             :     }
     650        5900 : }
     651             : 
     652             : //
     653             : // Update autogen::BgpRouter object for this BgpIfmapProtocolConfig.
     654             : //
     655       15702 : void BgpIfmapProtocolConfig::Update(BgpIfmapConfigManager *manager,
     656             :     const autogen::BgpRouter *router) {
     657       15702 :     bgp_router_.reset(router);
     658       15702 :     const autogen::BgpRouterParams &params = router->parameters();
     659       15702 :     data_.set_admin_down(params.admin_down);
     660       15702 :     data_.set_cluster_id(params.cluster_id);
     661       15702 :     data_.set_autonomous_system(params.autonomous_system);
     662       15702 :     data_.set_local_autonomous_system(params.local_autonomous_system);
     663       15702 :     data_.set_port(params.port ?: BgpConfigManager::kDefaultPort);
     664       15702 :     boost::system::error_code err;
     665       15702 :     IpAddress identifier = IpAddress::from_string(params.identifier, err);
     666       15702 :     if (!err) {
     667        7670 :         data_.set_identifier(IpAddressToBgpIdentifier(identifier));
     668             :     }
     669       15702 :     data_.set_hold_time(params.hold_time);
     670             : 
     671             :     // reset subcluster name and id,
     672             :     // will be set again if mapping is found in schema
     673       15702 :     data_.reset_subcluster_name();
     674       15702 :     data_.reset_subcluster_id();
     675             :     // get subcluster name this router is associated with
     676       15702 :     IFMapNode *node = node_proxy_.node();
     677       15702 :     if (!node)
     678        8031 :         return;
     679        7671 :     DBGraph *graph = manager->graph();
     680        7671 :     for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
     681       20889 :          iter != node->end(graph); ++iter) {
     682       13234 :         IFMapNode *adj = static_cast<IFMapNode *>(iter.operator->());
     683       13234 :         if (strcmp(adj->table()->Typename(), "sub-cluster") == 0) {
     684          16 :             data_.set_subcluster_name(adj->name());
     685             :             const autogen::SubCluster *sc =
     686          16 :                 static_cast<autogen::SubCluster *>(adj->GetObject());
     687          16 :             if (sc) {
     688          16 :                 data_.set_subcluster_id(sc->id());
     689             :             }
     690          16 :             break;
     691             :         }
     692             :     }
     693             : }
     694             : 
     695             : //
     696             : // Delete autogen::BgpRouter object for this BgpIfmapProtocolConfig.
     697             : //
     698        1379 : void BgpIfmapProtocolConfig::Delete(BgpIfmapConfigManager *manager) {
     699        1379 :     manager->Notify(&data_, BgpConfigManager::CFG_DELETE);
     700        1379 :     bgp_router_.reset();
     701        1379 : }
     702             : 
     703           0 : const string &BgpIfmapProtocolConfig::InstanceName() const {
     704           0 :     return instance_->name();
     705             : }
     706             : 
     707             : //
     708             : // Constructor for BgpIfmapInstanceConfig.
     709             : //
     710       50601 : BgpIfmapInstanceConfig::BgpIfmapInstanceConfig(const string &name)
     711       50601 :     : name_(name),
     712       50601 :       data_(name),
     713       50601 :       index_(-1),
     714      101202 :       protocol_(NULL) {
     715       50601 : }
     716             : 
     717             : //
     718             : // Destructor for BgpIfmapInstanceConfig.
     719             : //
     720       50601 : BgpIfmapInstanceConfig::~BgpIfmapInstanceConfig() {
     721       50601 : }
     722             : 
     723             : //
     724             : // Set the IFMapNodeProxy for the BgpIfmapInstanceConfig.
     725             : //
     726       48411 : void BgpIfmapInstanceConfig::SetNodeProxy(IFMapNodeProxy *proxy) {
     727       48411 :     if (proxy != NULL) {
     728       48411 :         node_proxy_.Swap(proxy);
     729             :     }
     730       48411 : }
     731             : 
     732             : //
     733             : // Get the BgpIfmapProtocolConfig for this BgpIfmapInstanceConfig, create
     734             : // it if needed.
     735             : //
     736        8596 : BgpIfmapProtocolConfig *BgpIfmapInstanceConfig::LocateProtocol() {
     737        8596 :     if (protocol_.get() == NULL) {
     738        8596 :         protocol_.reset(new BgpIfmapProtocolConfig(this));
     739             :     }
     740        8596 :     return protocol_.get();
     741             : }
     742             : 
     743             : //
     744             : // Delete the BgpIfmapProtocolConfig for this BgpIfmapInstanceConfig.
     745             : //
     746        1379 : void BgpIfmapInstanceConfig::ResetProtocol() {
     747        1379 :     protocol_.reset();
     748        1379 : }
     749             : 
     750             : //
     751             : // Get the route-target for an instance-target. The input IFMapNode is the
     752             : // midnode that represents the instance-target link. We traverse the graph
     753             : // the graph edges till we find the adjacency to the route-target.
     754             : //
     755             : // Return true and fill in the target string if we find the route-target.
     756             : //
     757      551076 : static bool GetInstanceTargetRouteTarget(DBGraph *graph, IFMapNode *node,
     758             :     string *target) {
     759      551076 :     for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
     760     1102152 :          iter != node->end(graph); ++iter) {
     761     1102152 :         IFMapNode *adj = static_cast<IFMapNode *>(iter.operator->());
     762     1102152 :         if (strcmp(adj->table()->Typename(), "route-target") == 0) {
     763      551076 :             *target = adj->name();
     764      551076 :             return true;
     765             :         }
     766             :     }
     767           0 :     return false;
     768             : }
     769             : 
     770             : //
     771             : // Fill in all the export route targets for a routing-instance.  The input
     772             : // IFMapNode represents the routing-instance.  We traverse the graph edges
     773             : // and look for instance-target adjacencies. If the instance-target is an
     774             : // export and import target, add it to the vector.
     775             : //
     776             : // Note that we purposely skip adding export only targets to the vector.
     777             : // Reasoning is that export only targets are manually configured by users
     778             : // and hence should not be imported based on policy.
     779             : //
     780       28123 : static void GetRoutingInstanceExportTargets(DBGraph *graph, IFMapNode *node,
     781             :     vector<string> *target_list) {
     782       28123 :     for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
     783      115069 :          iter != node->end(graph); ++iter) {
     784       86946 :         IFMapNode *adj = static_cast<IFMapNode *>(iter.operator->());
     785       86946 :         string target;
     786      115024 :         if ((strcmp(adj->table()->Typename(), "instance-target") == 0) &&
     787       28078 :             (GetInstanceTargetRouteTarget(graph, adj, &target))) {
     788             :             const autogen::InstanceTarget *itarget =
     789       28078 :                     dynamic_cast<autogen::InstanceTarget *>(adj->GetObject());
     790       28078 :             if (!itarget)
     791           0 :                 continue;
     792       28078 :             const autogen::InstanceTargetType &itt = itarget->data();
     793       28078 :             if (itt.import_export.empty())
     794       28074 :                 target_list->push_back(target);
     795             :         }
     796       86946 :     }
     797       28123 : }
     798             : 
     799             : //
     800             : // Fill in all the export route targets of the routing-instance at the other
     801             : // end of a connection.  The src_node is the routing-instance from which we
     802             : // reached the connection node. The name of the source routing-instance is
     803             : // src_instance.
     804             : //
     805             : // If the connection is unidirectional and the destination-instance for the
     806             : // connection is not the routing-instance from which we started, we should
     807             : // not get any targets from this connection.  This is what a unidirectional
     808             : // connection means.
     809             : //
     810       28127 : static void GetConnectionExportTargets(DBGraph *graph, IFMapNode *src_node,
     811             :     const string &src_instance, IFMapNode *node,
     812             :     vector<string> *target_list) {
     813             :     const autogen::Connection *conn =
     814       28127 :         dynamic_cast<autogen::Connection *>(node->GetObject());
     815       28127 :     if (!conn)
     816           0 :         return;
     817       28127 :     const autogen::ConnectionType &conn_type = conn->data();
     818       28135 :     if (!conn_type.destination_instance.empty() &&
     819           8 :          conn_type.destination_instance != src_instance)
     820           4 :         return;
     821       28123 :     for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
     822       84369 :          iter != node->end(graph); ++iter) {
     823       56246 :         IFMapNode *adj = static_cast<IFMapNode *>(iter.operator->());
     824       56246 :         if (adj == src_node)
     825       28123 :             continue;
     826       28123 :         if (strcmp(adj->table()->Typename(), "routing-instance") != 0)
     827           0 :             continue;
     828       28123 :         GetRoutingInstanceExportTargets(graph, adj, target_list);
     829             :     }
     830             : }
     831             : 
     832             : //
     833             : // Fill in all the routing-policies for a routing-instance.  The input
     834             : // IFMapNode represents the routing-policy-routing-instance.  We traverse to
     835             : // graph edges and look for routing-policy adjacency
     836             : //
     837         530 : static bool GetRoutingInstanceRoutingPolicy(DBGraph *graph, IFMapNode *node,
     838             :     RoutingPolicyAttachInfo *ri_rp_link) {
     839         530 :     string sequence;
     840             :     const autogen::RoutingPolicyRoutingInstance *policy =
     841         530 :         static_cast<autogen::RoutingPolicyRoutingInstance *>(node->GetObject());
     842         530 :     const autogen::RoutingPolicyType &attach_info = policy->data();
     843             : 
     844         530 :     ri_rp_link->sequence_ = attach_info.sequence;
     845             : 
     846         530 :     for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
     847        1060 :          iter != node->end(graph); ++iter) {
     848        1060 :         IFMapNode *adj = static_cast<IFMapNode *>(iter.operator->());
     849        1060 :         if (strcmp(adj->table()->Typename(), "routing-policy") == 0) {
     850         530 :             ri_rp_link->routing_policy_ = adj->name();
     851         530 :             return true;
     852             :         }
     853             :     }
     854           0 :     return false;
     855         530 : }
     856             : 
     857             : //
     858             : // Fill in all the route-aggregation for a routing-instance.
     859             : //
     860         726 : static bool GetRouteAggregateConfig(DBGraph *graph, IFMapNode *node,
     861             :     BgpInstanceConfig::AggregateRouteList *inet_list,
     862             :     BgpInstanceConfig::AggregateRouteList *inet6_list) {
     863             :     const autogen::RouteAggregate *ra =
     864         726 :         static_cast<autogen::RouteAggregate *>(node->GetObject());
     865         726 :     if (ra == NULL) return false;
     866             : 
     867         726 :     boost::system::error_code ec;
     868             :     IpAddress nexthop =
     869         726 :         IpAddress::from_string(ra->aggregate_route_nexthop(), ec);
     870         726 :     if (ec.failed()) return false;
     871             : 
     872        2464 :     BOOST_FOREACH(const string &route, ra->aggregate_route_entries()) {
     873         869 :         AggregateRouteConfig aggregate;
     874         869 :         aggregate.nexthop = nexthop;
     875             : 
     876         869 :         Ip4Address address;
     877         869 :         ec = Ip4SubnetParse(route, &address, &aggregate.prefix_length);
     878         869 :         if (!ec) {
     879         842 :             if (!nexthop.is_v4()) continue;
     880         836 :             aggregate.aggregate = address;
     881         836 :             inet_list->push_back(aggregate);
     882             :         } else {
     883          30 :             if (!nexthop.is_v6()) continue;
     884          27 :             Ip6Address address;
     885          27 :             ec = Inet6SubnetParse(route, &address, &aggregate.prefix_length);
     886          27 :             if (ec.failed()) continue;
     887          27 :             aggregate.aggregate = address;
     888          27 :             inet6_list->push_back(aggregate);
     889             :         }
     890             :     }
     891             : 
     892         726 :     return true;
     893             : }
     894             : 
     895             : //
     896             : // Get the network id for a virtual-network.  The input IFMapNode represents
     897             : // the virtual-network.
     898             : //
     899       74292 : static int GetVirtualNetworkIndex(DBGraph *graph, IFMapNode *node) {
     900             :     const autogen::VirtualNetwork *vn =
     901       74292 :         static_cast<autogen::VirtualNetwork *>(node->GetObject());
     902       74292 :     if (vn && vn->IsPropertySet(autogen::VirtualNetwork::NETWORK_ID))
     903         118 :         return vn->network_id();
     904       74174 :     if (vn && vn->IsPropertySet(autogen::VirtualNetwork::PROPERTIES))
     905       74107 :         return vn->properties().network_id;
     906          67 :     return 0;
     907             : }
     908             : 
     909             : //
     910             : // Check if a virtual-network allows transit. The input IFMapNode represents
     911             : // the virtual-network.
     912             : //
     913       74292 : static bool GetVirtualNetworkAllowTransit(DBGraph *graph, IFMapNode *node) {
     914             :     const autogen::VirtualNetwork *vn =
     915       74292 :         static_cast<autogen::VirtualNetwork *>(node->GetObject());
     916       74292 :     if (vn && vn->IsPropertySet(autogen::VirtualNetwork::PROPERTIES))
     917       74139 :         return vn->properties().allow_transit;
     918         153 :     return false;
     919             : }
     920             : 
     921             : 
     922             : //
     923             : // Check if a virtual-network has pbb-evpn enabled.
     924             : // The input IFMapNode represents the virtual-network.
     925             : //
     926       74292 : static bool GetVirtualNetworkPbbEvpnEnable(DBGraph *graph, IFMapNode *node) {
     927             :     const autogen::VirtualNetwork *vn =
     928       74292 :         static_cast<autogen::VirtualNetwork *>(node->GetObject());
     929       74292 :     if (vn && vn->IsPropertySet(autogen::VirtualNetwork::PBB_EVPN_ENABLE))
     930       15238 :         return vn->pbb_evpn_enable();
     931       59054 :     return false;
     932             : }
     933             : 
     934             : 
     935             : //
     936             : // Get the vxlan id for a virtual-network.  The input IFMapNode represents
     937             : // the virtual-network.
     938             : //
     939             : // The vxlan_network_identifier is 0 when automatic mode is in use. In that
     940             : // case, the network_id is used as vxlan id.
     941             : //
     942       74292 : static int GetVirtualNetworkVxlanId(DBGraph *graph, IFMapNode *node) {
     943             :     const autogen::VirtualNetwork *vn =
     944       74292 :         static_cast<autogen::VirtualNetwork *>(node->GetObject());
     945       74292 :     if (vn && vn->IsPropertySet(autogen::VirtualNetwork::PROPERTIES)) {
     946       74139 :         if (vn->properties().vxlan_network_identifier) {
     947           0 :             return vn->properties().vxlan_network_identifier;
     948             :         } else {
     949       74139 :             return vn->properties().network_id;
     950             :         }
     951             :     }
     952         153 :     return 0;
     953             : }
     954             : 
     955        4221 : static void SetStaticRouteConfig(BgpInstanceConfig *rti,
     956             :     const autogen::RoutingInstance *config) {
     957        4221 :     BgpInstanceConfig::StaticRouteList inet_list;
     958        4221 :     BgpInstanceConfig::StaticRouteList inet6_list;
     959        4973 :     BOOST_FOREACH(const autogen::StaticRouteType &route,
     960             :                   config->static_route_entries()) {
     961         376 :         boost::system::error_code ec;
     962         376 :         StaticRouteConfig item;
     963         376 :         item.nexthop = IpAddress::from_string(route.next_hop, ec);
     964         376 :         if (ec.failed())
     965           4 :             continue;
     966             : 
     967         372 :         item.route_targets = route.route_target;
     968         372 :         item.communities = route.community;
     969         372 :         if (item.nexthop.is_v4()) {
     970         291 :             Ip4Address address;
     971         291 :             ec = Ip4SubnetParse(route.prefix, &address, &item.prefix_length);
     972         291 :             if (ec.failed())
     973           3 :                 continue;
     974         288 :             item.address = address;
     975             :             std::pair<BgpInstanceConfig::StaticRouteList::iterator, bool> ret =
     976         288 :                 inet_list.insert(item);
     977         288 :             if (!ret.second) {
     978           0 :                 BGP_LOG_WARNING_STR(BgpConfig, BGP_LOG_FLAG_ALL,
     979             :                     "Duplicate static route prefix " << route.prefix <<
     980             :                     " with nexthop " << route.next_hop <<
     981             :                     " for routing instance " << rti->name());
     982             :             }
     983             :         } else {
     984          81 :             Ip6Address address;
     985          81 :             ec = Inet6SubnetParse(route.prefix, &address, &item.prefix_length);
     986          81 :             if (ec.failed())
     987           3 :                 continue;
     988          78 :             item.address = address;
     989             :             std::pair<BgpInstanceConfig::StaticRouteList::iterator, bool> ret =
     990          78 :                 inet6_list.insert(item);
     991          78 :             if (!ret.second) {
     992           0 :                 BGP_LOG_WARNING_STR(BgpConfig, BGP_LOG_FLAG_ALL,
     993             :                     "Duplicate static route prefix " << route.prefix <<
     994             :                     " with nexthop " << route.next_hop <<
     995             :                     " for routing instance " << rti->name());
     996             :             }
     997             :         }
     998         376 :     }
     999        4221 :     rti->swap_static_routes(Address::INET, &inet_list);
    1000        4221 :     rti->swap_static_routes(Address::INET6, &inet6_list);
    1001        4221 : }
    1002             : 
    1003        4221 : static void SetServiceChainConfig(BgpInstanceConfig *rti,
    1004             :     const autogen::RoutingInstance *config) {
    1005        4221 :     BgpInstanceConfig::ServiceChainList list;
    1006             :     const autogen::ServiceChainInfo &inet_chain =
    1007        4221 :         config->service_chain_information();
    1008        4221 :     if (config->IsPropertySet(
    1009             :         autogen::RoutingInstance::SERVICE_CHAIN_INFORMATION)) {
    1010        1178 :         ServiceChainConfig item = {
    1011             :             SCAddress::INET,
    1012        1178 :             inet_chain.routing_instance,
    1013        1178 :             inet_chain.prefix,
    1014        1178 :             inet_chain.service_chain_address,
    1015        1178 :             inet_chain.service_instance,
    1016        1178 :             inet_chain.source_routing_instance,
    1017        1178 :             inet_chain.service_chain_id,
    1018        1178 :             inet_chain.sc_head,
    1019        1178 :             inet_chain.retain_as_path,
    1020        1178 :         };
    1021        1178 :         list.push_back(item);
    1022        1178 :     }
    1023             : 
    1024             :     const autogen::ServiceChainInfo &inet6_chain =
    1025        4221 :         config->ipv6_service_chain_information();
    1026        4221 :     if (config->IsPropertySet(
    1027             :         autogen::RoutingInstance::IPV6_SERVICE_CHAIN_INFORMATION)) {
    1028        1048 :         ServiceChainConfig item = {
    1029             :             SCAddress::INET6,
    1030        1048 :             inet6_chain.routing_instance,
    1031        1048 :             inet6_chain.prefix,
    1032        1048 :             inet6_chain.service_chain_address,
    1033        1048 :             inet6_chain.service_instance,
    1034        1048 :             inet6_chain.source_routing_instance,
    1035        1048 :             inet6_chain.service_chain_id,
    1036        1048 :             inet6_chain.sc_head,
    1037        1048 :             inet6_chain.retain_as_path,
    1038        1048 :         };
    1039        1048 :         list.push_back(item);
    1040        1048 :     }
    1041             : 
    1042             :     const autogen::ServiceChainInfo &evpn_chain =
    1043        4221 :         config->evpn_service_chain_information();
    1044        4221 :     if (config->IsPropertySet(
    1045             :         autogen::RoutingInstance::EVPN_SERVICE_CHAIN_INFORMATION)) {
    1046         718 :         ServiceChainConfig item = {
    1047             :             SCAddress::EVPN,
    1048         718 :             evpn_chain.routing_instance,
    1049         718 :             evpn_chain.prefix,
    1050         718 :             evpn_chain.service_chain_address,
    1051         718 :             evpn_chain.service_instance,
    1052         718 :             evpn_chain.source_routing_instance,
    1053         718 :             evpn_chain.service_chain_id,
    1054         718 :             evpn_chain.sc_head,
    1055         718 :             evpn_chain.retain_as_path,
    1056         718 :         };
    1057         718 :         list.push_back(item);
    1058         718 :     }
    1059             : 
    1060             :     const autogen::ServiceChainInfo &evpnv6_chain =
    1061        4221 :         config->evpn_ipv6_service_chain_information();
    1062        4221 :     if (config->IsPropertySet(
    1063             :         autogen::RoutingInstance::EVPN_IPV6_SERVICE_CHAIN_INFORMATION)) {
    1064         720 :         ServiceChainConfig item = {
    1065             :             SCAddress::EVPN6,
    1066         720 :             evpnv6_chain.routing_instance,
    1067         720 :             evpnv6_chain.prefix,
    1068         720 :             evpnv6_chain.service_chain_address,
    1069         720 :             evpnv6_chain.service_instance,
    1070         720 :             evpnv6_chain.source_routing_instance,
    1071         720 :             evpnv6_chain.service_chain_id,
    1072         720 :             evpnv6_chain.sc_head,
    1073         720 :             evpnv6_chain.retain_as_path,
    1074         720 :         };
    1075         720 :         list.push_back(item);
    1076         720 :     }
    1077             : 
    1078        4221 :     rti->swap_service_chain_list(&list);
    1079        4221 : }
    1080             : 
    1081             : // Get name of vxlan RI for bridge RI
    1082             : 
    1083          17 : static string GetConnectedVxlanRiVn(DBGraph *graph, IFMapNode *node) {
    1084             :     const autogen::VirtualNetwork *vn_vxlan =
    1085          17 :         static_cast<autogen::VirtualNetwork *>(node->GetObject());
    1086          17 :     if (!vn_vxlan)
    1087           0 :         return "";
    1088          17 :     for (DBGraphVertex::adjacency_iterator iter_ri = node->begin(graph);
    1089         136 :         iter_ri != node->end(graph); ++iter_ri) {
    1090         136 :         IFMapNode *adj_ri = static_cast<IFMapNode *>(iter_ri.operator->());
    1091         136 :         if (strcmp(adj_ri->table()->Typename(), "routing-instance") == 0)  {
    1092             :             const autogen::RoutingInstance *iri =
    1093          17 :                     dynamic_cast<autogen::RoutingInstance *>(adj_ri->GetObject());
    1094          17 :             if (!iri)
    1095           0 :                 continue;
    1096          34 :             return adj_ri->name();
    1097             :         }
    1098             :     }
    1099           0 :     return "";
    1100             : }
    1101             : 
    1102          17 : static string GetConnectedVxlanRiLr(DBGraph *graph, IFMapNode *node) {
    1103          17 :     std::string ri_name = "";
    1104          17 :     for (DBGraphVertex::adjacency_iterator iter_lr = node->begin(graph);
    1105         102 :         iter_lr != node->end(graph); ++iter_lr) {
    1106         102 :         IFMapNode *adj_lr = static_cast<IFMapNode *>(iter_lr.operator->());
    1107         102 :         if (strcmp(adj_lr->table()->Typename(),
    1108         102 :                    "logical-router-virtual-network") == 0)  {
    1109          17 :             for (DBGraphVertex::adjacency_iterator iter_vn = adj_lr->begin(graph);
    1110          34 :                 iter_vn != adj_lr->end(graph); ++iter_vn) {
    1111          34 :                 IFMapNode *adj_vn = static_cast<IFMapNode *>(iter_vn.operator->());
    1112          34 :                 if (strcmp(adj_vn->table()->Typename(), "virtual-network") == 0)  {
    1113          17 :                     ri_name = GetConnectedVxlanRiVn(graph, adj_vn);
    1114          17 :                     if (ri_name != "") {
    1115          17 :                         return ri_name;
    1116             :                     }
    1117             :                 }
    1118             :             }
    1119             :         }
    1120             :     }
    1121           0 :     return "";
    1122          17 : }
    1123             : 
    1124             : 
    1125       74292 : static string GetConnectedVxlanRi(DBGraph *graph, IFMapNode *node) {
    1126       74292 :     std::string ri_name = "";
    1127             :     const autogen::VirtualNetwork *vn =
    1128       74292 :         static_cast<autogen::VirtualNetwork *>(node->GetObject());
    1129       74292 :     if (!vn) {
    1130          66 :         return "";
    1131             :     }
    1132       74226 :     for (DBGraphVertex::adjacency_iterator iter_vmi = node->begin(graph);
    1133      162557 :          iter_vmi != node->end(graph); ++iter_vmi) {
    1134       88348 :         IFMapNode *adj_vmi = static_cast<IFMapNode *>(iter_vmi.operator->());
    1135       88348 :         if (strcmp(adj_vmi->table()->Typename(),
    1136       88348 :                    "virtual-machine-interface") == 0) {
    1137         143 :             for (DBGraphVertex::adjacency_iterator iter_lr = adj_vmi->begin(graph);
    1138         958 :                 iter_lr != adj_vmi->end(graph); ++iter_lr) {
    1139         832 :                 IFMapNode *adj_lr = static_cast<IFMapNode *>(iter_lr.operator->());
    1140         832 :                 if (strcmp(adj_lr->table()->Typename(), "logical-router") == 0)  {
    1141          17 :                     ri_name = GetConnectedVxlanRiLr(graph, adj_lr);
    1142          17 :                     if (ri_name != "") {
    1143          17 :                         return ri_name;
    1144             :                     }
    1145             :                 }
    1146             :             }
    1147             :         }
    1148             :     }
    1149       74209 :     return "";
    1150       74292 : }
    1151             : 
    1152             : 
    1153         236 : void BgpIfmapConfigManager::ProcessRoutingPolicyLink(
    1154             :     const BgpConfigDelta &delta) {
    1155         236 :     CHECK_CONCURRENCY("bgp::Config");
    1156             : 
    1157             :     BgpIfmapRoutingPolicyLinkConfig *ri_rp_link
    1158         236 :         = config_->FindRoutingPolicyLink(delta.id_name);
    1159         236 :     if (ri_rp_link == NULL) {
    1160         165 :         IFMapNodeProxy *proxy = delta.node.get();
    1161         165 :         if (proxy == NULL) {
    1162           0 :             return;
    1163             :         }
    1164         165 :         IFMapNode *node = proxy->node();
    1165         165 :         if (node == NULL || delta.obj.get() == NULL) {
    1166           0 :             return;
    1167             :         }
    1168             : 
    1169         165 :         pair<IFMapNode *, IFMapNode *> ri_rp_pair;
    1170         165 :         if (!BgpIfmapRoutingPolicyLinkConfig::GetInstancePolicyPair(db_graph_,
    1171             :             node, &ri_rp_pair)) {
    1172           0 :             return;
    1173             :         }
    1174             : 
    1175         165 :         string instance_name = ri_rp_pair.first->name();
    1176         165 :         string policy_name = ri_rp_pair.second->name();
    1177             : 
    1178             :         BgpIfmapInstanceConfig *rti  =
    1179         165 :             config_->FindInstance(instance_name);
    1180             :         BgpIfmapRoutingPolicyConfig *rtp  =
    1181         165 :             config_->FindRoutingPolicy(policy_name);
    1182         165 :         if (!rti || !rtp) {
    1183           0 :             return;
    1184             :         }
    1185             : 
    1186         165 :         ri_rp_link = config_->CreateRoutingPolicyLink(rti, rtp, proxy);
    1187         165 :     } else {
    1188          71 :         const IFMapNode *node = ri_rp_link->node();
    1189          71 :         assert(node != NULL);
    1190          71 :         if (delta.obj.get() == NULL) {
    1191          46 :             BgpIfmapRoutingPolicyConfig *rtp = ri_rp_link->policy();
    1192          46 :             BgpIfmapInstanceConfig *rti = ri_rp_link->instance();
    1193          46 :             config_->DeleteRoutingPolicyLink(ri_rp_link);
    1194          46 :             if (rtp->DeleteIfEmpty(this)) {
    1195          38 :                 config_->DeleteRoutingPolicy(rtp);
    1196             :             }
    1197          46 :             if (rti->DeleteIfEmpty(this)) {
    1198           1 :                 BGP_CONFIG_LOG_INSTANCE(Delete, server(), rti,
    1199             :                     SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
    1200           1 :                 config_->DeleteInstance(rti);
    1201             :             }
    1202          46 :             return;
    1203             :         }
    1204             :     }
    1205             : 
    1206             :     autogen::RoutingPolicyRoutingInstance *ri_rp_link_cfg =
    1207         190 :         static_cast<autogen::RoutingPolicyRoutingInstance *>(delta.obj.get());
    1208             : 
    1209         190 :     ri_rp_link->Update(this, ri_rp_link_cfg);
    1210             : }
    1211             : 
    1212         151 : static bool CompareRoutingPolicyOrder(const RoutingPolicyAttachInfo &lhs,
    1213             :                                       const RoutingPolicyAttachInfo &rhs) {
    1214         151 :     return (lhs.sequence_ < rhs.sequence_);
    1215             : }
    1216             : 
    1217       18180 : void BgpIfmapInstanceConfig::ProcessIdentifierUpdate(uint32_t new_id,
    1218             :                                                      uint32_t old_id) {
    1219       18180 :     BgpInstanceConfig::RouteTargetList import_list = data_.import_list();
    1220       18180 :     if (old_id > 0) {
    1221         183 :         string old_vit = "target:" + GetVitFromId(ntohl(old_id));
    1222         183 :         import_list.erase(old_vit);
    1223         183 :     }
    1224       18180 :     if (new_id > 0) {
    1225       18180 :         string new_vit = "target:" + GetVitFromId(ntohl(new_id));
    1226       18180 :         import_list.insert(new_vit);
    1227       18180 :     }
    1228       18180 :     data_.set_import_list(import_list);
    1229       18180 : }
    1230             : 
    1231       12268 : void BgpIfmapInstanceConfig::ProcessASUpdate(uint32_t new_as, uint32_t old_as) {
    1232       12268 :     BgpInstanceConfig::RouteTargetList import_list = data_.import_list();
    1233       12268 :     if (old_as > 0) {
    1234       11519 :         string old_es_rtarget = "target:" + GetESRouteTarget(old_as);
    1235       11519 :         import_list.erase(old_es_rtarget);
    1236       11519 :     }
    1237       12268 :     if (new_as > 0) {
    1238       12267 :         string new_es_rtarget = "target:" + GetESRouteTarget(new_as);
    1239       12267 :         import_list.insert(new_es_rtarget);
    1240       12267 :     }
    1241       12268 :     data_.set_import_list(import_list);
    1242       12268 : }
    1243             : 
    1244       97058 : string BgpIfmapInstanceConfig::GetVitFromId(uint32_t identifier) const {
    1245       97058 :     if (identifier == 0)
    1246           0 :         return "";
    1247      194116 :     return Ip4Address(identifier).to_string() + ":" + integerToString(index());
    1248             : }
    1249             : 
    1250      147667 : string BgpIfmapInstanceConfig::GetESRouteTarget(uint32_t as) const {
    1251      147667 :     if (as == 0)
    1252           0 :         return "";
    1253      147667 :     if (as > 0xffFF)
    1254          80 :         return integerToString(as) + ":" +
    1255         120 :             integerToString(EVPN_ES_IMPORT_ROUTE_TARGET_AS4);
    1256      295254 :     return integerToString(as) + ":" +
    1257      442881 :         integerToString(EVPN_ES_IMPORT_ROUTE_TARGET_AS2);
    1258             : }
    1259             : 
    1260             : // Populate vrf import route-target (used for MVPN) and ES route target in
    1261             : // import list.
    1262      124446 : void BgpIfmapInstanceConfig::InsertVitAndESRTargetInImportList(
    1263             :                          BgpIfmapConfigManager *mgr,
    1264             :                          BgpInstanceConfig::RouteTargetList& import_list) {
    1265             :     const BgpIfmapInstanceConfig *master_instance =
    1266      124446 :         mgr->config()->FindInstance(BgpConfigManager::kMasterInstance);
    1267      124446 :     uint32_t bgp_identifier = 0;
    1268      124446 :     uint32_t as = 0;
    1269      124446 :     if (master_instance) {
    1270             :         const BgpIfmapProtocolConfig *master_protocol =
    1271      124446 :             master_instance->protocol_config();
    1272      124446 :         if (master_protocol) {
    1273      123881 :             if (master_protocol->protocol_config()) {
    1274             :                 bgp_identifier =
    1275      123881 :                     master_protocol->protocol_config()->identifier();
    1276      123881 :                 as = master_protocol->protocol_config()->autonomous_system();
    1277             :             }
    1278             :         }
    1279             :     }
    1280      124446 :     if (bgp_identifier > 0)
    1281       78695 :         import_list.insert("target:" + GetVitFromId(ntohl(bgp_identifier)));
    1282      124446 :     if (as > 0)
    1283      123881 :         import_list.insert("target:" + GetESRouteTarget(as));
    1284      124446 : }
    1285             : 
    1286             : //
    1287             : // Update BgpIfmapInstanceConfig based on a new autogen::RoutingInstance object.
    1288             : //
    1289             : // Rebuild the import and export route target lists and update the virtual
    1290             : // network information.
    1291             : //
    1292             : // Targets that are configured on this routing-instance (which corresponds
    1293             : // to all adjacencies to instance-target) are added to the import list or
    1294             : // export list or both depending on the import_export attribute.
    1295             : //
    1296             : // Export targets for all other routing-instances that we are connected to
    1297             : // are added to our import list.
    1298             : //
    1299      124446 : void BgpIfmapInstanceConfig::Update(BgpIfmapConfigManager *manager,
    1300             :     const autogen::RoutingInstance *config) {
    1301      124446 :     BgpInstanceConfig::RouteTargetList import_list, export_list;
    1302      124446 :     BgpInstanceConfig::AggregateRouteList inet6_aggregate_list;
    1303      124446 :     BgpInstanceConfig::AggregateRouteList inet_aggregate_list;
    1304      124446 :     RoutingPolicyConfigList policy_list;
    1305      124446 :     data_.Clear();
    1306             : 
    1307      124446 :     DBGraph *graph = manager->graph();
    1308      124446 :     IFMapNode *node = node_proxy_.node();
    1309      124446 :     for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
    1310      762560 :          iter != node->end(graph); ++iter) {
    1311      638114 :         IFMapNode *adj = static_cast<IFMapNode *>(iter.operator->());
    1312      638114 :         if (strcmp(adj->table()->Typename(), "instance-target") == 0) {
    1313      522998 :             string target;
    1314      522998 :             if (GetInstanceTargetRouteTarget(graph, adj, &target)) {
    1315             :                 const autogen::InstanceTarget *itarget =
    1316      522998 :                     dynamic_cast<autogen::InstanceTarget *>(adj->GetObject());
    1317      522998 :                 if (!itarget)
    1318           0 :                     continue;
    1319      522998 :                 const autogen::InstanceTargetType &itt = itarget->data();
    1320      522998 :                 if (itt.import_export == "import") {
    1321       10857 :                     import_list.insert(target);
    1322      512141 :                 } else if (itt.import_export == "export") {
    1323         889 :                     export_list.insert(target);
    1324             :                 } else {
    1325      511252 :                     import_list.insert(target);
    1326      511252 :                     export_list.insert(target);
    1327             :                 }
    1328             :             }
    1329      638114 :         } else if (strcmp(adj->table()->Typename(),
    1330      115116 :                           "routing-policy-routing-instance") == 0) {
    1331         530 :             RoutingPolicyAttachInfo policy_info;
    1332         530 :             if (GetRoutingInstanceRoutingPolicy(graph, adj, &policy_info)) {
    1333         530 :                 policy_list.push_back(policy_info);
    1334             :             }
    1335      115116 :         } else if (strcmp(adj->table()->Typename(), "route-aggregate") == 0) {
    1336         726 :             GetRouteAggregateConfig(graph, adj, &inet_aggregate_list,
    1337             :                                     &inet6_aggregate_list);
    1338      113860 :         } else if (strcmp(adj->table()->Typename(), "connection") == 0) {
    1339       28127 :             vector<string> target_list;
    1340       28127 :             GetConnectionExportTargets(graph, node, name_, adj, &target_list);
    1341       84275 :             BOOST_FOREACH(string target, target_list) {
    1342       28074 :                 import_list.insert(target);
    1343       28074 :             }
    1344      113860 :         } else if (strcmp(adj->table()->Typename(), "virtual-network") == 0) {
    1345       74292 :             data_.set_virtual_network(adj->name());
    1346       74292 :             data_.set_virtual_network_index(GetVirtualNetworkIndex(graph, adj));
    1347      148584 :             data_.set_virtual_network_allow_transit(
    1348       74292 :                 GetVirtualNetworkAllowTransit(graph, adj));
    1349       74292 :             data_.set_vxlan_id(GetVirtualNetworkVxlanId(graph, adj));
    1350      148584 :             data_.set_virtual_network_pbb_evpn_enable(
    1351       74292 :                 GetVirtualNetworkPbbEvpnEnable(graph, adj));
    1352       74292 :             data_.set_routing_instance_vxlan(GetConnectedVxlanRi(graph, adj));
    1353             :         }
    1354             :     }
    1355             : 
    1356      124446 :     InsertVitAndESRTargetInImportList(manager, import_list);
    1357      124446 :     data_.set_import_list(import_list);
    1358      124446 :     data_.set_export_list(export_list);
    1359             : 
    1360      124446 :     sort(policy_list.begin(), policy_list.end(), CompareRoutingPolicyOrder);
    1361      124446 :     data_.swap_routing_policy_list(&policy_list);
    1362      124446 :     data_.swap_aggregate_routes(Address::INET, &inet_aggregate_list);
    1363      124446 :     data_.swap_aggregate_routes(Address::INET6, &inet6_aggregate_list);
    1364             : 
    1365      124446 :     if (config) {
    1366        4221 :         data_.set_has_pnf(config->has_pnf());
    1367        4221 :         SetStaticRouteConfig(&data_, config);
    1368        4221 :         SetServiceChainConfig(&data_, config);
    1369             :     }
    1370      124446 : }
    1371             : 
    1372             : //
    1373             : // Reset IFMap related state in the BgpIfmapInstanceConfig.
    1374             : //
    1375       11643 : void BgpIfmapInstanceConfig::ResetConfig() {
    1376       11643 :     node_proxy_.Clear();
    1377       11643 : }
    1378             : 
    1379             : //
    1380             : // Return true if the BgpIfmapInstanceConfig is ready to be deleted.  The
    1381             : // caller is responsible for actually deleting it.
    1382             : //
    1383       15189 : bool BgpIfmapInstanceConfig::DeleteIfEmpty(BgpConfigManager *manager) {
    1384       15189 :     if (name_ == BgpConfigManager::kMasterInstance) {
    1385        4770 :         return false;
    1386             :     }
    1387       10419 :     if (node() != NULL || protocol_.get() != NULL) {
    1388          52 :         return false;
    1389             :     }
    1390       20691 :     if (!neighbors_.empty() || !peerings_.empty() ||
    1391       10324 :         !routing_policies_.empty()) {
    1392          44 :         return false;
    1393             :     }
    1394             : 
    1395       10323 :     manager->Notify(&data_, BgpConfigManager::CFG_DELETE);
    1396       10323 :     return true;
    1397             : }
    1398             : 
    1399             : //
    1400             : // Add a BgpNeighborConfig to this BgpIfmapInstanceConfig.
    1401             : //
    1402             : // The BgpNeighborConfig is added to the NeighborMap and the BgpConfigManager
    1403             : // is notified.
    1404             : //
    1405        9417 : void BgpIfmapInstanceConfig::AddNeighbor(BgpConfigManager *manager,
    1406             :     BgpNeighborConfig *neighbor) {
    1407        9417 :     BGP_CONFIG_LOG_NEIGHBOR(
    1408             :         Create, manager->server(), neighbor, SandeshLevel::SYS_DEBUG,
    1409             :         BGP_LOG_FLAG_ALL,
    1410             :         neighbor->admin_down(),
    1411             :         neighbor->passive(),
    1412             :         BgpIdentifierToString(neighbor->local_identifier()),
    1413             :         neighbor->local_as(),
    1414             :         neighbor->peer_address().to_string(), neighbor->peer_as(),
    1415             :         neighbor->GetAddressFamilies(), neighbor->AuthKeyTypeToString(),
    1416             :         neighbor->AuthKeysToString());
    1417        9417 :     neighbors_.insert(make_pair(neighbor->name(), neighbor));
    1418        9417 :     data_.add_neighbor(neighbor->name());
    1419        9417 :     manager->Notify(neighbor, BgpConfigManager::CFG_ADD);
    1420        9417 : }
    1421             : 
    1422             : //
    1423             : // Change a BgpNeighborConfig that's already in this BgpIfmapInstanceConfig.
    1424             : //
    1425         764 : void BgpIfmapInstanceConfig::ChangeNeighbor(BgpConfigManager *manager,
    1426             :     BgpNeighborConfig *neighbor) {
    1427         764 :     NeighborMap::iterator loc = neighbors_.find(neighbor->name());
    1428         764 :     assert(loc != neighbors_.end());
    1429         764 :     loc->second = neighbor;
    1430             : 
    1431         764 :     BGP_CONFIG_LOG_NEIGHBOR(
    1432             :         Update, manager->server(), neighbor,
    1433             :         SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
    1434             :         neighbor->admin_down(),
    1435             :         neighbor->passive(),
    1436             :         BgpIdentifierToString(neighbor->local_identifier()),
    1437             :         neighbor->local_as(),
    1438             :         neighbor->peer_address().to_string(), neighbor->peer_as(),
    1439             :         neighbor->GetAddressFamilies(), neighbor->AuthKeyTypeToString(),
    1440             :         neighbor->AuthKeysToString());
    1441         764 :     manager->Notify(neighbor, BgpConfigManager::CFG_CHANGE);
    1442         764 : }
    1443             : 
    1444             : //
    1445             : // Delete a BgpNeighborConfig from this BgpIfmapInstanceConfig.
    1446             : //
    1447             : // The BgpConfigManager is notified and BgpNeighborConfig is removed from the
    1448             : // NeighborMap. Note that the caller is responsible for actually deleting the
    1449             : // BgpNeighborConfig object.
    1450             : //
    1451        6719 : void BgpIfmapInstanceConfig::DeleteNeighbor(BgpConfigManager *manager,
    1452             :     BgpNeighborConfig *neighbor) {
    1453        6719 :     BGP_CONFIG_LOG_NEIGHBOR(Delete, manager->server(), neighbor,
    1454             :         SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
    1455        6719 :     manager->Notify(neighbor, BgpConfigManager::CFG_DELETE);
    1456        6719 :     neighbors_.erase(neighbor->name());
    1457        6719 :     data_.delete_neighbor(neighbor->name());
    1458        6719 : }
    1459             : 
    1460             : //
    1461             : // Find the BgpNeighborConfig by name in this BgpIfmapInstanceConfig.
    1462             : //
    1463        6802 : const BgpNeighborConfig *BgpIfmapInstanceConfig::FindNeighbor(
    1464             :     const string &name) const {
    1465        6802 :     NeighborMap::const_iterator loc;
    1466             : 
    1467        6802 :     if (name.find(name_) == string::npos) {
    1468           7 :         string fqn(name_);
    1469           7 :         fqn += ":";
    1470           7 :         fqn += name;
    1471           7 :         loc = neighbors_.find(fqn);
    1472           7 :     } else {
    1473        6795 :         loc = neighbors_.find(name);
    1474             :     }
    1475             : 
    1476        6802 :     return loc != neighbors_.end() ? loc->second : NULL;
    1477             : }
    1478             : 
    1479             : //
    1480             : // Add a BgpPeeringConfig to this BgpIfmapInstanceConfig.
    1481             : //
    1482        4312 : void BgpIfmapInstanceConfig::AddPeering(BgpIfmapPeeringConfig *peering) {
    1483        4312 :     peerings_.insert(make_pair(peering->name(), peering));
    1484        4312 : }
    1485             : 
    1486             : //
    1487             : // Delete a BgpPeeringConfig from this BgpIfmapInstanceConfig.
    1488             : //
    1489        2121 : void BgpIfmapInstanceConfig::DeletePeering(BgpIfmapPeeringConfig *peering) {
    1490        2121 :     peerings_.erase(peering->name());
    1491        2121 : }
    1492             : 
    1493             : //
    1494             : // Add a BgpIfmapRoutingPolicyConfig to this BgpIfmapInstanceConfig.
    1495             : //
    1496         165 : void BgpIfmapInstanceConfig::AddRoutingPolicy(
    1497             :     BgpIfmapRoutingPolicyConfig *rtp) {
    1498         165 :     routing_policies_.insert(make_pair(rtp->name(), rtp));
    1499         165 : }
    1500             : 
    1501             : //
    1502             : // Delete a BgpIfmapRoutingPolicyConfig from this BgpIfmapInstanceConfig.
    1503             : //
    1504          46 : void BgpIfmapInstanceConfig::DeleteRoutingPolicy(
    1505             :     BgpIfmapRoutingPolicyConfig *rtp) {
    1506          46 :     routing_policies_.erase(rtp->name());
    1507          46 : }
    1508             : 
    1509        6023 : void BgpIfmapConfigData::ProcessIdentifierAndASUpdate(
    1510             :                             BgpIfmapConfigManager* manager,
    1511             :                             uint32_t new_id, uint32_t old_id,
    1512             :                             uint32_t new_as, uint32_t old_as) {
    1513        6023 :     assert(new_id != old_id || new_as != old_as);
    1514       24306 :     for (unsigned int i = 0; i < instances_.size(); i++) {
    1515       18283 :         BgpIfmapInstanceConfig * ifmap_config = instances_.At(i);
    1516       18283 :         if (!ifmap_config)
    1517           0 :             continue;
    1518       18283 :         if (new_id != old_id)
    1519       18180 :             ifmap_config->ProcessIdentifierUpdate(new_id, old_id);
    1520       18283 :         if (new_as != old_as)
    1521       12268 :             ifmap_config->ProcessASUpdate(new_as, old_as);
    1522       18283 :         manager->UpdateInstanceConfig(ifmap_config,
    1523             :                                       BgpConfigManager::CFG_CHANGE);
    1524             :     }
    1525        6023 : }
    1526             : 
    1527             : //
    1528             : // Constructor for BgpIfmapConfigData.
    1529             : //
    1530        8049 : BgpIfmapConfigData::BgpIfmapConfigData() {
    1531             :     // Reserve bit 0 for master instance
    1532        8049 :     instances_.ReserveBit(0);
    1533        8049 : }
    1534             : 
    1535             : //
    1536             : // Destructor for BgpConfigData.
    1537             : //
    1538        8049 : BgpIfmapConfigData::~BgpIfmapConfigData() {
    1539        8049 :     instances_.clear();
    1540        8049 :     STLDeleteElements(&peerings_);
    1541        8049 :     STLDeleteElements(&routing_policies_);
    1542        8049 :     STLDeleteElements(&ri_rp_links_);
    1543        8049 : }
    1544             : 
    1545             : //
    1546             : // Locate the BgpIfmapInstanceConfig by name, create it if not found.  The newly
    1547             : // created BgpIfmapInstanceConfig gets added to the IfmapInstanceMap.
    1548             : //
    1549             : // Note that we do not have the IFMapNode representing the routing-instance
    1550             : // at this point.
    1551             : //
    1552       50601 : BgpIfmapInstanceConfig *BgpIfmapConfigData::LocateInstance(const string &name) {
    1553       50601 :     BgpIfmapInstanceConfig *rti = FindInstance(name);
    1554       50601 :     if (rti != NULL) {
    1555           0 :         return rti;
    1556             :     }
    1557       50601 :     rti = new BgpIfmapInstanceConfig(name);
    1558       50601 :     int index = -1;
    1559       50601 :     if (name == BgpConfigManager::kMasterInstance) {
    1560        8031 :         index = 0;
    1561             :     }
    1562       50601 :     index = instances_.Insert(name, rti, index);
    1563       50601 :     rti->set_index(index);
    1564             :     pair<BgpInstanceMap::iterator, bool> result2 =
    1565       50601 :             instance_config_map_.insert(
    1566      101202 :                 make_pair(name, rti->instance_config()));
    1567       50601 :     assert(result2.second);
    1568       50601 :     return rti;
    1569             : }
    1570             : 
    1571             : //
    1572             : // Remove the given BgpIfmapInstanceConfig from the IfmapInstanceMap
    1573             : // and delete it.
    1574             : //
    1575       10323 : void BgpIfmapConfigData::DeleteInstance(BgpIfmapInstanceConfig *rti) {
    1576       10323 :     BgpInstanceMap::iterator loc2 = instance_config_map_.find(rti->name());
    1577       10323 :     assert(loc2 != instance_config_map_.end());
    1578       10323 :     instance_config_map_.erase(loc2);
    1579       10323 :     instances_.Remove(rti->name(), rti->index(), false);
    1580       10323 : }
    1581             : 
    1582             : //
    1583             : // Find the BgpIfmapInstanceConfig by name.
    1584             : //
    1585      487051 : BgpIfmapInstanceConfig *BgpIfmapConfigData::FindInstance(const string &name) {
    1586      487051 :     return instances_.Find(name);
    1587             : }
    1588             : 
    1589             : //
    1590             : // Find the BgpIfmapInstanceConfig by name.
    1591             : // Const version.
    1592             : //
    1593           7 : const BgpIfmapInstanceConfig *BgpIfmapConfigData::FindInstance(
    1594             :     const string &name) const {
    1595           7 :     return instances_.Find(name);
    1596             : }
    1597             : 
    1598             : BgpConfigManager::NeighborMapRange
    1599         190 : BgpIfmapInstanceConfig::NeighborMapItems() const {
    1600         190 :     return make_pair(neighbors_.begin(), neighbors_.end());
    1601             : }
    1602             : 
    1603             : //
    1604             : // Create a new BgpIfmapRoutingPolicyLinkConfig.
    1605             : //
    1606             : // The IFMapNodeProxy is a proxy for the IFMapNode which is the midnode that
    1607             : // represents the routing-policy-routing-instance. The newly created
    1608             : // BgpIfmapRoutingPolicyLinkConfig gets added to the IfmapRoutingPolicyLinkMap.
    1609             : //
    1610         165 : BgpIfmapRoutingPolicyLinkConfig *BgpIfmapConfigData::CreateRoutingPolicyLink(
    1611             :     BgpIfmapInstanceConfig *rti, BgpIfmapRoutingPolicyConfig *rtp,
    1612             :     IFMapNodeProxy *proxy) {
    1613             :     BgpIfmapRoutingPolicyLinkConfig *ri_rp_link =
    1614         165 :         new BgpIfmapRoutingPolicyLinkConfig(rti, rtp);
    1615         165 :     ri_rp_link->SetNodeProxy(proxy);
    1616             :     pair<IfmapRoutingPolicyLinkMap::iterator, bool> result =
    1617         165 :         ri_rp_links_.insert(make_pair(ri_rp_link->node()->name(), ri_rp_link));
    1618         165 :     assert(result.second);
    1619         165 :     ri_rp_link->instance()->AddRoutingPolicy(rtp);
    1620         165 :     ri_rp_link->policy()->AddInstance(rti);
    1621         165 :     return ri_rp_link;
    1622             : }
    1623             : 
    1624             : //
    1625             : // Delete a BgpIfmapRoutingPolicyLinkConfig.
    1626             : //
    1627             : // The BgpIfmapRoutingPolicyLinkConfig is erased from IfmapRoutingPolicyLinkMap
    1628             : // and then deleted.
    1629             : // Note that the reference to the IFMapNode for routing-policy-routing-instance
    1630             : // gets released via the destructor when the IFMapNodeProxy is destroyed.
    1631             : //
    1632          46 : void BgpIfmapConfigData::DeleteRoutingPolicyLink(
    1633             :     BgpIfmapRoutingPolicyLinkConfig *ri_rp_link) {
    1634          46 :     ri_rp_links_.erase(ri_rp_link->node()->name());
    1635          46 :     ri_rp_link->instance()->DeleteRoutingPolicy(ri_rp_link->policy());
    1636          46 :     ri_rp_link->policy()->RemoveInstance(ri_rp_link->instance());
    1637          46 :     delete ri_rp_link;
    1638          46 : }
    1639             : 
    1640             : //
    1641             : // Find the BgpIfmapRoutingPolicyLinkConfig by name.
    1642             : //
    1643         236 : BgpIfmapRoutingPolicyLinkConfig *BgpIfmapConfigData::FindRoutingPolicyLink(
    1644             :     const string &name) {
    1645         236 :     IfmapRoutingPolicyLinkMap::iterator loc = ri_rp_links_.find(name);
    1646         236 :     if (loc != ri_rp_links_.end()) {
    1647          71 :         return loc->second;
    1648             :     }
    1649         165 :     return NULL;
    1650             : }
    1651             : 
    1652             : //
    1653             : // Find the BgpIfmapRoutingPolicyLinkConfig by name.
    1654             : // Const version.
    1655             : //
    1656             : const BgpIfmapRoutingPolicyLinkConfig *
    1657           0 : BgpIfmapConfigData::FindRoutingPolicyLink(const string &name) const {
    1658           0 :     IfmapRoutingPolicyLinkMap::const_iterator loc = ri_rp_links_.find(name);
    1659           0 :     if (loc != ri_rp_links_.end()) {
    1660           0 :         return loc->second;
    1661             :     }
    1662           0 :     return NULL;
    1663             : }
    1664             : 
    1665             : //
    1666             : // Create a new BgpIfmapPeeringConfig.
    1667             : //
    1668             : // The IFMapNodeProxy is a proxy for the IFMapNode which is the
    1669             : // midnode that represents the bgp-peering. The newly created
    1670             : // BgpIfmapPeeringConfig gets added to the IfmapPeeringMap.
    1671             : //
    1672        4312 : BgpIfmapPeeringConfig *BgpIfmapConfigData::CreatePeering(
    1673             :     BgpIfmapInstanceConfig *rti, IFMapNodeProxy *proxy) {
    1674        4312 :     BgpIfmapPeeringConfig *peering = new BgpIfmapPeeringConfig(rti);
    1675        4312 :     peering->SetNodeProxy(proxy);
    1676             :     pair<IfmapPeeringMap::iterator, bool> result =
    1677        4312 :             peerings_.insert(make_pair(peering->node()->name(), peering));
    1678        4312 :     assert(result.second);
    1679        4312 :     peering->instance()->AddPeering(peering);
    1680        4312 :     BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_SYSLOG,
    1681             :          "Creating BgpIfmapPeering " << peering->node()->name());
    1682        4312 :     return peering;
    1683             : }
    1684             : 
    1685             : //
    1686             : // Delete a BgpPeeringConfig.
    1687             : //
    1688             : // The BgpPeeringConfig is removed from the IfmapPeeringMap and then deleted.
    1689             : // Note that the reference to the IFMapNode for the bgp-peering gets released
    1690             : // via the destructor when the IFMapNodeProxy is destroyed.
    1691             : //
    1692        2121 : void BgpIfmapConfigData::DeletePeering(BgpIfmapPeeringConfig *peering) {
    1693        2121 :     BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_SYSLOG,
    1694             :          "Deleting BgpIfmapPeering " << peering->node()->name());
    1695        2121 :     peering->instance()->DeletePeering(peering);
    1696        2121 :     peerings_.erase(peering->node()->name());
    1697        2121 :     delete peering;
    1698        2121 : }
    1699             : 
    1700             : //
    1701             : // Find the BgpPeeringConfig by name.
    1702             : //
    1703       20900 : BgpIfmapPeeringConfig *BgpIfmapConfigData::FindPeering(const string &name) {
    1704       20900 :     IfmapPeeringMap::iterator loc = peerings_.find(name);
    1705       20900 :     if (loc != peerings_.end()) {
    1706       12879 :         return loc->second;
    1707             :     }
    1708        8021 :     return NULL;
    1709             : }
    1710             : 
    1711             : //
    1712             : // Find the BgpPeeringConfig by name.
    1713             : // Const version.
    1714             : //
    1715           0 : const BgpIfmapPeeringConfig *BgpIfmapConfigData::FindPeering(
    1716             :     const string &name) const {
    1717           0 :     IfmapPeeringMap::const_iterator loc = peerings_.find(name);
    1718           0 :     if (loc != peerings_.end()) {
    1719           0 :         return loc->second;
    1720             :     }
    1721           0 :     return NULL;
    1722             : }
    1723             : 
    1724             : BgpConfigManager::InstanceMapRange
    1725          59 : BgpIfmapConfigData::InstanceMapItems(const string &start_name) const {
    1726          59 :     return make_pair(instance_config_map_.lower_bound(start_name),
    1727         118 :         instance_config_map_.end());
    1728             : }
    1729             : 
    1730             : BgpConfigManager::RoutingPolicyMapRange
    1731           2 : BgpIfmapConfigData::RoutingPolicyMapItems(const string &start_name) const {
    1732           2 :     return make_pair(routing_policy_config_map_.lower_bound(start_name),
    1733           4 :         routing_policy_config_map_.end());
    1734             : }
    1735             : 
    1736             : //
    1737             : // Locate the BgpIfmapRoutingPolicyConfig by name, create it if not found.
    1738             : // The newly created BgpIfmapRoutingPolicyConfig gets added to the
    1739             : // IfmapRoutingPolicyMap.
    1740             : //
    1741         161 : BgpIfmapRoutingPolicyConfig *BgpIfmapConfigData::LocateRoutingPolicy(
    1742             :     const string &name) {
    1743         161 :     BgpIfmapRoutingPolicyConfig *rtp = FindRoutingPolicy(name);
    1744         161 :     if (rtp != NULL) {
    1745           0 :         return rtp;
    1746             :     }
    1747         161 :     rtp = new BgpIfmapRoutingPolicyConfig(name);
    1748             :     pair<IfmapRoutingPolicyMap::iterator, bool> result =
    1749         161 :             routing_policies_.insert(make_pair(name, rtp));
    1750         161 :     assert(result.second);
    1751             :     pair<BgpRoutingPolicyMap::iterator, bool> result2 =
    1752         161 :             routing_policy_config_map_.insert(
    1753         322 :                 make_pair(name, rtp->routing_policy_config()));
    1754         161 :     assert(result2.second);
    1755         161 :     return rtp;
    1756             : }
    1757             : 
    1758             : //
    1759             : // Remove the given BgpIfmapRoutingPolicyConfig from the IfmapRoutingPolicyMap
    1760             : // and delete it.
    1761             : //
    1762          43 : void BgpIfmapConfigData::DeleteRoutingPolicy(BgpIfmapRoutingPolicyConfig *rtp) {
    1763          43 :     IfmapRoutingPolicyMap::iterator loc = routing_policies_.find(rtp->name());
    1764          43 :     assert(loc != routing_policies_.end());
    1765          43 :     routing_policies_.erase(loc);
    1766             :     BgpRoutingPolicyMap::iterator loc2 =
    1767          43 :         routing_policy_config_map_.find(rtp->name());
    1768          43 :     assert(loc2 != routing_policy_config_map_.end());
    1769          43 :     routing_policy_config_map_.erase(loc2);
    1770          43 :     delete rtp;
    1771          43 : }
    1772             : 
    1773         830 : BgpIfmapRoutingPolicyConfig *BgpIfmapConfigData::FindRoutingPolicy(
    1774             :     const string &name) {
    1775         830 :     IfmapRoutingPolicyMap::iterator loc = routing_policies_.find(name);
    1776         830 :     if (loc != routing_policies_.end()) {
    1777         457 :         return loc->second;
    1778             :     }
    1779         373 :     return NULL;
    1780             : }
    1781             : 
    1782           0 : const BgpIfmapRoutingPolicyConfig *BgpIfmapConfigData::FindRoutingPolicy(
    1783             :     const string &name) const {
    1784           0 :     IfmapRoutingPolicyMap::const_iterator loc = routing_policies_.find(name);
    1785           0 :     if (loc != routing_policies_.end()) {
    1786           0 :         return loc->second;
    1787             :     }
    1788           0 :     return NULL;
    1789             : }
    1790             : 
    1791             : //
    1792             : // Constructor for BgpIfmapConfigManager.
    1793             : //
    1794        8049 : BgpIfmapConfigManager::BgpIfmapConfigManager(BgpServer *server)
    1795             :     : BgpConfigManager(server),
    1796        8049 :       db_(NULL),
    1797        8049 :       db_graph_(NULL),
    1798        8049 :       trigger_(boost::bind(&BgpIfmapConfigManager::ConfigHandler, this),
    1799             :           TaskScheduler::GetInstance()->GetTaskId("bgp::Config"),
    1800             :           kConfigTaskInstanceId),
    1801        8049 :       listener_(new BgpConfigListener(this)),
    1802       16098 :       config_(new BgpIfmapConfigData()) {
    1803        8049 :     IdentifierMapInit();
    1804        8049 : }
    1805             : 
    1806             : //
    1807             : // Destructor for BgpIfmapConfigManager.
    1808             : //
    1809       16098 : BgpIfmapConfigManager::~BgpIfmapConfigManager() {
    1810       16098 : }
    1811             : 
    1812             : //
    1813             : // Initialize the BgpConfigManager.
    1814             : //
    1815        8031 : void BgpIfmapConfigManager::Initialize(DB *db, DBGraph *db_graph,
    1816             :                                        const string &localname) {
    1817        8031 :     db_ = db;
    1818        8031 :     db_graph_ = db_graph;
    1819        8031 :     localname_ = localname;
    1820        8031 :     listener_->Initialize();
    1821        8031 :     DefaultConfig();
    1822        8031 : }
    1823             : 
    1824             : //
    1825             : // Used to trigger a build and subsequent evaluation of the ChangeList.
    1826             : //
    1827      219023 : void BgpIfmapConfigManager::OnChange() {
    1828      219023 :     CHECK_CONCURRENCY("db::IFMapTable");
    1829      219023 :     trigger_.Set();
    1830      219023 : }
    1831             : 
    1832             : BgpConfigManager::InstanceMapRange
    1833          59 : BgpIfmapConfigManager::InstanceMapItems(const string &start_name) const {
    1834          59 :     return config_->InstanceMapItems(start_name);
    1835             : }
    1836             : 
    1837             : BgpConfigManager::RoutingPolicyMapRange
    1838           2 : BgpIfmapConfigManager::RoutingPolicyMapItems(const string &start_name) const {
    1839           2 :     return config_->RoutingPolicyMapItems(start_name);
    1840             : }
    1841             : 
    1842             : BgpConfigManager::NeighborMapRange
    1843         190 : BgpIfmapConfigManager::NeighborMapItems(
    1844             :     const string &instance_name) const {
    1845         190 :     static BgpConfigManager::NeighborMap nilMap;
    1846         190 :     BgpIfmapInstanceConfig *rti = config_->FindInstance(instance_name);
    1847         190 :     if (rti == NULL) {
    1848           0 :         return make_pair(nilMap.begin(), nilMap.end());
    1849             :     }
    1850         190 :     return rti->NeighborMapItems();
    1851             : }
    1852             : 
    1853       50478 : void BgpIfmapConfigManager::ResetRoutingInstanceIndexBit(int index) {
    1854       50478 :     config()->instances().ResetBit(index);
    1855       50478 : }
    1856             : 
    1857          14 : int BgpIfmapConfigManager::NeighborCount(
    1858             :     const string &instance_name) const {
    1859          14 :     BgpIfmapInstanceConfig *rti = config_->FindInstance(instance_name);
    1860          14 :     if (rti == NULL) {
    1861           2 :         return 0;
    1862             :     }
    1863          12 :     return rti->neighbors().size();
    1864             : }
    1865             : 
    1866             : //
    1867             : // Constructor for BgpIfmapRoutingPolicyConfig.
    1868             : //
    1869         161 : BgpIfmapRoutingPolicyConfig::BgpIfmapRoutingPolicyConfig(
    1870         161 :     const string &name)
    1871         161 :     : name_(name),
    1872         161 :       data_(name) {
    1873         161 : }
    1874             : 
    1875             : //
    1876             : // Destructor for BgpIfmapRoutingPolicyConfig.
    1877             : //
    1878         161 : BgpIfmapRoutingPolicyConfig::~BgpIfmapRoutingPolicyConfig() {
    1879         161 : }
    1880             : 
    1881             : //
    1882             : // Set the IFMapNodeProxy for the BgpIfmapRoutingPolicyConfig.
    1883             : //
    1884         161 : void BgpIfmapRoutingPolicyConfig::SetNodeProxy(IFMapNodeProxy *proxy) {
    1885         161 :     if (proxy != NULL) {
    1886         161 :         node_proxy_.Swap(proxy);
    1887             :     }
    1888         161 : }
    1889             : 
    1890          43 : void BgpIfmapRoutingPolicyConfig::Delete(BgpConfigManager *manager) {
    1891          43 :     manager->Notify(&data_, BgpConfigManager::CFG_DELETE);
    1892          43 :     routing_policy_.reset();
    1893          43 : }
    1894             : 
    1895             : //
    1896             : // Return true if the BgpIfmapRoutingPolicyConfig is ready to be deleted.
    1897             : // The caller is responsible for actually deleting it.
    1898             : //
    1899          89 : bool BgpIfmapRoutingPolicyConfig::DeleteIfEmpty(BgpConfigManager *manager) {
    1900          89 :     if (node() != NULL) {
    1901           5 :         return false;
    1902             :     }
    1903          84 :     if (!instances_.empty()) {
    1904          41 :         return false;
    1905             :     }
    1906             : 
    1907          43 :     Delete(manager);
    1908          43 :     return true;
    1909             : }
    1910             : 
    1911             : //
    1912             : // Add a BgpIfmapInstanceConfig to BgpIfmapRoutingPolicyConfig.
    1913             : //
    1914         165 : void BgpIfmapRoutingPolicyConfig::AddInstance(BgpIfmapInstanceConfig *rti) {
    1915         165 :     instances_.insert(make_pair(rti->name(), rti));
    1916         165 : }
    1917             : 
    1918             : //
    1919             : // Remove a BgpIfmapInstanceConfig to BgpIfmapRoutingPolicyConfig.
    1920             : //
    1921          46 : void BgpIfmapRoutingPolicyConfig::RemoveInstance(BgpIfmapInstanceConfig *rti) {
    1922          46 :     instances_.erase(rti->name());
    1923          46 : }
    1924             : 
    1925             : 
    1926         477 : static void BuildPolicyTermConfig(autogen::PolicyTermType cfg_term,
    1927             :     RoutingPolicyTermConfig *term) {
    1928         477 :     term->match.protocols_match = cfg_term.term_match_condition.protocol;
    1929         933 :     BOOST_FOREACH(const autogen::PrefixMatchType &prefix_match,
    1930             :                   cfg_term.term_match_condition.prefix) {
    1931         228 :         string prefix_type(prefix_match.prefix_type);
    1932         228 :         PrefixMatchConfig match(prefix_match.prefix,
    1933         456 :             prefix_type.empty() ? "exact" : prefix_type);
    1934         228 :         term->match.prefixes_to_match.push_back(match);
    1935         228 :     }
    1936         477 :     term->match.community_match_all =
    1937         477 :         cfg_term.term_match_condition.community_match_all;
    1938         477 :     if (!cfg_term.term_match_condition.community_list.empty()) {
    1939             :         term->match.community_match =
    1940          24 :             cfg_term.term_match_condition.community_list;
    1941             :     }
    1942         477 :     if (!cfg_term.term_match_condition.community.empty()) {
    1943         272 :         term->match.community_match.push_back(
    1944         272 :             cfg_term.term_match_condition.community);
    1945             :     }
    1946         477 :     term->match.ext_community_match_all =
    1947         477 :         cfg_term.term_match_condition.extcommunity_match_all;
    1948         477 :     if (!cfg_term.term_match_condition.extcommunity_list.empty()) {
    1949             :         term->match.ext_community_match =
    1950          12 :             cfg_term.term_match_condition.extcommunity_list;
    1951             :     }
    1952             : 
    1953         493 :     BOOST_FOREACH(uint32_t asn,
    1954             :         cfg_term.term_action_list.update.as_path.expand.asn_list) {
    1955           8 :         term->action.update.aspath_expand.push_back(asn);
    1956             :     }
    1957         645 :     BOOST_FOREACH(const string community,
    1958             :                   cfg_term.term_action_list.update.community.add.community) {
    1959          84 :         term->action.update.community_add.push_back(community);
    1960          84 :     }
    1961         549 :     BOOST_FOREACH(const string community,
    1962             :                   cfg_term.term_action_list.update.community.remove.community) {
    1963          36 :         term->action.update.community_remove.push_back(community);
    1964          36 :     }
    1965         589 :     BOOST_FOREACH(const string community,
    1966             :                   cfg_term.term_action_list.update.community.set.community) {
    1967          56 :         term->action.update.community_set.push_back(community);
    1968          56 :     }
    1969         509 :     BOOST_FOREACH(const string community,
    1970             :                   cfg_term.term_action_list.update.extcommunity.add.community) {
    1971          16 :         term->action.update.ext_community_add.push_back(community);
    1972          16 :     }
    1973         521 :     BOOST_FOREACH(const string community,
    1974             :                   cfg_term.term_action_list.update.extcommunity.remove.community) {
    1975          22 :         term->action.update.ext_community_remove.push_back(community);
    1976          22 :     }
    1977         493 :     BOOST_FOREACH(const string community,
    1978             :                   cfg_term.term_action_list.update.extcommunity.set.community) {
    1979           8 :         term->action.update.ext_community_set.push_back(community);
    1980           8 :     }
    1981         477 :     term->action.update.local_pref =
    1982         477 :         cfg_term.term_action_list.update.local_pref;
    1983         477 :     term->action.update.med = cfg_term.term_action_list.update.med;
    1984             : 
    1985         477 :     term->action.action = RoutingPolicyActionConfig::NEXT_TERM;
    1986         477 :     if (strcmp(cfg_term.term_action_list.action.c_str(), "reject") == 0) {
    1987         134 :         term->action.action = RoutingPolicyActionConfig::REJECT;
    1988         343 :     } else if (
    1989         343 :         strcmp(cfg_term.term_action_list.action.c_str(), "accept") == 0) {
    1990         241 :         term->action.action = RoutingPolicyActionConfig::ACCEPT;
    1991             :     }
    1992         477 : }
    1993             : 
    1994         396 : static void BuildPolicyTermsConfig(BgpRoutingPolicyConfig *policy_cfg,
    1995             :     const autogen::RoutingPolicy *policy) {
    1996         396 :     vector<autogen::PolicyTermType> terms = policy->entries();
    1997        1350 :     BOOST_FOREACH(autogen::PolicyTermType cfg_term, terms) {
    1998         477 :         RoutingPolicyTermConfig policy_term_cfg;
    1999         477 :         BuildPolicyTermConfig(cfg_term, &policy_term_cfg);
    2000         477 :         policy_cfg->add_term(policy_term_cfg);
    2001         954 :     }
    2002         396 : }
    2003             : 
    2004         396 : void BgpIfmapRoutingPolicyConfig::Update(BgpIfmapConfigManager *manager,
    2005             :     const autogen::RoutingPolicy *policy) {
    2006         396 :     routing_policy_.reset(policy);
    2007         396 :     data_.Clear();
    2008         396 :     if (policy) {
    2009         396 :         BuildPolicyTermsConfig(&data_, policy);
    2010             :     }
    2011         396 : }
    2012             : 
    2013             : //
    2014             : // Reset IFMap related state in the BgpIfmapRoutingPolicyConfig.
    2015             : //
    2016          43 : void BgpIfmapRoutingPolicyConfig::ResetConfig() {
    2017          43 :     node_proxy_.Clear();
    2018          43 : }
    2019             : 
    2020          65 : const BgpRoutingPolicyConfig *BgpIfmapConfigManager::FindRoutingPolicy(
    2021             :     const string &name) const {
    2022          65 :     BgpIfmapRoutingPolicyConfig *rtp = config_->FindRoutingPolicy(name);
    2023          65 :     if (rtp == NULL) {
    2024          51 :         return NULL;
    2025             :     }
    2026          14 :     return rtp->routing_policy_config();
    2027             : }
    2028             : 
    2029       79113 : const BgpInstanceConfig *BgpIfmapConfigManager::FindInstance(
    2030             :     const string &name) const {
    2031       79113 :     BgpIfmapInstanceConfig *rti = config_->FindInstance(name);
    2032       78967 :     if (rti == NULL) {
    2033       10205 :         return NULL;
    2034             :     }
    2035       68762 :     return rti->instance_config();
    2036             : }
    2037             : 
    2038       62434 : const BgpProtocolConfig *BgpIfmapConfigManager::GetProtocolConfig(
    2039             :     const string &instance_name) const {
    2040       62434 :     BgpIfmapInstanceConfig *rti = config_->FindInstance(instance_name);
    2041       62401 :     if (rti == NULL) {
    2042        1016 :         return NULL;
    2043             :     }
    2044       61385 :     const BgpIfmapProtocolConfig *proto = rti->protocol_config();
    2045       61390 :     if (proto == NULL) {
    2046          55 :         return NULL;
    2047             :     }
    2048       61335 :     return proto->protocol_config();
    2049             : }
    2050             : 
    2051        6802 : const BgpNeighborConfig *BgpIfmapConfigManager::FindNeighbor(
    2052             :     const string &instance_name, const string &name) const {
    2053        6802 :     BgpIfmapInstanceConfig *rti = config_->FindInstance(instance_name);
    2054        6802 :     if (rti == NULL) {
    2055           0 :         return NULL;
    2056             :     }
    2057        6802 :     return rti->FindNeighbor(name);
    2058             : }
    2059             : 
    2060             : //
    2061             : // Initialize autogen::BgpRouterParams with default values.
    2062             : //
    2063        8031 : void BgpIfmapConfigManager::DefaultBgpRouterParams(
    2064             :     autogen::BgpRouterParams *param) {
    2065        8031 :     param->Clear();
    2066        8031 :     param->autonomous_system = BgpConfigManager::kDefaultAutonomousSystem;
    2067        8031 :     param->port = BgpConfigManager::kDefaultPort;
    2068        8031 : }
    2069             : 
    2070             : //
    2071             : // Create BgpInsatnceConfig for master routing-instance.  This
    2072             : // includes the BgpIfmapProtocolConfig for the local bgp-router in the
    2073             : // master routing-instance.
    2074             : //
    2075        8031 : void BgpIfmapConfigManager::DefaultConfig() {
    2076        8031 :     BgpIfmapInstanceConfig *rti = config_->LocateInstance(kMasterInstance);
    2077        8031 :     unique_ptr<autogen::BgpRouter> router(new autogen::BgpRouter());
    2078        8031 :     autogen::BgpRouterParams param;
    2079        8031 :     DefaultBgpRouterParams(&param);
    2080        8031 :     router->SetProperty("bgp-router-parameters", &param);
    2081        8031 :     BgpIfmapProtocolConfig *protocol = rti->LocateProtocol();
    2082        8031 :     protocol->Update(this, router.release());
    2083        8031 :     Notify(rti->instance_config(), BgpConfigManager::CFG_ADD);
    2084             : 
    2085        8031 :     vector<string> import_list;
    2086        8031 :     vector<string> export_list;
    2087        8031 :     BGP_CONFIG_LOG_INSTANCE(
    2088             :         Create, server(), rti, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
    2089             :         import_list, export_list,
    2090             :         rti->virtual_network(), rti->virtual_network_index());
    2091             : 
    2092        8031 :     BGP_CONFIG_LOG_PROTOCOL(
    2093             :         Create, server(), protocol,
    2094             :         SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
    2095             :         protocol->router_params().admin_down,
    2096             :         protocol->router_params().autonomous_system,
    2097             :         protocol->router_params().identifier,
    2098             :         protocol->router_params().address,
    2099             :         protocol->router_params().hold_time,
    2100             :         vector<string>());
    2101        8031 : }
    2102             : 
    2103        1136 : bool BgpIfmapGlobalSystemConfig::Update(BgpIfmapConfigManager *manager,
    2104             :         const autogen::GlobalSystemConfig *system) {
    2105        1136 :     bool changed = false;
    2106             : 
    2107        1136 :     if (data_.gr_enable() != system->graceful_restart_parameters().enable) {
    2108         564 :         data_.set_gr_enable(system->graceful_restart_parameters().enable);
    2109         564 :         changed |= true;
    2110             :     }
    2111             : 
    2112        1136 :     if (data_.gr_time() != system->graceful_restart_parameters().restart_time) {
    2113         784 :         data_.set_gr_time(system->graceful_restart_parameters().restart_time);
    2114         784 :         changed |= true;
    2115             :     }
    2116             : 
    2117        1136 :     if (data_.llgr_time() != static_cast<uint32_t>(
    2118        1136 :             system->graceful_restart_parameters().long_lived_restart_time)) {
    2119        1568 :         data_.set_llgr_time(
    2120         784 :             system->graceful_restart_parameters().long_lived_restart_time);
    2121         784 :         changed |= true;
    2122             :     }
    2123             : 
    2124        1136 :     if (data_.end_of_rib_timeout() !=
    2125        1136 :             system->graceful_restart_parameters().end_of_rib_timeout) {
    2126        1126 :         data_.set_end_of_rib_timeout(
    2127         563 :             system->graceful_restart_parameters().end_of_rib_timeout);
    2128         563 :         changed |= true;
    2129             :     }
    2130             : 
    2131        1136 :     if (data_.gr_bgp_helper() !=
    2132        1136 :             system->graceful_restart_parameters().bgp_helper_enable) {
    2133        1122 :         data_.set_gr_bgp_helper(
    2134         561 :             system->graceful_restart_parameters().bgp_helper_enable);
    2135         561 :         changed |= true;
    2136             :     }
    2137             : 
    2138        1136 :     if (data_.gr_xmpp_helper() !=
    2139        1136 :             system->graceful_restart_parameters().xmpp_helper_enable) {
    2140        1122 :         data_.set_gr_xmpp_helper(
    2141         561 :             system->graceful_restart_parameters().xmpp_helper_enable);
    2142         561 :         changed |= true;
    2143             :     }
    2144             : 
    2145        1136 :     if (data_.enable_4byte_as() != system->enable_4byte_as()) {
    2146          16 :         data_.set_enable_4byte_as(system->enable_4byte_as());
    2147          16 :         changed |= true;
    2148             :     }
    2149             : 
    2150        1136 :     if (data_.always_compare_med() != system->bgp_always_compare_med()) {
    2151           5 :         data_.set_always_compare_med(system->bgp_always_compare_med());
    2152           5 :         changed |= true;
    2153             :     }
    2154             : 
    2155        1136 :     if (data_.rd_cluster_seed() != system->rd_cluster_seed()) {
    2156          25 :         data_.set_rd_cluster_seed(system->rd_cluster_seed());
    2157          25 :         changed |= true;
    2158             :     }
    2159             : 
    2160        1136 :     if (data_.xmpp_hold_time() !=
    2161        1136 :             system->fast_convergence_parameters().xmpp_hold_time) {
    2162          22 :         data_.set_xmpp_hold_time(
    2163          11 :             system->fast_convergence_parameters().xmpp_hold_time);
    2164          11 :         changed |= true;
    2165             :     }
    2166             : 
    2167        1136 :     if (data_.bgpaas_port_start() != system->bgpaas_parameters().port_start) {
    2168         676 :         data_.set_bgpaas_port_start(system->bgpaas_parameters().port_start);
    2169         676 :         changed |= true;
    2170             :     }
    2171             : 
    2172        1136 :     if (data_.bgpaas_port_end() != system->bgpaas_parameters().port_end) {
    2173         676 :         data_.set_bgpaas_port_end(system->bgpaas_parameters().port_end);
    2174         676 :         changed |= true;
    2175             :     }
    2176             : 
    2177        1136 :     if (data_.fc_enabled() != system->fast_convergence_parameters().enable) {
    2178           9 :         data_.set_fc_enabled(system->fast_convergence_parameters().enable);
    2179           9 :         changed |= true;
    2180             :     }
    2181             : 
    2182        1136 :     if (data_.nh_check_enabled() !=
    2183        1136 :           system->fast_convergence_parameters().nh_reachability_check) {
    2184           4 :         data_.set_nh_check_enabled(
    2185           2 :             system->fast_convergence_parameters().nh_reachability_check);
    2186           2 :         changed |= true;
    2187             :     }
    2188             : 
    2189        1136 :     if (data_.all_tags_are_global() != system->bgp_all_tags_are_global()) {
    2190           4 :         data_.set_all_tags_are_global(system->bgp_all_tags_are_global());
    2191           4 :         changed |= true;
    2192             :     }
    2193             : 
    2194        1136 :     return changed;
    2195             : }
    2196             : 
    2197          11 : bool BgpIfmapGlobalQosConfig::Update(BgpIfmapConfigManager *manager,
    2198             :         const autogen::GlobalQosConfig *qos) {
    2199          11 :     bool changed = false;
    2200          11 :     const autogen::ControlTrafficDscpType &dscp = qos->control_traffic_dscp();
    2201             : 
    2202          11 :     if (data_.control_dscp() != dscp.control) {
    2203           9 :         data_.set_control_dscp(dscp.control);
    2204           9 :         Sandesh::SetDscpValue(dscp.control);
    2205           9 :         changed = true;
    2206             :     }
    2207          11 :     if (data_.analytics_dscp() != dscp.analytics) {
    2208           3 :         data_.set_analytics_dscp(dscp.analytics);
    2209           3 :         changed = true;
    2210             :     }
    2211          11 :     return changed;
    2212             : }
    2213             : 
    2214             : //
    2215             : // Initialize IdentifierMap with handlers for interesting identifier types.
    2216             : //
    2217             : // The IdentifierMap is used when processing BgpConfigDeltas generated by
    2218             : // the BgpConfigListener.
    2219             : //
    2220        8049 : void BgpIfmapConfigManager::IdentifierMapInit() {
    2221        8049 :     id_map_.insert(make_pair("routing-instance",
    2222        8049 :             boost::bind(&BgpIfmapConfigManager::ProcessRoutingInstance,
    2223             :                         this, _1)));
    2224        8049 :     id_map_.insert(make_pair("routing-policy",
    2225        8049 :         boost::bind(&BgpIfmapConfigManager::ProcessRoutingPolicy, this, _1)));
    2226        8049 :     id_map_.insert(make_pair("routing-policy-routing-instance",
    2227        8049 :         boost::bind(&BgpIfmapConfigManager::ProcessRoutingPolicyLink, this,
    2228             :             _1)));
    2229        8049 :     id_map_.insert(make_pair("bgp-router",
    2230        8049 :         boost::bind(&BgpIfmapConfigManager::ProcessBgpRouter, this, _1)));
    2231        8049 :     id_map_.insert(make_pair("bgp-peering",
    2232        8049 :         boost::bind(&BgpIfmapConfigManager::ProcessBgpPeering, this, _1)));
    2233        8049 :     id_map_.insert(make_pair("global-system-config",
    2234        8049 :         boost::bind(&BgpIfmapConfigManager::ProcessGlobalSystemConfig, this,
    2235             :                     _1)));
    2236        8049 :     id_map_.insert(make_pair("global-qos-config",
    2237        8049 :         boost::bind(&BgpIfmapConfigManager::ProcessGlobalQosConfig, this,
    2238             :                     _1)));
    2239        8049 : }
    2240             : 
    2241      142731 : void BgpIfmapConfigManager::UpdateInstanceConfig(BgpIfmapInstanceConfig *rti,
    2242             :         BgpConfigManager::EventType event) {
    2243      142731 :     if (!rti) {
    2244           0 :         return;
    2245             :     }
    2246             : 
    2247             :     // in case of id change, update import list and call subsequent code
    2248      142731 :     Notify(rti->instance_config(), event);
    2249             : 
    2250      142731 :     vector<string> import_rt(rti->import_list().begin(),
    2251      285462 :                              rti->import_list().end());
    2252      142731 :     vector<string> export_rt(rti->export_list().begin(),
    2253      285462 :                              rti->export_list().end());
    2254      142731 :     if (event == BgpConfigManager::CFG_ADD) {
    2255       42570 :         BGP_CONFIG_LOG_INSTANCE(Create, server(), rti,
    2256             :             SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
    2257             :             import_rt, export_rt,
    2258             :             rti->virtual_network(), rti->virtual_network_index());
    2259             :     } else {
    2260      100161 :         BGP_CONFIG_LOG_INSTANCE(Update, server(), rti,
    2261             :             SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
    2262             :             import_rt, export_rt,
    2263             :             rti->virtual_network(), rti->virtual_network_index());
    2264             :     }
    2265      142731 : }
    2266             : 
    2267             : //
    2268             : // Handler for routing-instance objects.
    2269             : //
    2270             : // Note that BgpIfmapInstanceConfig object for the master instance is created
    2271             : // before we have received any configuration for it i.e. there's no IFMapNode
    2272             : // or autogen::RoutingInstance for it. However, we will eventually receive a
    2273             : // delta for the master.  The IFMapNodeProxy and autogen::RoutingInstance are
    2274             : // set at that time.
    2275             : //
    2276             : // For other routing-instances BgpIfmapConfigInstance can get created before we
    2277             : // see the IFMapNode for the routing-instance if we see the IFMapNode for the
    2278             : // local bgp-router in the routing-instance.  In this case, the IFMapNodeProxy
    2279             : // and autogen::RoutingInstance are set when we later see the IFMapNode for the
    2280             : // routing-instance.
    2281             : //
    2282             : // In all other cases, BgpIfmapConfigInstance is created when we see IFMapNode
    2283             : // for the routing-instance.  The IFMapNodeProxy and autogen::RoutingInstance
    2284             : // are set right away.
    2285             : //
    2286             : // References to the IFMapNode and the autogen::RoutingInstance are
    2287             : // released when the IFMapNode is marked deleted.  However the
    2288             : // BgpIfmapInstanceConfig does not get deleted till the NeighborMap is
    2289             : // empty and the BgpIfmapProtocolConfig is gone.
    2290             : //
    2291      136089 : void BgpIfmapConfigManager::ProcessRoutingInstance(
    2292             :     const BgpConfigDelta &delta) {
    2293      136089 :     CHECK_CONCURRENCY("bgp::Config");
    2294             : 
    2295      136089 :     BgpConfigManager::EventType event = BgpConfigManager::CFG_CHANGE;
    2296      136089 :     string instance_name = delta.id_name;
    2297      136089 :     BgpIfmapInstanceConfig *rti = config_->FindInstance(instance_name);
    2298      136089 :     if (rti == NULL) {
    2299       42568 :         IFMapNodeProxy *proxy = delta.node.get();
    2300       42568 :         if (proxy == NULL) {
    2301           0 :             return;
    2302             :         }
    2303       42568 :         IFMapNode *node = proxy->node();
    2304       42568 :         if (node == NULL || node->IsDeleted()) {
    2305           0 :             return;
    2306             :         }
    2307       42568 :         event = BgpConfigManager::CFG_ADD;
    2308       42568 :         rti = config_->LocateInstance(instance_name);
    2309       42568 :         rti->SetNodeProxy(proxy);
    2310             :     } else {
    2311       93521 :         IFMapNode *node = rti->node();
    2312       93521 :         if (node == NULL) {
    2313        5843 :             IFMapNodeProxy *proxy = delta.node.get();
    2314        5843 :             if (proxy == NULL) {
    2315           0 :                 return;
    2316             :             }
    2317        5843 :             rti->SetNodeProxy(proxy);
    2318       87678 :         } else if (node->IsDeleted()) {
    2319       11643 :             rti->ResetConfig();
    2320       11643 :             if (rti->DeleteIfEmpty(this)) {
    2321       10300 :                 BGP_CONFIG_LOG_INSTANCE(
    2322             :                     Delete, server(), rti,
    2323             :                     SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
    2324       10300 :                 config_->DeleteInstance(rti);
    2325             :             }
    2326       11643 :             return;
    2327             :         }
    2328             :     }
    2329             : 
    2330             :     autogen::RoutingInstance *rti_config =
    2331      124446 :         static_cast<autogen::RoutingInstance *>(delta.obj.get());
    2332      124446 :     if (rti->index() != -1)
    2333      124446 :         rti->instance_config()->set_index(rti->index());
    2334      124446 :     rti->Update(this, rti_config);
    2335      124446 :     UpdateInstanceConfig(rti, event);
    2336      136089 : }
    2337             : 
    2338             : //
    2339             : // Handler for bgp protocol config.
    2340             : //
    2341             : // Note that there's no underlying IFMap object for the bgp protocol config.
    2342             : // This is called by the handler for bgp-router objects. The BgpConfigDelta
    2343             : // is a delta for the bgp-router object.
    2344             : //
    2345        9181 : void BgpIfmapConfigManager::ProcessBgpProtocol(const BgpConfigDelta &delta) {
    2346        9181 :     CHECK_CONCURRENCY("bgp::Config");
    2347             : 
    2348        9181 :     BgpConfigManager::EventType event = BgpConfigManager::CFG_CHANGE;
    2349        9181 :     string instance_name(IdentifierParent(delta.id_name));
    2350        9181 :     BgpIfmapInstanceConfig *rti = config_->FindInstance(instance_name);
    2351        9181 :     BgpIfmapProtocolConfig *protocol = NULL;
    2352        9181 :     if (rti != NULL) {
    2353        9181 :         protocol = rti->protocol_config_mutable();
    2354             :     }
    2355             : 
    2356        9181 :     if (protocol == NULL) {
    2357         565 :         IFMapNodeProxy *proxy = delta.node.get();
    2358         565 :         if (proxy == NULL) {
    2359           0 :             return;
    2360             :         }
    2361             :         // ignore identifier with no properties
    2362         565 :         if (delta.obj.get() == NULL) {
    2363           0 :             return;
    2364             :         }
    2365         565 :         IFMapNode *node = proxy->node();
    2366         565 :         if (node == NULL || node->IsDeleted()) {
    2367           0 :             return;
    2368             :         }
    2369         565 :         event = BgpConfigManager::CFG_ADD;
    2370         565 :         if (rti == NULL) {
    2371           0 :             rti = config_->LocateInstance(instance_name);
    2372           0 :             UpdateInstanceConfig(rti, event);
    2373             :         }
    2374         565 :         protocol = rti->LocateProtocol();
    2375         565 :         protocol->SetNodeProxy(proxy);
    2376             :     } else {
    2377        8616 :         IFMapNode *node = protocol->node();
    2378        8616 :         if (node == NULL) {
    2379             :             // The master instance creates a BgpRouter node internally. Ignore
    2380             :             // an update that doesn't specify any content.
    2381        5466 :             if (delta.obj.get() == NULL) {
    2382         131 :                 return;
    2383             :             }
    2384        5335 :             protocol->SetNodeProxy(delta.node.get());
    2385        3150 :         } else if (delta.obj.get() == NULL) {
    2386        1379 :             BGP_CONFIG_LOG_PROTOCOL(Delete, server(), protocol,
    2387             :                 SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
    2388        1379 :             protocol->Delete(this);
    2389        1379 :             rti->ResetProtocol();
    2390        1379 :             if (rti->DeleteIfEmpty(this)) {
    2391           0 :                 BGP_CONFIG_LOG_INSTANCE(Delete, server(), rti,
    2392             :                     SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
    2393           0 :                 config_->DeleteInstance(rti);
    2394             :             }
    2395        1379 :             return;
    2396             :         }
    2397             :     }
    2398             : 
    2399             :     autogen::BgpRouter *rt_config =
    2400        7671 :         static_cast<autogen::BgpRouter *>(delta.obj.get());
    2401        7671 :     uint32_t old_id = protocol->protocol_config()->identifier();
    2402        7671 :     uint32_t old_as = protocol->protocol_config()->autonomous_system();
    2403        7671 :     protocol->Update(this, rt_config);
    2404        7671 :     uint32_t new_id = protocol->protocol_config()->identifier();
    2405        7671 :     uint32_t new_as = protocol->protocol_config()->autonomous_system();
    2406        7671 :     if (new_id != old_id || new_as != old_as) {
    2407        6023 :         config_->ProcessIdentifierAndASUpdate(this, new_id, old_id, new_as,
    2408             :                                               old_as);
    2409             :     }
    2410        7671 :     Notify(protocol->protocol_config(), event);
    2411             : 
    2412        7671 :     if (!rt_config) {
    2413           0 :         return;
    2414             :     }
    2415             : 
    2416             :     vector<string> families(
    2417        7671 :         protocol->router_params().address_families.begin(),
    2418       15342 :         protocol->router_params().address_families.end());
    2419        7671 :     if (event == BgpConfigManager::CFG_ADD) {
    2420         565 :         BGP_CONFIG_LOG_PROTOCOL(Create, server(), protocol,
    2421             :             SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
    2422             :             protocol->router_params().admin_down,
    2423             :             protocol->router_params().autonomous_system,
    2424             :             protocol->router_params().identifier,
    2425             :             protocol->router_params().address,
    2426             :             protocol->router_params().hold_time,
    2427             :             families);
    2428             :     } else {
    2429        7106 :         BGP_CONFIG_LOG_PROTOCOL(Update, server(), protocol,
    2430             :             SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
    2431             :             protocol->router_params().admin_down,
    2432             :             protocol->router_params().autonomous_system,
    2433             :             protocol->router_params().identifier,
    2434             :             protocol->router_params().address,
    2435             :             protocol->router_params().hold_time,
    2436             :             families);
    2437             :     }
    2438        9181 : }
    2439             : 
    2440             : //
    2441             : // Handler for routing policy objects.
    2442             : //
    2443             : // BgpConfigListener::DependencyTracker ensures associated routing instances
    2444             : // are present in the change list.
    2445             : //
    2446         439 : void BgpIfmapConfigManager::ProcessRoutingPolicy(const BgpConfigDelta &delta) {
    2447         439 :     CHECK_CONCURRENCY("bgp::Config");
    2448             : 
    2449         439 :     BgpConfigManager::EventType event = BgpConfigManager::CFG_CHANGE;
    2450         439 :     string policy_name = delta.id_name;
    2451         439 :     BgpIfmapRoutingPolicyConfig *rtp = config_->FindRoutingPolicy(policy_name);
    2452         439 :     if (rtp == NULL) {
    2453         161 :         IFMapNodeProxy *proxy = delta.node.get();
    2454         161 :         if (proxy == NULL) {
    2455           0 :             return;
    2456             :         }
    2457         161 :         IFMapNode *node = proxy->node();
    2458         161 :         if (node == NULL || node->IsDeleted()) {
    2459           0 :             return;
    2460             :         }
    2461         161 :         event = BgpConfigManager::CFG_ADD;
    2462         161 :         rtp = config_->LocateRoutingPolicy(policy_name);
    2463         161 :         rtp->SetNodeProxy(proxy);
    2464             :     } else {
    2465         278 :         IFMapNode *node = rtp->node();
    2466         278 :         if (node == NULL) {
    2467           0 :             IFMapNodeProxy *proxy = delta.node.get();
    2468           0 :             if (proxy == NULL) {
    2469           0 :                 return;
    2470             :             }
    2471           0 :             rtp->SetNodeProxy(proxy);
    2472         278 :         } else if (node->IsDeleted()) {
    2473          43 :             rtp->ResetConfig();
    2474          43 :             if (rtp->DeleteIfEmpty(this)) {
    2475           5 :                 config_->DeleteRoutingPolicy(rtp);
    2476             :             }
    2477          43 :             return;
    2478             :         }
    2479             :     }
    2480             : 
    2481             :     autogen::RoutingPolicy *rtp_config =
    2482         396 :         static_cast<autogen::RoutingPolicy *>(delta.obj.get());
    2483         396 :     rtp->Update(this, rtp_config);
    2484         396 :     Notify(rtp->routing_policy_config(), event);
    2485         439 : }
    2486             : 
    2487             : 
    2488             : //
    2489             : // Handler for bgp-router objects.
    2490             : //
    2491       16272 : void BgpIfmapConfigManager::ProcessBgpRouter(const BgpConfigDelta &delta) {
    2492       16272 :     CHECK_CONCURRENCY("bgp::Config");
    2493             : 
    2494       16272 :     string instance_name(IdentifierParent(delta.id_name));
    2495       32544 :     if (instance_name.empty() ||
    2496       16272 :         instance_name != BgpConfigManager::kMasterInstance) {
    2497         449 :         return;
    2498             :     }
    2499             : 
    2500             :     // Ignore if this change is not for the local router.
    2501       15823 :     string name = delta.id_name.substr(instance_name.size() + 1);
    2502       15823 :     if (name != localname_) {
    2503        6642 :         return;
    2504             :     }
    2505             : 
    2506        9181 :     ProcessBgpProtocol(delta);
    2507             : 
    2508             :     // Update all peerings since we use local asn and identifier from master
    2509             :     // instance for all neighbors, including those in non-master instances.
    2510       16677 :     BOOST_FOREACH(const BgpIfmapConfigData::IfmapPeeringMap::value_type &value,
    2511             :         config_->peerings()) {
    2512        3748 :         BgpIfmapPeeringConfig *peering = value.second;
    2513        3748 :         peering->Update(this, peering->bgp_peering());
    2514             :     }
    2515       22914 : }
    2516             : 
    2517             : //
    2518             : // Handler for bgp-peering objects.
    2519             : //
    2520             : // We are only interested in this bgp-peering if it is adjacent to the local
    2521             : // router node.
    2522             : //
    2523             : // The BgpPeeringConfig is created the first time we see the bgp-peering.  It
    2524             : // is updated on subsequent changes and is deleted when the IFMapNode midnode
    2525             : // for the bgp-peering is deleted.
    2526             : //
    2527             : // Note that we are guaranteed that the IFMapNodes for the 2
    2528             : // bgp-routers for the bgp-peering already exist when we see the
    2529             : // bgp-peering. IFMap creates the nodes for the bgp-routers before
    2530             : // creating the midnode. This in turn guarantees that the
    2531             : // BgpIfmapInstanceConfig for the routing-instance also exists since we
    2532             : // create the BgpIfmapInstanceConfig before creating the
    2533             : // BgpIfmapProtocolConfig for a local bgp-router.
    2534             : //
    2535       17815 : void BgpIfmapConfigManager::ProcessBgpPeering(const BgpConfigDelta &delta) {
    2536       17815 :     CHECK_CONCURRENCY("bgp::Config");
    2537             : 
    2538       17815 :     BgpConfigManager::EventType event = BgpConfigManager::CFG_CHANGE;
    2539       17815 :     BgpIfmapPeeringConfig *peering = config_->FindPeering(delta.id_name);
    2540       17815 :     if (peering == NULL) {
    2541        8021 :         IFMapNodeProxy *proxy = delta.node.get();
    2542        8021 :         if (proxy == NULL) {
    2543        1843 :             BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_SYSLOG,
    2544             :                  "ProcessBgpPeering failed. Cannot find proxy " <<
    2545             :                  delta.id_name);
    2546        3709 :             return;
    2547             :         }
    2548        6178 :         IFMapNode *node = proxy->node();
    2549        6178 :         if (node == NULL || delta.obj.get() == NULL) {
    2550           0 :             BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_SYSLOG,
    2551             :                  "ProcessBgpPeering failed. Cannot find node/obj " <<
    2552             :                   delta.id_name);
    2553           0 :             return;
    2554             :         }
    2555             : 
    2556        6178 :         pair<IFMapNode *, IFMapNode *> routers;
    2557        6178 :         if (!BgpIfmapPeeringConfig::GetRouterPair(db_graph_, localname_, node,
    2558             :                                                   &routers)) {
    2559        1866 :             return;
    2560             :         }
    2561             : 
    2562        4312 :         string instance_name(IdentifierParent(routers.first->name()));
    2563        4312 :         BgpIfmapInstanceConfig *rti = config_->FindInstance(instance_name);
    2564        4312 :         event = BgpConfigManager::CFG_ADD;
    2565             :         // Create rti if not present.
    2566        4312 :         if (rti == NULL) {
    2567           2 :             rti = config_->LocateInstance(instance_name);
    2568           2 :             UpdateInstanceConfig(rti, event);
    2569             :         }
    2570        4312 :         peering = config_->CreatePeering(rti, proxy);
    2571        4312 :     } else {
    2572        9794 :         const IFMapNode *node = peering->node();
    2573        9794 :         assert(node != NULL);
    2574        9794 :         if (delta.obj.get() == NULL) {
    2575        2121 :             BGP_CONFIG_LOG_PEERING(Delete, server(), peering,
    2576             :                 SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
    2577        2121 :             BgpIfmapInstanceConfig *rti = peering->instance();
    2578        2121 :             peering->Delete(this);
    2579        2121 :             config_->DeletePeering(peering);
    2580        2121 :             if (rti->DeleteIfEmpty(this)) {
    2581          22 :                 BGP_CONFIG_LOG_INSTANCE(Delete, server(), rti,
    2582             :                     SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
    2583          22 :                 config_->DeleteInstance(rti);
    2584             :             }
    2585        2121 :             return;
    2586             :         }
    2587             :     }
    2588             : 
    2589       11985 :     if (event == BgpConfigManager::CFG_ADD) {
    2590        4312 :         BGP_CONFIG_LOG_PEERING(Create, server(), peering,
    2591             :             SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
    2592             :     } else {
    2593        7673 :         BGP_CONFIG_LOG_PEERING(Update, server(), peering,
    2594             :             SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
    2595             :     }
    2596             :     autogen::BgpPeering *peering_config =
    2597       11985 :             static_cast<autogen::BgpPeering *>(delta.obj.get());
    2598       11985 :     peering->Update(this, peering_config);
    2599             : }
    2600             : 
    2601        1136 : void BgpIfmapConfigManager::ProcessGlobalSystemConfig(
    2602             :         const BgpConfigDelta &delta) {
    2603        1136 :     IFMapNodeProxy *proxy = delta.node.get();
    2604        1136 :     if (proxy == NULL)
    2605           0 :         return;
    2606             : 
    2607        1136 :     IFMapNode *node = proxy->node();
    2608        1136 :     autogen::GlobalSystemConfig *config, default_config;
    2609        1136 :     if (node == NULL || node->IsDeleted() || delta.obj.get() == NULL) {
    2610           0 :         config = &default_config;
    2611             :     } else {
    2612        1136 :         config = static_cast<autogen::GlobalSystemConfig *>(delta.obj.get());
    2613             :     }
    2614             : 
    2615        1136 :     if (config_->global_config()->Update(this, config))
    2616         840 :         Notify(config_->global_config()->config(), BgpConfigManager::CFG_ADD);
    2617        1136 : }
    2618             : 
    2619          11 : void BgpIfmapConfigManager::ProcessGlobalQosConfig(
    2620             :         const BgpConfigDelta &delta) {
    2621          11 :     IFMapNodeProxy *proxy = delta.node.get();
    2622          11 :     if (proxy == NULL)
    2623           0 :         return;
    2624             : 
    2625          11 :     IFMapNode *node = proxy->node();
    2626          11 :     autogen::GlobalQosConfig *config, default_config;
    2627          11 :     if (node == NULL || node->IsDeleted() || delta.obj.get() == NULL) {
    2628           0 :         config = &default_config;
    2629             :     } else {
    2630          11 :         config = static_cast<autogen::GlobalQosConfig *>(delta.obj.get());
    2631             :     }
    2632             : 
    2633          11 :     if (config_->global_qos()->Update(this, config))
    2634           9 :         Notify(config_->global_qos()->config(), BgpConfigManager::CFG_ADD);
    2635          11 : }
    2636             : 
    2637             : //
    2638             : // Process the BgpConfigDeltas on the change list. We simply call the handler
    2639             : // for each delta based on the object's identifier type.
    2640             : //
    2641       24100 : void BgpIfmapConfigManager::ProcessChanges(const ChangeList &change_list) {
    2642       24100 :     CHECK_CONCURRENCY("bgp::Config");
    2643             : 
    2644       24100 :     for (ChangeList::const_iterator iter = change_list.begin();
    2645      219847 :          iter != change_list.end(); ++iter) {
    2646      195747 :         IdentifierMap::iterator loc = id_map_.find(iter->id_type);
    2647      195747 :         if (loc != id_map_.end()) {
    2648      171998 :             (loc->second)(*iter);
    2649             :         }
    2650             :     }
    2651       24100 : }
    2652             : 
    2653             : //
    2654             : // Build and process the change list of BgpConfigDeltas.  The logic to build
    2655             : // the list is in BgpConfigListener and BgpConfigListener::DependencyTracker.
    2656             : //
    2657       24100 : bool BgpIfmapConfigManager::ConfigHandler() {
    2658       24100 :     CHECK_CONCURRENCY("bgp::Config");
    2659             : 
    2660       24100 :     BgpConfigListener::ChangeList change_list;
    2661       24100 :     listener_->GetChangeList(&change_list);
    2662       24100 :     ProcessChanges(change_list);
    2663       24100 :     return true;
    2664       24100 : }
    2665             : 
    2666             : //
    2667             : // Terminate the BgpConfigManager.
    2668             : //
    2669        8049 : void BgpIfmapConfigManager::Terminate() {
    2670        8049 :     listener_->Terminate();
    2671        8049 :     config_.reset();
    2672        8049 : }

Generated by: LCOV version 1.14