From: Francis Dupont Date: Sun, 17 Dec 2017 00:39:52 +0000 (+0100) Subject: [5452] Checkpoint: ported #5351 subnet/hr toElement fixes X-Git-Tag: trac5494_base~3^2^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=467c1e918ad06bb2da16533edfb4b1b9e4795d63;p=thirdparty%2Fkea.git [5452] Checkpoint: ported #5351 subnet/hr toElement fixes --- diff --git a/src/lib/dhcpsrv/host.cc b/src/lib/dhcpsrv/host.cc index 573047bdaf..8359780141 100644 --- a/src/lib/dhcpsrv/host.cc +++ b/src/lib/dhcpsrv/host.cc @@ -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)); diff --git a/src/lib/dhcpsrv/srv_config.cc b/src/lib/dhcpsrv/srv_config.cc index c6b3202590..434b96c4a4 100644 --- a/src/lib/dhcpsrv/srv_config.cc +++ b/src/lib/dhcpsrv/srv_config.cc @@ -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 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 networks = shared_networks->listValue(); + for (auto network = networks.cbegin(); + network != networks.cend(); ++network) { + const std::vector 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 networks = shared_networks->listValue(); + for (auto network = networks.cbegin(); + network != networks.cend(); ++network) { + const std::vector 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& sn_list = subnets->listValue(); - for (std::vector::const_iterator subnet = sn_list.begin(); - subnet != sn_list.end(); ++subnet) { + for (std::vector::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");