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

Generated by: LCOV version 1.14