From a58621d8f1799360443be8b542561bc3684e98df Mon Sep 17 00:00:00 2001 From: Tomek Mrugalski Date: Fri, 31 Jan 2014 20:13:58 +0100 Subject: [PATCH] [3274] Relay info support added to DHCPv4 parsers. --- src/bin/dhcp4/config_parser.cc | 9 ++++- src/bin/dhcp4/dhcp4.spec | 14 +++++++- src/bin/dhcp4/tests/config_parser_unittest.cc | 33 +++++++++++++++++++ src/lib/dhcpsrv/dhcp_parsers.cc | 6 ++-- src/lib/dhcpsrv/dhcp_parsers.h | 10 +++++- 5 files changed, 67 insertions(+), 5 deletions(-) diff --git a/src/bin/dhcp4/config_parser.cc b/src/bin/dhcp4/config_parser.cc index 7774edcaa0..81223c7123 100644 --- a/src/bin/dhcp4/config_parser.cc +++ b/src/bin/dhcp4/config_parser.cc @@ -164,7 +164,7 @@ public: /// @param ignored first parameter /// stores global scope parameters, options, option defintions. Subnet4ConfigParser(const std::string&) - :SubnetConfigParser("", globalContext()) { + :SubnetConfigParser("", globalContext(), IOAddress("0.0.0.0")) { } /// @brief Adds the created subnet to a server's configuration. @@ -178,6 +178,11 @@ public: "Invalid cast in Subnet4ConfigParser::commit"); } + // Set relay information if it was parsed + if (relay_info_) { + sub4ptr->setRelay(*relay_info_); + } + isc::dhcp::CfgMgr::instance().addSubnet4(sub4ptr); } } @@ -204,6 +209,8 @@ protected: parser = new StringParser(config_id, string_values_); } else if (config_id.compare("pool") == 0) { parser = new Pool4Parser(config_id, pools_); + } else if (config_id.compare("relay") == 0) { + parser = new RelayInfoParser(config_id, relay_info_, IOAddress("0.0.0.0")); } else if (config_id.compare("option-data") == 0) { parser = new OptionDataListParser(config_id, options_, global_context_, diff --git a/src/bin/dhcp4/dhcp4.spec b/src/bin/dhcp4/dhcp4.spec index c6d2c32b80..4eddb7b2a8 100644 --- a/src/bin/dhcp4/dhcp4.spec +++ b/src/bin/dhcp4/dhcp4.spec @@ -249,7 +249,19 @@ "item_default": "" } }, - + { "item_name": "relay", + "item_type": "map", + "item_optional": false, + "item_default": {}, + "map_item_spec": [ + { + "item_name": "ip-address", + "item_type": "string", + "item_optional": false, + "item_default": "0.0.0.0" + } + ] + }, { "item_name": "option-data", "item_type": "list", "item_optional": false, diff --git a/src/bin/dhcp4/tests/config_parser_unittest.cc b/src/bin/dhcp4/tests/config_parser_unittest.cc index 1af66c5d83..63291ba7fc 100644 --- a/src/bin/dhcp4/tests/config_parser_unittest.cc +++ b/src/bin/dhcp4/tests/config_parser_unittest.cc @@ -2800,4 +2800,37 @@ TEST_F(Dhcp4ParserTest, invalidD2ClientConfig) { ASSERT_FALSE(CfgMgr::instance().ddnsEnabled()); } +// This test checks if it is possible to specify relay information +TEST_F(Dhcp4ParserTest, subnetRelayInfo) { + + ConstElementPtr status; + + // A config with relay information. + string config = "{ \"interfaces\": [ \"*\" ]," + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"subnet4\": [ { " + " \"pool\": [ \"192.0.2.1 - 192.0.2.100\" ]," + " \"renew-timer\": 1, " + " \"rebind-timer\": 2, " + " \"valid-lifetime\": 4," + " \"relay\": { " + " \"ip-address\": \"192.0.2.123\"" + " }," + " \"subnet\": \"192.0.2.0/24\" } ]," + "\"valid-lifetime\": 4000 }"; + + ElementPtr json = Element::fromJSON(config); + + EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json)); + + // returned value should be 0 (configuration success) + checkResult(status, 0); + + Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200")); + ASSERT_TRUE(subnet); + EXPECT_EQ("192.0.2.123", subnet->relay_.addr_.toText()); +} + + } diff --git a/src/lib/dhcpsrv/dhcp_parsers.cc b/src/lib/dhcpsrv/dhcp_parsers.cc index 394935bd3a..3eefd15152 100644 --- a/src/lib/dhcpsrv/dhcp_parsers.cc +++ b/src/lib/dhcpsrv/dhcp_parsers.cc @@ -941,10 +941,12 @@ PoolParser::commit() { //****************************** SubnetConfigParser ************************* SubnetConfigParser::SubnetConfigParser(const std::string&, - ParserContextPtr global_context) + ParserContextPtr global_context, + const isc::asiolink::IOAddress& default_addr) : uint32_values_(new Uint32Storage()), string_values_(new StringStorage()), pools_(new PoolStorage()), options_(new OptionStorage()), - global_context_(global_context) { + global_context_(global_context), + relay_info_(new isc::dhcp::Subnet::RelayInfo(default_addr)) { // The first parameter should always be "subnet", but we don't check // against that here in case some wants to reuse this parser somewhere. if (!global_context_) { diff --git a/src/lib/dhcpsrv/dhcp_parsers.h b/src/lib/dhcpsrv/dhcp_parsers.h index 827e33d7d0..32abc9afc3 100644 --- a/src/lib/dhcpsrv/dhcp_parsers.h +++ b/src/lib/dhcpsrv/dhcp_parsers.h @@ -802,7 +802,12 @@ class SubnetConfigParser : public DhcpConfigParser { public: /// @brief constructor - SubnetConfigParser(const std::string&, ParserContextPtr global_context); + /// + /// @param unusued + /// @param global_context + /// @param default_addr default IP address (0.0.0.0 for IPv4, :: for IPv6) + SubnetConfigParser(const std::string&, ParserContextPtr global_context, + const isc::asiolink::IOAddress& default_addr); /// @brief parses parameter value /// @@ -915,6 +920,9 @@ protected: /// Parsing context which contains global values, options and option /// definitions. ParserContextPtr global_context_; + + /// Pointer to relay information + isc::dhcp::Subnet::RelayInfoPtr relay_info_; }; /// @brief Parser for D2ClientConfig