Browse Source

[5314] Subnet to Element conversion moved to SubnetX classes.

Marcin Siodelski 7 years ago
parent
commit
62d94947c2
4 changed files with 302 additions and 266 deletions
  1. 1 100
      src/lib/dhcpsrv/cfg_subnets4.cc
  2. 1 165
      src/lib/dhcpsrv/cfg_subnets6.cc
  3. 275 0
      src/lib/dhcpsrv/subnet.cc
  4. 25 1
      src/lib/dhcpsrv/subnet.h

+ 1 - 100
src/lib/dhcpsrv/cfg_subnets4.cc

@@ -284,106 +284,7 @@ CfgSubnets4::toElement() const {
     // Iterate subnets
     // Iterate subnets
     for (Subnet4Collection::const_iterator subnet = subnets_.cbegin();
     for (Subnet4Collection::const_iterator subnet = subnets_.cbegin();
          subnet != subnets_.cend(); ++subnet) {
          subnet != subnets_.cend(); ++subnet) {
-        // Prepare the map
-        ElementPtr map = Element::createMap();
-        // Set subnet id
-        SubnetID id = (*subnet)->getID();
-        map->set("id", Element::create(static_cast<long long>(id)));
-        // Set relay info
-        const Subnet::RelayInfo& relay_info = (*subnet)->getRelayInfo();
-        ElementPtr relay = Element::createMap();
-        relay->set("ip-address", Element::create(relay_info.addr_.toText()));
-        map->set("relay", relay);
-        // Set subnet
-        map->set("subnet", Element::create((*subnet)->toText()));
-        // Set interface
-        const std::string& iface = (*subnet)->getIface();
-        map->set("interface", Element::create(iface));
-        // Set renew-timer
-        map->set("renew-timer",
-                 Element::create(static_cast<long long>
-                                 ((*subnet)->getT1().get())));
-        // Set rebind-timer
-        map->set("rebind-timer",
-                 Element::create(static_cast<long long>
-                                 ((*subnet)->getT2().get())));
-        // Set valid-lifetime
-        map->set("valid-lifetime",
-                 Element::create(static_cast<long long>
-                                 ((*subnet)->getValid().get())));
-        // Set pools
-        const PoolCollection& pools = (*subnet)->getPools(Lease::TYPE_V4);
-        ElementPtr pool_list = Element::createList();
-        for (PoolCollection::const_iterator pool = pools.cbegin();
-             pool != pools.cend(); ++pool) {
-            // Prepare the map for a pool (@todo move this code to pool.cc)
-            ElementPtr pool_map = Element::createMap();
-            // Set pool
-            const IOAddress& first = (*pool)->getFirstAddress();
-            const IOAddress& last = (*pool)->getLastAddress();
-            std::string range = first.toText() + "-" + last.toText();
-            // Try to output a prefix (vs a range)
-            int prefix_len = prefixLengthFromRange(first, last);
-            if (prefix_len >= 0) {
-                std::ostringstream oss;
-                oss << first.toText() << "/" << prefix_len;
-                range = oss.str();
-            }
-            pool_map->set("pool", Element::create(range));
-            // Set user-context
-            ConstElementPtr context = (*pool)->getContext();
-            if (!isNull(context)) {
-                pool_map->set("user-context", context);
-            }
-            // Set pool options
-            ConstCfgOptionPtr opts = (*pool)->getCfgOption();
-            pool_map->set("option-data", opts->toElement());
-            // Push on the pool list
-            pool_list->add(pool_map);
-        }
-        map->set("pools", pool_list);
-        // Set host reservation-mode
-        Subnet::HRMode hrmode = (*subnet)->getHostReservationMode();
-        std::string mode;
-        switch (hrmode) {
-        case Subnet::HR_DISABLED:
-            mode = "disabled";
-            break;
-        case Subnet::HR_OUT_OF_POOL:
-            mode = "out-of-pool";
-            break;
-        case Subnet::HR_ALL:
-            mode = "all";
-            break;
-        default:
-            isc_throw(ToElementError,
-                      "invalid host reservation mode: " << hrmode);
-        }
-        map->set("reservation-mode", Element::create(mode));
-        // Set match-client-id
-        map->set("match-client-id",
-                 Element::create((*subnet)->getMatchClientId()));
-        // Set next-server
-        map->set("next-server",
-                 Element::create((*subnet)->getSiaddr().toText()));
-        // Set DHCP4o6
-        const Cfg4o6& d4o6 = (*subnet)->get4o6();
-        isc::data::merge(map, d4o6.toElement());
-        // Set client-class
-        const ClientClasses& cclasses = (*subnet)->getClientClasses();
-        if (cclasses.size() > 1) {
-            isc_throw(ToElementError, "client-class has too many items: "
-                      << cclasses.size());
-        } else if (!cclasses.empty()) {
-            map->set("client-class", Element::create(*cclasses.cbegin()));
-        }
-        // Set options
-        ConstCfgOptionPtr opts = (*subnet)->getCfgOption();
-        map->set("option-data", opts->toElement());
-        // Not supported: interface-id
-        // Not supported: rapid-commit
-        // Push on the list
-        result->add(map);
+        result->add((*subnet)->toElement());
     }
     }
     return (result);
     return (result);
 }
 }

