LCOV - code coverage report
Current view: top level - bgp - bgp_config_parser.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 169 543 31.1 %
Date: 2026-09-21 02:11:39 Functions: 11 31 35.5 %
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_parser.h"
       6             : 
       7             : #include <boost/uuid/name_generator.hpp>
       8             : #include <pugixml/pugixml.hpp>
       9             : 
      10             : #include <map>
      11             : #include <set>
      12             : #include <sstream>
      13             : #include <utility>
      14             : #include <vector>
      15             : 
      16             : #include "bgp/bgp_config.h"
      17             : #include "bgp/bgp_log.h"
      18             : #include "bgp/rtarget/rtarget_address.h"
      19             : #include "ifmap/ifmap_server_table.h"
      20             : 
      21             : #include "schema/bgp_schema_types.h"
      22             : #include "schema/vnc_cfg_types.h"
      23             : 
      24             : using pugi::xml_attribute;
      25             : using pugi::xml_document;
      26             : using pugi::xml_node;
      27             : using pugi::xml_parse_result;
      28             : using std::unique_ptr;
      29             : using std::istringstream;
      30             : using std::list;
      31             : using std::ostringstream;
      32             : using std::make_pair;
      33             : using std::map;
      34             : using std::multimap;
      35             : using std::pair;
      36             : using std::set;
      37             : using std::string;
      38             : using std::vector;
      39             : 
      40             : typedef multimap<
      41             :     pair<string, string>,
      42             :     pair<autogen::BgpSessionAttributes, string> > SessionMap;
      43             : 
      44             : namespace {
      45             : 
      46          64 : static void MapObjectSetProperty(const string &ltype, const string &lname,
      47             :                                  const string &propname,
      48             :                                  AutogenProperty *property,
      49             :                                  BgpConfigParser::RequestList *requests) {
      50          64 :     DBRequest *request = new DBRequest;
      51          64 :     request->oper = DBRequest::DB_ENTRY_ADD_CHANGE;
      52          64 :     IFMapTable::RequestKey *key = new IFMapTable::RequestKey();
      53          64 :     request->key.reset(key);
      54          64 :     key->id_type = ltype;
      55          64 :     key->id_name = lname;
      56          64 :     IFMapServerTable::RequestData *data = new IFMapServerTable::RequestData();
      57          64 :     request->data.reset(data);
      58          64 :     data->metadata = propname;
      59          64 :     data->content.reset(property);
      60          64 :     data->origin.set_origin(IFMapOrigin::MAP_SERVER);
      61          64 :     requests->push_back(request);
      62          64 : }
      63             : 
      64           0 : static void MapObjectClearProperty(const string &ltype, const string &lname,
      65             :                                    const string &propname,
      66             :                                    BgpConfigParser::RequestList *requests) {
      67           0 :     DBRequest *request = new DBRequest;
      68           0 :     request->oper = DBRequest::DB_ENTRY_DELETE;
      69           0 :     IFMapTable::RequestKey *key = new IFMapTable::RequestKey();
      70           0 :     request->key.reset(key);
      71           0 :     key->id_type = ltype;
      72           0 :     key->id_name = lname;
      73           0 :     IFMapServerTable::RequestData *data = new IFMapServerTable::RequestData();
      74           0 :     request->data.reset(data);
      75           0 :     data->metadata = propname;
      76           0 :     data->origin.set_origin(IFMapOrigin::MAP_SERVER);
      77           0 :     requests->push_back(request);
      78           0 : }
      79             : 
      80          96 : static void MapObjectLink(const string &ltype, const string &lname,
      81             :                          const string &rtype, const string &rname,
      82             :                          const string &linkname,
      83             :                          BgpConfigParser::RequestList *requests) {
      84          96 :     DBRequest *request = new DBRequest;
      85          96 :     request->oper = DBRequest::DB_ENTRY_ADD_CHANGE;
      86          96 :     IFMapTable::RequestKey *key = new IFMapTable::RequestKey();
      87          96 :     request->key.reset(key);
      88          96 :     key->id_type = ltype;
      89          96 :     key->id_name = lname;
      90          96 :     IFMapServerTable::RequestData *data = new IFMapServerTable::RequestData();
      91          96 :     request->data.reset(data);
      92          96 :     data->metadata = linkname;
      93          96 :     data->id_type = rtype;
      94          96 :     data->id_name = rname;
      95          96 :     data->origin.set_origin(IFMapOrigin::MAP_SERVER);
      96          96 :     requests->push_back(request);
      97          96 : }
      98             : 
      99           0 : static void MapObjectUnlink(const string &ltype, const string &lname,
     100             :                             const string &rtype, const string &rname,
     101             :                             const string &linkname,
     102             :                             BgpConfigParser::RequestList *requests) {
     103           0 :     DBRequest *request = new DBRequest;
     104           0 :     request->oper = DBRequest::DB_ENTRY_DELETE;
     105           0 :     IFMapTable::RequestKey *key = new IFMapTable::RequestKey();
     106           0 :     request->key.reset(key);
     107           0 :     key->id_type = ltype;
     108           0 :     key->id_name = lname;
     109           0 :     IFMapServerTable::RequestData *data = new IFMapServerTable::RequestData();
     110           0 :     request->data.reset(data);
     111           0 :     data->metadata = linkname;
     112           0 :     data->id_type = rtype;
     113           0 :     data->id_name = rname;
     114           0 :     data->origin.set_origin(IFMapOrigin::MAP_SERVER);
     115           0 :     requests->push_back(request);
     116           0 : }
     117             : 
     118          96 : static void MapObjectLinkAttr(const string &ltype, const string &lname,
     119             :                              const string &rtype, const string &rname,
     120             :                              const string &linkname, AutogenProperty *attr,
     121             :                              BgpConfigParser::RequestList *requests) {
     122          96 :     DBRequest *request = new DBRequest;
     123          96 :     request->oper = DBRequest::DB_ENTRY_ADD_CHANGE;
     124          96 :     IFMapTable::RequestKey *key = new IFMapTable::RequestKey();
     125          96 :     request->key.reset(key);
     126          96 :     key->id_type = ltype;
     127          96 :     key->id_name = lname;
     128          96 :     IFMapServerTable::RequestData *data = new IFMapServerTable::RequestData();
     129          96 :     request->data.reset(data);
     130          96 :     data->metadata = linkname;
     131          96 :     data->id_type = rtype;
     132          96 :     data->id_name = rname;
     133          96 :     data->content.reset(attr);
     134          96 :     data->origin.set_origin(IFMapOrigin::MAP_SERVER);
     135          96 :     requests->push_back(request);
     136          96 : }
     137             : 
     138           0 : static autogen::BgpSessionAttributes *GetPeeringSessionAttribute(
     139             :         const pair<string, string> &key, autogen::BgpPeeringAttributes *peer,
     140             :         int session_id, const string config_uuid) {
     141           0 :     string uuid;
     142           0 :     if (!config_uuid.empty()) {
     143           0 :         uuid = config_uuid;
     144             :     } else {
     145           0 :         uuid = BgpConfigParser::session_uuid(key.first, key.second, session_id);
     146             :     }
     147             : 
     148           0 :     autogen::BgpSession *session = NULL;
     149           0 :     for (vector<autogen::BgpSession>::iterator iter =
     150           0 :             peer->session.begin();
     151           0 :          iter != peer->session.end(); ++iter) {
     152           0 :         if (iter->uuid == uuid) {
     153           0 :             session = iter.operator->();
     154           0 :             break;
     155             :         }
     156             :     }
     157           0 :     if (session == NULL) {
     158           0 :         peer->session.push_back(autogen::BgpSession());
     159           0 :         session = &peer->session.back();
     160           0 :         session->uuid = uuid;
     161             :     }
     162           0 :     session->attributes.push_back(autogen::BgpSessionAttributes());
     163           0 :     autogen::BgpSessionAttributes *sattr = &session->attributes.back();
     164           0 :     return sattr;
     165           0 : }
     166             : 
     167           0 : static void MaybeMergeBidirectionalSessionParams(
     168             :         autogen::BgpPeeringAttributes *peer) {
     169           0 : }
     170             : 
     171         160 : static void BuildPeeringLinks(const string &instance,
     172             :                               const SessionMap &sessions,
     173             :                               BgpConfigParser::RequestList *requests) {
     174             :     typedef map<pair<string, string>, autogen::BgpPeeringAttributes *>
     175             :         PeeringMap;
     176         160 :     PeeringMap peerings;
     177             : 
     178         160 :     pair<string, string> sprev;
     179         160 :     int session_id = 0;
     180         160 :     for (SessionMap::const_iterator iter = sessions.begin();
     181         160 :          iter != sessions.end(); ++iter) {
     182           0 :         const string &left = iter->first.first;
     183           0 :         const string &right = iter->first.second;
     184           0 :         pair<string, string> key;
     185           0 :         if (left <= right) {
     186           0 :             key = make_pair(left, right);
     187             :         } else {
     188           0 :             key = make_pair(right, left);
     189             :         }
     190             : 
     191           0 :         string config_uuid = iter->second.second;
     192           0 :         if ((sprev.first == left) && (sprev.second == right)) {
     193           0 :             session_id++;
     194             :         } else {
     195           0 :             session_id = 1;
     196           0 :             sprev = make_pair(left, right);
     197             :         }
     198             : 
     199           0 :         autogen::BgpPeeringAttributes *peer = NULL;
     200           0 :         PeeringMap::iterator loc = peerings.find(key);
     201           0 :         if (loc == peerings.end()) {
     202           0 :             peer = new autogen::BgpPeeringAttributes();
     203           0 :             peerings.insert(make_pair(key, peer));
     204             :         } else {
     205           0 :             peer = loc->second;
     206             :         }
     207             :         // add uni-directional attributes for this session.
     208             :         autogen::BgpSessionAttributes *attrp =
     209           0 :             GetPeeringSessionAttribute(key, peer, session_id, config_uuid);
     210           0 :         attrp->Copy(iter->second.first);
     211           0 :         attrp->bgp_router = left;
     212           0 :     }
     213             : 
     214             :     // generate the links.
     215             :     // merging uni-directional attributes into a common attribute when they
     216             :     // are the same.
     217         160 :     for (PeeringMap::iterator iter = peerings.begin(); iter != peerings.end();
     218           0 :          ++iter) {
     219           0 :         autogen::BgpPeeringAttributes *peer = iter->second;
     220           0 :         MaybeMergeBidirectionalSessionParams(peer);
     221           0 :         string left(instance + ':'), right(instance  + ':');
     222           0 :         left.append(iter->first.first);
     223           0 :         right.append(iter->first.second);
     224           0 :         MapObjectLinkAttr("bgp-router", left, "bgp-router", right,
     225             :                           "bgp-peering", peer, requests);
     226           0 :     }
     227         160 : }
     228             : 
     229           0 : static void RemovePeeringLinks(const string &instance,
     230             :                                const SessionMap &sessions,
     231             :                                BgpConfigParser::RequestList *requests) {
     232           0 :     set<pair<string, string> > key_set;
     233             : 
     234           0 :     for (SessionMap::const_iterator iter = sessions.begin();
     235           0 :          iter != sessions.end(); ++iter) {
     236           0 :         const string &left = iter->first.first;
     237           0 :         const string &right = iter->first.second;
     238           0 :         pair<string, string> key;
     239           0 :         if (left <= right) {
     240           0 :             key = make_pair(left, right);
     241             :         } else {
     242           0 :             key = make_pair(right, left);
     243             :         }
     244           0 :         if (key_set.count(key) > 0) {
     245           0 :             continue;
     246             :         }
     247           0 :         key_set.insert(key);
     248           0 :         string id_left(instance + ':'), id_right(instance  + ':');
     249           0 :         id_left.append(key.first);
     250           0 :         id_right.append(key.second);
     251             : 
     252           0 :         MapObjectUnlink("bgp-router", id_left, "bgp-router", id_right,
     253             :                         "bgp-peering", requests);
     254           0 :     }
     255           0 : }
     256             : 
     257           0 : static bool ParseSession(const string &identifier, const xml_node &node,
     258             :                          SessionMap *sessions) {
     259           0 :     autogen::BgpSessionAttributes attr;
     260           0 :     attr.Clear();
     261           0 :     xml_attribute to = node.attribute("to");
     262           0 :     assert(to);
     263           0 :     assert(attr.XmlParse(node));
     264             : 
     265           0 :     string to_value = to.value();
     266           0 :     string to_name, uuid;
     267           0 :     size_t pos = to_value.find(':');
     268           0 :     if (pos == string::npos) {
     269           0 :         to_name = to_value;
     270             :     } else {
     271           0 :         to_name = to_value.substr(0, pos);
     272           0 :         uuid = string(to_value, pos + 1);
     273             :     }
     274             : 
     275           0 :     sessions->insert(
     276           0 :         make_pair(make_pair(identifier, to_name), make_pair(attr, uuid)));
     277           0 :     return true;
     278           0 : }
     279             : 
     280           0 : static bool ParseServiceChain(const string &instance, const xml_node &node,
     281             :                               bool add_change, const string &sc_info,
     282             :                               BgpConfigParser::RequestList *requests) {
     283             :     unique_ptr<autogen::ServiceChainInfo> property(
     284           0 :         new autogen::ServiceChainInfo());
     285           0 :     property->sc_head = true;
     286           0 :     assert(property->XmlParse(node));
     287             : 
     288           0 :     if (add_change) {
     289           0 :         MapObjectSetProperty("routing-instance", instance,
     290           0 :             sc_info, property.release(), requests);
     291             :     } else {
     292           0 :         MapObjectClearProperty("routing-instance", instance,
     293             :             sc_info, requests);
     294             :     }
     295             : 
     296           0 :     return true;
     297           0 : }
     298             : 
     299           0 : static bool ParseInstanceRouteAggregate(const string &instance,
     300             :     const xml_node &node, bool add_change,
     301             :     BgpConfigParser::RequestList *requests) {
     302             : 
     303           0 :     xml_attribute to = node.attribute("to");
     304           0 :     assert(to);
     305           0 :     string aggregate_name = to.value();
     306           0 :     if (add_change) {
     307           0 :         MapObjectLinkAttr("routing-instance", instance,
     308             :             "route-aggregate", aggregate_name,
     309             :             "route-aggregate-routing-instance", NULL, requests);
     310             :     } else {
     311           0 :         MapObjectUnlink("routing-instance", instance,
     312             :             "route-aggregate", aggregate_name,
     313             :             "route-aggregate-routing-instance", requests);
     314             :     }
     315             : 
     316           0 :     return true;
     317           0 : }
     318             : 
     319           0 : static bool ParseInstanceRoutingPolicy(const string &instance,
     320             :     const xml_node &node, bool add_change,
     321             :     BgpConfigParser::RequestList *requests) {
     322             : 
     323           0 :     xml_attribute to = node.attribute("to");
     324           0 :     assert(to);
     325           0 :     string policy_name = to.value();
     326             :     unique_ptr<autogen::RoutingPolicyType> attr(
     327           0 :         new autogen::RoutingPolicyType());
     328           0 :     assert(attr->XmlParse(node));
     329           0 :     if (add_change) {
     330           0 :         MapObjectLinkAttr("routing-instance", instance,
     331             :             "routing-policy", policy_name,
     332           0 :             "routing-policy-routing-instance", attr.release(), requests);
     333             :     } else {
     334           0 :         MapObjectUnlink("routing-instance", instance,
     335             :             "routing-policy", policy_name,
     336             :             "routing-policy-routing-instance", requests);
     337             :     }
     338             : 
     339           0 :     return true;
     340           0 : }
     341             : 
     342           0 : static bool ParseStaticRoute(const string &instance, const xml_node &node,
     343             :                               bool add_change,
     344             :                               BgpConfigParser::RequestList *requests) {
     345             :     unique_ptr<autogen::StaticRouteEntriesType> property(
     346           0 :         new autogen::StaticRouteEntriesType());
     347           0 :     assert(property->XmlParse(node));
     348             : 
     349           0 :     if (add_change) {
     350           0 :         MapObjectSetProperty("routing-instance", instance,
     351           0 :             "static-route-entries", property.release(), requests);
     352             :     } else {
     353           0 :         MapObjectClearProperty("routing-instance", instance,
     354             :             "static-route-entries", requests);
     355             :     }
     356             : 
     357           0 :     return true;
     358           0 : }
     359             : 
     360           0 : static bool ParseInstanceHasPnf(const string &instance, const xml_node &node,
     361             :     bool add_change, BgpConfigParser::RequestList *requests) {
     362             :     unique_ptr<autogen::RoutingInstance::OolProperty> property(
     363           0 :         new autogen::RoutingInstance::OolProperty);
     364           0 :     property->data = (string(node.child_value()) == "true");
     365           0 :     if (add_change) {
     366           0 :         MapObjectSetProperty("routing-instance", instance,
     367           0 :             "routing-instance-has-pnf", property.release(), requests);
     368             :     } else {
     369           0 :         MapObjectClearProperty("routing-instance", instance,
     370             :             "routing-instance-has-pnf", requests);
     371             :     }
     372             : 
     373           0 :     return true;
     374           0 : }
     375             : 
     376          64 : static bool ParseBgpRouter(const string &instance, const xml_node &node,
     377             :                            bool add_change, string *nodename,
     378             :                            SessionMap *sessions,
     379             :                            BgpConfigParser::RequestList *requests) {
     380             :     unique_ptr<autogen::BgpRouterParams> property(
     381          64 :         new autogen::BgpRouterParams());
     382          64 :     xml_attribute name = node.attribute("name");
     383          64 :     assert(name);
     384          64 :     string identifier = name.value();
     385          64 :     assert(property->XmlParse(node));
     386             : 
     387          64 :     if (property->autonomous_system == 0) {
     388           0 :         property->autonomous_system =
     389           0 :             BgpConfigManager::kDefaultAutonomousSystem;
     390             :     }
     391          64 :     if (property->identifier.empty()) {
     392           0 :         property->identifier = property->address;
     393             :     }
     394             : 
     395          64 :     bool has_sessions = false;
     396          64 :     for (xml_node xsession = node.child("session"); xsession;
     397           0 :          xsession = xsession.next_sibling("session")) {
     398           0 :         has_sessions = true;
     399           0 :         ParseSession(identifier, xsession, sessions);
     400             :     }
     401             : 
     402          64 :     string fqname(instance + ":" + identifier);
     403          64 :     if (!has_sessions) {
     404          64 :         *nodename = fqname;
     405             :     }
     406             : 
     407          64 :     string subcluster_name;
     408          64 :     if (node.child("sub-cluster")) {
     409           0 :         xml_attribute sc = node.child("sub-cluster").attribute("name");
     410           0 :         subcluster_name = sc.value();
     411           0 :         assert(!subcluster_name.empty());
     412             :     }
     413             : 
     414          64 :     if (add_change) {
     415          64 :         MapObjectLink("routing-instance", instance,
     416             :             "bgp-router", fqname, "instance-bgp-router", requests);
     417          64 :         MapObjectSetProperty("bgp-router", fqname,
     418          64 :             "bgp-router-parameters", property.release(), requests);
     419          64 :         if (!subcluster_name.empty()) {
     420           0 :             MapObjectLink("bgp-router", fqname, "sub-cluster", subcluster_name,
     421             :                           "bgp-router-sub-cluster", requests);
     422             :         }
     423             :     } else {
     424           0 :         MapObjectClearProperty("bgp-router", fqname,
     425             :             "bgp-router-parameters", requests);
     426           0 :         MapObjectUnlink("routing-instance", instance,
     427             :             "bgp-router", fqname, "instance-bgp-router", requests);
     428           0 :         if (!subcluster_name.empty()) {
     429           0 :             MapObjectUnlink("bgp-router", fqname, "sub-cluster",
     430             :                     subcluster_name, "bgp-router-sub-cluster", requests);
     431             :         }
     432             :     }
     433             : 
     434          64 :     return true;
     435          64 : }
     436             : 
     437             : // Creates a full-mesh of links between all the routers that have been
     438             : // defined.
     439         160 : static void AddNeighborMesh(const list<string> &routers,
     440             :                             BgpConfigParser::RequestList *requests) {
     441         160 :     for (list<string>::const_iterator iter = routers.begin();
     442         224 :          iter != routers.end(); ) {
     443          64 :         const string &left = *iter;
     444          64 :         ++iter;
     445          64 :         for (list<string>::const_iterator tgt = iter;
     446          96 :              tgt != routers.end(); ++tgt) {
     447          32 :             MapObjectLink("bgp-router", left, "bgp-router", *tgt, "bgp-peering",
     448             :                          requests);
     449             :         }
     450             :     }
     451         160 : }
     452             : 
     453           0 : static void DeleteNeighborMesh(const list<string> &routers,
     454             :                                BgpConfigParser::RequestList *requests) {
     455           0 :     for (list<string>::const_iterator iter = routers.begin();
     456           0 :          iter != routers.end(); ) {
     457           0 :         const string &left = *iter;
     458           0 :         ++iter;
     459           0 :         for (list<string>::const_iterator tgt = iter;
     460           0 :              tgt != routers.end(); ++tgt) {
     461           0 :             MapObjectUnlink("bgp-router", left, "bgp-router", *tgt,
     462             :                 "bgp-peering", requests);
     463             :         }
     464             :     }
     465           0 : }
     466             : 
     467          96 : static bool ParseInstanceTarget(const string &instance, const xml_node &node,
     468             :                                 bool add_change,
     469             :                                 BgpConfigParser::RequestList *requests) {
     470          96 :     string rtarget(node.child_value());
     471          96 :     boost::trim(rtarget);
     472          96 :     boost::system::error_code parse_err;
     473          96 :     RouteTarget::FromString(rtarget, &parse_err);
     474          96 :     assert(!parse_err);
     475             : 
     476             :     unique_ptr<autogen::InstanceTargetType> params(
     477          96 :         new autogen::InstanceTargetType());
     478          96 :     assert(params->XmlParse(node));
     479             : 
     480          96 :     if (add_change) {
     481          96 :         MapObjectLinkAttr("routing-instance", instance, "route-target", rtarget,
     482          96 :             "instance-target", params.release(), requests);
     483             :     } else {
     484           0 :         MapObjectUnlink("routing-instance", instance, "route-target", rtarget,
     485             :             "instance-target", requests);
     486             :     }
     487             : 
     488          96 :     return true;
     489          96 : }
     490             : 
     491           0 : static bool ParseInstanceVirtualNetwork(const string &instance,
     492             :     const xml_node &node, bool add_change,
     493             :     BgpConfigParser::RequestList *requests) {
     494           0 :     string vn_name = node.child_value();
     495           0 :     if (add_change) {
     496           0 :         MapObjectLink("routing-instance", instance,
     497             :             "virtual-network", vn_name,
     498             :             "virtual-network-routing-instance", requests);
     499             :     } else {
     500           0 :         MapObjectUnlink("routing-instance", instance,
     501             :             "virtual-network", vn_name,
     502             :             "virtual-network-routing-instance", requests);
     503             :     }
     504             : 
     505           0 :     return true;
     506           0 : }
     507             : 
     508             : }  // namespace
     509             : 
     510          32 : BgpConfigParser::BgpConfigParser(DB *db)
     511          32 :         : db_(db) {
     512          32 : }
     513             : 
     514         128 : bool BgpConfigParser::ParseRoutingInstance(const xml_node &parent,
     515             :                                            bool add_change,
     516             :                                            RequestList *requests) const {
     517         128 :     string instance(parent.attribute("name").value());
     518         128 :     assert(!instance.empty());
     519             : 
     520         128 :     SessionMap sessions;
     521         128 :     list<string> routers;
     522             : 
     523         352 :     for (xml_node node = parent.first_child(); node;
     524         224 :          node = node.next_sibling()) {
     525         224 :         if (strcmp(node.name(), "bgp-router") == 0) {
     526          64 :             string router_name;
     527          64 :             ParseBgpRouter(instance, node, add_change, &router_name,
     528             :                            &sessions, requests);
     529          64 :             if (!router_name.empty()) {
     530          64 :                 routers.push_back(router_name);
     531             :             }
     532         224 :         } else if (strcmp(node.name(), "vrf-target") == 0) {
     533          96 :             ParseInstanceTarget(instance, node, add_change, requests);
     534          64 :         } else if (strcmp(node.name(), "virtual-network") == 0) {
     535           0 :             ParseInstanceVirtualNetwork(instance, node, add_change, requests);
     536          64 :         } else if (strcmp(node.name(), "service-chain-info") == 0) {
     537           0 :             ParseServiceChain(instance, node, add_change,
     538             :                               "service-chain-information", requests);
     539          64 :         } else if (strcmp(node.name(), "ipv6-service-chain-info") == 0) {
     540           0 :             ParseServiceChain(instance, node, add_change,
     541             :                               "ipv6-service-chain-information", requests);
     542          64 :         } else if (strcmp(node.name(), "evpn-service-chain-info") == 0) {
     543           0 :             ParseServiceChain(instance, node, add_change,
     544             :                               "evpn-service-chain-information", requests);
     545          64 :         } else if (strcmp(node.name(), "evpn-ipv6-service-chain-info") == 0) {
     546           0 :             ParseServiceChain(instance, node, add_change,
     547             :                               "evpn-ipv6-service-chain-information", requests);
     548          64 :         } else if (strcmp(node.name(), "route-aggregate") == 0) {
     549           0 :             ParseInstanceRouteAggregate(instance, node, add_change, requests);
     550          64 :         } else if (strcmp(node.name(), "routing-policy") == 0) {
     551           0 :             ParseInstanceRoutingPolicy(instance, node, add_change, requests);
     552          64 :         } else if (strcmp(node.name(), "static-route-entries") == 0) {
     553           0 :             ParseStaticRoute(instance, node, add_change, requests);
     554          64 :         } else if (strcmp(node.name(), "routing-instance-has-pnf") == 0) {
     555           0 :             ParseInstanceHasPnf(instance, node, add_change, requests);
     556             :         }
     557             :     }
     558             : 
     559         128 :     if (add_change) {
     560         128 :         BuildPeeringLinks(instance, sessions, requests);
     561             :         // Generate a full mesh of peering sessions for neighbors that do not
     562             :         // specify session attributes.
     563         128 :         AddNeighborMesh(routers, requests);
     564             :     } else {
     565           0 :         RemovePeeringLinks(instance, sessions, requests);
     566           0 :         DeleteNeighborMesh(routers, requests);
     567             :     }
     568         128 :     return true;
     569         128 : }
     570             : 
     571           0 : bool BgpConfigParser::ParseVirtualNetwork(const xml_node &node,
     572             :                                           bool add_change,
     573             :                                           RequestList *requests) const {
     574             :     // vn name
     575           0 :     string vn_name(node.attribute("name").value());
     576           0 :     assert(!vn_name.empty());
     577             : 
     578             :     unique_ptr<autogen::VirtualNetwork::OolProperty> pbb_property(
     579           0 :         new autogen::VirtualNetwork::OolProperty);
     580           0 :     pbb_property->data = false;
     581             : 
     582           0 :     if (node.attribute("pbb-evpn-enable")) {
     583           0 :         pbb_property->data =
     584           0 :             (string(node.attribute("pbb-evpn-enable").value()) == "true");
     585             :     }
     586             : 
     587             :     unique_ptr<autogen::VirtualNetworkType> property(
     588           0 :         new autogen::VirtualNetworkType());
     589           0 :     assert(property->XmlParse(node));
     590             : 
     591           0 :     if (add_change) {
     592           0 :         MapObjectSetProperty("virtual-network", vn_name,
     593           0 :             "virtual-network-properties", property.release(), requests);
     594           0 :         MapObjectSetProperty("virtual-network", vn_name,
     595           0 :             "pbb-evpn-enable", pbb_property.release(), requests);
     596             :     } else {
     597           0 :         MapObjectClearProperty("virtual-network", vn_name,
     598             :             "virtual-network-properties", requests);
     599           0 :         MapObjectClearProperty("virtual-network", vn_name,
     600             :             "pbb-evpn-enable", requests);
     601             :     }
     602             : 
     603           0 :     return true;
     604           0 : }
     605             : 
     606           0 : bool BgpConfigParser::ParseSubCluster(const xml_node &node,
     607             :                                       bool add_change,
     608             :                                       RequestList *requests) const {
     609           0 :     string subcluster_name(node.attribute("name").value());
     610           0 :     assert(!subcluster_name.empty());
     611             : 
     612             :     unique_ptr<autogen::SubCluster::StringProperty> subcluster_property(
     613           0 :         new autogen::SubCluster::StringProperty);
     614             : 
     615           0 :     if (node.child("sub-cluster-asn"))
     616           0 :         subcluster_property->data = string(node.child_value("sub-cluster-asn"));
     617             : 
     618           0 :     if (add_change) {
     619           0 :         MapObjectSetProperty("sub-cluster", subcluster_name,
     620           0 :             "sub-cluster-asn", subcluster_property.release(), requests);
     621             :     } else {
     622           0 :         MapObjectClearProperty("sub-cluster", subcluster_name,
     623             :                                "sub-cluster-asn", requests);
     624             :     }
     625             : 
     626             :     unique_ptr<autogen::SubCluster::NtProperty> id_property(
     627           0 :         new autogen::SubCluster::NtProperty);
     628           0 :     if (node.child("sub-cluster-id")) {
     629             :         std::stringstream sub_cluster_id(
     630           0 :                 string(node.child_value("sub-cluster-id")));
     631           0 :         sub_cluster_id >> id_property->data;
     632           0 :     }
     633           0 :     if (add_change) {
     634           0 :         MapObjectSetProperty("sub-cluster", subcluster_name,
     635           0 :             "sub-cluster-id", id_property.release(), requests);
     636             :     } else {
     637           0 :         MapObjectClearProperty("sub-cluster", subcluster_name,
     638             :                                "sub-cluster-id", requests);
     639             :     }
     640           0 :     return true;
     641           0 : }
     642             : 
     643           0 : bool BgpConfigParser::ParseRouteAggregate(const xml_node &node,
     644             :                                           bool add_change,
     645             :                                           RequestList *requests) const {
     646             :     // policy name
     647           0 :     string aggregate_name(node.attribute("name").value());
     648           0 :     assert(!aggregate_name.empty());
     649             : 
     650             : 
     651           0 :     for (xml_node child = node.first_child(); child;
     652           0 :          child = child.next_sibling()) {
     653           0 :         if (strcmp(child.name(), "aggregate-route-entries") == 0) {
     654           0 :             if (add_change) {
     655             :                 unique_ptr<autogen::RouteListType>
     656           0 :                     aggregate_routes(new autogen::RouteListType());
     657           0 :                 assert(aggregate_routes->XmlParse(child));
     658           0 :                 MapObjectSetProperty("route-aggregate", aggregate_name,
     659             :                                      "aggregate-route-entries",
     660           0 :                                      aggregate_routes.release(), requests);
     661           0 :             } else {
     662           0 :                 MapObjectClearProperty("route-aggregate", aggregate_name,
     663             :                                        "aggregate-route-entries", requests);
     664             :             }
     665           0 :         } else if (strcmp(child.name(), "nexthop") == 0) {
     666           0 :             if (add_change) {
     667           0 :                 string nexthop = child.child_value();
     668             : 
     669             :                 autogen::RouteAggregate::StringProperty *nexthop_property =
     670           0 :                     new autogen::RouteAggregate::StringProperty();
     671           0 :                 nexthop_property->data = nexthop;
     672           0 :                 MapObjectSetProperty("route-aggregate", aggregate_name,
     673             :                                      "aggregate-route-nexthop",
     674             :                                      nexthop_property, requests);
     675           0 :             } else {
     676           0 :                 MapObjectClearProperty("route-aggregate", aggregate_name,
     677             :                                        "aggregate-route-nexthop", requests);
     678             :             }
     679             :         }
     680             :     }
     681             : 
     682           0 :     return true;
     683           0 : }
     684             : 
     685           0 : bool BgpConfigParser::ParseRoutingPolicy(const xml_node &node,
     686             :                                           bool add_change,
     687             :                                           RequestList *requests) const {
     688             :     // policy name
     689           0 :     string policy_name(node.attribute("name").value());
     690           0 :     assert(!policy_name.empty());
     691             : 
     692             :     unique_ptr<autogen::PolicyStatementType> policy_statement(
     693           0 :         new autogen::PolicyStatementType());
     694           0 :     assert(policy_statement->XmlParse(node));
     695             : 
     696           0 :     if (add_change) {
     697           0 :         MapObjectSetProperty("routing-policy", policy_name,
     698           0 :             "routing-policy-entries", policy_statement.release(), requests);
     699             :     } else {
     700           0 :         MapObjectClearProperty("routing-policy", policy_name,
     701             :             "routing-policy-entries", requests);
     702             :     }
     703             : 
     704           0 :     return true;
     705           0 : }
     706             : 
     707           0 : bool BgpConfigParser::ParseGlobalSystemConfig(const xml_node &node,
     708             :                                               bool add_change,
     709             :                                               RequestList *requests) const {
     710           0 :     for (xml_node child = node.first_child(); child;
     711           0 :             child = child.next_sibling()) {
     712           0 :         if (strcmp(child.name(), "graceful-restart-parameters") == 0) {
     713             :             unique_ptr<autogen::GracefulRestartParametersType> gr_config(
     714           0 :                     new autogen::GracefulRestartParametersType());
     715           0 :             assert(gr_config->XmlParse(child));
     716             : 
     717           0 :             if (add_change) {
     718           0 :                 MapObjectSetProperty("global-system-config", "",
     719             :                     "graceful-restart-parameters",
     720           0 :                     gr_config.release(), requests);
     721             :             } else {
     722           0 :                 MapObjectClearProperty("global-system-config", "",
     723             :                                        "graceful-restart-parameters", requests);
     724             :             }
     725           0 :         }
     726           0 :         if (strcmp(child.name(), "bgpaas-parameters") == 0) {
     727             :             unique_ptr<autogen::BGPaaServiceParametersType> bgpaas_config(
     728           0 :                     new autogen::BGPaaServiceParametersType());
     729           0 :             assert(bgpaas_config->XmlParse(child));
     730             : 
     731           0 :             if (add_change) {
     732           0 :                 MapObjectSetProperty("global-system-config", "",
     733           0 :                     "bgpaas-parameters", bgpaas_config.release(), requests);
     734             :             } else {
     735           0 :                 MapObjectClearProperty("global-system-config", "",
     736             :                                        "bgpaas-parameters", requests);
     737             :             }
     738           0 :         }
     739           0 :         if (strcmp(child.name(), "bgp-always-compare-med") == 0) {
     740             :             unique_ptr<autogen::GlobalSystemConfig::OolProperty> property(
     741           0 :                 new autogen::GlobalSystemConfig::OolProperty);
     742           0 :             property->data = (string(child.child_value()) == "true");
     743           0 :             if (add_change) {
     744           0 :                 MapObjectSetProperty("global-system-config", "",
     745           0 :                     "bgp-always-compare-med", property.release(), requests);
     746             :             } else {
     747           0 :                 MapObjectClearProperty("global-system-config", "",
     748             :                     "bgp-always-compare-med", requests);
     749             :             }
     750           0 :         }
     751           0 :         if (strcmp(child.name(), "bgp-all-tags-are-global") == 0) {
     752             :             unique_ptr<autogen::GlobalSystemConfig::OolProperty> property(
     753           0 :                 new autogen::GlobalSystemConfig::OolProperty);
     754           0 :             property->data = (string(child.child_value()) == "true");
     755           0 :             if (add_change) {
     756           0 :                 MapObjectSetProperty("global-system-config", "",
     757           0 :                     "bgp-all-tags-are-global", property.release(), requests);
     758             :             } else {
     759           0 :                 MapObjectClearProperty("global-system-config", "",
     760             :                     "bgp-all-tags-are-global", requests);
     761             :             }
     762           0 :         }
     763           0 :         if (strcmp(child.name(), "enable-4byte-as") == 0) {
     764             :             unique_ptr<autogen::GlobalSystemConfig::OolProperty> property(
     765           0 :                 new autogen::GlobalSystemConfig::OolProperty);
     766           0 :             property->data = (string(child.child_value()) == "true");
     767           0 :             if (add_change) {
     768           0 :                 MapObjectSetProperty("global-system-config", "",
     769           0 :                     "enable-4byte-as", property.release(), requests);
     770             :             } else {
     771           0 :                 MapObjectClearProperty("global-system-config", "",
     772             :                     "enable-4byte-as", requests);
     773             :             }
     774           0 :         }
     775           0 :         if (strcmp(child.name(), "fast-convergence-parameters") == 0) {
     776             :             unique_ptr<autogen::FastConvergenceParametersType> property(
     777           0 :                     new autogen::FastConvergenceParametersType());
     778           0 :             assert(property->XmlParse(child));
     779           0 :             if (add_change) {
     780           0 :                 MapObjectSetProperty("global-system-config", "",
     781           0 :                     "fast-convergence-parameters", property.release(), requests);
     782             :             } else {
     783           0 :                 MapObjectClearProperty("global-system-config", "",
     784             :                     "fast-convergence-parameters", requests);
     785             :             }
     786           0 :         }
     787           0 :         if (strcmp(child.name(), "rd-cluster-seed") == 0) {
     788             :             unique_ptr<autogen::GlobalSystemConfig::NtProperty> property(
     789           0 :                 new autogen::GlobalSystemConfig::NtProperty);
     790           0 :             property->data = atoi(child.child_value());
     791           0 :             if (add_change) {
     792           0 :                 MapObjectSetProperty("global-system-config", "",
     793           0 :                     "rd-cluster-seed", property.release(), requests);
     794             :             } else {
     795           0 :                 MapObjectClearProperty("global-system-config", "",
     796             :                     "rd-cluster-seed", requests);
     797             :             }
     798           0 :         }
     799             :     }
     800           0 :     return true;
     801             : }
     802             : 
     803           0 : bool BgpConfigParser::ParseGlobalQosConfig(const xml_node &node,
     804             :                                            bool add_change,
     805             :                                            RequestList *requests) const {
     806           0 :     for (xml_node child = node.first_child(); child;
     807           0 :             child = child.next_sibling()) {
     808           0 :         if (strcmp(child.name(), "control-traffic-dscp") == 0) {
     809             :             unique_ptr<autogen::ControlTrafficDscpType> cfg(
     810           0 :                     new autogen::ControlTrafficDscpType());
     811           0 :             assert(cfg->XmlParse(child));
     812             : 
     813           0 :             if (add_change) {
     814           0 :                 MapObjectSetProperty("global-qos-config", "",
     815           0 :                     "control-traffic-dscp", cfg.release(), requests);
     816             :             } else {
     817           0 :                 MapObjectClearProperty("global-qos-config", "",
     818             :                                        "control-traffic-dscp", requests);
     819             :             }
     820           0 :         }
     821             :     }
     822           0 :     return true;
     823             : }
     824             : 
     825          32 : bool BgpConfigParser::ParseConfig(const xml_node &root, bool add_change,
     826             :                                   RequestList *requests) const {
     827          32 :     SessionMap sessions;
     828          32 :     list<string> routers;
     829             : 
     830         192 :     for (xml_node node = root.first_child(); node; node = node.next_sibling()) {
     831         160 :         if (strcmp(node.name(), "bgp-router") == 0) {
     832           0 :             string router_name;
     833           0 :             ParseBgpRouter(BgpConfigManager::kMasterInstance, node, add_change,
     834             :                            &router_name, &sessions, requests);
     835           0 :             if (!router_name.empty()) {
     836           0 :                 routers.push_back(router_name);
     837             :             }
     838           0 :         }
     839         160 :         if (strcmp(node.name(), "routing-instance") == 0) {
     840         128 :             ParseRoutingInstance(node, add_change, requests);
     841             :         }
     842         160 :         if (strcmp(node.name(), "virtual-network") == 0) {
     843           0 :             ParseVirtualNetwork(node, add_change, requests);
     844             :         }
     845         160 :         if (strcmp(node.name(), "sub-cluster") == 0) {
     846           0 :             ParseSubCluster(node, add_change, requests);
     847             :         }
     848         160 :         if (strcmp(node.name(), "route-aggregate") == 0) {
     849           0 :             ParseRouteAggregate(node, add_change, requests);
     850             :         }
     851         160 :         if (strcmp(node.name(), "routing-policy") == 0) {
     852           0 :             ParseRoutingPolicy(node, add_change, requests);
     853             :         }
     854         160 :         if (strcmp(node.name(), "global-system-config") == 0) {
     855           0 :             ParseGlobalSystemConfig(node, add_change, requests);
     856             :         }
     857         160 :         if (strcmp(node.name(), "global-qos-config") == 0) {
     858           0 :             ParseGlobalQosConfig(node, add_change, requests);
     859             :         }
     860             :     }
     861             : 
     862          32 :     if (add_change) {
     863          32 :         BuildPeeringLinks(BgpConfigManager::kMasterInstance, sessions,
     864             :                           requests);
     865             :         // Generate a full mesh of peering sessions for neighbors that do not
     866             :         // specify session attributes.
     867          32 :         AddNeighborMesh(routers, requests);
     868             :     } else {
     869           0 :         RemovePeeringLinks(BgpConfigManager::kMasterInstance, sessions,
     870             :                            requests);
     871           0 :         DeleteNeighborMesh(routers, requests);
     872             :     }
     873             : 
     874          32 :     return true;
     875          32 : }
     876             : 
     877          32 : bool BgpConfigParser::Parse(const string &content)  {
     878          32 :     istringstream sstream(content);
     879          32 :     xml_document xdoc;
     880          32 :     xml_parse_result result = xdoc.load(sstream);
     881          32 :     if (result.status == pugi::status_no_document_element) {
     882           0 :         return true;
     883             :     }
     884             : 
     885          32 :     if (result.status == pugi::status_ok) {
     886          32 :         RequestList requests;
     887          64 :         for (xml_node node = xdoc.first_child(); node; node = node.next_sibling()) {
     888          32 :             const char *oper = node.name();
     889          32 :             assert((strcmp(oper, "config") == 0) || (strcmp(oper, "delete") == 0));
     890          32 :             bool add_change = (strcmp(oper, "config") == 0);
     891          32 :             assert(ParseConfig(node, add_change, &requests));
     892             :         }
     893             : 
     894         288 :         while (!requests.empty()) {
     895         256 :             unique_ptr<DBRequest> req(requests.front());
     896         256 :             requests.pop_front();
     897             : 
     898             :             IFMapTable::RequestKey *key =
     899         256 :                     static_cast<IFMapTable::RequestKey *>(req->key.get());
     900             : 
     901         256 :             IFMapTable *table = IFMapTable::FindTable(db_, key->id_type);
     902         256 :             assert(table);
     903         256 :             table->Enqueue(req.get());
     904         256 :         }
     905             : 
     906          32 :         return true;
     907          32 :     }
     908           0 :     return false;
     909          32 : }
     910             : 
     911           0 : string BgpConfigParser::session_uuid(const string &left, const string &right,
     912             :                                      int index) {
     913             :     boost::uuids::nil_generator nil;
     914           0 :     boost::uuids::name_generator gen(nil());
     915             :     boost::uuids::uuid uuid;
     916           0 :     ostringstream oss;
     917           0 :     oss << left << ":" << right << ":" << index;
     918           0 :     uuid = gen(oss.str());
     919           0 :     return boost::uuids::to_string(uuid);
     920           0 : }

Generated by: LCOV version 1.14