From: Marcin Siodelski Date: Thu, 7 Sep 2017 16:08:35 +0000 (+0200) Subject: [master] Merge branch 'trac5305' X-Git-Tag: trac5073a_base~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=76dd46f7070c141cc89d772d69a897b67bd179a1;p=thirdparty%2Fkea.git [master] Merge branch 'trac5305' # Conflicts: # src/lib/dhcpsrv/parsers/dhcp_parsers.cc # src/lib/dhcpsrv/subnet.cc # src/lib/dhcpsrv/subnet.h --- 76dd46f7070c141cc89d772d69a897b67bd179a1 diff --cc src/lib/dhcpsrv/parsers/dhcp_parsers.cc index 5cfb34cab0,8e6d88c49f..cfb1dc78c3 --- a/src/lib/dhcpsrv/parsers/dhcp_parsers.cc +++ b/src/lib/dhcpsrv/parsers/dhcp_parsers.cc @@@ -585,57 -585,6 +585,16 @@@ SubnetConfigParser::createSubnet(ConstE ex.what() << " (" << params->getPosition() << ")"); } } - - // Now configure parameters that are common for v4 and v6: - - // Get interface name. If it is defined, then the subnet is available - // directly over specified network interface. - std::string iface = getString(params, "interface"); - if (!iface.empty()) { - if (!IfaceMgr::instance().getIface(iface)) { - ConstElementPtr error = params->get("interface"); - isc_throw(DhcpConfigError, "Specified network interface name " << iface - << " for subnet " << subnet_->toText() - << " is not present in the system (" - << error->getPosition() << ")"); - } - - subnet_->setIface(iface); - } - - // Let's set host reservation mode. If not specified, the default value of - // all will be used. - try { - std::string hr_mode = getString(params, "reservation-mode"); - subnet_->setHostReservationMode(hrModeFromText(hr_mode)); - } catch (const BadValue& ex) { - isc_throw(DhcpConfigError, "Failed to process specified value " - " of reservation-mode parameter: " << ex.what() - << "(" << getPosition("reservation-mode", params) << ")"); - } - - // Try setting up client class. - string client_class = getString(params, "client-class"); - if (!client_class.empty()) { - subnet_->allowClientClass(client_class); - } - + // If there's user-context specified, store it. + ConstElementPtr user_context = params->get("user-context"); + if (user_context) { + if (user_context->getType() != Element::map) { + isc_throw(isc::dhcp::DhcpConfigError, "User context has to be a map (" + << user_context->getPosition() << ")"); + } + subnet_->setContext(user_context); + } + - // Here globally defined options were merged to the subnet specific - // options but this is no longer the case (they have a different - // and not consecutive priority). - - // Copy options to the subnet configuration. - options_->copyTo(*subnet_->getCfgOption()); } //****************************** Subnet4ConfigParser ************************* diff --cc src/lib/dhcpsrv/subnet.cc index 76cb0789ac,4317277a45..f48e42b468 --- a/src/lib/dhcpsrv/subnet.cc +++ b/src/lib/dhcpsrv/subnet.cc @@@ -485,69 -450,6 +450,12 @@@ Subnet::toElement() const // Set subnet map->set("subnet", Element::create(toText())); - // Set interface - const std::string& iface = getIface(); - if (!iface.empty()) { - map->set("interface", Element::create(iface)); - } - - // Set renew-timer - map->set("renew-timer", - Element::create(static_cast - (getT1().get()))); - // Set rebind-timer - map->set("rebind-timer", - Element::create(static_cast - (getT2().get()))); - // Set valid-lifetime - map->set("valid-lifetime", - Element::create(static_cast - (getValid().get()))); - - // Set 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()); - + // Add user-context, but only if defined. Omit if it was not. + ConstElementPtr ctx = getContext(); + if (ctx) { + map->set("user-context", ctx); + } + return (map); } diff --cc src/lib/dhcpsrv/subnet.h index 0647db833f,e086d95ae6..3f81e43c59 --- a/src/lib/dhcpsrv/subnet.h +++ b/src/lib/dhcpsrv/subnet.h @@@ -258,108 -184,41 +184,54 @@@ public static_id_ = 1; } - /// @brief Sets information about relay - /// - /// In some situations where there are shared subnets (i.e. two different - /// subnets are available on the same physical link), there is only one - /// relay that handles incoming requests from clients. In such a case, - /// the usual subnet selection criteria based on relay belonging to the - /// subnet being selected are no longer sufficient and we need to explicitly - /// specify a relay. One notable example of such uncommon, but valid - /// scenario is a cable network, where there is only one CMTS (one relay), - /// but there are 2 distinct subnets behind it: one for cable modems - /// and another one for CPEs and other user equipment behind modems. - /// From manageability perspective, it is essential that modems get addresses - /// from different subnet, so users won't tinker with their modems. + /// @brief Retrieves pointer to a shared network associated with a subnet. /// - /// Setting this parameter is not needed in most deployments. - /// This structure holds IP address only for now, but it is expected to - /// be extended in the future. + /// By implementing it as a template function we overcome a need to + /// include shared_network.h header file to specify return type explicitly. + /// The header can't be included because it would cause circular dependency + /// between subnet.h and shared_network.h. /// - /// @param relay structure that contains relay information - void setRelayInfo(const isc::dhcp::Subnet::RelayInfo& relay); - - - /// @brief Returns const reference to relay information + /// This method uses an argument to hold a return value to allow the compiler + /// to infer the return type without a need to call this function with an + /// explicit return type as template argument. /// - /// @note The returned reference is only valid as long as the object - /// returned it is valid. + /// @param [out] shared_network Pointer to the shared network where returned + /// value should be assigned. /// - /// @return const reference to the relay information - const isc::dhcp::Subnet::RelayInfo& getRelayInfo() const { - return (relay_); + /// @tparam Type of the shared network, i.e. @ref SharedNetwork4 or a + /// @ref SharedNetwork6. + template + void getSharedNetwork(SharedNetworkPtrType& shared_network) const { + shared_network = boost::dynamic_pointer_cast< + typename SharedNetworkPtrType::element_type>(shared_network_.lock()); } - /// @brief checks whether this subnet supports client that belongs to - /// specified classes. - /// - /// This method checks whether a client that belongs to given classes can - /// use this subnet. For example, if this class is reserved for client - /// class "foo" and the client belongs to classes "foo", "bar" and "baz", - /// it is supported. On the other hand, client belonging to classes - /// "foobar" and "zyxxy" is not supported. - /// - /// @todo: Currently the logic is simple: client is supported if it belongs - /// to any class mentioned in white_list_. We will eventually need a - /// way to specify more fancy logic (e.g. to meet all classes, not just - /// any) - /// - /// @param client_classes list of all classes the client belongs to - /// @return true if client can be supported, false otherwise - bool - clientSupported(const isc::dhcp::ClientClasses& client_classes) const; - - /// @brief adds class class_name to the list of supported classes - /// - /// Also see explanation note in @ref white_list_. - /// - /// @param class_name client class to be supported by this subnet - void - allowClientClass(const isc::dhcp::ClientClass& class_name); - - /// @brief returns the client class white list - /// - /// @note The returned reference is only valid as long as the object - /// returned it is valid. - /// - /// @return client classes @ref white_list_ - const isc::dhcp::ClientClasses& getClientClasses() const { - return (white_list_); - } + private: - /// @brief Specifies what type of Host Reservations are supported. + /// @brief Assigns shared network to a subnet. /// - /// Host reservations may be either in-pool (they reserve an address that - /// is in the dynamic pool) or out-of-pool (they reserve an address that is - /// not in the dynamic pool). HR may also be completely disabled for - /// performance reasons. + /// This method replaces any shared network associated with a subnet with + /// a new shared network. /// - /// @return whether in-pool host reservations are allowed. - HRMode - getHostReservationMode() const { - return (host_reservation_mode_); + /// @param shared_network Pointer to a new shared network to be associated + /// with the subnet. + void setSharedNetwork(const NetworkPtr& shared_network) { + shared_network_ = shared_network; } - /// @brief Sets host reservation mode. - /// - /// See @ref getHostReservationMode for details. - /// - /// @param mode mode to be set - void setHostReservationMode(HRMode mode) { - host_reservation_mode_ = mode; - } ++public: + + /// @brief Sets user context. + /// @param ctx user context to be stored. + void setContext(const data::ConstElementPtr& ctx) { + user_context_ = ctx; + } + + /// @brief Returns const pointer to the user context. + data::ConstElementPtr getContext() const { + return (user_context_); + } + protected: /// @brief Returns all pools (non-const variant) /// @@@ -505,37 -347,8 +360,11 @@@ /// @brief Name of the network interface (if connected directly) std::string iface_; - /// @brief Relay information - /// - /// See @ref RelayInfo for detailed description. This structure is public, - /// so its fields are easily accessible. Making it protected would bring in - /// the issue of returning references that may become stale after its parent - /// subnet object disappears. - RelayInfo relay_; - - /// @brief optional definition of a client class - /// - /// If defined, only clients belonging to that class will be allowed to use - /// this particular subnet. The default value for this is an empty list, - /// which means that any client is allowed, regardless of its class. - /// - /// @todo This is just a single list of allowed classes. We'll also need - /// to add a black-list (only classes on the list are rejected, the rest - /// are allowed). Implementing this will require more fancy parser logic, - /// so it may be a while until we support this. - ClientClasses white_list_; - - /// @brief Specifies host reservation mode - /// - /// See @ref HRMode type for details. - HRMode host_reservation_mode_; + /// @brief Pointer to a shared network that subnet belongs to. + WeakNetworkPtr shared_network_; + + /// @brief Pointer to the user context (may be NULL) + data::ConstElementPtr user_context_; - private: - - /// @brief Pointer to the option data configuration for this subnet. - CfgOptionPtr cfg_option_; }; /// @brief A generic pointer to either Subnet4 or Subnet6 object