]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1387] Checkpoint: fixes
authorFrancis Dupont <fdupont@isc.org>
Tue, 2 Jul 2024 08:32:37 +0000 (10:32 +0200)
committerFrancis Dupont <fdupont@isc.org>
Wed, 4 Sep 2024 13:09:40 +0000 (15:09 +0200)
src/lib/dhcpsrv/parsers/host_reservation_parser.cc
src/share/database/scripts/pgsql/upgrade_023_to_024.sh.in

index 470ec395546feb9c0a509a4aab6efae9a4fb5cde..bf2185e41ae2a09b17bb0fc2aaf52a0ac61071ad 100644 (file)
@@ -19,6 +19,9 @@
 using namespace isc::asiolink;
 using namespace isc::data;
 
+namespace isc {
+namespace dhcp {
+
 namespace {
 
 /// @brief Returns set of the supported parameters for DHCPv4.
@@ -94,10 +97,62 @@ getSupportedParams6(const bool identifiers_only = false) {
     return (identifiers_only ? identifiers_set : params_set);
 }
 
+/// @brief Extract the prefix from the value specified in
+/// the following format: 2001:db8:2000::/64.
+///
+/// @param prefix Prefix in text format.
+/// @param[out] addr Address part of the prefix.
+/// @param[out] len Length part of the prefix.
+/// @param msg Message to prepend to first error log.
+void
+parsePrefix(std::string prefix, IOAddress& addr, uint8_t& len, std::string msg) {
+    // The slash is mandatory for prefixes. If there is no slash,
+    // return an error.
+    size_t len_pos  = prefix.find('/');
+    if (len_pos == std::string::npos) {
+        isc_throw(DhcpConfigError, msg << " requires prefix length "
+                  << "be specified in '" << prefix << "'");
+    } else if (len_pos >= prefix.length() - 1) {
+        // If there is nothing after the slash, we should also
+        // report an error.
+        isc_throw(DhcpConfigError, "prefix '" <<  prefix
+                  << "' requires length after '/'");
+
+    }
+
+    // Convert the prefix length from the string to the number.
+    // Note, that we don't use the uint8_t type as the lexical cast
+    // would expect a character, e.g. 'a', instead of prefix length,
+    // e.g. '64'.
+    unsigned int prefix_len = len;
+    try {
+        prefix_len = boost::lexical_cast<unsigned int>(prefix.substr(len_pos + 1));
+    } catch (const boost::bad_lexical_cast&) {
+        isc_throw(DhcpConfigError, "prefix length value '"
+                  << prefix.substr(len_pos + 1) << "' is invalid");
+    }
+    if ((prefix_len == 0) || (prefix_len > 128)) {
+        isc_throw(OutOfRange,
+                  "'prefix-len' value must be in range of [1..128]");
+    }
+    len = static_cast<uint8_t>(prefix_len);
+
+    // Remove the slash character and the prefix length from the
+    // parsed value.
+    prefix.erase(len_pos);
+    addr = IOAddress(prefix);
+
+    if (len != 128) {
+        IOAddress first_address = firstAddrInPrefix(addr, len);
+        if (first_address != addr) {
+            isc_throw(BadValue, "Prefix address: " << addr
+                      << " exceeds prefix/prefix-len pair: " << first_address
+                      << "/" << prefix_len);
+        }
+    }
 }
 
-namespace isc {
-namespace dhcp {
+}
 
 HostPtr
 HostReservationParser::parse(const SubnetID& subnet_id,
@@ -247,63 +302,6 @@ HostReservationParser4::getSupportedParameters(const bool identifiers_only) cons
     return (getSupportedParams4(identifiers_only));
 }
 
-namespace {
-
-// Extract the prefix length from the value specified in
-// the following format: 2001:db8:2000::/64.
-std::pair<IOAddress, uint8_t>
-parsePrefix(std::string prefix, std::string msg) {
-    uint8_t prefix_len = 128;
-    // The slash is mandatory for prefixes. If there is no slash,
-    // return an error.
-    size_t len_pos  = prefix.find('/');
-    if (len_pos == std::string::npos) {
-        isc_throw(DhcpConfigError, msg << " requires prefix length "
-                  << "be specified in '" << prefix << "'");
-
-        // If there is nothing after the slash, we should also
-        // report an error.
-    } else if (len_pos >= prefix.length() - 1) {
-        isc_throw(DhcpConfigError, "prefix '" <<  prefix
-                  << "' requires length after '/'");
-
-    }
-
-    // Convert the prefix length from the string to the number.
-    // Note, that we don't use the uint8_t type as the lexical cast
-    // would expect a character, e.g. 'a', instead of prefix length,
-    // e.g. '64'.
-
-    try {
-        prefix_len = boost::lexical_cast<unsigned int>(prefix.substr(len_pos + 1));
-    } catch (const boost::bad_lexical_cast&) {
-        isc_throw(DhcpConfigError, "prefix length value '"
-                  << prefix.substr(len_pos + 1) << "' is invalid");
-    }
-
-    if ((prefix_len == 0) || (prefix_len > 128)) {
-        isc_throw(OutOfRange,
-                  "'prefix-len' value must be in range of [1..128]");
-    }
-
-    // Remove the slash character and the prefix length from the
-    // parsed value.
-    prefix.erase(len_pos);
-    IOAddress addr(prefix);
-
-    if (prefix_len != 128) {
-        IOAddress first_address = firstAddrInPrefix(addr, prefix_len);
-        if (first_address != addr) {
-            isc_throw(BadValue, "Prefix address: " << addr
-                      << " exceeds prefix/prefix-len pair: " << first_address
-                      << "/" << static_cast<uint32_t>(prefix_len));
-        }
-    }
-    return (std::pair<IOAddress, uint8_t>(addr, prefix_len));
-}
-
-} // end of anonymous namespace.
-
 HostPtr
 HostReservationParser6::parseInternal(const SubnetID& subnet_id,
                                       isc::data::ConstElementPtr reservation_data,
@@ -369,16 +367,21 @@ HostReservationParser6::parseInternal(const SubnetID& subnet_id,
             ConstElementPtr element = prefixes->get(idx);
             try {
                 std::string prefix = element->stringValue();
-                auto const p = parsePrefix(prefix, "prefix reservation");
-                IPv6Resrv res(IPv6Resrv::TYPE_PD, p.first, p.second);
+                IOAddress addr("::");
+                uint8_t prefix_len(128);
+                parsePrefix(prefix, addr, prefix_len, "prefix reservation");
+                IPv6Resrv res(IPv6Resrv::TYPE_PD, addr, prefix_len);
                 std::string exclude("");
                 if (excluded_prefixes) {
                     element = excluded_prefixes->get(idx);
                     exclude = element->stringValue();
                 }
                 if (!exclude.empty()) {
-                    auto const x = parsePrefix(exclude, "exclude prefix");
-                    res.setPDExclude(x.first, x.second);
+                    IOAddress excluded_prefix("::");
+                    uint8_t excluded_prefix_len(0);
+                    parsePrefix(exclude, excluded_prefix, excluded_prefix_len,
+                                "exclude prefix");
+                    res.setPDExclude(excluded_prefix, excluded_prefix_len);
                 }
                 host->addReservation(res);
             } catch (const std::exception& ex) {
index e46a4f701a6e41050988fddf414cd34c960a3c03..5130e4ce588414be8ee2d3449e0f80e7acb2855e 100644 (file)
@@ -113,7 +113,6 @@ SELECT updateOptionDataDef();
 -- Get rid of the now obsolete function.
 DROP FUNCTION IF EXISTS updateOptionDataDef();
 
--- Update the schema version number.
 UPDATE schema_version
     SET version = '24', minor = '0';