+ 1 - 165
src/lib/dhcpsrv/cfg_subnets6.cc

@@ -240,171 +240,7 @@ CfgSubnets6::toElement() const {
     // Iterate subnets
     // Iterate subnets
     for (Subnet6Collection::const_iterator subnet = subnets_.cbegin();
     for (Subnet6Collection::const_iterator subnet = subnets_.cbegin();
          subnet != subnets_.cend(); ++subnet) {
          subnet != subnets_.cend(); ++subnet) {
-        // Prepare the map
-        ElementPtr map = Element::createMap();
-        // Set subnet id
-        SubnetID id = (*subnet)->getID();
-        map->set("id", Element::create(static_cast<long long>(id)));
-        // Set relay info
-        const Subnet::RelayInfo& relay_info = (*subnet)->getRelayInfo();
-        ElementPtr relay = Element::createMap();
-        relay->set("ip-address", Element::create(relay_info.addr_.toText()));
-        map->set("relay", relay);
-        // Set subnet
-        map->set("subnet", Element::create((*subnet)->toText()));
-        // Set interface
-        const std::string& iface = (*subnet)->getIface();
-        map->set("interface", Element::create(iface));
-        // Set interface-id
-        const OptionPtr& ifaceid = (*subnet)->getInterfaceId();
-        if (ifaceid) {
-            std::vector<uint8_t> bin = ifaceid->getData();
-            std::string ifid;
-            ifid.resize(bin.size());
-            if (!bin.empty()) {
-                std::memcpy(&ifid[0], &bin[0], bin.size());
-            }
-            map->set("interface-id", Element::create(ifid));
-        } else {
-            map->set("interface-id", Element::create(std::string()));
-        }
-        // Set renew-timer
-        map->set("renew-timer",
-                 Element::create(static_cast<long long>
-                                 ((*subnet)->getT1().get())));
-        // Set rebind-timer
-        map->set("rebind-timer",
-                 Element::create(static_cast<long long>
-                                 ((*subnet)->getT2().get())));
-        // Set preferred-lifetime
-        map->set("preferred-lifetime",
-                 Element::create(static_cast<long long>
-                                 ((*subnet)->getPreferred().get())));
-        // Set valid-lifetime
-        map->set("valid-lifetime",
-                 Element::create(static_cast<long long>
-                                 ((*subnet)->getValid().get())));
-        // Set rapid-commit
-        bool rapid_commit = (*subnet)->getRapidCommit();
-        map->set("rapid-commit", Element::create(rapid_commit));
-        // Set pools
-        const PoolCollection& pools = (*subnet)->getPools(Lease::TYPE_NA);
-        ElementPtr pool_list = Element::createList();
-        for (PoolCollection::const_iterator pool = pools.cbegin();
-             pool != pools.cend(); ++pool) {
-            // Prepare the map for a pool (@todo move this code to pool.cc)
-            ElementPtr pool_map = Element::createMap();
-            // Set pool
-            const IOAddress& first = (*pool)->getFirstAddress();
-            const IOAddress& last = (*pool)->getLastAddress();
-            std::string range = first.toText() + "-" + last.toText();
-            // Try to output a prefix (vs a range)
-            int prefix_len = prefixLengthFromRange(first, last);
-            if (prefix_len >= 0) {
-                std::ostringstream oss;
-                oss << first.toText() << "/" << prefix_len;
-                range = oss.str();
-            }
-            pool_map->set("pool", Element::create(range));
-            // Set user-context
-            ConstElementPtr context = (*pool)->getContext();
-            if (!isNull(context)) {
-                pool_map->set("user-context", context);
-            }
-            // Set pool options
-            ConstCfgOptionPtr opts = (*pool)->getCfgOption();
-            pool_map->set("option-data", opts->toElement());
-            // Push on the pool list
-            pool_list->add(pool_map);
-        }
-        map->set("pools", pool_list);
-        // Set pd-pools
-        const PoolCollection& pdpools = (*subnet)->getPools(Lease::TYPE_PD);
-        ElementPtr pdpool_list = Element::createList();
-        for (PoolCollection::const_iterator pool = pdpools.cbegin();
-             pool != pdpools.cend(); ++pool) {
-            // Get it as a Pool6 (@todo move this code to pool.cc)
-            const Pool6* pdpool = dynamic_cast<Pool6*>(pool->get());
-            if (!pdpool) {
-                isc_throw(ToElementError, "invalid pd-pool pointer");
-            }
-            // Prepare the map for a pd-pool
-            ElementPtr pool_map = Element::createMap();
-            // Set prefix
-            const IOAddress& prefix = pdpool->getFirstAddress();
-            pool_map->set("prefix", Element::create(prefix.toText()));
-            // Set prefix-len (get it from min - max)
-            const IOAddress& last = pdpool->getLastAddress();
-            int prefix_len = prefixLengthFromRange(prefix, last);
-            if (prefix_len < 0) {
-                // The pool is bad: give up
-                isc_throw(ToElementError, "invalid prefix range "
-                          << prefix.toText() << "-" << last.toText());
-            }
-            pool_map->set("prefix-len", Element::create(prefix_len));
-            // Set delegated-len
-            uint8_t len = pdpool->getLength();
-            pool_map->set("delegated-len",
-                          Element::create(static_cast<int>(len)));
-            // Set excluded prefix
-            const Option6PDExcludePtr& xopt =
-                pdpool->getPrefixExcludeOption();
-            if (xopt) {
-                const IOAddress& xprefix =
-                    xopt->getExcludedPrefix(prefix, len);
-                pool_map->set("excluded-prefix",
-                              Element::create(xprefix.toText()));
-                uint8_t xlen = xopt->getExcludedPrefixLength();
-                pool_map->set("excluded-prefix-len",
-                              Element::create(static_cast<int>(xlen)));
-            } else {
-                pool_map->set("excluded-prefix",
-                              Element::create(std::string("::")));
-                pool_map->set("excluded-prefix-len", Element::create(0));
-            }
-            // Set user-context
-            ConstElementPtr context = pdpool->getContext();
-            if (!isNull(context)) {
-                pool_map->set("user-context", context);
-            }
-            // Set pool options
-            ConstCfgOptionPtr opts = pdpool->getCfgOption();
-            pool_map->set("option-data", opts->toElement());
-            // Push on the pool list
-            pdpool_list->add(pool_map);
-        }
-        map->set("pd-pools", pdpool_list);
-        // Set host reservation-mode
-        Subnet::HRMode hrmode = (*subnet)->getHostReservationMode();
-        std::string mode;
-        switch (hrmode) {
-        case Subnet::HR_DISABLED:
-            mode = "disabled";
-            break;
-        case Subnet::HR_OUT_OF_POOL:
-            mode = "out-of-pool";
-            break;
-        case Subnet::HR_ALL:
-            mode = "all";
-            break;
-        default:
-            isc_throw(ToElementError,
-                      "invalid host reservation mode: " << hrmode);
-        }
-        map->set("reservation-mode", Element::create(mode));
-        // Set client-class
-        const ClientClasses& cclasses = (*subnet)->getClientClasses();
-        if (cclasses.size() > 1) {
-            isc_throw(ToElementError, "client-class has too many items: "
-                      << cclasses.size());
-        } else if (!cclasses.empty()) {
-            map->set("client-class", Element::create(*cclasses.cbegin()));
-        }
-        // Set options
-        ConstCfgOptionPtr opts = (*subnet)->getCfgOption();
-        map->set("option-data", opts->toElement());
-        // Push on the list
-        result->add(map);
+        result->add((*subnet)->toElement());
     }
     }
     return (result);
     return (result);
 }
 }

