summaryrefslogtreecommitdiffstats
path: root/src/lib/dhcpsrv/parsers/ifaces_config_parser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dhcpsrv/parsers/ifaces_config_parser.cc')
-rw-r--r--src/lib/dhcpsrv/parsers/ifaces_config_parser.cc131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/lib/dhcpsrv/parsers/ifaces_config_parser.cc b/src/lib/dhcpsrv/parsers/ifaces_config_parser.cc
new file mode 100644
index 0000000..adc821f
--- /dev/null
+++ b/src/lib/dhcpsrv/parsers/ifaces_config_parser.cc
@@ -0,0 +1,131 @@
+// Copyright (C) 2015-2022 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <config.h>
+#include <cc/data.h>
+#include <dhcpsrv/cfgmgr.h>
+#include <dhcpsrv/dhcpsrv_log.h>
+#include <dhcpsrv/parsers/ifaces_config_parser.h>
+#include <boost/foreach.hpp>
+#include <string>
+#include <sys/types.h>
+
+using namespace isc::data;
+
+namespace isc {
+namespace dhcp {
+
+void
+IfacesConfigParser::parseInterfacesList(const CfgIfacePtr& cfg_iface,
+ ConstElementPtr ifaces_list) {
+ BOOST_FOREACH(ConstElementPtr iface, ifaces_list->listValue()) {
+ std::string iface_name = iface->stringValue();
+ try {
+ cfg_iface->use(protocol_, iface_name);
+
+ } catch (const std::exception& ex) {
+ isc_throw(DhcpConfigError, "Failed to select interface: "
+ << ex.what() << " (" << iface->getPosition() << ")");
+ }
+ }
+}
+
+IfacesConfigParser::IfacesConfigParser(const uint16_t protocol, bool test_mode)
+ : protocol_(protocol), test_mode_(test_mode) {
+}
+
+void
+IfacesConfigParser::parse(const CfgIfacePtr& cfg,
+ const isc::data::ConstElementPtr& ifaces_config) {
+
+ // Check for re-detect before calling parseInterfacesList()
+ bool re_detect = getBoolean(ifaces_config, "re-detect");
+ cfg->setReDetect(re_detect);
+ if (re_detect && !test_mode_) {
+ IfaceMgr::instance().clearIfaces();
+ IfaceMgr::instance().detectIfaces();
+ }
+
+ bool socket_type_specified = false;
+ BOOST_FOREACH(ConfigPair element, ifaces_config->mapValue()) {
+ try {
+ if (element.first == "re-detect") {
+ continue;
+ }
+
+ if (element.first == "interfaces") {
+ parseInterfacesList(cfg, element.second);
+ continue;
+
+ }
+
+ if (element.first == "dhcp-socket-type") {
+ if (protocol_ == AF_INET) {
+ cfg->useSocketType(AF_INET, element.second->stringValue());
+ socket_type_specified = true;
+ continue;
+ } else {
+ isc_throw(DhcpConfigError,
+ "dhcp-socket-type is not supported in DHCPv6");
+ }
+ }
+
+ if (element.first == "outbound-interface") {
+ if (protocol_ == AF_INET) {
+ CfgIface::OutboundIface type =
+ CfgIface::textToOutboundIface(element.second->stringValue());
+ cfg->setOutboundIface(type);
+ continue;
+ } else {
+ isc_throw(DhcpConfigError,
+ "outbound-interface is not supported in DHCPv6");
+ }
+ }
+
+ if (element.first == "service-sockets-require-all") {
+ cfg->setServiceSocketsRequireAll(element.second->boolValue());
+ continue;
+ }
+
+ if (element.first == "service-sockets-retry-wait-time") {
+ cfg->setServiceSocketsRetryWaitTime(static_cast<uint32_t>(element.second->intValue()));
+ continue;
+ }
+
+ if (element.first == "service-sockets-max-retries") {
+ cfg->setServiceSocketsMaxRetries(static_cast<uint32_t>(element.second->intValue()));
+ continue;
+ }
+
+ if (element.first == "user-context") {
+ cfg->setContext(element.second);
+ continue;
+ }
+
+ // This should never happen as the input produced by the parser
+ // see (src/bin/dhcpX/dhcpX_parser.yy) should not produce any
+ // other parameter, so this case is only to catch bugs in
+ // the parser.
+ isc_throw(DhcpConfigError, "unsupported parameter '"
+ << element.first << "'");
+ } catch (const std::exception& ex) {
+ // Append line number where the error occurred.
+ isc_throw(DhcpConfigError, ex.what() << " ("
+ << element.second->getPosition() << ")");
+ }
+ }
+
+ // User hasn't specified the socket type. Log that we are using
+ // the default type. Log it only if this is DHCPv4. (DHCPv6 does not use
+ // raw sockets).
+ if (!socket_type_specified && (protocol_ == AF_INET) ) {
+ LOG_INFO(dhcpsrv_logger, DHCPSRV_CFGMGR_SOCKET_TYPE_DEFAULT)
+ .arg(cfg->socketTypeToText());
+ }
+}
+
+} // end of namespace isc::dhcp
+} // end of namespace isc