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: 703 1455 48.3 %
Date: 2026-09-28 02:13:17 Functions: 70 131 53.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14