LCOV - code coverage report
Current view: top level - dns/cfg - dns_config_parser.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 166 199 83.4 %
Date: 2026-06-08 02:02:55 Functions: 11 12 91.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include "dns_config_parser.h"
       6             : 
       7             : #include <sstream>
       8             : #include <boost/algorithm/string/trim.hpp>
       9             : #include <boost/asio/ip/address.hpp>
      10             : #include <boost/uuid/name_generator.hpp>
      11             : #include <boost/uuid/nil_generator.hpp>
      12             : #include <boost/uuid/uuid.hpp>
      13             : #include <boost/uuid/uuid_io.hpp>
      14             : #include <pugixml/pugixml.hpp>
      15             : #include "base/logging.h"
      16             : #include "bind/bind_util.h"
      17             : #include "cfg/dns_config.h"
      18             : #include "ifmap/ifmap_server_table.h"
      19             : 
      20             : using namespace std;
      21             : using namespace pugi;
      22             : 
      23             : namespace {
      24             : 
      25          90 : static void MapObjectLink(const string &ltype, const string &lname,
      26             :                          const string &rtype, const string &rname,
      27             :                          const string &linkname,
      28             :                          DnsConfigParser::RequestList *requests,
      29             :                          DBRequest::DBOperation oper) {
      30          90 :     DBRequest *request = new DBRequest;
      31          90 :     request->oper = oper;
      32          90 :     IFMapTable::RequestKey *key = new IFMapTable::RequestKey();
      33          90 :     request->key.reset(key);
      34          90 :     key->id_type = ltype;
      35          90 :     key->id_name = lname;
      36          90 :     IFMapServerTable::RequestData *data = new IFMapServerTable::RequestData();
      37          90 :     request->data.reset(data);
      38          90 :     data->metadata = linkname;
      39          90 :     data->id_type = rtype;
      40          90 :     data->id_name = rname;
      41          90 :     data->origin.set_origin(IFMapOrigin::MAP_SERVER);
      42          90 :     requests->push_back(request);
      43          90 : }
      44             : 
      45          48 : static void MapObjectLinkAttr(const string &ltype, const string &lname,
      46             :                               const string &rtype, const string &rname,
      47             :                               const string &linkname, AutogenProperty *attr,
      48             :                               DnsConfigParser::RequestList *requests,
      49             :                               DBRequest::DBOperation oper) {
      50          48 :     DBRequest *request = new DBRequest;
      51          48 :     request->oper = oper;
      52          48 :     IFMapTable::RequestKey *key = new IFMapTable::RequestKey();
      53          48 :     request->key.reset(key);
      54          48 :     key->id_type = ltype;
      55          48 :     key->id_name = lname;
      56          48 :     IFMapServerTable::RequestData *data = new IFMapServerTable::RequestData();
      57          48 :     request->data.reset(data);
      58          48 :     data->metadata = linkname;
      59          48 :     data->id_type = rtype;
      60          48 :     data->id_name = rname;
      61          48 :     data->content.reset(attr);
      62          48 :     data->origin.set_origin(IFMapOrigin::MAP_SERVER);
      63          48 :     requests->push_back(request);
      64          48 : }
      65             : 
      66          74 : static void SetData(const string &identifier, const string &id_type,
      67             :                     const string &metadata, AutogenProperty *params,
      68             :                     DnsConfigParser::RequestList *requests) {
      69          74 :     DBRequest *request = new DBRequest;
      70          74 :     request->oper = DBRequest::DB_ENTRY_ADD_CHANGE;
      71          74 :     IFMapTable::RequestKey *key = new IFMapTable::RequestKey();
      72          74 :     request->key.reset(key);
      73          74 :     key->id_type = id_type;
      74          74 :     key->id_name = identifier;
      75          74 :     IFMapServerTable::RequestData *data = new IFMapServerTable::RequestData();
      76          74 :     request->data.reset(data);
      77          74 :     data->metadata = metadata;
      78          74 :     data->content.reset(params);
      79          74 :     data->origin.set_origin(IFMapOrigin::MAP_SERVER);
      80          74 :     requests->push_back(request);
      81          74 : }
      82             : 
      83          44 : static void ClearData(const string &identifier, const string &id_type,
      84             :                       const string &metadata,
      85             :                       DnsConfigParser::RequestList *requests) {
      86          44 :     DBRequest *request = new DBRequest;
      87          44 :     request->oper = DBRequest::DB_ENTRY_DELETE;
      88          44 :     IFMapTable::RequestKey *key = new IFMapTable::RequestKey();
      89          44 :     request->key.reset(key);
      90          44 :     key->id_type = id_type;
      91          44 :     key->id_name = identifier;
      92          44 :     IFMapServerTable::RequestData *data = new IFMapServerTable::RequestData();
      93          44 :     request->data.reset(data);
      94          44 :     data->metadata = metadata;
      95          44 :     data->origin.set_origin(IFMapOrigin::MAP_SERVER);
      96          44 :     requests->push_back(request);
      97          44 : }
      98             : 
      99          48 : static bool ParseVnNetworkIpam(const xml_node &node, bool add_change,
     100             :                                DnsConfigParser::RequestList *requests) {
     101          48 :     xml_attribute name_attr = node.attribute("name");
     102          48 :     xml_attribute ipam_attr = node.attribute("ipam");
     103          48 :     xml_attribute vn_attr = node.attribute("vn");
     104          48 :     string name;
     105          48 :     string ipam;
     106          48 :     string vn;
     107             : 
     108          48 :     if (name_attr)
     109           4 :         name = name_attr.value();
     110          48 :     if (ipam_attr)
     111          48 :         ipam = ipam_attr.value();
     112          48 :     if (vn_attr)
     113          48 :         vn = vn_attr.value();
     114             : 
     115          48 :     unique_ptr<autogen::VnSubnetsType> params(new autogen::VnSubnetsType());
     116          48 :     if (!params->XmlParse(node)) {
     117           0 :         assert(0);
     118             :     }
     119             : 
     120          48 :     if (add_change) {
     121          30 :         MapObjectLinkAttr("virtual-network", vn, "network-ipam", ipam,
     122          30 :                           "virtual-network-network-ipam", params.release(), requests,
     123             :                           DBRequest::DB_ENTRY_ADD_CHANGE);
     124             :     } else {
     125          18 :         MapObjectLinkAttr("virtual-network", vn, "network-ipam", ipam,
     126          18 :                           "virtual-network-network-ipam", params.release(), requests,
     127             :                           DBRequest::DB_ENTRY_DELETE);
     128             :     }
     129             : 
     130          48 :     return true;
     131          48 : }
     132             : 
     133          28 : static bool ParseNetworkIpam(const xml_node &node, bool add_change,
     134             :                              DnsConfigParser::RequestList *requests) {
     135          28 :     xml_attribute name = node.attribute("name");
     136          28 :     string identifier;
     137          28 :     if (name)
     138          28 :         identifier = name.value();
     139             : 
     140          28 :     unique_ptr<autogen::IpamType> params(new autogen::IpamType());
     141          28 :     if (!params->XmlParse(node)) {
     142           0 :         assert(0);
     143             :     }
     144             : 
     145          28 :     if (add_change) {
     146          17 :         SetData(identifier, "network-ipam", "network-ipam-mgmt",
     147          17 :                 params.release(), requests);
     148             :     } else {
     149          11 :         ClearData(identifier, "network-ipam", "network-ipam-mgmt", requests);
     150             :     }
     151             : 
     152          28 :     return true;
     153          28 : }
     154             : 
     155          30 : static bool ParseVirtualDNS(const xml_node &node, bool add_change,
     156             :                             DnsConfigParser::RequestList *requests) {
     157          30 :     xml_attribute name = node.attribute("name");
     158          30 :     xml_attribute domain = node.attribute("domain");
     159          30 :     string identifier;
     160          30 :     string view;
     161             : 
     162          30 :     if (name)
     163          30 :         identifier = name.value();
     164          30 :     if (domain)
     165          30 :         view = domain.value();
     166             : 
     167          30 :     unique_ptr<autogen::VirtualDnsType> params(new autogen::VirtualDnsType());
     168          30 :     if (!params->XmlParse(node)) {
     169           0 :         assert(0);
     170             :     }
     171             : 
     172          30 :     if (add_change) {
     173          19 :         SetData(identifier, "virtual-DNS", "virtual-DNS-data",
     174          19 :                 params.release(), requests);
     175          19 :         MapObjectLink("domain", view, "virtual-DNS", identifier,
     176             :                       "domain-virtual-DNS", requests,
     177             :                       DBRequest::DB_ENTRY_ADD_CHANGE);
     178             :     } else {
     179          11 :         ClearData(identifier, "virtual-DNS", "virtual-DNS-data", requests);
     180          11 :         MapObjectLink("domain", view, "virtual-DNS", identifier,
     181             :                       "domain-virtual-DNS", requests,
     182             :                       DBRequest::DB_ENTRY_DELETE);
     183             :     }
     184             : 
     185          30 :     return true;
     186          30 : }
     187             : 
     188          60 : static bool ParseVirtualDNSRecord(const xml_node &node, bool add_change,
     189             :                                   DnsConfigParser::RequestList *requests) {
     190          60 :     xml_attribute name = node.attribute("name");
     191          60 :     xml_attribute dns = node.attribute("dns");
     192          60 :     string identifier;
     193          60 :     string virtual_dns;
     194             : 
     195          60 :     if (name)
     196          60 :         identifier = name.value();
     197          60 :     if (dns)
     198          60 :         virtual_dns = dns.value();
     199             : 
     200          60 :     unique_ptr<autogen::VirtualDnsRecordType> params(new autogen::VirtualDnsRecordType());
     201          60 :     if (!params->XmlParse(node)) {
     202           0 :         assert(0);
     203             :     }
     204             : 
     205          60 :     if (add_change) {
     206          38 :         SetData(identifier, "virtual-DNS-record", "virtual-DNS-record-data",
     207          38 :                 params.release(), requests);
     208          38 :         MapObjectLink("virtual-DNS", virtual_dns,
     209             :                       "virtual-DNS-record", identifier,
     210             :                       "virtual-DNS-virtual-DNS-record", requests,
     211             :                       DBRequest::DB_ENTRY_ADD_CHANGE);
     212             :     } else {
     213          22 :         ClearData(identifier, "virtual-DNS-record",
     214             :                   "virtual-DNS-record-data", requests);
     215          22 :         MapObjectLink("virtual-DNS", virtual_dns,
     216             :                         "virtual-DNS-record", identifier,
     217             :                         "virtual-DNS-virtual-DNS-record", requests,
     218             :                         DBRequest::DB_ENTRY_DELETE);
     219             :     }
     220             : 
     221          60 :     return true;
     222          60 : }
     223             : 
     224           0 : static bool ParseGlobalQosConfig(const xml_node &node, bool add_change,
     225             :                                  DnsConfigParser::RequestList *requests) {
     226           0 :     xml_attribute name = node.attribute("name");
     227           0 :     string identifier;
     228           0 :     if (name)
     229           0 :         identifier = name.value();
     230             : 
     231           0 :     for (xml_node child = node.first_child(); child;
     232           0 :             child = child.next_sibling()) {
     233           0 :         if (strcmp(child.name(), "control-traffic-dscp") == 0) {
     234             :             unique_ptr<autogen::ControlTrafficDscpType> cfg(
     235           0 :                     new autogen::ControlTrafficDscpType());
     236           0 :             assert(cfg->XmlParse(child));
     237             : 
     238           0 :             if (add_change) {
     239           0 :                 SetData(identifier, "global-qos-config",
     240           0 :                         "control-traffic-dscp", cfg.release(), requests);
     241             :             } else {
     242           0 :                 ClearData(identifier, "global-qos-config",
     243             :                           "control-traffic-dscp", requests);
     244             :             }
     245           0 :         }
     246             :     }
     247           0 :     return true;
     248           0 : }
     249             : 
     250             : }  // namespace
     251             : 
     252          15 : DnsConfigParser::DnsConfigParser(DB *db) : db_(db) {
     253          15 : }
     254             : 
     255          24 : bool DnsConfigParser::ParseConfig(const xml_node &root, bool add_change,
     256             :                                   RequestList *requests) const {
     257             : 
     258         190 :     for (xml_node node = root.first_child(); node; node = node.next_sibling()) {
     259         166 :         if (strcmp(node.name(), "network-ipam") == 0) {
     260          28 :             ParseNetworkIpam(node, add_change, requests);
     261             :         }
     262         138 :         else if (strcmp(node.name(), "virtual-network-network-ipam") == 0) {
     263          48 :             ParseVnNetworkIpam(node, add_change, requests);
     264             :         }
     265          90 :         else if (strcmp(node.name(), "virtual-DNS") == 0) {
     266          30 :             ParseVirtualDNS(node, add_change, requests);
     267             :         }
     268          60 :         else if (strcmp(node.name(), "virtual-DNS-record") == 0) {
     269          60 :             ParseVirtualDNSRecord(node, add_change, requests);
     270             :         }
     271           0 :         else if (strcmp(node.name(), "global-qos-config") == 0) {
     272           0 :             ParseGlobalQosConfig(node, add_change, requests);
     273             :         }
     274             :     }
     275             : 
     276          24 :     return true;
     277             : }
     278             : 
     279          24 : bool DnsConfigParser::Parse(const std::string &content)  {
     280          24 :     istringstream sstream(content);
     281          24 :     xml_document xdoc;
     282          24 :     xml_parse_result result = xdoc.load(sstream);
     283          24 :     if (!result) {
     284           0 :         std::stringstream str;
     285           0 :         str << "Unable to load XML document. (status="
     286           0 :             << result.status << ", offset=" << result.offset << ")";
     287           0 :         DNS_TRACE(DnsError, str.str());
     288           0 :         return false;
     289           0 :     }
     290             : 
     291          24 :     RequestList requests;
     292          48 :     for (xml_node node = xdoc.first_child(); node; node = node.next_sibling()) {
     293             :         bool add_change;
     294          24 :         if (strcmp(node.name(), "config") == 0) {
     295          14 :             add_change = true;
     296          10 :         } else if (strcmp(node.name(), "delete") == 0) {
     297          10 :             add_change = false;
     298             :         } else {
     299           0 :             continue;
     300             :         }
     301          24 :         if (!ParseConfig(node, add_change, &requests)) {
     302           0 :             STLDeleteValues(&requests);
     303           0 :             return false;
     304             :         }
     305             :     }
     306             : 
     307         280 :     while (!requests.empty()) {
     308         256 :         unique_ptr<DBRequest> req(requests.front());
     309         256 :         requests.pop_front();
     310             : 
     311             :         IFMapTable::RequestKey *key =
     312         256 :                 static_cast<IFMapTable::RequestKey *>(req->key.get());
     313             : 
     314         256 :         IFMapTable *table = IFMapTable::FindTable(db_, key->id_type);
     315         256 :         if (table == NULL) {
     316           0 :             continue;
     317             :         }
     318         256 :         table->Enqueue(req.get());
     319         256 :     }
     320             : 
     321          24 :     return true;
     322          24 : }

Generated by: LCOV version 1.14