]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5452] Checkpoint: ported #5351 subnet/hr toElement fixes
authorFrancis Dupont <fdupont@isc.org>
Sun, 17 Dec 2017 00:39:52 +0000 (01:39 +0100)
committerFrancis Dupont <fdupont@isc.org>
Sun, 17 Dec 2017 00:39:52 +0000 (01:39 +0100)
src/lib/dhcpsrv/host.cc
src/lib/dhcpsrv/srv_config.cc

index 573047bdaf8fe4688210109f43113a21a09365bc..8359780141f83941c6933a13d7123b04442341bc 100644 (file)
@@ -432,9 +432,11 @@ Host::toElement4() const {
     } else {
         isc_throw(ToElementError, "invalid identifier type: " << id_type);
     }
-    // Set the reservation
+    // Set the reservation (if not 0.0.0.0 which may not be re-read)
     const IOAddress& address = getIPv4Reservation();
-    map->set("ip-address", Element::create(address.toText()));
+    if (!address.isV4Zero()) {
+        map->set("ip-address", Element::create(address.toText()));
+    }
     // Set the hostname
     const std::string& hostname = getHostname();
     map->set("hostname", Element::create(hostname));
index c6b3202590d9202f77ddb2dd7e3ede97398d4a4f..434b96c4a4d11999605930b87d7edcfbef5b8595 100644 (file)
@@ -234,27 +234,91 @@ SrvConfig::toElement() const {
     dhcp->set("option-data", cfg_option_->toElement());
 
     // Set subnets and shared networks.
-    ConstElementPtr subnets;
+
+    // We have two problems to solve:
+    //   - a subnet is unparsed once:
+    //       * if it is a plain subnet in the global subnet list
+    //       * if it is a member of a shared network in the shared network
+    //         subnet list
+    //   - unparsed subnets must be kept to add host reservations in them.
+    //     Of course this can be done only when subnets are unparsed.
+
+    // The list of all unparsed subnets
+    std::vector<ElementPtr> sn_list;
+
     if (family == AF_INET) {
-        subnets = cfg_subnets4_->toElement();
-        dhcp->set("subnet4", subnets);
+        // Get plain subnets
+        ElementPtr plain_subnets = Element::createList();
+        const Subnet4Collection* subnets = cfg_subnets4_->getAll();
+        for (Subnet4Collection::const_iterator subnet = subnets->cbegin();
+             subnet != subnets->cend(); ++subnet) {
+            // Skip subnets which are in a shared-network
+            SharedNetwork4Ptr network;
+            (*subnet)->getSharedNetwork(network);
+            if (network) {
+                continue;
+            }
+            ElementPtr subnet_cfg = (*subnet)->toElement();
+            sn_list.push_back(subnet_cfg);
+            plain_subnets->add(subnet_cfg);
+        }
+        dhcp->set("subnet4", plain_subnets);
 
-        ConstElementPtr shared_networks = cfg_shared_networks4_->toElement();
+        // Get shared networks
+        ElementPtr shared_networks = cfg_shared_networks4_->toElement();
         dhcp->set("shared-networks", shared_networks);
 
+        // Get subnets in shared network subnet lists
+        const std::vector<ElementPtr> networks = shared_networks->listValue();
+        for (auto network = networks.cbegin();
+             network != networks.cend(); ++network) {
+            const std::vector<ElementPtr> sh_list =
+                (*network)->get("subnet4")->listValue();
+            for (auto subnet = sh_list.cbegin();
+                 subnet != sh_list.cend(); ++subnet) {
+                sn_list.push_back(*subnet);
+            }
+        }
+
     } else {
-        subnets = cfg_subnets6_->toElement();
-        dhcp->set("subnet6", subnets);
+        // Get plain subnets
+        ElementPtr plain_subnets = Element::createList();
+        const Subnet6Collection* subnets = cfg_subnets6_->getAll();
+        for (Subnet6Collection::const_iterator subnet = subnets->cbegin();
+             subnet != subnets->cend(); ++subnet) {
+            // Skip subnets which are in a shared-network
+            SharedNetwork6Ptr network;
+            (*subnet)->getSharedNetwork(network);
+            if (network) {
+                continue;
+            }
+            ElementPtr subnet_cfg = (*subnet)->toElement();
+            sn_list.push_back(subnet_cfg);
+            plain_subnets->add(subnet_cfg);
+        }
+        dhcp->set("subnet6", plain_subnets);
 
-        ConstElementPtr shared_networks = cfg_shared_networks6_->toElement();
+        // Get shared networks
+        ElementPtr shared_networks = cfg_shared_networks6_->toElement();
         dhcp->set("shared-networks", shared_networks);
+
+        // Get subnets in shared network subnet lists
+        const std::vector<ElementPtr> networks = shared_networks->listValue();
+        for (auto network = networks.cbegin();
+             network != networks.cend(); ++network) {
+            const std::vector<ElementPtr> sh_list =
+                (*network)->get("subnet6")->listValue();
+            for (auto subnet = sh_list.cbegin();
+                 subnet != sh_list.cend(); ++subnet) {
+                sn_list.push_back(*subnet);
+            }
+        }
     }
     // Insert reservations
     CfgHostsList resv_list;
     resv_list.internalize(cfg_hosts_->toElement());
-    const std::vector<ElementPtr>& sn_list = subnets->listValue();
-    for (std::vector<ElementPtr>::const_iterator subnet = sn_list.begin();
-         subnet != sn_list.end(); ++subnet) {
+    for (std::vector<ElementPtr>::const_iterator subnet = sn_list.cbegin();
+         subnet != sn_list.cend(); ++subnet) {
         ConstElementPtr id = (*subnet)->get("id");
         if (isNull(id)) {
             isc_throw(ToElementError, "subnet has no id");