+ 275 - 0
src/lib/dhcpsrv/subnet.cc

@@ -14,6 +14,7 @@
 #include <sstream>
 #include <sstream>
 
 
 using namespace isc::asiolink;
 using namespace isc::asiolink;
+using namespace isc::data;
 using namespace isc::dhcp;
 using namespace isc::dhcp;
 
 
 namespace {
 namespace {
@@ -472,5 +473,279 @@ void Subnet6::checkType(Lease::Type type) const {
     }
     }
 }
 }
 
 
+data::ElementPtr
+Subnet4::toElement() const {
+    // Prepare the map
+    ElementPtr map = Element::createMap();
+    // Set subnet id
+    SubnetID id = getID();
+    map->set("id", Element::create(static_cast<long long>(id)));
+    // Set relay info
+    const Subnet::RelayInfo& relay_info = getRelayInfo();
+    ElementPtr relay = Element::createMap();
+    relay->set("ip-address", Element::create(relay_info.addr_.toText()));
+    map->set("relay", relay);
+    // Set subnet
+    map->set("subnet", Element::create(toText()));
+    // Set interface
+    const std::string& iface = getIface();
+    map->set("interface", Element::create(iface));
+    // Set renew-timer
+    map->set("renew-timer",
+             Element::create(static_cast<long long>
+                                 (getT1().get())));
+    // Set rebind-timer
+    map->set("rebind-timer",
+             Element::create(static_cast<long long>
+                                 (getT2().get())));
+    // Set valid-lifetime
+    map->set("valid-lifetime",
+             Element::create(static_cast<long long>
+                                 (getValid().get())));
+    // Set pools
+    const PoolCollection& pools = getPools(Lease::TYPE_V4);
+    ElementPtr pool_list = Element::createList();
+    for (PoolCollection::const_iterator pool = pools.cbegin();
+         pool != pools.cend(); ++pool) {
+        // Prepare the map for a pool (@todo move this code to pool.cc)
+        ElementPtr pool_map = Element::createMap();
+        // Set pool
+        const IOAddress& first = (*pool)->getFirstAddress();
+        const IOAddress& last = (*pool)->getLastAddress();
+        std::string range = first.toText() + "-" + last.toText();
+        // Try to output a prefix (vs a range)
+        int prefix_len = prefixLengthFromRange(first, last);
+        if (prefix_len >= 0) {
+            std::ostringstream oss;
+            oss << first.toText() << "/" << prefix_len;
+            range = oss.str();
+        }
+        pool_map->set("pool", Element::create(range));
+        // Set user-context
+        ConstElementPtr context = (*pool)->getContext();
+        if (!isNull(context)) {
+            pool_map->set("user-context", context);
+        }
+        // Set pool options
+        ConstCfgOptionPtr opts = (*pool)->getCfgOption();
+        pool_map->set("option-data", opts->toElement());
+        // Push on the pool list
+        pool_list->add(pool_map);
+    }
+    map->set("pools", pool_list);
+    // Set host reservation-mode
+    Subnet::HRMode hrmode = getHostReservationMode();
+    std::string mode;
+    switch (hrmode) {
+    case Subnet::HR_DISABLED:
+        mode = "disabled";
+        break;
+    case Subnet::HR_OUT_OF_POOL:
+        mode = "out-of-pool";
+        break;
+    case Subnet::HR_ALL:
+        mode = "all";
+        break;
+    default:
+        isc_throw(ToElementError,
+                  "invalid host reservation mode: " << hrmode);
+    }
+    map->set("reservation-mode", Element::create(mode));
+    // Set match-client-id
+    map->set("match-client-id",
+             Element::create(getMatchClientId()));
+    // Set next-server
+    map->set("next-server",
+             Element::create(getSiaddr().toText()));
+    // Set DHCP4o6
+    const Cfg4o6& d4o6 = get4o6();
+    isc::data::merge(map, d4o6.toElement());
+    // Set client-class
+    const ClientClasses& cclasses = getClientClasses();
+    if (cclasses.size() > 1) {
+        isc_throw(ToElementError, "client-class has too many items: "
+                  << cclasses.size());
+    } else if (!cclasses.empty()) {
+        map->set("client-class", Element::create(*cclasses.cbegin()));
+    }
+    // Set options
+    ConstCfgOptionPtr opts = getCfgOption();
+    map->set("option-data", opts->toElement());
+    // Not supported: interface-id
+    // Not supported: rapid-commit
+
+    return (map);
+}
+
+data::ElementPtr
+Subnet6::toElement() const {
+    // Prepare the map
+    ElementPtr map = Element::createMap();
+    // Set subnet id
+    SubnetID id = getID();
+    map->set("id", Element::create(static_cast<long long>(id)));
+    // Set relay info
+    const Subnet::RelayInfo& relay_info = getRelayInfo();
+    ElementPtr relay = Element::createMap();
+    relay->set("ip-address", Element::create(relay_info.addr_.toText()));
+    map->set("relay", relay);
+    // Set subnet
+    map->set("subnet", Element::create(toText()));
+    // Set interface
+    const std::string& iface = getIface();
+    map->set("interface", Element::create(iface));
+    // Set interface-id
+    const OptionPtr& ifaceid = getInterfaceId();
+    if (ifaceid) {
+        std::vector<uint8_t> bin = ifaceid->getData();
+        std::string ifid;
+        ifid.resize(bin.size());
+        if (!bin.empty()) {
+            std::memcpy(&ifid[0], &bin[0], bin.size());
+        }
+        map->set("interface-id", Element::create(ifid));
+    } else {
+        map->set("interface-id", Element::create(std::string()));
+    }
+    // Set renew-timer
+    map->set("renew-timer",
+             Element::create(static_cast<long long>
+                             (getT1().get())));
+    // Set rebind-timer
+    map->set("rebind-timer",
+             Element::create(static_cast<long long>
+                             (getT2().get())));
+    // Set preferred-lifetime
+    map->set("preferred-lifetime",
+             Element::create(static_cast<long long>
+                             (getPreferred().get())));
+    // Set valid-lifetime
+    map->set("valid-lifetime",
+             Element::create(static_cast<long long>
+                             (getValid().get())));
+    // Set rapid-commit
+    bool rapid_commit = getRapidCommit();
+    map->set("rapid-commit", Element::create(rapid_commit));
+    // Set pools
+    const PoolCollection& pools = getPools(Lease::TYPE_NA);
+    ElementPtr pool_list = Element::createList();
+    for (PoolCollection::const_iterator pool = pools.cbegin();
+         pool != pools.cend(); ++pool) {
+        // Prepare the map for a pool (@todo move this code to pool.cc)
+        ElementPtr pool_map = Element::createMap();
+        // Set pool
+        const IOAddress& first = (*pool)->getFirstAddress();
+        const IOAddress& last = (*pool)->getLastAddress();
+        std::string range = first.toText() + "-" + last.toText();
+        // Try to output a prefix (vs a range)
+        int prefix_len = prefixLengthFromRange(first, last);
+        if (prefix_len >= 0) {
+            std::ostringstream oss;
+            oss << first.toText() << "/" << prefix_len;
+            range = oss.str();
+        }
+        pool_map->set("pool", Element::create(range));
+        // Set user-context
+        ConstElementPtr context = (*pool)->getContext();
+        if (!isNull(context)) {
+            pool_map->set("user-context", context);
+        }
+        // Set pool options
+        ConstCfgOptionPtr opts = (*pool)->getCfgOption();
+        pool_map->set("option-data", opts->toElement());
+        // Push on the pool list
+        pool_list->add(pool_map);
+    }
+    map->set("pools", pool_list);
+    // Set pd-pools
+    const PoolCollection& pdpools = getPools(Lease::TYPE_PD);
+    ElementPtr pdpool_list = Element::createList();
+    for (PoolCollection::const_iterator pool = pdpools.cbegin();
+         pool != pdpools.cend(); ++pool) {
+        // Get it as a Pool6 (@todo move this code to pool.cc)
+        const Pool6* pdpool = dynamic_cast<Pool6*>(pool->get());
+        if (!pdpool) {
+            isc_throw(ToElementError, "invalid pd-pool pointer");
+        }
+        // Prepare the map for a pd-pool
+        ElementPtr pool_map = Element::createMap();
+        // Set prefix
+        const IOAddress& prefix = pdpool->getFirstAddress();
+        pool_map->set("prefix", Element::create(prefix.toText()));
+        // Set prefix-len (get it from min - max)
+        const IOAddress& last = pdpool->getLastAddress();
+        int prefix_len = prefixLengthFromRange(prefix, last);
+        if (prefix_len < 0) {
+            // The pool is bad: give up
+            isc_throw(ToElementError, "invalid prefix range "
+                      << prefix.toText() << "-" << last.toText());
+        }
+        pool_map->set("prefix-len", Element::create(prefix_len));
+        // Set delegated-len
+        uint8_t len = pdpool->getLength();
+        pool_map->set("delegated-len",
+                      Element::create(static_cast<int>(len)));
+        // Set excluded prefix
+        const Option6PDExcludePtr& xopt =
+            pdpool->getPrefixExcludeOption();
+        if (xopt) {
+            const IOAddress& xprefix =
+                xopt->getExcludedPrefix(prefix, len);
+            pool_map->set("excluded-prefix",
+                          Element::create(xprefix.toText()));
+            uint8_t xlen = xopt->getExcludedPrefixLength();
+            pool_map->set("excluded-prefix-len",
+                          Element::create(static_cast<int>(xlen)));
+        } else {
+            pool_map->set("excluded-prefix",
+                          Element::create(std::string("::")));
+            pool_map->set("excluded-prefix-len", Element::create(0));
+        }
+        // Set user-context
+        ConstElementPtr context = pdpool->getContext();
+        if (!isNull(context)) {
+            pool_map->set("user-context", context);
+        }
+        // Set pool options
+        ConstCfgOptionPtr opts = pdpool->getCfgOption();
+        pool_map->set("option-data", opts->toElement());
+        // Push on the pool list
+        pdpool_list->add(pool_map);
+    }
+    map->set("pd-pools", pdpool_list);
+    // Set host reservation-mode
+    Subnet::HRMode hrmode = getHostReservationMode();
+    std::string mode;
+    switch (hrmode) {
+    case Subnet::HR_DISABLED:
+        mode = "disabled";
+        break;
+    case Subnet::HR_OUT_OF_POOL:
+        mode = "out-of-pool";
+        break;
+    case Subnet::HR_ALL:
+        mode = "all";
+        break;
+    default:
+        isc_throw(ToElementError,
+                  "invalid host reservation mode: " << hrmode);
+    }
+    map->set("reservation-mode", Element::create(mode));
+    // Set client-class
+    const ClientClasses& cclasses = getClientClasses();
+    if (cclasses.size() > 1) {
+        isc_throw(ToElementError, "client-class has too many items: "
+                  << cclasses.size());
+    } else if (!cclasses.empty()) {
+        map->set("client-class", Element::create(*cclasses.cbegin()));
+    }
+    // Set options
+    ConstCfgOptionPtr opts = getCfgOption();
+    map->set("option-data", opts->toElement());
+
+    return (map);
+}
+
+
 } // end of isc::dhcp namespace
 } // end of isc::dhcp namespace
 } // end of isc namespace
 } // end of isc namespace

+ 25 - 1
src/lib/dhcpsrv/subnet.h

@@ -8,6 +8,7 @@
 #define SUBNET_H
 #define SUBNET_H
 
 
 #include <asiolink/io_address.h>
 #include <asiolink/io_address.h>
+#include <cc/data.h>
 #include <dhcp/option.h>
 #include <dhcp/option.h>
 #include <dhcp/classify.h>
 #include <dhcp/classify.h>
 #include <dhcp/option_space_container.h>
 #include <dhcp/option_space_container.h>
@@ -280,7 +281,7 @@ public:
     /// returned it is valid.
     /// returned it is valid.
     ///
     ///
     /// @return const reference to the relay information
     /// @return const reference to the relay information
-    const isc::dhcp::Subnet::RelayInfo& getRelayInfo() {
+    const isc::dhcp::Subnet::RelayInfo& getRelayInfo() const {
         return (relay_);
         return (relay_);
     }
     }
 
 
@@ -429,6 +430,11 @@ protected:
     /// type.
     /// type.
     bool poolOverlaps(const Lease::Type& pool_type, const PoolPtr& pool) const;
     bool poolOverlaps(const Lease::Type& pool_type, const PoolPtr& pool) const;
 
 
+    /// @brief Unparse a subnet object.
+    ///
+    /// @return A pointer to unparsed subnet configuration.
+    virtual data::ElementPtr toElement() const = 0;
+
     /// @brief subnet-id
     /// @brief subnet-id
     ///
     ///
     /// Subnet-id is a unique value that can be used to find or identify
     /// Subnet-id is a unique value that can be used to find or identify
@@ -577,6 +583,19 @@ public:
         return (dhcp4o6_);
         return (dhcp4o6_);
     }
     }
 
 
+    /// @brief Returns const DHCP4o6 configuration parameters.
+    ///
+    /// This structure is always available. If the 4o6 is not enabled, its
+    /// enabled_ field will be set to false.
+    const Cfg4o6& get4o6() const {
+        return (dhcp4o6_);
+    }
+
+    /// @brief Unparse a subnet object.
+    ///
+    /// @return A pointer to unparsed subnet configuration.
+    virtual data::ElementPtr toElement() const;
+
 private:
 private:
 
 
     /// @brief Returns default address for pool selection
     /// @brief Returns default address for pool selection
@@ -676,6 +695,11 @@ public:
         return (rapid_commit_);
         return (rapid_commit_);
     }
     }
 
 
+    /// @brief Unparse a subnet object.
+    ///
+    /// @return A pointer to unparsed subnet configuration.
+    virtual data::ElementPtr toElement() const;
+
 private:
 private:
 
 
     /// @brief Returns default address for pool selection
     /// @brief Returns default address for pool selection